Fix #1997 - Bring pyscript stdlib to the PyEditor (#2010)

* Fix #1997 - Bring pyscript stdlib to the PyEditor
This commit is contained in:
Andrea Giammarchi
2024-03-28 10:43:26 +01:00
committed by GitHub
parent 2f3659b676
commit 1447cb3094
8 changed files with 140 additions and 75 deletions

View File

@@ -26,6 +26,9 @@ import { ErrorCode } from "./exceptions.js";
import { robustFetch as fetch, getText } from "./fetch.js";
import { hooks, main, worker, codeFor, createFunction } from "./hooks.js";
import stdlib from "./stdlib.js";
export { stdlib };
// generic helper to disambiguate between custom element and script
const isScript = ({ tagName }) => tagName === "SCRIPT";

View File

@@ -1,6 +1,6 @@
// PyScript py-editor plugin
import { Hook, XWorker, dedent } from "polyscript/exports";
import { TYPES } from "../core.js";
import { TYPES, stdlib } from "../core.js";
const RUN_BUTTON = `<svg style="height:20px;width:20px;vertical-align:-.125em;transform-origin:center;overflow:visible;color:green" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>`;
@@ -8,9 +8,11 @@ let id = 0;
const getID = (type) => `${type}-editor-${id++}`;
const envs = new Map();
const configs = new Map();
const hooks = {
worker: {
codeBeforeRun: () => stdlib,
// works on both Pyodide and MicroPython
onReady: ({ runAsync, io }, { sync }) => {
io.stdout = (line) => sync.write(line);
@@ -32,9 +34,17 @@ async function execute({ currentTarget }) {
if (!envs.has(env)) {
const srcLink = URL.createObjectURL(new Blob([""]));
const xworker = XWorker.call(new Hook(null, hooks), srcLink, {
type: this.interpreter,
});
const details = { type: this.interpreter };
const { config } = this;
if (config) {
details.configURL = config;
const { parse } = config.endsWith(".toml")
? await import(/* webpackIgnore: true */ "../3rd-party/toml.js")
: JSON;
details.config = parse(await fetch(config).then((r) => r.text()));
}
const xworker = XWorker.call(new Hook(null, hooks), srcLink, details);
const { sync } = xworker;
const { promise, resolve } = Promise.withResolvers();
@@ -138,13 +148,28 @@ const init = async (script, type, interpreter) => {
]);
const isSetup = script.hasAttribute("setup");
const hasConfig = script.hasAttribute("config");
const env = `${interpreter}-${script.getAttribute("env") || getID(type)}`;
if (hasConfig && configs.has(env)) {
throw new SyntaxError(
configs.get(env)
? `duplicated config for env: ${env}`
: `unable to add a config to the env: ${env}`,
);
}
configs.set(env, hasConfig);
const source = script.src
? await fetch(script.src).then((b) => b.text())
: script.textContent;
const context = {
interpreter,
env,
config:
hasConfig &&
new URL(script.getAttribute("config"), location.href).href,
get pySrc() {
return isSetup ? source : editor.state.doc.toString();
},
@@ -225,7 +250,7 @@ const resetTimeout = () => {
};
// triggered both ASAP on the living DOM and via MutationObserver later
const pyEditor = async () => {
const pyEditor = () => {
if (timeout) return;
timeout = setTimeout(resetTimeout, 250);
for (const [type, interpreter] of TYPES) {