import type { RegexExecutionRequest, RegexExecutionResult, RegexReplacementRequest, RegexReplacementResult, } from "../model/match"; import { WorkerSupervisor } from "./WorkerSupervisor"; import type { EngineWorkerOperation, EngineWorkerResult, } from "./worker-protocol"; export type EngineRuntimeState = | { readonly status: "unloaded" } | { readonly status: "running"; readonly operation: "execute" | "replace" } | { readonly status: "ready" } | { readonly status: "recovering"; readonly reason: string } | { readonly status: "failed"; readonly error: Error }; export class EngineSupervisor { private readonly supervisor = new WorkerSupervisor< EngineWorkerOperation, EngineWorkerResult >( "ECMAScript engine", () => new Worker( new URL("../../workers/ecmascript.worker.ts", import.meta.url), { type: "module", name: "regex-tools-ecmascript", }, ), ); async execute( request: RegexExecutionRequest, timeoutMs: number, ): Promise { const response = await this.supervisor.run( { kind: "execute", request }, timeoutMs, { supersede: true }, ); if (response.kind !== "execute") { throw new Error("Engine worker returned the wrong response kind"); } return response.result; } async replace( request: RegexReplacementRequest, timeoutMs: number, ): Promise { const response = await this.supervisor.run( { kind: "replace", request }, timeoutMs, { supersede: true }, ); if (response.kind !== "replace") { throw new Error("Engine worker returned the wrong response kind"); } return response.result; } cancel(): void { this.supervisor.cancel(); } dispose(): void { this.supervisor.dispose(); } }