/// /// /// /// /// import type { ExtractType } from "./types.ts"; export class WorkerChannel { queue: T[] = []; waiting: ((value: T) => void)[] = []; constructor(private worker?: Worker) { const callback = ({ data }: { data: unknown }) => { const waiting = this.waiting.shift(); if (waiting) { waiting(data as T); } else { this.queue.push(data as T); } }; if (worker) { worker.addEventListener("message", callback); } else { self.addEventListener("message", callback); } } async recvType( type: K, ): Promise> { const data = await this.recv(); if (data.type !== type) { throw new Error(`Unexpected type: ${data.type}`); } return data as ExtractType; } recv(): Promise { return new Promise((resolve) => { const data = this.queue.shift(); if (data) { resolve(data); } else { this.waiting.push(resolve); } }); } send(data: T) { if (this.worker) { this.worker.postMessage(data); } else { self.postMessage(data); } } }