Files
kestrove-core/crates/kv-wasm/build.sh
T
samiandClaude Opus 5.5 b5ced32be3 Add kv-wasm: the core compiled to WebAssembly for the web vault
New crate crates/kv-wasm runs the same crypto, item model and sync engine in the browser:
- WebStore: in-memory replica of kv-store's Store, each changed entry written to IndexedDB
  (ciphertext only) before the JS call resolves.
- Device key: non-extractable WebCrypto ECDSA P-256 key in IndexedDB (raw r||s signatures).
- WebCore mirrors kv-ffi's VaultCore; wasm-bindgen surface in camelCase with TypeScript types,
  plus a Web Worker wrapper (connectVault) so Argon2id never blocks the page.
- Tests: Chrome (IndexedDB, WebCrypto, RFC 9421 verify), shared envelope fixtures both ways
  with kv-ffi, native sync with kv-ffi via the test server, Node smoke of the built package.

Small changes to shared crates so they build for wasm32:
- kv-store: SqliteStore moved to a native-only module.
- kv-sync: rustls/pinning/tokio native only (fetch on wasm); DeviceSigner::sign_async (default
  wraps sign) used by ApiClient; unix_now() instead of SystemTime/now_utc.
- kv-model: Public Suffix List behind a default `psl` feature (kv-ffi keeps it; the web build
  drops ~0.9 MB of code and matches same-host only).
- wasm-release profile (opt-level z, Argon2 at 3) and a wasm CI job.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 23:58:07 +09:00

30 lines
1.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Builds the web vault package: wasm-pack (size profile, wasm-opt -Oz) plus the Web Worker wrapper.
# crates/kv-wasm/build.sh -> crates/kv-wasm/pkg/
# Then run the Node smoke test: node crates/kv-wasm/js/smoke.mjs
set -euo pipefail
here="$(cd "$(dirname "$0")" && pwd)"
cd "$here"
wasm-pack build . --target web --profile wasm-release --out-dir pkg --scope kestrove --out-name kv_wasm
cp js/worker.js js/client.js js/client.d.ts pkg/
# Ship the worker files and point the package's types at the client (it re-exports everything).
node -e '
const fs = require("fs");
const p = JSON.parse(fs.readFileSync("pkg/package.json", "utf8"));
p.files = Array.from(new Set([...(p.files || []), "worker.js", "client.js", "client.d.ts"]));
p.exports = {
".": { types: "./kv_wasm.d.ts", default: "./kv_wasm.js" },
"./client.js": { types: "./client.d.ts", default: "./client.js" },
"./worker.js": "./worker.js",
"./kv_wasm_bg.wasm": "./kv_wasm_bg.wasm",
};
fs.writeFileSync("pkg/package.json", JSON.stringify(p, null, 2) + "\n");
'
wasm="pkg/kv_wasm_bg.wasm"
printf 'kv_wasm_bg.wasm: %s bytes, gzip -9 %s, brotli %s\n' \
"$(wc -c <"$wasm" | tr -d ' ')" "$(gzip -9 -c "$wasm" | wc -c | tr -d ' ')" \
"$( (command -v brotli >/dev/null && brotli -c -q 11 "$wasm" | wc -c | tr -d ' ') || echo n/a)"