import type { BeadSystem, Excitation, SimOptions, SimResult } from './types'; export interface Running { promise: Promise; cancel: () => void; } // Starts a solver worker (src/sim/worker.ts). The page loads it from its own file; the // embedded widget, which runs on other sites, has it inlined (a worker must be same-origin). export type MakeWorker = () => Worker; // onPartial gets the result so far every few seconds while the run is in progress export function runInWorker( makeWorker: MakeWorker, sys: BeadSystem, exc: Excitation, opt: SimOptions, gpu: boolean, onProgress: (f: number) => void, onPartial?: (r: SimResult) => void, ): Running { const worker = makeWorker(); let reject!: (e: Error) => void; const promise = new Promise((res, rej) => { reject = rej; worker.onmessage = (ev) => { const m = ev.data; if (m.type === 'progress') onProgress(m.fraction); else if (m.type === 'partial') onPartial?.(m.result); else if (m.type === 'done') { worker.terminate(); res(m.result); } else { worker.terminate(); rej(new Error(m.message)); } }; worker.onerror = (e) => { worker.terminate(); rej(new Error(e.message)); }; }); worker.postMessage({ sys, exc, opt, gpu }); return { promise, cancel: () => { worker.terminate(); reject(new Error('cancelled')); }, }; }