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]>
This commit is contained in:
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/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)"
|
||||
Reference in New Issue
Block a user