You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: NEWS.md
+2
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,8 @@
6
6
7
7
* The capturing mechanism of `captureR()` has been updated so that memory reallocation is performed when outputting very long lines. If reallocation is not possible (e.g. the environment does not have enough free memory to hold the entire line), the previous behaviour of truncating the line output is maintained (#434).
8
8
9
+
* Enabled the Emscripten IDBFS virtual filesystem driver. This filesystem type can be used to persist data in web browser storage across page reloads. This filesystem type must be used with the `PostMessage` communication channel (#56, #442).
10
+
9
11
## Breaking changes
10
12
11
13
* The `ServiceWorker` communication channel has been deprecated. Users should use the `SharedArrayBuffer` channel where cross-origin isolation is possible, or otherwise use the `PostMessage` channel. For the moment the `ServiceWorker` channel can still be used, but emits a warning at start up. The channel will be removed entirely in a future version of webR.
Copy file name to clipboardexpand all lines: src/docs/mounting.qmd
+79-4
Original file line number
Diff line number
Diff line change
@@ -10,15 +10,21 @@ The [Emscripten filesystem API](https://emscripten.org/docs/api_reference/Filesy
10
10
11
11
Mounting images and directories in this way gives the Wasm R process access to arbitrary external data, potentially including datasets, scripts, or R packages [pre-compiled for WebAssembly](building.qmd).
12
12
13
-
Emscripten's API provides several types of virtual filesystem, but for technical reasons^[Currently, webR blocks in the JavaScript worker thread while it waits for R input to be evaluated. This blocking means that Emscripten filesystems that depend on asynchronous browser APIs, such as [`IDBFS`](https://emscripten.org/docs/api_reference/Filesystem-API.html#filesystem-api-idbfs), do not work.] only the following filesystems are available for use with webR.
13
+
Emscripten's API allows for several types of virtual filesystem, depending on the execution environment. The following filesystems are available for use with webR:
14
14
15
15
| Filesystem | Description | Web Browser | Node.js |
16
16
|------|-----|------|------|
17
-
|`WORKERFS`| Mount filesystem images. |✅|✅|
17
+
|`WORKERFS`| Mount Emscripten filesystem images. |✅|✅[^workerfs]|
18
18
|`NODEFS`| Mount existing host directories. |❌|✅|
19
+
|`IDBFS`| Browser-based persistent storage using the [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). |✅[^idbfs]|❌|
20
+
21
+
[^workerfs]: Be aware of the current GitHub issue [#328](https://github.com/r-wasm/webr/issues/328).
22
+
[^idbfs]: Using the `PostMessage`[communication channel](communication.qmd) only.
19
23
20
24
## Emscripten filesystem images
21
25
26
+
Emscripten filesystem images can be mounted using the `WORKERFS` filesystem type.
27
+
22
28
The [`file_packager`](https://emscripten.org/docs/porting/files/packaging_files.html#packaging-using-the-file-packager-tool) tool, provided by Emscripten, takes in a directory structure as input and produces webR compatible filesystem images as output. The [`file_packager`](https://emscripten.org/docs/porting/files/packaging_files.html#packaging-using-the-file-packager-tool) tool may be invoked from R using the [rwasm](https://r-wasm.github.io/rwasm/) R package:
23
29
24
30
```{r eval=FALSE}
@@ -105,12 +111,12 @@ See the [Emscripten `FS.mount()` documentation](https://emscripten.org/docs/api_
105
111
106
112
## Mount an existing host directory
107
113
114
+
The `NODEFS` filesystem type maps directories that exist on the host machine so that they are accessible in the WebAssembly process.
115
+
108
116
::: callout-warning
109
117
`NODEFS` is only available when running webR under Node.js.
110
118
:::
111
119
112
-
The `NODEFS` filesystem type maps directories that exist on the host machine so that they are accessible in the WebAssembly process.
113
-
114
120
To mount the directory `./extra` on the virtual filesystem at `/data`, use either the JavaScript or R mount API with the filesystem type set to `"NODEFS"`.
115
121
116
122
::: {.panel-tabset}
@@ -130,6 +136,75 @@ webr::mount(
130
136
)
131
137
```
132
138
139
+
:::
140
+
141
+
## IndexedDB Filesystem Storage
142
+
143
+
When using webR in a web browser, an [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)-based persistent storage space can be mounted using the `IDBFS` filesystem type.
144
+
145
+
::: {.callout-warning}
146
+
147
+
Due to the way webR blocks for input in the worker thread, the `IDBFS` filesystem type **does not work** when using the `SharedArrayBuffer` communication channel. WebR must be configured to use the `PostMessage` communication channel to use `IDBFS` persistent storage.
148
+
149
+
:::
150
+
151
+
### Mounting
152
+
153
+
First, create a directory to contain the IndexedDB filesystem, then use either the JavaScript or R mount API with type `"IDBFS"`.
154
+
155
+
::: {.panel-tabset}
156
+
## JavaScript
157
+
158
+
```javascript
159
+
awaitwebR.FS.mkdir('/data');
160
+
awaitwebR.FS.mount('IDBFS', {}, '/data');
161
+
awaitwebR.FS.syncfs(true);
162
+
```
163
+
164
+
## R
165
+
```{r eval=FALSE}
166
+
dir.create("/data")
167
+
webr::mount(mountpoint = "/data", type = "IDBFS")
168
+
webr::syncfs(TRUE)
169
+
```
133
170
134
171
:::
135
172
173
+
After mounting the filesystem using [`mount()`](api/r.html#mount), the [`syncfs()`](api/r.html#syncfs) function should been invoked with its `populate` argument set to `true`. This extra step is **required** to initialise the virtual filesystem with any previously existing data files in the browser's IndexedDB storage. Without it, the filesystem will always be initially mounted as an empty directory.
174
+
175
+
For more information, see the Emscripten FS API [`IDBFS` and `FS.syncfs()`](https://emscripten.org/docs/api_reference/Filesystem-API.html#filesystem-api-idbfs) documentation.
176
+
177
+
### Persisting the filesystem to IndexedDB
178
+
179
+
The `syncfs()` function should be invoked with its `populate` argument set to `false` to persist the current state of the filesystem to the browser's IndexedDB storage.
180
+
181
+
::: {.panel-tabset}
182
+
## JavaScript
183
+
184
+
```javascript
185
+
awaitwebR.FS.syncfs(false);
186
+
```
187
+
188
+
## R
189
+
```{r eval=FALSE}
190
+
webr::syncfs(FALSE)
191
+
```
192
+
193
+
:::
194
+
195
+
After writing to the virtual filesystem you should be sure to invoke `syncfs(false)` before the web page containing webR is closed to ensure that the filesystem data is flushed and written to the IndexedDB-based persistent storage.
196
+
197
+
::: {.callout-warning}
198
+
199
+
Operations performed using IndexedDB are done asynchronously. If you are mounting `IDBFS` filesystems and accessing data non-interactively you should use the JavaScript API and be sure to wait for the `Promise` returned by `webR.FS.syncfs(false)` to resolve before continuing, for example by using the `await` keyword.
200
+
201
+
In a future version of webR the `webr::syncfs()` function will similarly return a Promise-like object.
202
+
:::
203
+
204
+
### Web storage caveats
205
+
206
+
Filesystem data stored in an IndexedDB database can only be accessed within the current [origin](https://developer.mozilla.org/en-US/docs/Glossary/Origin), loosely defined as the current web page's host domain and port.
207
+
208
+
The way in which web browsers decide how much storage space to allocate for data and what to remove when limits are reached differs between browsers and is not always simple to calculate. Be aware of browser [storage quotas and eviction criteria](https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria) and note that data stored in an `IDBFS` filesystem type is stored only on a "best-effort" basis. It can be removed by the browser at any time, autonomously or by the user interacting through the browser's UI.
209
+
210
+
In private browsing mode, for example, stored data is usually deleted when the private session ends.
0 commit comments