Tracking issue for the work delivered in #496 (merged).
What shipped
A new @cipherstash/stack/wasm-inline subpath so Protect runs in any V8-only runtime — Deno, Bun, Cloudflare Workers, Supabase Edge Functions, browsers — where the native @cipherstash/protect-ffi NAPI bindings are unavailable.
packages/stack/src/wasm-inline.ts — Encryption() factory + WasmEncryptionClient (encrypt / decrypt round-trip) wired to WASM protect-ffi + AccessKeyStrategy from @cipherstash/auth/wasm-inline, plus schema builder re-exports (encryptedTable, encryptedColumn, …) and isEncrypted.
- ESM-only bundle — protect-ffi's wasm-inline is ESM and crashes under Node CJS
require() (ERR_REQUIRE_ESM); the ./wasm-inline export deliberately omits the require branch, and tsup.config.ts builds it ESM-only. A cjs-require.test.ts guard asserts the .cjs artifact stays absent.
cast_as normalization — normalizeCastAs() converts SDK-facing cast_as values to the EQL-native variants the WASM newClient expects (the Node entry does this internally; the WASM bindings don't). Unit-tested for drift in __tests__/wasm-inline-normalize.test.ts.
- Deno E2E smoke test (
e2e/wasm/roundtrip.test.ts) — round-trips an encryption against ZeroKMS/CTS with no --allow-ffi, so a silent fallback to native bindings would fail the test loudly. New wasm-e2e-tests CI job (Deno 2.x) runs it on every PR.
examples/supabase-worker/ — runnable Supabase Edge Function demo importing from @cipherstash/stack/wasm-inline.
Dependency bumps
@cipherstash/protect-ffi 0.23.0 → 0.24.0
@cipherstash/auth → 0.38.0 (for the WASM AccessKeyStrategy)
Known follow-ups
Delivered in #496.
Tracking issue for the work delivered in #496 (merged).
What shipped
A new
@cipherstash/stack/wasm-inlinesubpath so Protect runs in any V8-only runtime — Deno, Bun, Cloudflare Workers, Supabase Edge Functions, browsers — where the native@cipherstash/protect-ffiNAPI bindings are unavailable.packages/stack/src/wasm-inline.ts—Encryption()factory +WasmEncryptionClient(encrypt / decrypt round-trip) wired to WASM protect-ffi +AccessKeyStrategyfrom@cipherstash/auth/wasm-inline, plus schema builder re-exports (encryptedTable,encryptedColumn, …) andisEncrypted.require()(ERR_REQUIRE_ESM); the./wasm-inlineexport deliberately omits therequirebranch, andtsup.config.tsbuilds it ESM-only. Acjs-require.test.tsguard asserts the.cjsartifact stays absent.cast_asnormalization —normalizeCastAs()converts SDK-facingcast_asvalues to the EQL-native variants the WASMnewClientexpects (the Node entry does this internally; the WASM bindings don't). Unit-tested for drift in__tests__/wasm-inline-normalize.test.ts.e2e/wasm/roundtrip.test.ts) — round-trips an encryption against ZeroKMS/CTS with no--allow-ffi, so a silent fallback to native bindings would fail the test loudly. Newwasm-e2e-testsCI job (Deno 2.x) runs it on every PR.examples/supabase-worker/— runnable Supabase Edge Function demo importing from@cipherstash/stack/wasm-inline.Dependency bumps
@cipherstash/protect-ffi0.23.0 → 0.24.0@cipherstash/auth→ 0.38.0 (for the WASMAccessKeyStrategy)Known follow-ups
CS_WORKSPACE_CRNparity gap — the WASM client derives workspace identity from the access-key token rather than the CRN. Tracked in WASM-inline: support CS_WORKSPACE_CRN / derive region from workspace CRN #523.regionis currently required and will be replaced byworkspaceCrnonce@cipherstash/authswitchesAccessKeyStrategy.create()to derive the region from a CRN.Delivered in #496.