Skip to content

Commit

Permalink
Fix #1997 - Bring pyscript stdlib to the PyEditor (#2010)
Browse files Browse the repository at this point in the history
* Fix #1997 - Bring pyscript stdlib to the PyEditor
  • Loading branch information
WebReflection committed Mar 28, 2024
1 parent 2f3659b commit 1447cb3
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 75 deletions.
130 changes: 72 additions & 58 deletions pyscript.core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyscript.core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pyscript/core",
"version": "0.4.10",
"version": "0.4.11",
"type": "module",
"description": "PyScript",
"module": "./index.js",
Expand Down Expand Up @@ -62,7 +62,7 @@
"chokidar": "^3.6.0",
"codemirror": "^6.0.1",
"eslint": "^8.57.0",
"rollup": "^4.13.0",
"rollup": "^4.13.1",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-string": "^3.0.0",
"static-handler": "^0.4.3",
Expand Down
3 changes: 3 additions & 0 deletions pyscript.core/src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
35 changes: 30 additions & 5 deletions pyscript.core/src/plugins/py-editor.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
// 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>`;

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);
Expand All @@ -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();
Expand Down Expand Up @@ -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();
},
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions pyscript.core/test/py-editor/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[js_modules.worker]
"https://cdn.jsdelivr.net/npm/html-escaper/+esm" = "html_escaper"

0 comments on commit 1447cb3

Please sign in to comment.