importScripts("https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"); async function initializePyodide() { self.pyodide = await loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.23.4/full/" }); // Expose a function to send messages from Python to JavaScript self.pyodide.globals.set("send_to_main", (event, data) => { self.postMessage({ type: event, data: data }); }); // Define the fire() and turn(deg) functions in Python self.pyodide.runPython(` import sys import pyodide def fire(): pyodide.ffi.to_js(send_to_main)("fire", None) def turn(deg): pyodide.ffi.to_js(send_to_main)("turn", deg) class ConsoleOutput: def write(self, text): if text.strip(): # Avoid empty writes pyodide.ffi.to_js(send_to_main)("console", text) return None # Prevent 'undefined' from appearing def flush(self): pass sys.stdout = ConsoleOutput() sys.stderr = ConsoleOutput() `); self.postMessage({ type: "ready" }); // Notify main thread that Pyodide is ready } initializePyodide(); self.onmessage = async (event) => { if (!self.pyodide) { self.postMessage({ type: "error", message: "Pyodide not initialized yet." }); return; } try { let result = await self.pyodide.runPythonAsync(event.data.code); if (result !== undefined && result !== null && result !== "") { self.postMessage({ type: "console", data: result }); } } catch (error) { self.postMessage({ type: "error", message: error.toString() }); } };