Files
2026-07-24 13:29:16 +00:00

59 lines
2.3 KiB
JavaScript

'use strict';
// Web Worker that hosts the sing-vis WebAssembly engine. It loads the Go runtime
// shim + singvis.wasm, keeps the Go program alive, and forwards analyze requests
// to the JS-exported `singvisAnalyze`. Running in a worker keeps the wasm work
// (DoH resolution, rule-set fetching, matching) off the UI thread.
//
// Message protocol:
// main → worker: { id, request } request = the analyze payload
// worker → main: { id, result } on success (result = parsed engine.Result)
// { id, error } on failure (error = message string)
// { type:'ready' } once the wasm engine is initialized
// { type:'loaderror', error } if the wasm failed to load
importScripts('wasm_exec.js');
// Resolved by the Go program (via the `singvisReady` callback it invokes in main)
// once `singvisAnalyze` has been registered on the global scope.
let signalStarted;
const started = new Promise((resolve) => { signalStarted = resolve; });
globalThis.singvisReady = () => signalStarted();
const ready = (async () => {
const go = new Go();
let instance;
try {
// Preferred path; requires the server to send Content-Type: application/wasm.
const res = await WebAssembly.instantiateStreaming(fetch('singvis.wasm'), go.importObject);
instance = res.instance;
} catch (streamErr) {
// Fallback for static servers that don't set the wasm MIME type.
const resp = await fetch('singvis.wasm');
if (!resp.ok) throw new Error('failed to load singvis.wasm (HTTP ' + resp.status + ')');
const bytes = await resp.arrayBuffer();
const res = await WebAssembly.instantiate(bytes, go.importObject);
instance = res.instance;
}
// Do NOT await: the Go main blocks forever (select{}) to keep serving calls.
go.run(instance);
await started;
})();
ready.then(
() => self.postMessage({ type: 'ready' }),
(err) => self.postMessage({ type: 'loaderror', error: (err && err.message) || String(err) })
);
self.onmessage = async (e) => {
const data = e.data || {};
if (data.id == null) return;
try {
await ready;
const out = await globalThis.singvisAnalyze(JSON.stringify(data.request || {}));
self.postMessage({ id: data.id, result: JSON.parse(out) });
} catch (err) {
self.postMessage({ id: data.id, error: (err && err.message) || String(err) });
}
};