import { chooseMove } from './ai'; import { AIWorkerChooseMoveRequest, AIWorkerErrorMessage, AIWorkerRequestMessage, AIWorkerResponseMessage, } from './ai-worker-protocol'; import { CardInferenceEngine } from './card-inference'; import { CardTracker } from './card-tracker'; interface AIWorkerScope { addEventListener(type: 'message', listener: (event: MessageEvent) => void): void; postMessage(message: AIWorkerResponseMessage): void; } const workerScope = globalThis as unknown as AIWorkerScope; function serializeError(requestId: string, error: unknown): AIWorkerErrorMessage { if (error instanceof Error) { return { type: 'error', requestId, error: { message: error.message, name: error.name, stack: error.stack, }, }; } return { type: 'error', requestId, error: { message: typeof error === 'string' ? error : 'Unknown AI worker error', name: 'Error', }, }; } async function handleChooseMove(request: AIWorkerChooseMoveRequest): Promise { const tracker = request.trackerSnapshot ? CardTracker.fromSnapshot(request.trackerSnapshot) : undefined; const inference = request.inferenceSnapshot && tracker ? CardInferenceEngine.fromSnapshot(request.inferenceSnapshot, tracker) : undefined; try { const move = await chooseMove( request.state, request.playerIdx, request.difficulty, tracker, (progress) => { workerScope.postMessage({ type: 'progress', requestId: request.requestId, progress, }); }, inference ? { inference } : undefined, ); workerScope.postMessage({ type: 'result', requestId: request.requestId, move, }); } catch (error) { workerScope.postMessage(serializeError(request.requestId, error)); } } workerScope.addEventListener('message', (event: MessageEvent) => { const message = event.data; if (message.type !== 'choose-move') { return; } void handleChooseMove(message); }); export {};