diff --git a/extension/src/service-worker/index.ts b/extension/src/service-worker/index.ts index 01e98f2..39640c7 100644 --- a/extension/src/service-worker/index.ts +++ b/extension/src/service-worker/index.ts @@ -21,27 +21,30 @@ const totpSecretCache: Map = new Map(); // --- WASM initialization --- -// We use a dynamic import so webpack treats idfoto_wasm.js as a separate chunk. -// The WASM file (idfoto_wasm_bg.wasm) is loaded by the JS glue code. -type WasmModule = typeof import('idfoto-wasm'); +// Chrome MV3 service workers do NOT support dynamic import(). +// Instead we load the WASM binary via fetch() and use the synchronous +// initSync() function exported by wasm-pack's --target web output. +// The JS glue is imported statically so webpack bundles it into +// the service worker script. + +// @ts-ignore TS2307 — resolved by webpack alias / copy +import initSync, * as wasmBindings from '../../wasm/idfoto_wasm.js'; + +type WasmModule = typeof wasmBindings; let wasm: WasmModule | null = null; async function initWasm(): Promise { if (wasm) return wasm; - // wasm-pack --target web produces an ES module with an `default` init function - // that loads the .wasm file. In a Chrome MV3 service worker we import the JS - // glue and call init() with the wasm URL. - const mod = await import( - // @ts-ignore TS2307 — resolved at runtime by the service worker, not by TS/webpack - /* webpackIgnore: true */ './idfoto_wasm.js' - ) as WasmModule & { default: (input?: string | URL) => Promise }; + // Fetch the .wasm binary and instantiate synchronously + const wasmResponse = await fetch(chrome.runtime.getURL('idfoto_wasm_bg.wasm')); + const wasmBytes = await wasmResponse.arrayBuffer(); + initSync({ module: new WebAssembly.Module(wasmBytes) }); - await mod.default('./idfoto_wasm_bg.wasm'); - vault.setWasm(mod); - wasm = mod; + vault.setWasm(wasmBindings); + wasm = wasmBindings; wasmReady = true; - return mod; + return wasm; } // --- Storage helpers --- diff --git a/extension/src/service-worker/vault.ts b/extension/src/service-worker/vault.ts index e89e639..28391aa 100644 --- a/extension/src/service-worker/vault.ts +++ b/extension/src/service-worker/vault.ts @@ -8,14 +8,16 @@ import type { GitHost } from './git-host'; import type { Entry, Manifest, ManifestEntry } from '../shared/types'; // WASM module reference — set once during init. -let wasm: typeof import('idfoto-wasm') | null = null; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +let wasm: any = null; -/// Store the WASM module reference after dynamic import. -export function setWasm(w: typeof import('idfoto-wasm')): void { +/// Store the WASM module reference after initialization. +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function setWasm(w: any): void { wasm = w; } -function requireWasm(): NonNullable { +function requireWasm(): any { if (!wasm) throw new Error('WASM module not initialized'); return wasm; }