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:
2026-10-17 23:58:07 +09:00
co-authored by Claude Opus 5.5
parent f20380d293
commit b5ced32be3
35 changed files with 4488 additions and 363 deletions
+12 -1
View File
@@ -12,7 +12,8 @@ publish = false
[workspace.dependencies]
kv-proto = { path = "crates/kv-proto" }
kv-crypto = { path = "crates/kv-crypto" }
kv-model = { path = "crates/kv-model" }
# The `psl` feature (eTLD+1 matching, ~0.9 MB of code) is enabled by kv-ffi; the web build leaves it out.
kv-model = { path = "crates/kv-model", default-features = false }
kv-store = { path = "crates/kv-store" }
kv-sync = { path = "crates/kv-sync" }
kv-import = { path = "crates/kv-import" }
@@ -65,3 +66,13 @@ strip = true
opt-level = 3
[profile.dev.package.blake2]
opt-level = 3
# Web vault (`wasm-pack build crates/kv-wasm --profile wasm-release`): optimize for download size,
# but keep Argon2id's hot loop at full speed.
[profile.wasm-release]
inherits = "release"
opt-level = "z"
[profile.wasm-release.package.argon2]
opt-level = 3
[profile.wasm-release.package.blake2]
opt-level = 3