feat: add environment-aware WASM loading for Chrome/Firefox
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
/// Service worker entry point for the idfoto Chrome extension.
|
||||
/// Background script entry point for the idfoto browser extension.
|
||||
///
|
||||
/// In Chrome this runs as a service worker (MV3). In Firefox this runs
|
||||
/// as a persistent background script. WASM loading adapts automatically.
|
||||
///
|
||||
/// Loads the WASM module, manages vault state (master key, manifest, git host),
|
||||
/// and routes all messages from the popup and content scripts.
|
||||
@@ -22,14 +25,14 @@ const totpSecretCache: Map<string, string> = new Map();
|
||||
|
||||
// --- WASM initialization ---
|
||||
|
||||
// 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.
|
||||
// Chrome MV3 uses service workers which do NOT support dynamic import().
|
||||
// Firefox MV3 uses background scripts which DO support dynamic import().
|
||||
// We detect the environment at runtime and use the appropriate loading strategy.
|
||||
|
||||
// @ts-ignore TS2307 — resolved by webpack alias / copy
|
||||
import initSync, * as wasmBindings from '../../wasm/idfoto_wasm.js';
|
||||
import initDefault, { initSync } from '../../wasm/idfoto_wasm.js';
|
||||
// @ts-ignore TS2307
|
||||
import * as wasmBindings from '../../wasm/idfoto_wasm.js';
|
||||
|
||||
type WasmModule = typeof wasmBindings;
|
||||
let wasm: WasmModule | null = null;
|
||||
@@ -37,10 +40,21 @@ let wasm: WasmModule | null = null;
|
||||
async function initWasm(): Promise<WasmModule> {
|
||||
if (wasm) return wasm;
|
||||
|
||||
// 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) });
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const SWGlobalScope = (globalThis as any).ServiceWorkerGlobalScope as (new () => ServiceWorker) | undefined;
|
||||
const isServiceWorker = typeof SWGlobalScope !== 'undefined'
|
||||
&& self instanceof (SWGlobalScope as unknown as typeof EventTarget);
|
||||
|
||||
if (isServiceWorker) {
|
||||
// Chrome: fetch 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) });
|
||||
} else {
|
||||
// Firefox: background script — async init works
|
||||
const wasmUrl = chrome.runtime.getURL('idfoto_wasm_bg.wasm');
|
||||
await initDefault(wasmUrl);
|
||||
}
|
||||
|
||||
vault.setWasm(wasmBindings);
|
||||
wasm = wasmBindings;
|
||||
|
||||
Reference in New Issue
Block a user