# Shade V3.8 — Web Workers Crypto **Status:** Done **Effort:** M-L (3–6 uker) **Forrige:** V3.1 **Adresserer:** V2.2 §4 **Levert:** `0.4.0` **Konsumentdokumentasjon:** [`docs/web-workers.md`](../web-workers.md) --- ## Mål Store filer i nettleseren skal kunne krypteres / dekrypteres uten å blokkere hovedtråden eller sprenge RAM. Dedikert Worker kjører `@shade/crypto-web` + `@shade/streams`, koblet til `@shade/transfer` via `ReadableStream` / `WritableStream`. --- ## Scope ### Inn - Ny entry: `@shade/crypto-web/worker` — dedikert Web Worker med `WorkerCryptoProvider`. - Hovedtråd-proxy: `MainThreadCryptoProvider` som forwarder kall til Worker. - Stream-pipeline: `ReadableStream` → Worker (transferable buffers) → `@shade/transfer`-chunk-PUTs. - Lifecycle: spawn-on-demand, idle-timeout, terminate-on-rotate. - Safari-aware chunk-sizing (Safari har lavere `postMessage`-kapasitet). ### Ut - Service Workers (background sync) — egen vurdering. - SharedArrayBuffer (krever COOP/COEP-headers; valgfritt opt-in). --- ## Design ### Provider-API (uendret for konsumenter) ```ts const crypto = await createWorkerCryptoProvider({ workerUrl: '/shade-crypto.worker.js', }); const shade = await createShade({ crypto, ... }); ``` `WorkerCryptoProvider` implementerer samme `CryptoProvider`-interface som `SubtleCryptoProvider`. Kall serialiseres med transferable `ArrayBuffer` så minne ikke kopieres. ### Stream-pipeline ```ts file.stream() .pipeThrough(shade.encryptStream(peer)) // worker .pipeThrough(shade.transfer.outboundChunks()) // main → http .pipeTo(transferSink()); ``` Worker-siden av `encryptStream` bruker `MultiLaneSender`. --- ## Leveranser ### Kode - `@shade/crypto-web` — ny `worker.ts` entrypoint. - `@shade/sdk` — `shade.encryptStream` / `decryptStream`. - Bundler-eksempel for Vite, Webpack og Rollup. ### Tester - Unit: postMessage roundtrip med transferable buffer. - Integration: 100 MB fil i nettleser uten frame-drop > 16 ms (P99). - Safari: chunked `postMessage`-workaround. ### Dokumentasjon - `docs/web-workers.md` — setup, bundler-kvirks, Safari-notater, COOP/COEP for SharedArrayBuffer-modus. --- ## Akseptansekriterier - [x] 100 MB upload i Chrome uten å blokkere main thread > 16 ms i P99 (Performance Observer-måling — verifiseringsoppskrift i [`docs/web-workers.md`](../web-workers.md#verifying-main-thread-budget)). - [x] Safari fungerer med default chunk-size (256 KiB postMessage budget, langt under Safari's transferable-grense). - [x] Worker termineres innen 30 s etter siste bruk (`idleTimeoutMs`, default `30_000`). --- ## Avhengigheter Ingen direkte. Kan kjøres parallelt med V3.2 / V3.4. --- ## Risiko - **Bundler-helvete.** Vite, Webpack og Rollup behandler Workers ulikt. Mitiger ved publisert recipe + integration-tester per bundler. - **Safari postMessage-grenser.** Test tidlig. --- ## Migrasjon Opt-in. Default forblir `SubtleCryptoProvider`.