/ concept-collection / fastandaccurate
Sign in
concept-collection / fastandaccurate
fastandaccurate / src / app / workerClient.ts
74 lines · 2.2 KBBlameHistoryRaw
1// Host-side wrapper for the compute worker: one shared worker, one
2// promise per request. Requests are serviced one at a time in order.
4import type { WorkerRequest, WorkerResponse } from "./worker";
5import type { ResultPoint } from "../harness/resultSchema";
6import type { TimingPolicy } from "../harness/timing";
8type Pending = {
9 onPoint?: (point: ResultPoint, index: number, total: number) => void;
10 resolve: (value: never) => void;
11 reject: (err: Error) => void;
12};
14let worker: Worker | null = null;
15let nextId = 1;
16const pending = new Map<number, Pending>();
18function getWorker(): Worker {
19 if (!worker) {
20 worker = new Worker(new URL("./worker.ts", import.meta.url), {
21 type: "module",
22 });
23 worker.onmessage = (e: MessageEvent<WorkerResponse>) => {
24 const msg = e.data;
25 const p = pending.get(msg.id);
26 if (!p) return;
27 if (msg.type === "point") {
28 p.onPoint?.(msg.point, msg.index, msg.total);
29 } else if (msg.type === "sweepDone") {
30 pending.delete(msg.id);
31 (p.resolve as (v: ResultPoint[]) => void)(msg.points);
32 } else if (msg.type === "solutionDone") {
33 pending.delete(msg.id);
34 (p.resolve as (v: { point: ResultPoint; uGrid: Float64Array }) => void)({
35 point: msg.point,
36 uGrid: msg.uGrid,
37 });
38 } else if (msg.type === "error") {
39 pending.delete(msg.id);
40 p.reject(new Error(msg.message));
41 }
42 };
43 }
44 return worker;
47function post(req: WorkerRequest) {
48 getWorker().postMessage(req);
51export function sweepInBrowser(
52 instanceId: string,
53 solverId: string,
54 timing: TimingPolicy,
55 onPoint: (point: ResultPoint, index: number, total: number) => void
56): Promise<ResultPoint[]> {
57 const id = nextId++;
58 return new Promise((resolve, reject) => {
59 pending.set(id, { onPoint, resolve: resolve as never, reject });
60 post({ type: "sweep", id, instanceId, solverId, timing });
61 });
64export function solutionInBrowser(
65 instanceId: string,
66 solverId: string,
67 n: number
68): Promise<{ point: ResultPoint; uGrid: Float64Array }> {
69 const id = nextId++;
70 return new Promise((resolve, reject) => {
71 pending.set(id, { resolve: resolve as never, reject });
72 post({ type: "solution", id, instanceId, solverId, n });
73 });
moveopenescclose