function postReply(id, type, payload) { self.postMessage({ id, type, ok: true, ...payload }); } function postError(id, type, error) { self.postMessage({ id, type, ok: false, error: error?.message ?? String(error), }); } function pythonRuntimeAvailable() { return typeof self.loadPyodide === "function" || Boolean(self.pyodide?.runPythonAsync); } function getRuntimeProvider() { return self.linuxCncPythonRemapRuntimeProvider ?? null; } async function loadRuntimeProvider(moduleUrl) { if (!moduleUrl) { return { status: "blocked_browser_python_wasm_runtime_missing", provider: getRuntimeProvider(), }; } try { await import(moduleUrl); } catch (error) { return { status: "blocked_browser_python_wasm_runtime_load_failed", error, provider: getRuntimeProvider(), }; } const provider = getRuntimeProvider(); if (!provider) { return { status: "blocked_browser_python_remap_provider_missing", provider, }; } return { status: "browser_python_remap_wasm_runtime_ready", provider, }; } async function callProvider(type, message) { const provider = getRuntimeProvider(); const method = provider?.[type]; if (!method) { throw new Error("blocked_browser_python_wasm_runtime_missing"); } return method.call(provider, message); } self.addEventListener("message", async (event) => { const message = event.data ?? {}; const { id, type } = message; try { if (type === "start") { const runtimeLoad = await loadRuntimeProvider(message.pythonRuntimeModuleUrl); const provider = runtimeLoad.provider; const requiredMethods = [ "initializePython", "applyIniPythonPath", "executeTopLevel", "importModule", "lookupCallable", "invokeGenerator", "observeFirstYield", "finishGenerator", "exportInterpreterState", "exportDiagnostics", ]; const providerReady = requiredMethods.every((method) => typeof provider?.[method] === "function"); const ready = providerReady || pythonRuntimeAvailable(); if (providerReady && provider.start) { await provider.start(message); } postReply(id, type, { runtimeMode: "browser-python-wasm-worker", runtimeExecutionReady: ready, status: ready ? "browser_python_remap_wasm_runtime_ready" : runtimeLoad.status, error: runtimeLoad.error?.message ?? null, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }); return; } if (type === "close") { const provider = getRuntimeProvider(); if (provider?.close) { await provider.close(); } postReply(id, type, { executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }); return; } const result = await callProvider(type, message); postReply(id, type, { status: result?.status ?? "ok", value: result?.value ?? null, ready: result?.ready !== false, source: result?.source ?? "linuxcnc-python-remap-runtime-provider", executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }); } catch (error) { postError(id, type, error); } });