Skip to content

inline rules-engine WASM binary at build time#123

Merged
bpapillon merged 4 commits into
mainfrom
inline-wasm-binary-at-build-time
Jun 3, 2026
Merged

inline rules-engine WASM binary at build time#123
bpapillon merged 4 commits into
mainfrom
inline-wasm-binary-at-build-time

Conversation

@bpapillon
Copy link
Copy Markdown
Contributor

@bpapillon bpapillon commented May 22, 2026

The wasm-bindgen dist/wasm/rulesengine.js loads its .wasm sibling via fs.readFileSync(${__dirname}/...), which breaks under bundlers that rewrite __dirname (Next.js surfaces it as ENOENT at SDK init, and the rules engine silently falls back to API-only) and in runtimes without fs.

Two changes:

  1. Inline the WASM at build time (build.js) — base64-encode the binary into the loader (Buffer.from(...)), removing the filesystem read, and drop the standalone .wasm. Init becomes bundler/runtime-agnostic. Tarball +138 KB.

  2. Load the loader via dynamic import() (src/rules-engine.ts) instead of require, so bundlers code-split the wasm into its own async chunk. A consumer that only uses the HTTP API (never calls initialize()) no longer ships the inlined binary in its entry bundle — measured HTTP-only entry bundle: webpack/Next 282 KB → 71 KB gz, Vite/Rollup/esbuild-splitting 283 KB → 77 KB gz. (esbuild single-file mode still re-inlines.)

verify-package CI updated to assert the inlined sentinel and the absence of the standalone .wasm.

Follow-up SCH-6542: publish web/bundler wasm-bindgen targets for the size-optimal native WASM path on Cloudflare/edge.

@bpapillon bpapillon marked this pull request as ready for review May 22, 2026 19:13
@bpapillon bpapillon requested a review from a team as a code owner May 22, 2026 19:13
cbrady
cbrady previously approved these changes May 22, 2026
bpapillon added 3 commits June 3, 2026 09:49
The wasm-bindgen-generated `dist/wasm/rulesengine.js` loads its `.wasm`
sibling at runtime via `fs.readFileSync(${__dirname}/rulesengine_bg.wasm)`.
That works in plain Node, but breaks the moment a downstream bundler
follows the require chain — webpack rewrites `__dirname` to point inside
the bundle output, where the `.wasm` sibling never gets copied. Symptom
in a Next.js consumer:

  ENOENT: no such file or directory, open
    '.next/dev/server/vendor-chunks/rulesengine_bg.wasm'

…and the SDK silently falls back to API-only checks, disabling DataStream
and credit-lease paths.

This adds a build step that reads the WASM binary, base64-encodes it,
and rewrites `dist/wasm/rulesengine.js` to instantiate from an inlined
`Buffer.from(BASE64, 'base64')` instead of touching the filesystem. The
standalone `.wasm` is then removed from `dist/` since nothing reads it
at runtime anymore.

Tarball delta is +138 KB (base64 overhead on the ~414 KB binary). For
consumers that use creditLeases / DataStream the net bundle size is
unchanged — the WASM bytes are in either form. For consumers that don't,
practical tree-shaking ends up the same regardless of inlining: the
require chain is reachable from the package's main entry point and the
WASM init runs as a module-level side effect. Materially reducing the
WASM cost for non-credit-lease consumers would require splitting credit
leases into a separate entry point — out of scope here.

If wasm-bindgen output ever stops matching the regex this script keys
on, the build throws with a clear pointer instead of silently shipping
a broken loader.
The verify-package step asserted on `dist/wasm/rulesengine_bg.wasm`
presence, which the inlining step now intentionally removes. Replace
those checks with a content-sentinel grep on the inlined comment so a
future change that silently reverts to disk-based loading still fails
CI, plus an explicit assertion that the standalone .wasm is gone.
@bpapillon bpapillon force-pushed the inline-wasm-binary-at-build-time branch from 4196c85 to d8e475f Compare June 3, 2026 17:12
@bpapillon bpapillon requested a review from cbrady June 3, 2026 18:06
@bpapillon bpapillon merged commit 0edf413 into main Jun 3, 2026
5 checks passed
@bpapillon bpapillon deleted the inline-wasm-binary-at-build-time branch June 3, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants