///
import type { PlanningOutcome } from './leave-planner.service';
import type { WorkerRequest, WorkerResponse } from './leave-planner.worker-messages';
import {
analyzeCounterfactualInternal,
calculatePlanningAsyncInternal,
explainIncompleteCheckpoint,
type PlanningArtifacts,
} from './leave-planner.core';
const worker = self as DedicatedWorkerGlobalScope;
let activeCalculation: { cancelled: boolean } | undefined;
worker.onmessage = async (event: MessageEvent) => {
try {
if (event.data?.type === 'cancel') {
if (activeCalculation) activeCalculation.cancelled = true;
return;
}
if (event.data?.type === 'plan') {
const calculation = { cancelled: false };
activeCalculation = calculation;
let artifacts: PlanningArtifacts = {};
let outcomePosted = false;
let outcome: PlanningOutcome;
// The cooperative driver yields during preparation and search, even within one phase.
const heartbeat = () =>
worker.postMessage({ type: 'heartbeat' } satisfies WorkerResponse);
const heartbeatTimer = setInterval(heartbeat, 1000);
try {
heartbeat();
outcome = await calculatePlanningAsyncInternal(
{
...event.data.request,
progress: (stage: string) =>
worker.postMessage({
type: 'progress',
stage,
} satisfies WorkerResponse),
},
(plan, state) =>
worker.postMessage({
type: 'checkpoint',
plan,
state,
} satisfies WorkerResponse),
(value) => (artifacts = value),
(value) => {
outcomePosted = true;
worker.postMessage({
type: 'result',
outcome: value,
} satisfies WorkerResponse);
},
(explanation, explanationError, finalState) =>
worker.postMessage({
type: 'explanation',
explanation,
explanationError,
finalState,
} satisfies WorkerResponse),
() => calculation.cancelled,
);
} catch (error) {
worker.postMessage({
type: 'error',
code: 'planner-error',
message: error instanceof Error ? error.message : String(error),
} satisfies WorkerResponse);
return;
} finally {
clearInterval(heartbeatTimer);
if (activeCalculation === calculation) activeCalculation = undefined;
}
if (!outcomePosted)
worker.postMessage({ type: 'result', outcome } satisfies WorkerResponse);
worker.postMessage({ type: 'artifacts', artifacts } satisfies WorkerResponse);
return;
}
if (event.data?.type === 'explain-checkpoint') {
const result = explainIncompleteCheckpoint(
event.data.request,
event.data.plan,
event.data.state,
event.data.interruption,
);
worker.postMessage({ type: 'explanation', ...result } satisfies WorkerResponse);
return;
}
if (event.data?.type !== 'counterfactual') return;
try {
const analysis = analyzeCounterfactualInternal(
event.data.request,
event.data.plan,
event.data.placement,
event.data.state,
);
worker.postMessage({
type: 'counterfactual-result',
analysis,
} satisfies WorkerResponse);
} catch (error) {
worker.postMessage({
type: 'error',
code: 'counterfactual-error',
message: error instanceof Error ? error.message : String(error),
} satisfies WorkerResponse);
}
} catch (error) {
worker.postMessage({
type: 'error',
code: 'worker-error',
message: error instanceof Error ? error.message : String(error),
} satisfies WorkerResponse);
}
};