18 lines
2.3 KiB
TypeScript
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")); };
|