sandboxedjs 0.1.34 → 0.1.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,6 +46,7 @@ Node 18.17+. Everything is pure JavaScript and WebAssembly — no compilation st
46
46
  | **Coreutils** | 154 programs — `ls cat cp mv rm mkdir grep sed awk find head tail sort uniq wc cut tr tee xargs chmod chown ln du df ps tar gzip base64 sha256sum diff curl wget` and the rest — plus 54 shell builtins |
47
47
  | **Node.js** | Its own module engine — `require` *and* `import`, live bindings, `exports` maps, top-level `await`, npm packages, `http`, `fs`, streams, `child_process` |
48
48
  | **Python** | CPython 3.13 (Pyodide) on the *same* filesystem, with the real standard library |
49
+ | **WebAssembly** | A WASI (`preview1`) host — run any `wasm32-wasi` binary from clang, Rust, Zig or TinyGo as an ordinary process, on the same filesystem |
49
50
  | **FFmpeg** | `ffmpeg` and `ffprobe` (FFmpeg 5.1) reading and writing container files directly — [optional install](#video-and-audio) |
50
51
  | **`/proc`** | Live and synthesised — `ps`, `top`, `free` and `uptime` all read the same source |
51
52
  | **Networking** | Virtual interfaces, `/etc/hosts` resolution, in-container HTTP servers, an optional bridge to a real host port |
@@ -359,6 +360,46 @@ The bundled standard library includes `json`, `re`, `os`, `sys`, `math`, `random
359
360
  Real CPython, so `sqlite3`, `dataclasses`, `decimal` and `typing` all work. Packages must be built for WebAssembly: `micropip` installs pure-Python wheels, and Pyodide's own distribution covers the rest
360
361
  (and only with outbound networking enabled).
361
362
 
363
+ ### WebAssembly binaries
364
+
365
+ Anything compiled to `wasm32-wasi` runs as a normal container process — same filesystem, same
366
+ environment, same pipes:
367
+
368
+ ```ts
369
+ await box.fs.writeFile("/usr/local/bin/tool", await readFile("tool.wasm"), { mode: 0o755 });
370
+ await box.exec("tool --version");
371
+ await box.exec("cat data.csv | tool summarise | sort");
372
+ ```
373
+
374
+ An executable `.wasm` file is dispatched automatically, the way a `#!` script is — `./tool.wasm`
375
+ runs without naming an interpreter, and a binary installed into `$PATH` under a bare name is
376
+ found by its magic number. You can also invoke the interpreter directly:
377
+
378
+ ```
379
+ wasi [--dir PATH] [--mapdir GUEST=PATH] [--env K=V] MODULE.wasm [args...]
380
+ ```
381
+
382
+ By default the module sees the whole filesystem. `--dir` and `--mapdir` replace that with exactly
383
+ what you list, and a path that climbs out of a preopened directory is refused with `ENOTCAPABLE`.
384
+
385
+ Building one, with any wasi-sdk clang:
386
+
387
+ ```bash
388
+ clang --target=wasm32-wasip1 --sysroot="$WASI_SYSROOT" -O2 tool.c -o tool.wasm
389
+ ```
390
+
391
+ Two things to know, both of which match how `wasmtime` behaves:
392
+
393
+ - **A WASI program has no working directory.** wasi-libc fixes its own at `/`, so a guest's
394
+ relative path resolves from the root. Pass absolute paths.
395
+ - **Sockets report `ENOTSUP`.** This container's network is an HTTP router rather than a packet
396
+ path, so a guest that wants to `bind()` cannot. Files, clocks, randomness, arguments,
397
+ environment and standard I/O all work.
398
+
399
+ Standard input is drained before the module starts, because WASI's `fd_read` is synchronous and
400
+ the container's streams are not — so piping and redirection work, but a wasm program reading a
401
+ live terminal sees end-of-file.
402
+
362
403
  ### Filesystem from the host
363
404
 
364
405
  ```ts
@@ -422,6 +463,7 @@ sandboxedjs — a Linux-like container inside Node.js
422
463
  node v22.12.0 npm, require, http servers
423
464
  python3 CPython 3.13 only WebAssembly-built C extensions
424
465
  ffmpeg 5.1.4 video and audio
466
+ wasi preview1 run wasm32-wasi binaries; ./tool.wasm works
425
467
  network on npm install reaches the real registry
426
468
  ```
427
469
 
@@ -171,10 +171,11 @@ async function printReplBanner(box, opts) {
171
171
  }
172
172
  };
173
173
 
174
- const [node, python, ffmpeg] = await Promise.all([
174
+ const [node, python, ffmpeg, wasi] = await Promise.all([
175
175
  probe("node -v", (out) => out.match(/v[\d.]+/)?.[0]),
176
176
  probe("python3 -c \"import sys; print(sys.version.split()[0])\"", (out) => out),
177
177
  probe("ffmpeg -version", (out) => out.match(/ffmpeg version (\S+)/)?.[1]),
178
+ probe("which wasi", () => "preview1"),
178
179
  ]);
179
180
 
180
181
  const row = (name, value, note) =>
@@ -187,6 +188,7 @@ async function printReplBanner(box, opts) {
187
188
  row("node", node, "npm, require, http servers"),
188
189
  row("python3", python, "CPython via Pyodide; WebAssembly wheels only"),
189
190
  row("ffmpeg", ffmpeg, ffmpeg ? "video and audio" : "npm install @ffmpeg/core"),
191
+ row("wasi", wasi, "run wasm32-wasi binaries; ./tool.wasm works"),
190
192
  row(
191
193
  "network",
192
194
  opts.network ? "on" : "off",