[RC] Work on the reverted changes (#1753)

This commit is contained in:
Andrea Giammarchi
2023-09-25 11:41:34 +02:00
committed by GitHub
parent c9e7fe16e4
commit e4eedd80bc
14 changed files with 184 additions and 120 deletions

View File

@@ -1,3 +1,4 @@
.pytest_cache/
node_modules/
rollup/
test/

View File

@@ -1,12 +1,12 @@
{
"name": "@pyscript/core",
"version": "0.2.0",
"version": "0.2.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@pyscript/core",
"version": "0.2.0",
"version": "0.2.2",
"license": "APACHE-2.0",
"dependencies": {
"@ungap/with-resolvers": "^0.1.0",
@@ -16,7 +16,7 @@
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-terser": "^0.4.3",
"rollup": "^3.29.2",
"rollup": "^3.29.3",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-string": "^3.0.0",
"static-handler": "^0.4.2",
@@ -160,9 +160,9 @@
}
},
"node_modules/@types/estree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz",
"integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==",
"dev": true
},
"node_modules/@types/resolve": {
@@ -220,9 +220,9 @@
"dev": true
},
"node_modules/browserslist": {
"version": "4.21.10",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
"integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
"version": "4.21.11",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.11.tgz",
"integrity": "sha512-xn1UXOKUz7DjdGlg9RrUr0GGiWzI97UQJnugHtH0OLDfJB7jMgoIkYvRIEO1l9EeEERVqeqLYOcFBW9ldjypbQ==",
"dev": true,
"funding": [
{
@@ -239,10 +239,10 @@
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001517",
"electron-to-chromium": "^1.4.477",
"caniuse-lite": "^1.0.30001538",
"electron-to-chromium": "^1.4.526",
"node-releases": "^2.0.13",
"update-browserslist-db": "^1.0.11"
"update-browserslist-db": "^1.0.13"
},
"bin": {
"browserslist": "cli.js"
@@ -282,9 +282,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001534",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz",
"integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==",
"version": "1.0.30001539",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001539.tgz",
"integrity": "sha512-hfS5tE8bnNiNvEOEkm8HElUHroYwlqMMENEzELymy77+tJ6m+gA2krtHl5hxJaj71OlpC2cHZbdSMX1/YEqEkA==",
"dev": true,
"funding": [
{
@@ -597,9 +597,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.520",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.520.tgz",
"integrity": "sha512-Frfus2VpYADsrh1lB3v/ft/WVFlVzOIm+Q0p7U7VqHI6qr7NWHYKe+Wif3W50n7JAFoBsWVsoU0+qDks6WQ60g==",
"version": "1.4.528",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.528.tgz",
"integrity": "sha512-UdREXMXzLkREF4jA8t89FQjA8WHI6ssP38PMY4/4KhXFQbtImnghh4GkCgrtiZwLKUKVD2iTVXvDVQjfomEQuA==",
"dev": true
},
"node_modules/entities": {
@@ -960,9 +960,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz",
"integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==",
"version": "8.4.30",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz",
"integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
"dev": true,
"funding": [
{
@@ -1538,9 +1538,9 @@
}
},
"node_modules/resolve": {
"version": "1.22.4",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
"integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==",
"version": "1.22.6",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
"integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==",
"dev": true,
"dependencies": {
"is-core-module": "^2.13.0",
@@ -1564,9 +1564,9 @@
}
},
"node_modules/rollup": {
"version": "3.29.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz",
"integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==",
"version": "3.29.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.3.tgz",
"integrity": "sha512-T7du6Hum8jOkSWetjRgbwpM6Sy0nECYrYRSmZjayFcOddtKJWU4d17AC3HNUk7HRuqy4p+G7aEZclSHytqUmEg==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
@@ -1666,9 +1666,9 @@
}
},
"node_modules/smob": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz",
"integrity": "sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==",
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz",
"integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==",
"dev": true
},
"node_modules/source-map": {
@@ -1796,9 +1796,9 @@
}
},
"node_modules/terser": {
"version": "5.19.4",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz",
"integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==",
"version": "5.20.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz",
"integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -1833,9 +1833,9 @@
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
"integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
"dev": true,
"funding": [
{
@@ -1869,9 +1869,9 @@
"dev": true
},
"node_modules/ws": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.1.tgz",
"integrity": "sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==",
"version": "8.14.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
"optional": true,
"engines": {
"node": ">=10.0.0"

View File

@@ -1,6 +1,6 @@
{
"name": "@pyscript/core",
"version": "0.2.0",
"version": "0.2.2",
"type": "module",
"description": "PyScript",
"module": "./index.js",
@@ -38,7 +38,7 @@
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-terser": "^0.4.3",
"rollup": "^3.29.2",
"rollup": "^3.29.3",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-string": "^3.0.0",
"static-handler": "^0.4.2",

View File

@@ -5,6 +5,7 @@
*/
import { $ } from "basic-devtools";
import TYPES from "./types.js";
import allPlugins from "./plugins.js";
import { robustFetch as fetch, getText } from "./fetch.js";
import { ErrorCode } from "./exceptions.js";
@@ -19,9 +20,10 @@ const badURL = (url, expected = "") => {
* Given a string, returns its trimmed content as text,
* fetching it from a file if the content is a URL.
* @param {string} config either JSON, TOML, or a file to fetch
* @param {string?} type the optional type to enforce
* @returns {{json: boolean, toml: boolean, text: string}}
*/
const configDetails = async (config) => {
const configDetails = async (config, type) => {
let text = config?.trim();
// we only support an object as root config
let url = "",
@@ -45,74 +47,81 @@ const syntaxError = (type, url, { message }) => {
return new SyntaxError(`${str}\n${message}`);
};
// find the shared config for all py-script elements
let config, type;
const configs = new Map();
/** @type {Promise<any> | undefined} A Promise wrapping any plugins which should be loaded. */
let plugins;
/** @type {any} The PyScript configuration parsed from the JSON or TOML object*. May be any of the return types of JSON.parse() or toml-j0.4's parse() ( {number | string | boolean | null | object | Array} ) */
let parsed;
/** @type {SyntaxError | undefined} The error thrown when parsing the PyScript config, if any.*/
let error;
for (const [TYPE] of TYPES) {
/** @type {Promise<any> | undefined} A Promise wrapping any plugins which should be loaded. */
let plugins;
let pyConfig = $("py-config");
if (pyConfig) {
config = pyConfig.getAttribute("src") || pyConfig.textContent;
type = pyConfig.getAttribute("type");
} else {
pyConfig = $(
[
'script[type="py"][config]:not([worker])',
"py-script[config]:not([worker])",
].join(","),
);
if (pyConfig) config = pyConfig.getAttribute("config");
}
/** @type {any} The PyScript configuration parsed from the JSON or TOML object*. May be any of the return types of JSON.parse() or toml-j0.4's parse() ( {number | string | boolean | null | object | Array} ) */
let parsed;
// catch possible fetch errors
if (config) {
try {
const { json, toml, text, url } = await configDetails(config);
config = text;
if (json || type === "json") {
try {
parsed = JSON.parse(text);
} catch (e) {
error = syntaxError("JSON", url, e);
}
} else if (toml || type === "toml") {
try {
const { parse } = await import(
/* webpackIgnore: true */
"https://cdn.jsdelivr.net/npm/@webreflection/toml-j0.4/toml.js"
);
parsed = parse(text);
} catch (e) {
error = syntaxError("TOML", url, e);
}
}
} catch (e) {
error = e;
/** @type {SyntaxError | undefined} The error thrown when parsing the PyScript config, if any.*/
let error;
let config,
type,
pyConfig = $(`${TYPE}-config`);
if (pyConfig) {
config = pyConfig.getAttribute("src") || pyConfig.textContent;
type = pyConfig.getAttribute("type");
} else {
pyConfig = $(
[
`script[type="${TYPE}"][config]:not([worker])`,
`${TYPE}-script[config]:not([worker])`,
].join(","),
);
if (pyConfig) config = pyConfig.getAttribute("config");
}
}
// parse all plugins and optionally ignore only
// those flagged as "undesired" via `!` prefix
const toBeAwaited = [];
for (const [key, value] of Object.entries(allPlugins)) {
if (error) {
if (key === "error") {
// show on page the config is broken, meaning that
// it was not possible to disable error plugin neither
// as that part wasn't correctly parsed anyway
value().then(({ notify }) => notify(error.message));
// catch possible fetch errors
if (config) {
try {
const { json, toml, text, url } = await configDetails(config, type);
config = text;
if (json || type === "json") {
try {
parsed = JSON.parse(text);
} catch (e) {
error = syntaxError("JSON", url, e);
}
} else if (toml || type === "toml") {
try {
const { parse } = await import(
/* webpackIgnore: true */
"https://cdn.jsdelivr.net/npm/@webreflection/toml-j0.4/toml.js"
);
parsed = parse(text);
} catch (e) {
error = syntaxError("TOML", url, e);
}
}
} catch (e) {
error = e;
}
} else if (!parsed?.plugins?.includes(`!${key}`)) {
toBeAwaited.push(value());
}
// parse all plugins and optionally ignore only
// those flagged as "undesired" via `!` prefix
const toBeAwaited = [];
for (const [key, value] of Object.entries(allPlugins)) {
if (error) {
if (key === "error") {
// show on page the config is broken, meaning that
// it was not possible to disable error plugin neither
// as that part wasn't correctly parsed anyway
value().then(({ notify }) => notify(error.message));
}
} else if (!parsed?.plugins?.includes(`!${key}`)) {
toBeAwaited.push(value());
}
}
// assign plugins as Promise.all only if needed
if (toBeAwaited.length) plugins = Promise.all(toBeAwaited);
configs.set(TYPE, { config: parsed, plugins, error });
}
// assign plugins as Promise.all only if needed
if (toBeAwaited.length) plugins = Promise.all(toBeAwaited);
export { parsed as config, plugins, error };
export default configs;

View File

@@ -9,10 +9,11 @@ import { queryTarget } from "../node_modules/polyscript/esm/script-handler.js";
import { dedent, dispatch } from "../node_modules/polyscript/esm/utils.js";
import { Hook } from "../node_modules/polyscript/esm/worker/hooks.js";
import { ErrorCode } from "./exceptions.js";
import TYPES from "./types.js";
import configs from "./config.js";
import sync from "./sync.js";
import stdlib from "./stdlib.js";
import { config, plugins, error } from "./config.js";
import { ErrorCode } from "./exceptions.js";
import { robustFetch as fetch, getText } from "./fetch.js";
const { assign, defineProperty } = Object;
@@ -20,11 +21,6 @@ const { assign, defineProperty } = Object;
// allows lazy element features on code evaluation
let currentElement;
const TYPES = new Map([
["py", "pyodide"],
["mpy", "micropython"],
]);
// generic helper to disambiguate between custom element and script
const isScript = ({ tagName }) => tagName === "SCRIPT";
@@ -103,7 +99,12 @@ const workerHooks = {
[...hooks.codeAfterRunWorkerAsync].map(dedent).join("\n"),
};
const exportedConfig = {};
export { exportedConfig as config };
for (const [TYPE, interpreter] of TYPES) {
const { config, plugins, error } = configs.get(TYPE);
// create a unique identifier when/if needed
let id = 0;
const getID = (prefix = TYPE) => `${prefix}-${id++}`;
@@ -273,6 +274,9 @@ for (const [TYPE, interpreter] of TYPES) {
// define py-script only if the config didn't throw an error
if (!error) customElements.define(`${TYPE}-script`, PyScriptElement);
// export the used config without allowing leaks through it
exportedConfig[TYPE] = structuredClone(config);
}
// TBD: I think manual worker cases are interesting in pyodide only

View File

@@ -0,0 +1,4 @@
export default new Map([
["py", "pyodide"],
["mpy", "micropython"],
]);

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Arrr - Piratical PyScript</title>
<link rel="stylesheet" href="../dist/core.css" />
<script type="module" src="../dist/core.js"></script>
</head>
<body>
<h1>Arrr</h1>
<p>Translate English into Pirate speak...</p>
<input type="text" id="english" placeholder="Type English here..." />
<button py-click="translate_english">Translate</button>
<div id="output"></div>
<script type="py" src="./piratical.py" config="./piratical.toml"></script>
</body>
</html>

View File

@@ -0,0 +1,9 @@
import arrr
from js import document
def translate_english(event):
input_text = document.querySelector("#english")
english = input_text.value
output_div = document.querySelector("#output")
output_div.innerText = arrr.translate(english)

View File

@@ -0,0 +1 @@
packages = ["arrr"]

View File

@@ -0,0 +1,20 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PyScript Config</title>
<script type="module">
import { config } from "../dist/core.js";
console.log(config.mpy);
</script>
<link rel="stylesheet" href="../dist/core.css">
<mpy-config>
[[fetch]]
files = ["a.py"]
</mpy-config>
<script type="mpy">
import a
</script>
</head>
</html>

View File

@@ -15,7 +15,7 @@
</script>
<!-- the worker attribute -->
<script type="py" worker="./worker.py" config="./config.json"></script>
<script type="py" src="./worker.py" config="./config.json" worker></script>
<!-- this is only to test the non-blocking behavior -->
<script>

View File

@@ -1,7 +1,2 @@
/** @type {any} The PyScript configuration parsed from the JSON or TOML object*. May be any of the return types of JSON.parse() ( {number | string | boolean | null | object | Array} */
declare let parsed: any;
/** @type {Promise<any> | undefined} A Promise wrapping any plugins which should be loaded. */
export let plugins: Promise<any> | undefined;
/** @type {SyntaxError | undefined} The error thrown when parsing the PyScript config, if any.*/
export let error: SyntaxError | undefined;
export { parsed as config };
export default configs;
declare const configs: Map<any, any>;

View File

@@ -21,5 +21,6 @@ export namespace hooks {
let codeAfterRunWorker: Set<string>;
let codeAfterRunWorkerAsync: Set<string>;
}
import { config } from "./config.js";
export { exportedConfig as config };
import sync from "./sync.js";
declare const exportedConfig: {};

2
pyscript.core/types/types.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
declare const _default: Map<string, string>;
export default _default;