r-wasm / webr

The statistical language R compiled to WebAssembly via Emscripten, for use in web browsers and Node.
https://docs.r-wasm.org/webr/latest/
Other
839 stars 65 forks source link

Access to the local file system #469

Open gregvolny opened 1 month ago

gregvolny commented 1 month ago

Since my last post, a lot of progress has been done with WebR. And, I'm coming back with a new request... a) Can we use this new API : https://developer.chrome.com/blog/persistent-permissions-for-the-file-system-access-api for accessing/using and saving files ( for example, downloaded packages) to and from the local file system?

In the meantime, do you have a workaround for accessing to a sqlite database stored in the local file system without any api call? I tried to upload it to a new directory created in the virtual file system and use

library(DBI)
setwd(file.path("/", "Sqlite","inv_Agr.db3"))
con <- dbConnect(RSQLite::SQLite(),"inv_Agr.db3")

without any success... it display _Error in setwd(file.path("/", "Sqlite", "invAgr.db3")) : cannot change working directory

georgestagg commented 2 weeks ago

Can we use this new API [...] for accessing/using and saving files ( for example, downloaded packages) to and from the local file system?

No, not currently. There are deep technical reasons that makes using these kinds of browser APIs difficult in webR. We're tracking this in https://github.com/r-wasm/webr/issues/56


In the meantime, do you have a workaround for accessing to a sqlite database stored in the local file system without any api call? I tried to upload it to a new directory created in the virtual file system and use [...]

Can you please tell me more about your setup? Are you running webR from the REPL at https://webr.r-wasm.org/latest/, or in your own webR application? How are you uploading the sqlite database to the virtual filesystem? Are you using the webR JavaScript API? Can you create a small self-contained example of your use case for me to experiment with?


If you are using your own application there is a possibility for persistent storage, but it requires that webR is loaded using the PostMessage communication channel. When webR is loaded using that channel, you can use the IDBFS filesystem type to mount a directory that will be persisted in the user's web browser:

dir.create("/data")
webr::mount(mountpoint = "/data", type = "IDBFS")
webr::syncfs(TRUE)

Write to the directory by writing to /data and then persisting the data using webr::syncfs(FALSE):

write.csv(mtcars, "/data/mtcars.csv")
webr::syncfs(FALSE)

Then, when the mountpoint is mounted in the future (say, after the page has been refreshed), the data will be available again after running webr::syncfs(TRUE) and the underlying JavaScript promise has resolved.

There are some subtleties here, since the underlying mechanism is asynchronous. Some more documentation is available at: https://docs.r-wasm.org/webr/latest/mounting.html#indexeddb-filesystem-storage