Add JZ WebAssembly kernel example#76
Conversation
syrusakbary
left a comment
There was a problem hiding this comment.
Awesome, great first step.
Ideally I'd like to see JZ as another engine supported by Edge.js. But perhaps that might be better done in another PR. Thoughts @dy ?
|
@syrusakbary so how do you see JZ integration the best way? I lean to option 2, I could fix compat layer.
|
Edge's node:sqlite (sqlite-via-wasm) only supported :memory: — a file path SQLITE_CANTOPEN'd because @sqlite.org/sqlite-wasm is freestanding (no POSIX VFS). Route file DBs to the native opfs-sahpool block VFS: durable, block-level (reads/writes only needed blocks — the right shape for a large DB), survives reload, no COOP/COEP, keyed by path (opfs://-style), bypassing sab-vfs. This is the plug-and-play storage thesis: a DB wants durable block storage (OPFS), not the live-coherent RAM fs (sab-vfs is for editable app files; its own OPFS persistence is the separate wasmerio#76). - vendor-adapters/sqlite-wasm.ts: installOpfsSAHPoolVfs at load (best-effort; name has NO leading slash — getDirectoryHandle rejects it), stash on sqlite3. - presets/sqlite-via-wasm.runtime.js: __edgeOpenInternal opens file paths via sahPool.OpfsSAHPoolDb(path); :memory: keeps the default in-memory VFS. - Both Vite-live, no wasm rebuild. Verified (edge-sqlite-probe.js): :memory: CRUD ok; file DB write={n:42} → reopen-count={c:1} DURABLE=true. Surfaced by running opencode in-edge (OPENCODE_EDGE_GAPS.md GAP-7).
…oad (opt-in ?durable=1) The sab-vfs disk is RedoxFS (copy-on-write) over a SharedArrayBuffer (RAM) — ephemeral. Persist the block image to OPFS so the in-edge filesystem survives a page reload. The bridge worker is the single owner of the disk SAB (peers write to the shared SAB + bump a GEN counter); it loads the image in before mount and flushes it out when GEN advances. - sab-vfs-durable.ts: ping-pong pair of OPFS sync-access-handle files (img.0/img.1) + a 1-byte ptr for an atomic flip (crash mid-flush leaves the previous complete image active). restore() reads the active image at its stored size (it IS the live disk = prebuilt + writes, so it's authoritative); attach() debounce-flushes on GEN change. - bridge-worker.ts: load-in precedence OPFS > prebuilt host image > format-fresh; attach the flush-out after mount. - main.ts: forward ?durable=1 to the bridge worker. Pure TS, no Rust/wasm rebuild (disk bytes live in sab-vfs.ts's diskSab; crate/src/disk.rs is a test scaffold). Default OFF → no change to existing studios. Verified: sabvfs-durable-test.mjs (2 pages / 1 OPFS origin) → durable-reload-survival=true. Whole-image flush + best-effort snapshot is the first cut; dirty-block + locked-snapshot crash-consistency is the documented hardening follow-up (NOTES wasmerio#76).
…, node:sqlite surface Bake opencode-discovery patches into edge core as general fixes (Node-faithful behavior in the runtime). VERIFIED non-regressing: opencode GUI renders, next studio E2E PASS, wasmerio#76 durable-reload-survival=true. - GAP-2 (verified): vite.config.ts /app handler sets Content-Type by extension (.mjs/.js->text/javascript, .wasm->application/wasm, ...) instead of octet-stream, so a NATIVE import() of an /app URL no longer MIME-rejects. Safe/general: handler responds before Vite transform, bytes stay raw. - wasmerio#76 hardening (verified, durable test passes): sab-vfs-durable.ts now flushes only changed 4KiB blocks (bridge-owned shadow diff) + crash-consistent data->header->ptr ordering (v2 block-structured image), replacing the whole-128MiB-image flush. Crash-recovery fallback confirmed. - GAP-8 (get/all verified via opencode; surface completed): setReadBigInts now returns real BigInt (sqlite3_column_int64), iterate() is a real generator, shared readRow() helper. - GAP-1 (HONEST: unverified, NOT claimed fixed): added a synthetic BuiltinModule('sqlite') registration as a foundation for native ESM-import, but the -e/vm probe still fails (it uses vm's importModuleDynamically, a SEPARATE gap, not the esm-via-blob-import short-circuit). CJS path works; opencode keeps its createRequire shim. See OPENCODE_EDGE_GAPS.md GAP-1. run-wait.mjs: generic wait-for-marker harness (runs past the _start sentinel to capture async probe output).
Add JZ WebAssembly kernel example
Adds
examples/jz-kernel.jzcompiles a JavaScript-subset numeric kernel to standard WebAssembly; EdgeJS loads it throughWebAssembly.Module/WebAssembly.Instance. JZ is used as a kernel compiler, not as a JavaScript engine for EdgeJS.Reproduce
From
examples/jz-kernel:Local EdgeJS native result (4x4
Float64Arraymatrix kernel, 200k iterations, 9 runs after 5 warmups):Limits
napi_v10/napi_extension_wasmer_v0).jz@^0.1.1.