Files
FreeCADWasmDev/web/src/python-runtime.worker.ts
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

18 lines
2.3 KiB
TypeScript

import { FacadeCancel, FacadeResponse, FacadeSerialQueue, createFailure, isFacadeCancel } from "./facade-envelope.js";
import { dispatchPythonRuntime, isPythonRuntimeRequest, PythonRuntimeKernel, PythonRuntimeRequest } from "./python-runtime-facade.js";
type Factory = (options?: Record<string, unknown>) => Promise<PythonRuntimeKernel>;
type Request = PythonRuntimeRequest | FacadeCancel | { kind: "reset"; requestId: string };
type Response = FacadeResponse | { kind: "ready"; action: string } | { kind: "reset"; requestId: string };
const scope = self as unknown as { postMessage(message: Response): void; onmessage: ((event: MessageEvent<Request>) => void) | null };
async function load(): Promise<PythonRuntimeKernel> {
const source = await fetch("/kernel/FreeCADWebPythonProbe.js").then((response) => { if (!response.ok) throw new Error(`Python runtime loader failed: HTTP ${response.status}`); return response.text(); });
const url = URL.createObjectURL(new Blob([source], { type: "text/javascript" }));
try { const module = await import(/* @vite-ignore */ url) as unknown as { default: Factory }; return module.default({ locateFile: (file: string) => `/kernel/${file}` }); }
finally { URL.revokeObjectURL(url); }
}
let queue = new FacadeSerialQueue();
let kernel = load();
kernel.then((value) => { if (Number(value.ccall("fc_web_python_runtime_start", "number")) !== 1) throw new Error(String(value.ccall("fc_web_python_runtime_error", "string"))); scope.postMessage({ kind: "ready", action: "python.eval" }); }).catch((error) => scope.postMessage(createFailure("ready", "python_runtime_load_failed", error instanceof Error ? error.message : String(error))));
scope.onmessage = async (event) => { const message = event.data; if (message.kind === "reset") { queue = new FacadeSerialQueue(); kernel = load(); kernel.then((value) => value.ccall("fc_web_python_runtime_start", "number")).catch(() => undefined); scope.postMessage({ kind: "reset", requestId: message.requestId }); return; } if (isFacadeCancel(message)) { if (!queue.cancel(message)) scope.postMessage(createFailure(message.requestId, "cancel_rejected", "request is not active")); return; } if (isPythonRuntimeRequest(message)) { scope.postMessage(await dispatchPythonRuntime(queue, message, kernel)); return; } scope.postMessage(createFailure("invalid", "invalid_request", "Python runtime envelope is invalid")); };