Reduce conflicts on multiple custom scripts (#1897)

This commit is contained in:
Andrea Giammarchi
2023-12-14 18:32:46 +01:00
committed by GitHub
parent 6a3e2834b6
commit 136e95498f
4 changed files with 55 additions and 32 deletions

View File

@@ -1,12 +1,12 @@
{
"name": "@pyscript/core",
"version": "0.3.9",
"version": "0.3.10",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@pyscript/core",
"version": "0.3.9",
"version": "0.3.10",
"license": "APACHE-2.0",
"dependencies": {
"@ungap/with-resolvers": "^0.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@pyscript/core",
"version": "0.3.9",
"version": "0.3.10",
"type": "module",
"description": "PyScript",
"module": "./index.js",

View File

@@ -26,33 +26,9 @@ import { ErrorCode } from "./exceptions.js";
import { robustFetch as fetch, getText } from "./fetch.js";
import { hooks, main, worker, codeFor, createFunction } from "./hooks.js";
// allows lazy element features on code evaluation
let currentElement;
// generic helper to disambiguate between custom element and script
const isScript = ({ tagName }) => tagName === "SCRIPT";
let shouldRegister = true;
const registerModule = ({ XWorker: $XWorker, interpreter, io }) => {
// automatically use the pyscript stderr (when/if defined)
// this defaults to console.error
function PyWorker(...args) {
const worker = $XWorker(...args);
worker.onerror = ({ error }) => io.stderr(error);
return worker;
}
// enrich the Python env with some JS utility for main
interpreter.registerJsModule("_pyscript", {
PyWorker,
get target() {
return isScript(currentElement)
? currentElement.target.id
: currentElement.id;
},
});
};
// avoid multiple initialization of the same library
const [
{
@@ -118,6 +94,36 @@ for (const [TYPE, interpreter] of TYPES) {
return code;
};
// register once any interpreter
let alreadyRegistered = false;
// allows lazy element features on code evaluation
let currentElement;
const registerModule = ({ XWorker, interpreter, io }) => {
// avoid multiple registration of the same interpreter
if (alreadyRegistered) return;
alreadyRegistered = true;
// automatically use the pyscript stderr (when/if defined)
// this defaults to console.error
function PyWorker(...args) {
const worker = XWorker(...args);
worker.onerror = ({ error }) => io.stderr(error);
return worker;
}
// enrich the Python env with some JS utility for main
interpreter.registerJsModule("_pyscript", {
PyWorker,
get target() {
return isScript(currentElement)
? currentElement.target.id
: currentElement.id;
},
});
};
// define the module as both `<script type="py">` and `<py-script>`
// but only if the config didn't throw an error
if (!error) {
@@ -133,10 +139,7 @@ for (const [TYPE, interpreter] of TYPES) {
main: {
...codeFor(main),
async onReady(wrap, element) {
if (shouldRegister) {
shouldRegister = false;
registerModule(wrap);
}
registerModule(wrap);
// allows plugins to do whatever they want with the element
// before regular stuff happens in here
@@ -320,7 +323,7 @@ for (const [TYPE, interpreter] of TYPES) {
function PyWorker(file, options) {
const hooks = hooked.get("py");
// this propagates pyscript worker hooks without needing a pyscript
// bootstrap + it passes arguments and enforces `pyodide`
// bootstrap + it passes arguments and it defaults to `pyodide`
// as the interpreter to use in the worker, as all hooks assume that
// and as `pyodide` is the only default interpreter that can deal with
// all the features we need to deliver pyscript out there.

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">
<script type="module" src="../dist/core.js"></script>
</head>
<body>
<script type="mpy">
from pyscript import document
import sys
document.body.append(sys.version)
</script>
<script type="py">
from pyscript import document
import sys
document.body.append(sys.version)
</script>
</body>
</html>