import EmscriptenModule from "./python.mjs"; import fs from "node:fs"; if (process?.versions?.node) { const nodeVersion = Number(process.versions.node.split(".", 1)[0]); if (nodeVersion < 18) { process.stderr.write( `Node version must be >= 18, got version ${process.version}\n`, ); process.exit(1); } } function rootDirsToMount(Module) { return fs .readdirSync("/") .filter((dir) => !["dev", "lib", "proc"].includes(dir)) .map((dir) => "/" + dir); } function mountDirectories(Module) { for (const dir of rootDirsToMount(Module)) { Module.FS.mkdirTree(dir); Module.FS.mount(Module.FS.filesystems.NODEFS, { root: dir }, dir); } } const thisProgram = "--this-program="; const thisProgramIndex = process.argv.findIndex((x) => x.startsWith(thisProgram), ); const settings = { preRun(Module) { // Globally expose API object so we can access it if we raise on startup. globalThis.Module = Module; mountDirectories(Module); Module.FS.chdir(process.cwd()); Object.assign(Module.ENV, process.env); delete Module.ENV.PATH; }, // Ensure that sys.executable, sys._base_executable, etc point to python.sh // not to this file. To properly handle symlinks, python.sh needs to compute // its own path. thisProgram: process.argv[thisProgramIndex].slice(thisProgram.length), // After python.sh come the arguments thatthe user passed to python.sh. arguments: process.argv.slice(thisProgramIndex + 1), }; try { await EmscriptenModule(settings); } catch(e) { // Show JavaScript exception and traceback console.warn(e); // Show Python exception and traceback Module.__Py_DumpTraceback(2, Module._PyGILState_GetThisThreadState()); process.exit(1); }