@pyscript/core 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +33 -0
  2. package/cjs/custom-types.js +212 -0
  3. package/cjs/fetch-utils.js +12 -0
  4. package/cjs/index.js +73 -0
  5. package/cjs/interpreter/_python.js +16 -0
  6. package/cjs/interpreter/_utils.js +141 -0
  7. package/cjs/interpreter/micropython.js +34 -0
  8. package/cjs/interpreter/pyodide.js +38 -0
  9. package/cjs/interpreter/ruby-wasm-wasi.js +43 -0
  10. package/cjs/interpreter/wasmoon.js +40 -0
  11. package/cjs/interpreters.js +64 -0
  12. package/cjs/listeners.js +71 -0
  13. package/cjs/loader.js +43 -0
  14. package/cjs/package.json +1 -0
  15. package/cjs/plugins/pyscript.js +105 -0
  16. package/cjs/script-handler.js +141 -0
  17. package/cjs/toml.js +10 -0
  18. package/cjs/utils.js +19 -0
  19. package/cjs/worker/class.js +46 -0
  20. package/cjs/worker/hooks.js +2 -0
  21. package/cjs/worker/xworker.js +3 -0
  22. package/esm/custom-types.js +207 -0
  23. package/esm/fetch-utils.js +8 -0
  24. package/esm/index.js +68 -0
  25. package/esm/interpreter/_python.js +12 -0
  26. package/esm/interpreter/_utils.js +133 -0
  27. package/esm/interpreter/micropython.js +33 -0
  28. package/esm/interpreter/pyodide.js +37 -0
  29. package/esm/interpreter/ruby-wasm-wasi.js +42 -0
  30. package/esm/interpreter/wasmoon.js +39 -0
  31. package/esm/interpreters.js +58 -0
  32. package/esm/listeners.js +68 -0
  33. package/esm/loader.js +40 -0
  34. package/esm/script-handler.js +136 -0
  35. package/esm/toml.js +8 -0
  36. package/esm/utils.js +20 -0
  37. package/esm/worker/class.js +45 -0
  38. package/esm/worker/hooks.js +1 -0
  39. package/esm/worker/xworker.js +2 -0
  40. package/min.js +2 -0
  41. package/package.json +55 -0
  42. package/types/coincident/structured.d.ts +5 -0
  43. package/types/fetch-utils.d.ts +3 -0
  44. package/types/index.d.ts +2 -0
  45. package/types/loader.d.ts +2 -0
  46. package/types/plugins.d.ts +61 -0
  47. package/types/pyscript/pyscript.core/esm/custom-types.d.ts +54 -0
  48. package/types/pyscript/pyscript.core/esm/fetch-utils.d.ts +3 -0
  49. package/types/pyscript/pyscript.core/esm/index.d.ts +2 -0
  50. package/types/pyscript/pyscript.core/esm/interpreter/_python.d.ts +5 -0
  51. package/types/pyscript/pyscript.core/esm/interpreter/_utils.d.ts +11 -0
  52. package/types/pyscript/pyscript.core/esm/interpreter/micropython.d.ts +17 -0
  53. package/types/pyscript/pyscript.core/esm/interpreter/pyodide.d.ts +17 -0
  54. package/types/pyscript/pyscript.core/esm/interpreter/ruby-wasm-wasi.d.ts +15 -0
  55. package/types/pyscript/pyscript.core/esm/interpreter/ruby.d.ts +16 -0
  56. package/types/pyscript/pyscript.core/esm/interpreter/wasmoon.d.ts +21 -0
  57. package/types/pyscript/pyscript.core/esm/interpreters.d.ts +9 -0
  58. package/types/pyscript/pyscript.core/esm/listeners.d.ts +2 -0
  59. package/types/pyscript/pyscript.core/esm/loader.d.ts +2 -0
  60. package/types/pyscript/pyscript.core/esm/plugins.d.ts +54 -0
  61. package/types/pyscript/pyscript.core/esm/runtime/_python.d.ts +8 -0
  62. package/types/pyscript/pyscript.core/esm/runtime/_utils.d.ts +11 -0
  63. package/types/pyscript/pyscript.core/esm/runtime/micropython.d.ts +20 -0
  64. package/types/pyscript/pyscript.core/esm/runtime/pyodide.d.ts +20 -0
  65. package/types/pyscript/pyscript.core/esm/runtime/ruby.d.ts +15 -0
  66. package/types/pyscript/pyscript.core/esm/runtime/wasmoon.d.ts +21 -0
  67. package/types/pyscript/pyscript.core/esm/runtimes.d.ts +9 -0
  68. package/types/pyscript/pyscript.core/esm/script-handler.d.ts +4 -0
  69. package/types/pyscript/pyscript.core/esm/toml.d.ts +1 -0
  70. package/types/pyscript/pyscript.core/esm/utils.d.ts +23 -0
  71. package/types/pyscript/pyscript.core/esm/worker/class.d.ts +19 -0
  72. package/types/pyscript/pyscript.core/esm/worker/hooks.d.ts +2 -0
  73. package/types/pyscript/pyscript.core/esm/worker/xworker.d.ts +2 -0
  74. package/types/runtime/_python.d.ts +8 -0
  75. package/types/runtime/_utils.d.ts +11 -0
  76. package/types/runtime/micropython.d.ts +20 -0
  77. package/types/runtime/pyodide.d.ts +20 -0
  78. package/types/runtime/ruby.d.ts +15 -0
  79. package/types/runtime/wasmoon.d.ts +21 -0
  80. package/types/runtimes.d.ts +9 -0
  81. package/types/script-handler.d.ts +3 -0
  82. package/types/toml.d.ts +1 -0
  83. package/types/utils.d.ts +23 -0
  84. package/types/worker/class.d.ts +19 -0
  85. package/types/worker/hooks.d.ts +2 -0
  86. package/types/worker/xworker.d.ts +2 -0
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+ // ⚠️ Part of this file is automatically generated
3
+ // The :RUNTIMES comment is a delimiter and no code should be written/changed after
4
+ // See rollup/build_interpreters.cjs to know more
5
+
6
+ const { base } = require("./interpreter/_utils.js");
7
+
8
+ /** @type {Map<string, object>} */
9
+ const registry = new Map();
10
+ exports.registry = registry;
11
+
12
+ /** @type {Map<string, object>} */
13
+ const configs = new Map();
14
+ exports.configs = configs;
15
+
16
+ /** @type {string[]} */
17
+ const selectors = [];
18
+ exports.selectors = selectors;
19
+
20
+ /** @type {string[]} */
21
+ const prefixes = [];
22
+ exports.prefixes = prefixes;
23
+
24
+ const interpreter = new Proxy(new Map(), {
25
+ get(map, id) {
26
+ if (!map.has(id)) {
27
+ const [type, ...rest] = id.split("@");
28
+ const interpreter = registry.get(type);
29
+ const url = /^https?:\/\//i.test(rest)
30
+ ? rest.join("@")
31
+ : interpreter.module(...rest);
32
+ map.set(id, {
33
+ url,
34
+ module: import(url),
35
+ engine: interpreter.engine.bind(interpreter),
36
+ });
37
+ }
38
+ const { url, module, engine } = map.get(id);
39
+ return (config, baseURL) =>
40
+ module.then((module) => {
41
+ configs.set(id, config);
42
+ const fetch = config?.fetch;
43
+ if (fetch) base.set(fetch, baseURL);
44
+ return engine(module, config, url);
45
+ });
46
+ },
47
+ });
48
+ exports.interpreter = interpreter;
49
+
50
+ const register = (interpreter) => {
51
+ for (const type of [].concat(interpreter.type)) {
52
+ registry.set(type, interpreter);
53
+ selectors.push(`script[type="${type}"]`);
54
+ prefixes.push(`${type}-`);
55
+ }
56
+ };
57
+
58
+ //:RUNTIMES
59
+ const micropython = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("./interpreter/micropython.js"));
60
+ const pyodide = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("./interpreter/pyodide.js"));
61
+ const ruby_wasm_wasi = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("./interpreter/ruby-wasm-wasi.js"));
62
+ const wasmoon = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("./interpreter/wasmoon.js"));
63
+ for (const interpreter of [micropython, pyodide, ruby_wasm_wasi, wasmoon])
64
+ register(interpreter);
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+ const { $x } = require("basic-devtools");
3
+
4
+ const { interpreters } = require("./script-handler.js");
5
+ const { all, create, defineProperty } = require("./utils.js");
6
+ const { registry, prefixes } = require("./interpreters.js");
7
+
8
+ // TODO: this is ugly; need to find a better way
9
+ defineProperty(globalThis, "pyscript", {
10
+ value: {
11
+ env: new Proxy(create(null), {
12
+ get: (_, name) => awaitInterpreter(name),
13
+ }),
14
+ },
15
+ });
16
+
17
+ /* c8 ignore start */ // attributes are tested via integration / e2e
18
+ // ensure both interpreter and its queue are awaited then returns the interpreter
19
+ const awaitInterpreter = async (key) => {
20
+ if (interpreters.has(key)) {
21
+ const { interpreter, queue } = interpreters.get(key);
22
+ return (await all([interpreter, queue]))[0];
23
+ }
24
+
25
+ const available = interpreters.size
26
+ ? `Available interpreters are: ${[...interpreters.keys()]
27
+ .map((r) => `"${r}"`)
28
+ .join(", ")}.`
29
+ : `There are no interpreters in this page.`;
30
+
31
+ throw new Error(`The interpreter "${key}" was not found. ${available}`);
32
+ };
33
+
34
+ const listener = async (event) => {
35
+ const { type, currentTarget } = event;
36
+ for (let { name, value, ownerElement: el } of $x(
37
+ `./@*[${prefixes.map((p) => `name()="${p}${type}"`).join(" or ")}]`,
38
+ currentTarget,
39
+ )) {
40
+ name = name.slice(0, -(type.length + 1));
41
+ const interpreter = await awaitInterpreter(
42
+ el.getAttribute(`${name}-env`) || name,
43
+ );
44
+ const handler = registry.get(name);
45
+ try {
46
+ handler.setGlobal(interpreter, "event", event);
47
+ handler.run(interpreter, value);
48
+ } finally {
49
+ handler.deleteGlobal(interpreter, "event");
50
+ }
51
+ }
52
+ };
53
+ exports.listener = listener;
54
+
55
+ /**
56
+ * Look for known prefixes and add related listeners.
57
+ * @param {Document | Element} root
58
+ */
59
+ const addAllListeners = (root) => {
60
+ for (let { name, ownerElement: el } of $x(
61
+ `.//@*[${prefixes
62
+ .map((p) => `starts-with(name(),"${p}")`)
63
+ .join(" or ")}]`,
64
+ root,
65
+ )) {
66
+ name = name.slice(name.lastIndexOf("-") + 1);
67
+ if (name !== "env") el.addEventListener(name, listener);
68
+ }
69
+ };
70
+ exports.addAllListeners = addAllListeners;
71
+ /* c8 ignore stop */
package/cjs/loader.js ADDED
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+ const { interpreter } = require("./interpreters.js");
3
+ const { absoluteURL, resolve } = require("./utils.js");
4
+ const { parse } = require("./toml.js");
5
+ const { getJSON, getText } = require("./fetch-utils.js");
6
+
7
+ /**
8
+ * @param {string} id the interpreter name @ version identifier
9
+ * @param {string} [config] optional config file to parse
10
+ * @returns
11
+ */
12
+ const getRuntime = (id, config) => {
13
+ let options = {};
14
+ if (config) {
15
+ // REQUIRES INTEGRATION TEST
16
+ /* c8 ignore start */
17
+ if (config.endsWith(".json")) {
18
+ options = fetch(config).then(getJSON);
19
+ } else if (config.endsWith(".toml")) {
20
+ options = fetch(config).then(getText).then(parse);
21
+ } else {
22
+ try {
23
+ options = JSON.parse(config);
24
+ } catch (_) {
25
+ options = parse(config);
26
+ }
27
+ // make the config a URL to be able to retrieve relative paths from it
28
+ config = absoluteURL("./config.txt");
29
+ }
30
+ /* c8 ignore stop */
31
+ }
32
+ return resolve(options).then((options) => interpreter[id](options, config));
33
+ };
34
+ exports.getRuntime = getRuntime;
35
+
36
+ /**
37
+ * @param {string} type the interpreter type
38
+ * @param {string} [version] the optional interpreter version
39
+ * @returns
40
+ */
41
+ const getRuntimeID = (type, version = "") =>
42
+ `${type}@${version}`.replace(/@$/, "");
43
+ exports.getRuntimeID = getRuntimeID;
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+ require("@ungap/with-resolvers");
3
+ const { $ } = require("basic-devtools");
4
+
5
+ const { define } = require("../index.js");
6
+ const { queryTarget } = require("../script-handler.js");
7
+ const { defineProperty } = require("../utils.js");
8
+ const { getText } = require("../fetch-utils.js");
9
+
10
+ // append ASAP CSS to avoid showing content
11
+ document.head.appendChild(document.createElement("style")).textContent = `
12
+ py-script, py-config {
13
+ display: none;
14
+ }
15
+ `;
16
+
17
+ // create a unique identifier when/if needed
18
+ let id = 0;
19
+ const getID = (prefix = "py-script") => `${prefix}-${id++}`;
20
+
21
+ // find the shared config for all py-script elements
22
+ let config;
23
+ let pyConfig = $("py-config");
24
+ if (pyConfig)
25
+ config = pyConfig.getAttribute("src") || pyConfig.textContent;
26
+ else {
27
+ pyConfig = $('script[type="py"]');
28
+ config = pyConfig?.getAttribute("config");
29
+ }
30
+
31
+ // generic helper to disambiguate between custom element and script
32
+ const isScript = element => element.tagName === "SCRIPT";
33
+
34
+ // helper for all script[type="py"] out there
35
+ const before = (script) => {
36
+ defineProperty(document, "currentScript", {
37
+ configurable: true,
38
+ get: () => script,
39
+ });
40
+ };
41
+
42
+ const after = () => {
43
+ delete document.currentScript;
44
+ };
45
+
46
+ // define the module as both `<script type="py">` and `<py-script>`
47
+ define("py", {
48
+ config,
49
+ env: "py-script",
50
+ interpreter: "pyodide",
51
+ codeBeforeRunWorker: `print("codeBeforeRunWorker")`,
52
+ codeAfterRunWorker: `print("codeAfterRunWorker")`,
53
+ onBeforeRun(pyodide, element) {
54
+ if (isScript(element)) before(element);
55
+ },
56
+ onBeforeRunAync(pyodide, element) {
57
+ if (isScript(element)) before(element);
58
+ },
59
+ onAfterRun(pyodide, element) {
60
+ if (isScript(element)) after();
61
+ },
62
+ onAfterRunAsync(pyodide, element) {
63
+ if (isScript(element)) after();
64
+ },
65
+ async onRuntimeReady(pyodide, element) {
66
+ if (isScript(element)) {
67
+ const {
68
+ attributes: { async: isAsync, target },
69
+ src,
70
+ } = element;
71
+ const hasTarget = !!target?.value;
72
+ const show = hasTarget ?
73
+ queryTarget(target.value) : document.createElement("script-py");
74
+
75
+ if (!hasTarget) element.after(show);
76
+ if (!show.id) show.id = getID();
77
+
78
+ // allows the code to retrieve the target element via
79
+ // document.currentScript.target if needed
80
+ defineProperty(element, "target", {value: show});
81
+
82
+ const code = src ? (await fetch(src).then(getText)) : element.textContent;
83
+ pyodide[`run${isAsync ? "Async" : ""}`](code);
84
+ }
85
+ else {
86
+ // resolve PyScriptElement to allow connectedCallback
87
+ element._pyodide.resolve(pyodide);
88
+ }
89
+ },
90
+ });
91
+
92
+ class PyScriptElement extends HTMLElement {
93
+ constructor() {
94
+ if (!super().id) this.id = getID();
95
+ this._pyodide = Promise.withResolvers();
96
+ }
97
+ async connectedCallback() {
98
+ const { run } = await this._pyodide.promise;
99
+ const result = run(this.textContent);
100
+ if (result) this.replaceChildren(result);
101
+ this.style.display = "block";
102
+ }
103
+ }
104
+
105
+ customElements.define("py-script", PyScriptElement);
@@ -0,0 +1,141 @@
1
+ 'use strict';
2
+ const { $ } = require("basic-devtools");
3
+
4
+ const xworker = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("./worker/class.js"));
5
+ const { getRuntime, getRuntimeID } = require("./loader.js");
6
+ const { registry } = require("./interpreters.js");
7
+ const { all, resolve, defineProperty, absoluteURL } = require("./utils.js");
8
+ const { getText } = require("./fetch-utils.js");
9
+
10
+ const getRoot = (script) => {
11
+ let parent = script;
12
+ while (parent.parentNode) parent = parent.parentNode;
13
+ return parent;
14
+ };
15
+
16
+ const queryTarget = (script, idOrSelector) => {
17
+ const root = getRoot(script);
18
+ return root.getElementById(idOrSelector) || $(idOrSelector, root);
19
+ };
20
+ exports.queryTarget = queryTarget;
21
+
22
+ const targets = new WeakMap();
23
+ const targetDescriptor = {
24
+ get() {
25
+ let target = targets.get(this);
26
+ if (!target) {
27
+ target = document.createElement(`${this.type}-script`);
28
+ targets.set(this, target);
29
+ handle(this);
30
+ }
31
+ return target;
32
+ },
33
+ set(target) {
34
+ if (typeof target === "string")
35
+ targets.set(this, queryTarget(this, target));
36
+ else {
37
+ targets.set(this, target);
38
+ handle(this);
39
+ }
40
+ },
41
+ };
42
+
43
+ const handled = new WeakMap();
44
+
45
+ const interpreters = new Map();
46
+ exports.interpreters = interpreters;
47
+
48
+ const execute = async (script, source, XWorker, isAsync) => {
49
+ const module = registry.get(script.type);
50
+ /* c8 ignore next */
51
+ if (module.experimental)
52
+ console.warn(`The ${script.type} interpreter is experimental`);
53
+ const [interpreter, content] = await all([
54
+ handled.get(script).interpreter,
55
+ source,
56
+ ]);
57
+ try {
58
+ // temporarily override inherited document.currentScript in a non writable way
59
+ // but it deletes it right after to preserve native behavior (as it's sync: no trouble)
60
+ defineProperty(document, "currentScript", {
61
+ configurable: true,
62
+ get: () => script,
63
+ });
64
+ module.setGlobal(interpreter, "XWorker", XWorker);
65
+ return module[isAsync ? "runAsync" : "run"](interpreter, content);
66
+ } finally {
67
+ delete document.currentScript;
68
+ module.deleteGlobal(interpreter, "XWorker");
69
+ }
70
+ };
71
+
72
+ const getValue = (ref, prefix) => {
73
+ const value = ref?.value;
74
+ return value ? prefix + value : "";
75
+ };
76
+
77
+ const getDetails = (type, id, name, version, config) => {
78
+ if (!interpreters.has(id)) {
79
+ const details = {
80
+ interpreter: getRuntime(name, config),
81
+ queue: resolve(),
82
+ XWorker: xworker(type, version),
83
+ };
84
+ interpreters.set(id, details);
85
+ // enable sane defaults when single interpreter *of kind* is used in the page
86
+ // this allows `xxx-*` attributes to refer to such interpreter without `env` around
87
+ if (!interpreters.has(type)) interpreters.set(type, details);
88
+ }
89
+ return interpreters.get(id);
90
+ };
91
+ exports.getDetails = getDetails;
92
+
93
+ /**
94
+ * @param {HTMLScriptElement} script a special type of <script>
95
+ */
96
+ const handle = async (script) => {
97
+ // known node, move its companion target after
98
+ // vDOM or other use cases where the script is a tracked element
99
+ if (handled.has(script)) {
100
+ const { target } = script;
101
+ if (target) {
102
+ // if the script is in the head just append target to the body
103
+ if (script.closest("head")) document.body.append(target);
104
+ // in any other case preserve the script position
105
+ else script.after(target);
106
+ }
107
+ }
108
+ // new script to handle ... allow newly created scripts to work
109
+ // just exactly like any other script would
110
+ else {
111
+ // allow a shared config among scripts, beside interpreter,
112
+ // and/or source code with different config or interpreter
113
+ const {
114
+ attributes: { async: isAsync, config, env, target, version },
115
+ src,
116
+ type,
117
+ } = script;
118
+ const versionValue = version?.value;
119
+ const name = getRuntimeID(type, versionValue);
120
+ const targetValue = getValue(target, "");
121
+ let configValue = getValue(config, "|");
122
+ const id = getValue(env, "") || `${name}${configValue}`;
123
+ configValue = configValue.slice(1);
124
+ if (configValue) configValue = absoluteURL(configValue);
125
+ const details = getDetails(type, id, name, versionValue, configValue);
126
+
127
+ handled.set(
128
+ defineProperty(script, "target", targetDescriptor),
129
+ details,
130
+ );
131
+
132
+ if (targetValue) targets.set(script, queryTarget(script, targetValue));
133
+
134
+ // start fetching external resources ASAP
135
+ const source = src ? fetch(src).then(getText) : script.textContent;
136
+ details.queue = details.queue.then(() =>
137
+ execute(script, source, details.XWorker, !!isAsync),
138
+ );
139
+ }
140
+ };
141
+ exports.handle = handle;
package/cjs/toml.js ADDED
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+ // lazy TOML parser (fast-toml might be a better alternative)
3
+ const TOML_LIB = `https://cdn.jsdelivr.net/npm/basic-toml@0.3.1/es.js`;
4
+
5
+ /**
6
+ * @param {string} text TOML text to parse
7
+ * @returns {object} the resulting JS object
8
+ */
9
+ const parse = async (text) => (await import(TOML_LIB)).parse(text);
10
+ exports.parse = parse;
package/cjs/utils.js ADDED
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+ const { isArray } = Array;
3
+
4
+ const { assign, create, defineProperties, defineProperty } = Object;
5
+
6
+ const { all, resolve } = new Proxy(Promise, {
7
+ get: ($, name) => $[name].bind($),
8
+ });
9
+
10
+ const absoluteURL = (path, base = location.href) => new URL(path, base).href;
11
+
12
+ exports.isArray = isArray;
13
+ exports.assign = assign;
14
+ exports.create = create;
15
+ exports.defineProperties = defineProperties;
16
+ exports.defineProperty = defineProperty;
17
+ exports.all = all;
18
+ exports.resolve = resolve;
19
+ exports.absoluteURL = absoluteURL;
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+ const coincident = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("coincident/structured"));
3
+ const xworker = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("./xworker.js"));
4
+ const { assign, defineProperties, absoluteURL } = require("../utils.js");
5
+ const { getText } = require("../fetch-utils.js");
6
+ const workerHooks = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require("./hooks.js"));
7
+
8
+ /**
9
+ * @typedef {Object} WorkerOptions custom configuration
10
+ * @prop {string} type the interpreter type to use
11
+ * @prop {string} [version] the optional interpreter version to use
12
+ * @prop {string} [config] the optional config to use within such interpreter
13
+ */
14
+
15
+ module.exports = (...args) =>
16
+ /**
17
+ * A XWorker is a Worker facade able to bootstrap a channel with any desired interpreter.
18
+ * @param {string} url the remote file to evaluate on bootstrap
19
+ * @param {WorkerOptions} [options] optional arguments to define the interpreter to use
20
+ * @returns {Worker}
21
+ */
22
+ function XWorker(url, options) {
23
+ const hooks = workerHooks.get(XWorker);
24
+ const worker = xworker();
25
+ const { postMessage } = worker;
26
+ if (args.length) {
27
+ const [type, version] = args;
28
+ options = assign({}, options || { type, version });
29
+ if (!options.type) options.type = type;
30
+ }
31
+ if (options?.config) options.config = absoluteURL(options.config);
32
+ const bootstrap = fetch(url)
33
+ .then(getText)
34
+ .then((code) => postMessage.call(worker, { options, code, hooks }));
35
+ return defineProperties(worker, {
36
+ postMessage: {
37
+ value: (data, ...rest) =>
38
+ bootstrap.then(() =>
39
+ postMessage.call(worker, data, ...rest),
40
+ ),
41
+ },
42
+ sync: {
43
+ value: coincident(worker),
44
+ },
45
+ });
46
+ };
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+ module.exports = new WeakMap();
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+ /* c8 ignore next */
3
+ module.exports = () => new Worker(URL.createObjectURL(new Blob(["const e=\"object\"==typeof self?self:globalThis,t=t=>((t,r)=>{const n=(e,r)=>(t.set(r,e),e),s=o=>{if(t.has(o))return t.get(o);const[a,i]=r[o];switch(a){case 0:case-1:return n(i,o);case 1:{const e=n([],o);for(const t of i)e.push(s(t));return e}case 2:{const e=n({},o);for(const[t,r]of i)e[s(t)]=s(r);return e}case 3:return n(new Date(i),o);case 4:{const{source:e,flags:t}=i;return n(new RegExp(e,t),o)}case 5:{const e=n(new Map,o);for(const[t,r]of i)e.set(s(t),s(r));return e}case 6:{const e=n(new Set,o);for(const t of i)e.add(s(t));return e}case 7:{const{name:t,message:r}=i;return n(new e[t](r),o)}case 8:return n(BigInt(i),o);case\"BigInt\":return n(Object(BigInt(i)),o)}return n(new e[a](i),o)};return s})(new Map,t)(0),r=\"\",{toString:n}={},{keys:s}=Object,o=e=>{const t=typeof e;if(\"object\"!==t||!e)return[0,t];const s=n.call(e).slice(8,-1);switch(s){case\"Array\":return[1,r];case\"Object\":return[2,r];case\"Date\":return[3,r];case\"RegExp\":return[4,r];case\"Map\":return[5,r];case\"Set\":return[6,r]}return s.includes(\"Array\")?[1,s]:s.includes(\"Error\")?[7,s]:[2,s]},a=([e,t])=>0===e&&(\"function\"===t||\"symbol\"===t),i=(e,{json:t,lossy:r}={})=>{const n=[];return((e,t,r,n)=>{const i=(e,t)=>{const s=n.push(e)-1;return r.set(t,s),s},c=n=>{if(r.has(n))return r.get(n);let[l,u]=o(n);switch(l){case 0:{let t=n;switch(u){case\"bigint\":l=8,t=n.toString();break;case\"function\":case\"symbol\":if(e)throw new TypeError(\"unable to serialize \"+u);t=null;break;case\"undefined\":return i([-1],n)}return i([l,t],n)}case 1:{if(u)return i([u,[...n]],n);const e=[],t=i([l,e],n);for(const t of n)e.push(c(t));return t}case 2:{if(u)switch(u){case\"BigInt\":return i([u,n.toString()],n);case\"Boolean\":case\"Number\":case\"String\":return i([u,n.valueOf()],n)}if(t&&\"toJSON\"in n)return c(n.toJSON());const r=[],f=i([l,r],n);for(const t of s(n))!e&&a(o(n[t]))||r.push([c(t),c(n[t])]);return f}case 3:return i([l,n.toISOString()],n);case 4:{const{source:e,flags:t}=n;return i([l,{source:e,flags:t}],n)}case 5:{const t=[],r=i([l,t],n);for(const[r,s]of n)(e||!a(o(r))&&!a(o(s)))&&t.push([c(r),c(s)]);return r}case 6:{const t=[],r=i([l,t],n);for(const r of n)!e&&a(o(r))||t.push(c(r));return r}}const{message:f}=n;return i([l,{name:u,message:f}],n)};return c})(!(t||r),!!t,new Map,n)(e),n},{parse:c,stringify:l}=JSON,u={json:!0,lossy:!0};var f=Object.freeze({__proto__:null,parse:e=>t(c(e)),stringify:e=>l(i(e,u))}),p=e=>({value:new Promise((t=>{let r=new Worker(\"data:application/javascript,\"+encodeURIComponent('onmessage=({data:b})=>(Atomics.wait(b,0),postMessage(\"ok\"))'));r.onmessage=t,r.postMessage(e)}))})\n/*! (c) Andrea Giammarchi - ISC */;const d=\"eef159e0-b39b-4e0e-b711-43432daf4928\",{Int32Array:h,Map:w,SharedArrayBuffer:y,Uint16Array:g}=globalThis,{BYTES_PER_ELEMENT:m}=h,{BYTES_PER_ELEMENT:b}=g,{isArray:v}=Array,{notify:$,wait:_,waitAsync:j}=Atomics,{fromCharCode:S}=String,A=(e,t)=>e?(j||p)(t,0):(_(t,0),{value:{then:e=>e()}}),E=new WeakSet,M=new WeakMap;let k=0;const P=(e,{parse:t,stringify:r}=JSON)=>{if(!M.has(e)){const n=(t,...r)=>e.postMessage({[d]:r},{transfer:t});M.set(e,new Proxy(new w,{get:(r,s)=>\"then\"===s?null:(...r)=>{const o=k++;let a=new y(m);const i=new h(a);let c=[];E.has(r.at(-1)||c)&&E.delete(c=r.pop()),n(c,o,a,s,r);const l=e instanceof Worker;return A(l,i).value.then((()=>{const e=i[0];if(!e)return;const r=b*e;return a=new y(r+r%m),n([],o,a),A(l,new h(a)).value.then((()=>t(S(...new g(a).slice(0,e)))))}))},set(t,n,s){if(!t.size){const n=new w;e.addEventListener(\"message\",(async({data:e})=>{const s=e?.[d];if(v(s)){const[e,o,...a]=s,i=new h(o);if(a.length){const[s,o]=a;if(!t.has(s))throw new Error(`Unsupported action: ${s}`);{const a=r(await t.get(s)(...o));a&&(n.set(e,a),i[0]=a.length)}}else{const t=n.get(e);n.delete(e);for(let e=new g(o),r=0;r<t.length;r++)e[r]=t.charCodeAt(r)}$(i,0)}}))}return!!t.set(n,s)}}))}return M.get(e)},O=e=>P(e,f);O.transfer=P.transfer=(...e)=>(E.add(e),e);const{isArray:x}=Array,{assign:R,create:B,defineProperties:F,defineProperty:T}=Object,{all:W,resolve:G}=new Proxy(Promise,{get:(e,t)=>e[t].bind(e)}),I=(e,t=location.href)=>new URL(e,t).href;Promise.withResolvers||(Promise.withResolvers=function(){var e,t,r=new this((function(r,n){e=r,t=n}));return{resolve:e,reject:t,promise:r}});const U=e=>e.arrayBuffer(),L=e=>e.json(),N=e=>e.text(),J=e=>e.replace(/^[^\\r\\n]+$/,(e=>e.trim())),z=new WeakMap,C=e=>{const t=e||console,r={stderr:(t.stderr||console.error).bind(t),stdout:(t.stdout||console.log).bind(t)};return{stderr:(...e)=>r.stderr(...e),stdout:(...e)=>r.stdout(...e),async get(e){const t=await e;return z.set(t,r),t}}},D=e=>{const t=e.split(\"/\");return t.pop(),t.join(\"/\")},q=(e,t)=>{const r=[];for(const n of t.split(\"/\"))r.push(n),n&&e.mkdir(r.join(\"/\"))},Y=(e,t)=>{const r=[];for(const e of t.split(\"/\"))switch(e){case\"\":case\".\":break;case\"..\":r.pop();break;default:r.push(e)}return[e.cwd()].concat(r).join(\"/\").replace(/^\\/+/,\"/\")},V=e=>{const t=e.map((e=>e.trim().replace(/(^[/]*|[/]*$)/g,\"\"))).filter((e=>\"\"!==e&&\".\"!==e)).join(\"/\");return e[0].startsWith(\"/\")?`/${t}`:t},H=new WeakMap,K=(e,t,r)=>W((e=>{for(const{files:t,to_file:r,from:n=\"\"}of e){if(void 0!==t&&void 0!==r)throw new Error(\"Cannot use 'to_file' and 'files' parameters together!\");if(void 0===t&&void 0===r&&n.endsWith(\"/\"))throw new Error(`Couldn't determine the filename from the path ${n}, please supply 'to_file' parameter.`)}return e.flatMap((({from:e=\"\",to_folder:t=\".\",to_file:r,files:n})=>{if(x(n))return n.map((r=>({url:V([e,r]),path:V([t,r])})));const s=r||e.slice(1+e.lastIndexOf(\"/\"));return[{url:e,path:V([t,s])}]}))})(r).map((({url:n,path:s})=>((e,t)=>fetch(I(t,H.get(e))))(r,n).then(U).then((r=>e.writeFile(t,s,r)))))),Q=(e,t)=>e.runPython(J(t)),X=(e,t)=>e.runPythonAsync(J(t)),Z=({FS:e},t,r)=>((e,t,r)=>{const{parentPath:n,name:s}=e.analyzePath(t,!0);return e.mkdirTree(n),e.writeFile([n,s].join(\"/\"),new Uint8Array(r),{canOwn:!0})})(e,t,r);var ee={type:\"micropython\",module:(e=\"1.20.0-239\")=>`https://cdn.jsdelivr.net/npm/@micropython/micropython-webassembly-pyscript@${e}/micropython.mjs`,async engine({loadMicroPython:e},t,r){const{stderr:n,stdout:s,get:o}=C();r=r.replace(/\\.m?js$/,\".wasm\");const a=await o(e({stderr:n,stdout:s,url:r}));return t.fetch&&await K(this,a,t.fetch),a},setGlobal(e,t,r){const n=`__pyscript_${this.type}_${t}`;globalThis[n]=r,this.run(e,`from js import ${n};${t}=${n};`)},deleteGlobal(e,t){const r=`__pyscript_${this.type}_${t}`;this.run(e,`del ${r};del ${t}`),delete globalThis[r]},run:Q,runAsync:X,writeFile:Z};var te={type:\"pyodide\",module:(e=\"0.23.2\")=>`https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs`,async engine({loadPyodide:e},t,r){const{stderr:n,stdout:s,get:o}=C(),a=r.slice(0,r.lastIndexOf(\"/\")),i=await o(e({stderr:n,stdout:s,indexURL:a}));if(t.fetch&&await K(this,i,t.fetch),t.packages){await i.loadPackage(\"micropip\");const e=await i.pyimport(\"micropip\");await e.install(t.packages),e.destroy()}return i},setGlobal(e,t,r){e.globals.set(t,r)},deleteGlobal(e,t){e.globals.delete(t)},run:Q,runAsync:X,writeFile:Z};const re=\"ruby-wasm-wasi\";var ne={type:re,experimental:!0,module:(e=\"2.0.0\")=>`https://cdn.jsdelivr.net/npm/ruby-3_2-wasm-wasi@${e}/dist/browser.esm.js`,async engine({DefaultRubyVM:e},t,r){const n=await fetch(`${r.slice(0,r.lastIndexOf(\"/\"))}/ruby.wasm`),s=await WebAssembly.compile(await n.arrayBuffer()),{vm:o}=await e(s);return t.fetch&&await K(this,o,t.fetch),o},setGlobal(e,t,r){const n=`__pyscript_ruby_wasm_wasi_${t}`;globalThis[n]=r,this.run(e,`require \"js\";$${t}=JS::eval(\"return ${n}\")`)},deleteGlobal(e,t){const r=`__pyscript_ruby_wasm_wasi_${t}`;this.run(e,`$${t}=nil`),delete globalThis[r]},run:(e,t)=>e.eval(J(t)),runAsync:(e,t)=>e.evalAsync(J(t)),writeFile:()=>{throw new Error(`writeFile is not supported in ${re}`)}};var se={type:\"wasmoon\",module:(e=\"1.15.0\")=>`https://cdn.jsdelivr.net/npm/wasmoon@${e}/+esm`,async engine({LuaFactory:e,LuaLibraries:t},r){const{stderr:n,stdout:s,get:o}=C(),a=await o((new e).createEngine());return a.global.getTable(t.Base,(e=>{a.global.setField(e,\"print\",s),a.global.setField(e,\"printErr\",n)})),r.fetch&&await K(this,a,r.fetch),a},setGlobal(e,t,r){e.global.set(t,r)},deleteGlobal(e,t){e.global.set(t,void 0)},run:(e,t)=>e.doStringSync(J(t)),runAsync:(e,t)=>e.doString(J(t)),writeFile:({cmodule:{module:{FS:e}}},t,r)=>((e,t,r)=>(t=Y(e,t),q(e,D(t)),e.writeFile(t,new Uint8Array(r),{canOwn:!0})))(e,t,r)};const oe=new Map,ae=new Map,ie=new Proxy(new Map,{get(e,t){if(!e.has(t)){const[r,...n]=t.split(\"@\"),s=oe.get(r),o=/^https?:\\/\\//i.test(n)?n.join(\"@\"):s.module(...n);e.set(t,{url:o,module:import(o),engine:s.engine.bind(s)})}const{url:r,module:n,engine:s}=e.get(t);return(e,o)=>n.then((n=>{ae.set(t,e);const a=e?.fetch;return a&&H.set(a,o),s(n,e,r)}))}}),ce=e=>{for(const t of[].concat(e.type))oe.set(t,e)};for(const e of[ee,te,ne,se])ce(e);const le=async e=>(await import(\"https://cdn.jsdelivr.net/npm/basic-toml@0.3.1/es.js\")).parse(e);try{new SharedArrayBuffer(4)}catch(e){throw new Error([\"Unable to use SharedArrayBuffer due insecure environment.\",\"Please read requirements in MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements\"].join(\"\\n\"))}let ue,fe,pe;const de=(e,t)=>{addEventListener(e,t||(async t=>{await ue,pe=t,fe(`xworker.on${e}(xworker.event);`,he)}),!!t&&{once:!0})},he={sync:O(self),onerror(){},onmessage(){},onmessageerror(){},postMessage:postMessage.bind(self),get event(){const e=pe;if(!e)throw new Error(\"Unauthorized event access\");return pe=void 0,e}};de(\"message\",(({data:{options:e,code:t,hooks:r}})=>{ue=(async()=>{const{type:n,version:s,config:o,async:a}=e,i=await((e,t)=>{let r={};if(t)if(t.endsWith(\".json\"))r=fetch(t).then(L);else if(t.endsWith(\".toml\"))r=fetch(t).then(N).then(le);else{try{r=JSON.parse(t)}catch(e){r=le(t)}t=I(\"./config.txt\")}return G(r).then((r=>ie[e](r,t)))})(((e,t=\"\")=>`${e}@${t}`.replace(/@$/,\"\"))(n,s),o),c=B(oe.get(n)),l=\"run\"+(a?\"Async\":\"\");if(r){const{beforeRun:e,beforeRunAsync:t,afterRun:n,afterRunAsync:s}=r,o=n||s,a=e||t;if(o){const e=c[l].bind(c);c[l]=(t,r)=>e(t,`${r}\\n${o}`)}if(a){const e=c[l].bind(c);c[l]=(t,r)=>e(t,`${a}\\n${r}`)}}return c.setGlobal(i,\"xworker\",he),fe=c[l].bind(c,i),fe(t),i})(),de(\"error\"),de(\"message\"),de(\"messageerror\")}));\n"],{type:'application/javascript'})),{type:'module'});