Skip to content

Commit

Permalink
Add webr::syncfs()
Browse files Browse the repository at this point in the history
  • Loading branch information
georgestagg committed Jun 19, 2024
1 parent 38f0f4a commit 367ca0e
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 6 deletions.
1 change: 1 addition & 0 deletions packages/webr/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export(mount)
export(pager_install)
export(require_shim)
export(shim_install)
export(syncfs)
export(test_package)
export(unmount)
useDynLib(webr, .registration = TRUE)
2 changes: 2 additions & 0 deletions packages/webr/R/library.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
#' `show_menu` argument. By default, if no global option is set and no argument
#' is provided, the menu will not be shown.
#'
#' @param pkg Character vector of package names
#' @param show_menu Show a menu asking the user if they would like to install
#' the package if it is missing. Defaults to `getOption("webr.show_menu")`.
#' @param ... Other arguments to be passed to `library` and `require`.
#'
#' @export
library_shim <- function(pkg, ..., show_menu = getOption("webr.show_menu")) {
Expand Down
23 changes: 20 additions & 3 deletions packages/webr/R/mount.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
#' under Node.
#'
#' When mounting an Emscripten "idbfs" type filesystem, files will be persisted
#' or populated from/to a browser-based IndexedDB database when the JavaScript
#' function `Module.FS.syncfs` is invoked. See the Emscripten `IDBFS`
#' to or populated from a browser-based IndexedDB database whenever the
#' JavaScript function `Module.FS.syncfs` is invoked. See the Emscripten `IDBFS`
#' documentation for more information. This filesystem type can only be used
#' when webR is running in a web browser.
#' when webR is running in a web browser and using the `PostMessage`
#' communication channel.
#'
#' @param mountpoint a character string giving the path to a directory to mount
#' onto in the Emscripten virtual filesystem.
Expand Down Expand Up @@ -52,3 +53,19 @@ mount <- function(mountpoint, source, type = "workerfs") {
unmount <- function(mountpoint) {
invisible(.Call(ffi_unmount, mountpoint))
}

#' Synchronise the Emscripten virtual filesystem
#'
#' @description
#' Uses the Emscripten filesystem API to synchronise all mounted virtual
#' filesystems with their backing storage, where it exists. The `populate`
#' argument controls the direction of the synchronisation between Emscripten's
#' internal data and the file system's persistent store.
#'
#' @param populate A boolean. When `true`, initialises the filesystem with data
#' from persistent storage. When `false`, writes current filesystem data to
#' the persistent storage.
#' @export
syncfs <- function(populate) {
invisible(.Call(ffi_syncfs, populate))
}
4 changes: 4 additions & 0 deletions packages/webr/man/library_shim.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions packages/webr/man/mount.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions packages/webr/man/syncfs.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/webr/src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern SEXP ffi_dev_canvas_destroy(SEXP);
extern SEXP ffi_mount_workerfs(SEXP, SEXP);
extern SEXP ffi_mount_nodefs(SEXP, SEXP);
extern SEXP ffi_mount_idbfs(SEXP);
extern SEXP ffi_syncfs(SEXP);
extern SEXP ffi_unmount(SEXP);

static
Expand All @@ -25,6 +26,7 @@ const R_CallMethodDef CallEntries[] = {
{ "ffi_mount_workerfs", (DL_FUNC) &ffi_mount_workerfs, 2},
{ "ffi_mount_nodefs", (DL_FUNC) &ffi_mount_nodefs, 2},
{ "ffi_mount_idbfs", (DL_FUNC) &ffi_mount_idbfs, 1},
{ "ffi_syncfs", (DL_FUNC) &ffi_syncfs, 1},
{ "ffi_unmount", (DL_FUNC) &ffi_unmount, 1},
{ NULL, NULL, 0}
};
Expand Down
18 changes: 18 additions & 0 deletions packages/webr/src/mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
Rf_error("`" #arg "` can't be `NA`."); \
}

#define CHECK_LOGICAL(arg) \
if (!Rf_isLogical(arg) || LENGTH(arg) != 1) { \
Rf_error("`" #arg "` must be a logical."); \
} \
if (LOGICAL(arg)[0] == NA_LOGICAL){ \
Rf_error("`" #arg "` can't be `NA`."); \
}

SEXP ffi_mount_workerfs(SEXP source, SEXP mountpoint) {
#ifdef __EMSCRIPTEN__
CHECK_STRING(source);
Expand Down Expand Up @@ -105,6 +113,16 @@ SEXP ffi_mount_idbfs(SEXP mountpoint) {
#endif
}

SEXP ffi_syncfs(SEXP populate) {
#ifdef __EMSCRIPTEN__
CHECK_LOGICAL(populate);
EM_ASM({ Module.FS.syncfs($0, () => {}) }, LOGICAL(populate)[0]);
return R_NilValue;
#else
Rf_error("Function must be running under Emscripten.");
#endif
}

SEXP ffi_unmount(SEXP mountpoint) {
#ifdef __EMSCRIPTEN__
CHECK_STRING(mountpoint);
Expand Down

0 comments on commit 367ca0e

Please sign in to comment.