feat: publish Regex Tools 0.2.0

This commit is contained in:
2026-07-27 01:06:57 +02:00
parent 873b9b218d
commit 4951c966d4
180 changed files with 35344 additions and 503 deletions

View File

@@ -9,6 +9,11 @@ import type {
EngineWorkerOperation,
EngineWorkerResult,
} from "./worker-protocol";
import {
ENGINE_WORKER_REGISTRY,
type EngineWorkerRegistry,
} from "./engine-registry";
import type { RegexFlavourId } from "../model/flavour";
export type EngineRuntimeState =
| { readonly status: "unloaded" }
@@ -18,26 +23,39 @@ export type EngineRuntimeState =
| { 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",
},
),
);
private readonly registry: EngineWorkerRegistry;
private readonly supervisors = new Map<
RegexFlavourId,
WorkerSupervisor<EngineWorkerOperation, EngineWorkerResult>
>();
private disposed = false;
constructor(registry: EngineWorkerRegistry = ENGINE_WORKER_REGISTRY) {
this.registry = registry;
}
private supervisorFor(
flavour: RegexFlavourId,
): WorkerSupervisor<EngineWorkerOperation, EngineWorkerResult> {
if (this.disposed) {
throw new Error("Engine supervisor has been disposed.");
}
const current = this.supervisors.get(flavour);
if (current) return current;
const registration = this.registry.require(flavour);
const supervisor = new WorkerSupervisor<
EngineWorkerOperation,
EngineWorkerResult
>(registration.label, registration.createWorker);
this.supervisors.set(flavour, supervisor);
return supervisor;
}
async execute(
request: RegexExecutionRequest,
timeoutMs: number,
): Promise<RegexExecutionResult> {
const response = await this.supervisor.run(
const response = await this.supervisorFor(request.flavour).run(
{ kind: "execute", request },
timeoutMs,
{ supersede: true },
@@ -45,6 +63,11 @@ export class EngineSupervisor {
if (response.kind !== "execute") {
throw new Error("Engine worker returned the wrong response kind");
}
if (response.result.engine.flavour !== request.flavour) {
throw new Error(
`Engine worker for ${request.flavour} returned a ${response.result.engine.flavour} result.`,
);
}
return response.result;
}
@@ -52,7 +75,7 @@ export class EngineSupervisor {
request: RegexReplacementRequest,
timeoutMs: number,
): Promise<RegexReplacementResult> {
const response = await this.supervisor.run(
const response = await this.supervisorFor(request.flavour).run(
{ kind: "replace", request },
timeoutMs,
{ supersede: true },
@@ -60,14 +83,22 @@ export class EngineSupervisor {
if (response.kind !== "replace") {
throw new Error("Engine worker returned the wrong response kind");
}
if (response.result.execution.engine.flavour !== request.flavour) {
throw new Error(
`Engine worker for ${request.flavour} returned a ${response.result.execution.engine.flavour} result.`,
);
}
return response.result;
}
cancel(): void {
this.supervisor.cancel();
for (const supervisor of this.supervisors.values()) supervisor.cancel();
}
dispose(): void {
this.supervisor.dispose();
if (this.disposed) return;
this.disposed = true;
for (const supervisor of this.supervisors.values()) supervisor.dispose();
this.supervisors.clear();
}
}