/*! (c) PyScript Development Team */ import stickyModule from "sticky-module"; import "@ungap/with-resolvers"; import { INVALID_CONTENT, Hook, XWorker, assign, dedent, define, defineProperty, dispatch, queryTarget, unescape, whenDefined, } from "polyscript/exports"; import "./all-done.js"; import TYPES from "./types.js"; import configs from "./config.js"; import sync from "./sync.js"; import bootstrapNodeAndPlugins from "./plugins-helper.js"; import { ErrorCode } from "./exceptions.js"; import { robustFetch as fetch, getText } from "./fetch.js"; import { hooks, main, worker, codeFor, createFunction } from "./hooks.js"; import { stdlib, optional } from "./stdlib.js"; export { stdlib, optional }; // generic helper to disambiguate between custom element and script const isScript = ({ tagName }) => tagName === "SCRIPT"; // Used to create either Pyodide or MicroPython workers // with the PyScript module available within the code const [PyWorker, MPWorker] = [...TYPES.entries()].map( ([TYPE, interpreter]) => /** * A `Worker` facade able to bootstrap on the worker thread only a PyScript module. * @param {string} file the python file to run ina worker. * @param {{config?: string | object, async?: boolean}} [options] optional configuration for the worker. * @returns {Promise} */ async function PyScriptWorker(file, options) { await configs.get(TYPE).plugins; const xworker = XWorker.call( new Hook(null, hooked.get(TYPE)), file, { ...options, type: interpreter, }, ); assign(xworker.sync, sync); return xworker.ready; }, ); // avoid multiple initialization of the same library const [ { PyWorker: exportedPyWorker, MPWorker: exportedMPWorker, hooks: exportedHooks, config: exportedConfig, whenDefined: exportedWhenDefined, }, alreadyLive, ] = stickyModule("@pyscript/core", { PyWorker, MPWorker, hooks, config: {}, whenDefined, }); export { TYPES, exportedPyWorker as PyWorker, exportedMPWorker as MPWorker, exportedHooks as hooks, exportedConfig as config, exportedWhenDefined as whenDefined, }; const hooked = new Map(); for (const [TYPE, interpreter] of TYPES) { // avoid any dance if the module already landed if (alreadyLive) break; const dispatchDone = (element, isAsync, result) => { if (isAsync) result.then(() => dispatch(element, TYPE, "done")); else dispatch(element, TYPE, "done"); }; const { config, configURL, plugins, error } = configs.get(TYPE); // create a unique identifier when/if needed let id = 0; const getID = (prefix = TYPE) => `${prefix}-${id++}`; /** * Given a generic DOM Element, tries to fetch the 'src' attribute, if present. * It either throws an error if the 'src' can't be fetched or it returns a fallback * content as source. */ const fetchSource = async (tag, io, asText) => { if (tag.hasAttribute("src")) { try { return await fetch(tag.getAttribute("src")).then(getText); } catch (error) { io.stderr(error); } } if (asText) return dedent(tag.textContent); const code = dedent(unescape(tag.innerHTML)); console.warn( `Deprecated: use