From af72e232c310327264c6bb072a8d6c779e7c39ba Mon Sep 17 00:00:00 2001 From: Andrea Giammarchi Date: Thu, 8 Jun 2023 11:10:47 +0200 Subject: [PATCH] Worker sync utility (#1511) * patched an issue with wasmoon randomly asking to resolve proxy references * simplified pyodide and micropython dance by grouping their common utilities together * created an integration test around a worker to main thread input between MicroPython and Lua * commented some weird bugs / funny behaviors around both MicroPython and Pyodide * other minor clean ups --- .pre-commit-config.yaml | 2 +- .prettierignore | 1 + pyscript.core/cjs/package.json | 1 + pyscript.core/esm/loader.js | 7 ++- pyscript.core/esm/runtime/_python.js | 27 +++++++++ pyscript.core/esm/runtime/_utils.js | 20 ++++++- pyscript.core/esm/runtime/micropython.js | 33 +++++------ pyscript.core/esm/runtime/pyodide.js | 33 +++++------ pyscript.core/esm/toml.js | 2 +- pyscript.core/esm/utils.js | 13 ++++- pyscript.core/esm/worker/_template.js | 14 +++-- pyscript.core/esm/worker/class.js | 16 ++++-- pyscript.core/node.importmap | 2 +- pyscript.core/package-lock.json | 68 +++++++++++++++++----- pyscript.core/package.json | 12 ++-- pyscript.core/rollup/min.config.js | 2 +- pyscript.core/rollup/xworker.config.js | 2 +- pyscript.core/test/order.html | 4 +- pyscript.core/test/ruby.html | 4 +- pyscript.core/test/test.html | 4 +- pyscript.core/test/wasmoon.html | 4 +- pyscript.core/test/worker/index.html | 2 + pyscript.core/test/worker/input.html | 73 ++++++++++++++++++++++++ pyscript.core/test/worker/input.lua | 2 + pyscript.core/test/worker/input.py | 4 ++ pyscript.core/test/worker/input.rb | 6 ++ 26 files changed, 277 insertions(+), 81 deletions(-) create mode 100644 pyscript.core/cjs/package.json create mode 100644 pyscript.core/esm/runtime/_python.js create mode 100644 pyscript.core/test/worker/input.html create mode 100644 pyscript.core/test/worker/input.lua create mode 100644 pyscript.core/test/worker/input.py create mode 100644 pyscript.core/test/worker/input.rb diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e8751823..14e99e2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: check-docstring-first - id: check-executables-have-shebangs - id: check-json - exclude: tsconfig.json + exclude: tsconfig.json pyscript.core/cjs/package.json - id: check-toml - id: check-xml - id: check-yaml diff --git a/.prettierignore b/.prettierignore index ac0df8f6..2797bf5c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,4 +7,5 @@ pyscript.core/micropython/ pyscript.core/pyscript/ pyscript.core/types/ pyscript.core/esm/worker/xworker.js +pyscript.core/cjs/package.json pyscript.core/min.js diff --git a/pyscript.core/cjs/package.json b/pyscript.core/cjs/package.json new file mode 100644 index 00000000..729ac4d9 --- /dev/null +++ b/pyscript.core/cjs/package.json @@ -0,0 +1 @@ +{"type":"commonjs"} diff --git a/pyscript.core/esm/loader.js b/pyscript.core/esm/loader.js index 610ed737..ce69789b 100644 --- a/pyscript.core/esm/loader.js +++ b/pyscript.core/esm/loader.js @@ -13,10 +13,11 @@ export const getRuntime = (id, config) => { if (config) { // REQUIRES INTEGRATION TEST /* c8 ignore start */ - if (config.endsWith(".json")) options = fetch(config).then(getJSON); - else if (config.endsWith(".toml")) + if (config.endsWith(".json")) { + options = fetch(config).then(getJSON); + } else if (config.endsWith(".toml")) { options = fetch(config).then(getText).then(parse); - else { + } else { try { options = JSON.parse(config); } catch (_) { diff --git a/pyscript.core/esm/runtime/_python.js b/pyscript.core/esm/runtime/_python.js new file mode 100644 index 00000000..7ff88a6b --- /dev/null +++ b/pyscript.core/esm/runtime/_python.js @@ -0,0 +1,27 @@ +import { clean, writeFile as writeFileUtil } from "./_utils.js"; + +// REQUIRES INTEGRATION TEST +/* c8 ignore start */ +export const run = (runtime, code) => runtime.runPython(clean(code)); + +export const runAsync = (runtime, code) => runtime.runPythonAsync(clean(code)); + +export function runEvent(runtime, code, key) { + code = `import js;event=js.__events.get(${key});${code}`; + return this.run(runtime, code); +} + +const worker = (method) => + function (runtime, code, xworker) { + code = `from js import xworker;${code}`; + globalThis.xworker = xworker; + return this[method](runtime, code); + }; + +export const runWorker = worker("run"); + +export const runWorkerAsync = worker("runAsync"); + +export const writeFile = ({ FS }, path, buffer) => + writeFileUtil(FS, path, buffer); +/* c8 ignore stop */ diff --git a/pyscript.core/esm/runtime/_utils.js b/pyscript.core/esm/runtime/_utils.js index eac9972f..e36570a4 100644 --- a/pyscript.core/esm/runtime/_utils.js +++ b/pyscript.core/esm/runtime/_utils.js @@ -1,10 +1,26 @@ import { getBuffer } from "../fetch-utils.js"; -import { absoluteURL } from "../utils.js"; +import { absoluteURL, defineProperty } from "../utils.js"; +import "@ungap/with-resolvers"; + +// REQUIRES INTEGRATION TEST +/* c8 ignore start */ +// TODO: this should *NOT* be needed as the polyfill +// already patches on demand the Promise object +const { withResolvers } = Promise; +defineProperty(globalThis, "Promise", { + configurable: true, + value: class extends Promise { + withResolvers() { + return withResolvers.call(this); + } + }, +}); +/* c8 ignore stop */ /** * Trim code only if it's a single line that prettier or other tools might have modified. * @param {string} code code that might be a single line - * @returns {strong} + * @returns {string} */ export const clean = (code) => code.replace(/^[^\r\n]+$/, (line) => line.trim()); diff --git a/pyscript.core/esm/runtime/micropython.js b/pyscript.core/esm/runtime/micropython.js index 08cbe221..3098dab8 100644 --- a/pyscript.core/esm/runtime/micropython.js +++ b/pyscript.core/esm/runtime/micropython.js @@ -1,15 +1,17 @@ -import { clean, fetchPaths, stdio, writeFile } from "./_utils.js"; +import { fetchPaths, stdio } from "./_utils.js"; +import { + run, + runAsync, + runEvent, + runWorker, + runWorkerAsync, + writeFile, +} from "./_python.js"; const type = "micropython"; // REQUIRES INTEGRATION TEST /* c8 ignore start */ -const worker = (method) => - function (runtime, code, xworker) { - globalThis.xworker = xworker; - return this[method](runtime, `from js import xworker;${code}`); - }; - export default { type: [type, "mpy"], module: () => `http://localhost:8080/micropython/micropython.mjs`, @@ -20,16 +22,11 @@ export default { if (config.fetch) await fetchPaths(this, runtime, config.fetch); return runtime; }, - run: (runtime, code) => runtime.runPython(clean(code)), - runAsync: (runtime, code) => runtime.runPythonAsync(clean(code)), - runEvent(runtime, code, key) { - return this.run( - runtime, - `import js;event=js.__events.get(${key});${code}`, - ); - }, - runWorker: worker("run"), - runWorkerAsync: worker("runAsync"), - writeFile: ({ FS }, path, buffer) => writeFile(FS, path, buffer), + run, + runAsync, + runEvent, + runWorker, + runWorkerAsync, + writeFile, }; /* c8 ignore stop */ diff --git a/pyscript.core/esm/runtime/pyodide.js b/pyscript.core/esm/runtime/pyodide.js index 9068d7e6..244d8eaa 100644 --- a/pyscript.core/esm/runtime/pyodide.js +++ b/pyscript.core/esm/runtime/pyodide.js @@ -1,15 +1,17 @@ -import { clean, fetchPaths, stdio, writeFile } from "./_utils.js"; +import { fetchPaths, stdio } from "./_utils.js"; +import { + run, + runAsync, + runEvent, + runWorker, + runWorkerAsync, + writeFile, +} from "./_python.js"; const type = "pyodide"; // REQUIRES INTEGRATION TEST /* c8 ignore start */ -const worker = (method) => - function (runtime, code, xworker) { - globalThis.xworker = xworker; - return this[method](runtime, `from js import xworker;${code}`); - }; - export default { type: [type, "py"], module: (version = "0.22.1") => @@ -26,16 +28,11 @@ export default { } return runtime; }, - run: (runtime, code) => runtime.runPython(clean(code)), - runAsync: (runtime, code) => runtime.runPythonAsync(clean(code)), - runEvent(runtime, code, key) { - return this.run( - runtime, - `import js;event=js.__events.get(${key});${code}`, - ); - }, - runWorker: worker("run"), - runWorkerAsync: worker("runAsync"), - writeFile: ({ FS }, path, buffer) => writeFile(FS, path, buffer), + run, + runAsync, + runEvent, + runWorker, + runWorkerAsync, + writeFile, }; /* c8 ignore stop */ diff --git a/pyscript.core/esm/toml.js b/pyscript.core/esm/toml.js index aba6ace7..34f464f3 100644 --- a/pyscript.core/esm/toml.js +++ b/pyscript.core/esm/toml.js @@ -1,5 +1,5 @@ // lazy TOML parser (fast-toml might be a better alternative) -const TOML_LIB = `https://unpkg.com/basic-toml@0.3.1/es.js`; +const TOML_LIB = `https://cdn.jsdelivr.net/npm/basic-toml@0.3.1/es.js`; /** * @param {string} text TOML text to parse diff --git a/pyscript.core/esm/utils.js b/pyscript.core/esm/utils.js index c1a80c2a..d5c18482 100644 --- a/pyscript.core/esm/utils.js +++ b/pyscript.core/esm/utils.js @@ -1,6 +1,6 @@ const { isArray } = Array; -const { assign, create, defineProperty } = Object; +const { assign, create, defineProperties, defineProperty } = Object; const { all, resolve } = new Proxy(Promise, { get: ($, name) => $[name].bind($), @@ -8,4 +8,13 @@ const { all, resolve } = new Proxy(Promise, { const absoluteURL = (path, base = location.href) => new URL(path, base).href; -export { isArray, assign, create, defineProperty, all, resolve, absoluteURL }; +export { + isArray, + assign, + create, + defineProperties, + defineProperty, + all, + resolve, + absoluteURL, +}; diff --git a/pyscript.core/esm/worker/_template.js b/pyscript.core/esm/worker/_template.js index 825fb349..1f55c412 100644 --- a/pyscript.core/esm/worker/_template.js +++ b/pyscript.core/esm/worker/_template.js @@ -4,6 +4,8 @@ // Please check via `npm run size` that worker code is not much // bigger than it used to be before any changes is applied to this file. +import coincident from "coincident/structured"; + import { registry } from "../runtimes.js"; import { getRuntime, getRuntimeID } from "../loader.js"; @@ -20,7 +22,11 @@ const add = (type, fn) => { !!fn && { once: true }, ); }; + const xworker = { + // allows synchronous utilities between this worker and the main thread + sync: coincident(self), + // standard worker related events / features onerror() {}, onmessage() {}, onmessageerror() {}, @@ -35,16 +41,14 @@ const xworker = { return event; }, }; + add("message", ({ data: { options, code } }) => { engine = (async () => { const { type, version, config, async: isAsync } = options; const engine = await getRuntime(getRuntimeID(type, version), config); const details = registry.get(type); - (run = details[`runWorker${isAsync ? "Async" : ""}`].bind(details))( - engine, - code, - (globalThis.xworker = xworker), - ); + run = details[`runWorker${isAsync ? "Async" : ""}`].bind(details); + run(engine, code, xworker); return engine; })(); add("error"); diff --git a/pyscript.core/esm/worker/class.js b/pyscript.core/esm/worker/class.js index 888f29f9..11c073c1 100644 --- a/pyscript.core/esm/worker/class.js +++ b/pyscript.core/esm/worker/class.js @@ -1,5 +1,6 @@ +import coincident from "coincident/structured"; import xworker from "./xworker.js"; -import { assign, defineProperty, absoluteURL } from "../utils.js"; +import { assign, defineProperties, absoluteURL } from "../utils.js"; import { getText } from "../fetch-utils.js"; /** @@ -28,8 +29,15 @@ export default (...args) => const bootstrap = fetch(url) .then(getText) .then((code) => postMessage.call(worker, { options, code })); - return defineProperty(worker, "postMessage", { - value: (data, ...rest) => - bootstrap.then(() => postMessage.call(worker, data, ...rest)), + return defineProperties(worker, { + postMessage: { + value: (data, ...rest) => + bootstrap.then(() => + postMessage.call(worker, data, ...rest), + ), + }, + sync: { + value: coincident(worker), + }, }); }; diff --git a/pyscript.core/node.importmap b/pyscript.core/node.importmap index 6044292c..83d0226b 100644 --- a/pyscript.core/node.importmap +++ b/pyscript.core/node.importmap @@ -3,6 +3,6 @@ "http://pyodide": "./test/mocked/pyodide.mjs", "https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.mjs": "./test/mocked/pyodide.mjs", "http://localhost:8080/micropython/micropython.mjs": "./test/mocked/micropython.mjs", - "https://unpkg.com/basic-toml@0.3.1/es.js": "./test/mocked/toml.mjs" + "https://cdn.jsdelivr.net/npm/basic-toml@0.3.1/es.js": "./test/mocked/toml.mjs" } } diff --git a/pyscript.core/package-lock.json b/pyscript.core/package-lock.json index 003a3ea9..bf9480f7 100644 --- a/pyscript.core/package-lock.json +++ b/pyscript.core/package-lock.json @@ -9,7 +9,9 @@ "version": "0.0.0", "license": "ISC", "dependencies": { - "basic-devtools": "^0.1.6" + "@ungap/with-resolvers": "^0.1.0", + "basic-devtools": "^0.1.6", + "coincident": "^0.2.3" }, "devDependencies": { "@node-loader/import-maps": "^1.1.0", @@ -19,8 +21,8 @@ "c8": "^7.14.0", "eslint": "^8.42.0", "linkedom": "^0.14.26", - "rollup": "^3.23.1", - "static-handler": "^0.4.0", + "rollup": "^3.24.0", + "static-handler": "^0.4.1", "typescript": "^5.1.3" } }, @@ -335,6 +337,16 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@ungap/with-resolvers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@ungap/with-resolvers/-/with-resolvers-0.1.0.tgz", + "integrity": "sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw==" + }, "node_modules/acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", @@ -521,6 +533,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/coincident": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/coincident/-/coincident-0.2.3.tgz", + "integrity": "sha512-zCHSEa8x6HcXTaPQLH89//mu7UQn/Iie2xcSOhTMPu546lboT7Js2vr1HIlZHISe82++0y7JSnX/7gIWy0bcrw==", + "dependencies": { + "@ungap/structured-clone": "^1.2.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1647,9 +1667,9 @@ } }, "node_modules/rollup": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.23.1.tgz", - "integrity": "sha512-ybRdFVHOoljGEFILHLd2g/qateqUdjE6YS41WXq4p3C/WwD3xtWxV4FYWETA1u9TeXQc5K8L8zHE5d/scOvrOQ==", + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.24.0.tgz", + "integrity": "sha512-OgraHOIg2YpHQTjl0/ymWfFNBEyPucB7lmhXrQUh38qNOegxLapSPFs9sNr0qKR75awW41D93XafoR2QfhBdUQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -1776,9 +1796,9 @@ } }, "node_modules/static-handler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/static-handler/-/static-handler-0.4.0.tgz", - "integrity": "sha512-ixtyrMNaN6Z0jW4RDJWL9BJT2kZ4wX05+D1XNGOOXxeUqrpk4MhZtMXdqQGxitRSrDCO6/Esjdq28rrvzDeYEw==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/static-handler/-/static-handler-0.4.1.tgz", + "integrity": "sha512-atl+UofbqCECS4Ag1ZZIjC606I1I40CuDsdq4YQ5Vq3vTsUbvqVaNG4evFsKktlnPcEm217vBUSEFKyi9lsJ8Q==", "dev": true, "dependencies": { "mime-types": "^2.1.34" @@ -2275,6 +2295,16 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "@ungap/with-resolvers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@ungap/with-resolvers/-/with-resolvers-0.1.0.tgz", + "integrity": "sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw==" + }, "acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", @@ -2416,6 +2446,14 @@ "wrap-ansi": "^7.0.0" } }, + "coincident": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/coincident/-/coincident-0.2.3.tgz", + "integrity": "sha512-zCHSEa8x6HcXTaPQLH89//mu7UQn/Iie2xcSOhTMPu546lboT7Js2vr1HIlZHISe82++0y7JSnX/7gIWy0bcrw==", + "requires": { + "@ungap/structured-clone": "^1.2.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3243,9 +3281,9 @@ } }, "rollup": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.23.1.tgz", - "integrity": "sha512-ybRdFVHOoljGEFILHLd2g/qateqUdjE6YS41WXq4p3C/WwD3xtWxV4FYWETA1u9TeXQc5K8L8zHE5d/scOvrOQ==", + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.24.0.tgz", + "integrity": "sha512-OgraHOIg2YpHQTjl0/ymWfFNBEyPucB7lmhXrQUh38qNOegxLapSPFs9sNr0qKR75awW41D93XafoR2QfhBdUQ==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -3325,9 +3363,9 @@ } }, "static-handler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/static-handler/-/static-handler-0.4.0.tgz", - "integrity": "sha512-ixtyrMNaN6Z0jW4RDJWL9BJT2kZ4wX05+D1XNGOOXxeUqrpk4MhZtMXdqQGxitRSrDCO6/Esjdq28rrvzDeYEw==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/static-handler/-/static-handler-0.4.1.tgz", + "integrity": "sha512-atl+UofbqCECS4Ag1ZZIjC606I1I40CuDsdq4YQ5Vq3vTsUbvqVaNG4evFsKktlnPcEm217vBUSEFKyi9lsJ8Q==", "dev": true, "requires": { "mime-types": "^2.1.34" diff --git a/pyscript.core/package.json b/pyscript.core/package.json index c7a4696a..5a49fc0c 100644 --- a/pyscript.core/package.json +++ b/pyscript.core/package.json @@ -5,7 +5,7 @@ "main": "./cjs/index.js", "types": "./types/index.d.ts", "scripts": { - "server": "npx static-handler --cors --coep --coop .", + "server": "npx static-handler --cors --coep --coop --corp .", "build": "npm run rollup:xworker && npm run rollup:min && eslint esm/ && npm run ts && npm run cjs && npm run test", "cjs": "ascjs --no-default esm cjs", "rollup:min": "rollup --config rollup/min.config.js", @@ -29,8 +29,8 @@ "c8": "^7.14.0", "eslint": "^8.42.0", "linkedom": "^0.14.26", - "rollup": "^3.23.1", - "static-handler": "^0.4.0", + "rollup": "^3.24.0", + "static-handler": "^0.4.1", "typescript": "^5.1.3" }, "module": "./esm/index.js", @@ -45,9 +45,11 @@ }, "unpkg": "min.js", "dependencies": { - "basic-devtools": "^0.1.6" + "@ungap/with-resolvers": "^0.1.0", + "basic-devtools": "^0.1.6", + "coincident": "^0.2.3" }, "worker": { - "blob": "sha256-kYwW0+fdul6LFbjoFeqku+pa9ARFxRtfmeM6zF53zLo=" + "blob": "sha256-T0DDfoQde+3gciIoHqPGP2SgMQpbY/nAMjfd1cg8jyA=" } } diff --git a/pyscript.core/rollup/min.config.js b/pyscript.core/rollup/min.config.js index c9300fb4..3ab77e97 100644 --- a/pyscript.core/rollup/min.config.js +++ b/pyscript.core/rollup/min.config.js @@ -10,7 +10,7 @@ createRequire(import.meta.url)("./build_xworker.cjs"); export default { input: "./esm/index.js", - plugins: [nodeResolve(), terser()], + plugins: process.env.NO_MIN ? [nodeResolve()] : [nodeResolve(), terser()], output: { esModule: true, file: "./min.js", diff --git a/pyscript.core/rollup/xworker.config.js b/pyscript.core/rollup/xworker.config.js index 28f74149..a6b06f95 100644 --- a/pyscript.core/rollup/xworker.config.js +++ b/pyscript.core/rollup/xworker.config.js @@ -16,7 +16,7 @@ const WORKERS_DIR = resolve( export default { input: join(WORKERS_DIR, "_template.js"), - plugins: [nodeResolve(), terser()], + plugins: process.env.NO_MIN ? [nodeResolve()] : [nodeResolve(), terser()], output: { esModule: true, file: join(WORKERS_DIR, "__template.js"), diff --git a/pyscript.core/test/order.html b/pyscript.core/test/order.html index f78e5772..91e05912 100644 --- a/pyscript.core/test/order.html +++ b/pyscript.core/test/order.html @@ -8,7 +8,9 @@ diff --git a/pyscript.core/test/ruby.html b/pyscript.core/test/ruby.html index fc230612..d42b729e 100644 --- a/pyscript.core/test/ruby.html +++ b/pyscript.core/test/ruby.html @@ -8,7 +8,9 @@ diff --git a/pyscript.core/test/test.html b/pyscript.core/test/test.html index 5b34f105..dce7a02d 100644 --- a/pyscript.core/test/test.html +++ b/pyscript.core/test/test.html @@ -8,7 +8,9 @@ diff --git a/pyscript.core/test/wasmoon.html b/pyscript.core/test/wasmoon.html index 3ea9ebd5..6076a680 100644 --- a/pyscript.core/test/wasmoon.html +++ b/pyscript.core/test/wasmoon.html @@ -8,7 +8,9 @@ diff --git a/pyscript.core/test/worker/index.html b/pyscript.core/test/worker/index.html index 3a3c30e4..aecdfac7 100644 --- a/pyscript.core/test/worker/index.html +++ b/pyscript.core/test/worker/index.html @@ -8,6 +8,8 @@ { "imports": { "basic-devtools": "../../node_modules/basic-devtools/esm/index.js", + "coincident/structured": "../../node_modules/coincident/structured.js", + "@ungap/with-resolvers": "../../node_modules/@ungap/with-resolvers/index.js", "@pyscript/core": "../../esm/index.js" } } diff --git a/pyscript.core/test/worker/input.html b/pyscript.core/test/worker/input.html new file mode 100644 index 00000000..11d10a73 --- /dev/null +++ b/pyscript.core/test/worker/input.html @@ -0,0 +1,73 @@ + + + + + + python workers + + + + + + + + + + + + diff --git a/pyscript.core/test/worker/input.lua b/pyscript.core/test/worker/input.lua new file mode 100644 index 00000000..a341e2d0 --- /dev/null +++ b/pyscript.core/test/worker/input.lua @@ -0,0 +1,2 @@ +print('What is 2 + 3?') +print('Answer: ' .. xworker.sync.input('What is 2 + 3?')) diff --git a/pyscript.core/test/worker/input.py b/pyscript.core/test/worker/input.py new file mode 100644 index 00000000..b94e4aed --- /dev/null +++ b/pyscript.core/test/worker/input.py @@ -0,0 +1,4 @@ +from js import xworker + +print("What is 2 + 3?") +print("Answer: " + xworker.sync.input("What is 2 + 3?")) diff --git a/pyscript.core/test/worker/input.rb b/pyscript.core/test/worker/input.rb new file mode 100644 index 00000000..b5f8d218 --- /dev/null +++ b/pyscript.core/test/worker/input.rb @@ -0,0 +1,6 @@ +require "js" + +xworker = JS::eval("return xworker") + +puts "What is 2 + 3?" +puts xworker.sync.input("What is 2 + 3?")