@pyscript/core 0.1.6 → 0.1.8
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.
- package/README.md +41 -0
- package/dist/core.js +2 -0
- package/dist/error-f33e3b18.js +1 -0
- package/package.json +9 -13
- package/src/core.js +69 -66
- package/src/plugins/error.js +40 -0
- package/src/plugins.js +4 -0
- package/src/stdlib/pyscript.js +8 -0
- package/src/stdlib.js +33 -0
- package/src/sync.js +5 -0
- package/src/utils.js +6 -0
- package/types/core.d.ts +1 -0
- package/types/plugins/error.d.ts +1 -0
- package/types/plugins.d.ts +4 -0
- package/types/stdlib/pyscript.d.ts +8 -0
- package/types/stdlib.d.ts +2 -0
- package/types/sync.d.ts +4 -0
- package/types/utils.d.ts +1 -0
- package/core.js +0 -2
- package/src/display.py +0 -140
- package/types/coincident/window.d.ts +0 -10
- package/types/polyscript/esm/custom.d.ts +0 -54
- package/types/polyscript/esm/fetch-utils.d.ts +0 -3
- package/types/polyscript/esm/index.d.ts +0 -3
- package/types/polyscript/esm/interpreter/_python.d.ts +0 -4
- package/types/polyscript/esm/interpreter/_utils.d.ts +0 -15
- package/types/polyscript/esm/interpreter/micropython.d.ts +0 -25
- package/types/polyscript/esm/interpreter/pyodide.d.ts +0 -25
- package/types/polyscript/esm/interpreter/ruby-wasm-wasi.d.ts +0 -16
- package/types/polyscript/esm/interpreter/wasmoon.d.ts +0 -22
- package/types/polyscript/esm/interpreters.d.ts +0 -9
- package/types/polyscript/esm/listeners.d.ts +0 -3
- package/types/polyscript/esm/loader.d.ts +0 -2
- package/types/polyscript/esm/script-handler.d.ts +0 -4
- package/types/polyscript/esm/toml.d.ts +0 -1
- package/types/polyscript/esm/utils.d.ts +0 -29
- package/types/polyscript/esm/worker/class.d.ts +0 -19
- package/types/polyscript/esm/worker/hooks.d.ts +0 -6
- package/types/polyscript/esm/worker/xworker.d.ts +0 -2
- package/types/pyscript/pyscript.core/src/core.d.ts +0 -25
- package/types/pyscript/pyscript.core/src/exceptions.d.ts +0 -27
- package/types/pyscript/pyscript.core/src/fetch.d.ts +0 -10
- /package/{core.css → dist/core.css} +0 -0
package/README.md
CHANGED
@@ -1,3 +1,44 @@
|
|
1
1
|
# @pyscript/core
|
2
2
|
|
3
3
|
We have moved and renamed previous _core_ module as [polyscript](https://github.com/pyscript/polyscript/#readme), which is the base module used in here to build up _PyScript Next_, now hosted in this folder.
|
4
|
+
|
5
|
+
## Documentation
|
6
|
+
|
7
|
+
Please read [core documentation](./docs/README.md) to know more about this project.
|
8
|
+
|
9
|
+
## Development
|
10
|
+
|
11
|
+
Clone this repository then run `npm install` within its folder.
|
12
|
+
|
13
|
+
Use `npm run build` to create all artifacts and _dist_ files.
|
14
|
+
|
15
|
+
Use `npm run server` to test locally, via the `http://localhost:8080/test/` url, smoke tests or to test manually anything you'd like to check.
|
16
|
+
|
17
|
+
### Artifacts
|
18
|
+
|
19
|
+
There are two main artifacts in this project:
|
20
|
+
|
21
|
+
- **stdlib** and its content, where `src/stdlib/pyscript.js` exposes as object literal all the _Python_ content within the folder (recursively)
|
22
|
+
- **plugins** and its content, where `src/plugins.js` exposes all available _dynamic imports_, able to instrument the bundler to create files a part within the _dist/_ folder, so that by default _core_ remains as small as possible
|
23
|
+
|
24
|
+
Accordingly, whenever a file contains this warning at its first line, please do not change such file directly before submitting a merge request, as that file will be overwritten at the next `npm run build` command, either here or in _CI_:
|
25
|
+
|
26
|
+
```js
|
27
|
+
// ⚠️ This file is an artifact: DO NOT MODIFY
|
28
|
+
```
|
29
|
+
|
30
|
+
## Python stdlib
|
31
|
+
|
32
|
+
The `pyscript` module available in _Python_ defines its exported utilities via `src/stdlib/pyscript.py`. Any file that would like to provide an export should be placed into `src/stdlib/_pyscript` folder (see the `display.py` as example) and its public functionalities should be explicit in the `src/stdlib/pyscript.py` file.
|
33
|
+
|
34
|
+
All _Python_ files will be embedded automatically whenever `npm run build` happens and reflected into the `src/stdlib/pyscript.js` file.
|
35
|
+
|
36
|
+
It is _core_ responsibility to ensure those files will be available through the Filesystem in either the _main_ thread, or any _worker_.
|
37
|
+
|
38
|
+
## JS plugins
|
39
|
+
|
40
|
+
While community or third party plugins don't need to be part of this repository and can be added just importing `@pyscript/core` as module, there are a few plugins that we would like to make available by default and these are considered _core plugins_.
|
41
|
+
|
42
|
+
To add a _core plugin_ to this project you can define your plugin entry-point and name in the `src/plugins` folder (see the `error.js` example) and create, if necessary, a folder with the same name where extra files or dependencies can be added.
|
43
|
+
|
44
|
+
The _build_ command will bring plugins by name as artifact so that the bundler can create ad-hoc files within the `dist/` folder.
|
package/dist/core.js
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
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 e=(e,t=document)=>t.querySelector(e),t=(e,t=document)=>[...t.querySelectorAll(e)],r=(e,t=document)=>{const r=(new XPathEvaluator).createExpression(e).evaluate(t,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE),n=[];for(let e=0,{snapshotLength:t}=r;e<t;e++)n.push(r.snapshotItem(e));return n},n="object"==typeof self?self:globalThis,s=e=>((e,t)=>{const r=(t,r)=>(e.set(r,t),t),s=o=>{if(e.has(o))return e.get(o);const[a,i]=t[o];switch(a){case 0:case-1:return r(i,o);case 1:{const e=r([],o);for(const t of i)e.push(s(t));return e}case 2:{const e=r({},o);for(const[t,r]of i)e[s(t)]=s(r);return e}case 3:return r(new Date(i),o);case 4:{const{source:e,flags:t}=i;return r(new RegExp(e,t),o)}case 5:{const e=r(new Map,o);for(const[t,r]of i)e.set(s(t),s(r));return e}case 6:{const e=r(new Set,o);for(const t of i)e.add(s(t));return e}case 7:{const{name:e,message:t}=i;return r(new n[e](t),o)}case 8:return r(BigInt(i),o);case"BigInt":return r(Object(BigInt(i)),o)}return r(new n[a](i),o)};return s})(new Map,e)(0),o="",{toString:a}={},{keys:i}=Object,c=e=>{const t=typeof e;if("object"!==t||!e)return[0,t];const r=a.call(e).slice(8,-1);switch(r){case"Array":return[1,o];case"Object":return[2,o];case"Date":return[3,o];case"RegExp":return[4,o];case"Map":return[5,o];case"Set":return[6,o]}return r.includes("Array")?[1,r]:r.includes("Error")?[7,r]:[2,r]},l=([e,t])=>0===e&&("function"===t||"symbol"===t),u=(e,{json:t,lossy:r}={})=>{const n=[];return((e,t,r,n)=>{const s=(e,t)=>{const s=n.push(e)-1;return r.set(t,s),s},o=n=>{if(r.has(n))return r.get(n);let[a,u]=c(n);switch(a){case 0:{let t=n;switch(u){case"bigint":a=8,t=n.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+u);t=null;break;case"undefined":return s([-1],n)}return s([a,t],n)}case 1:{if(u)return s([u,[...n]],n);const e=[],t=s([a,e],n);for(const t of n)e.push(o(t));return t}case 2:{if(u)switch(u){case"BigInt":return s([u,n.toString()],n);case"Boolean":case"Number":case"String":return s([u,n.valueOf()],n)}if(t&&"toJSON"in n)return o(n.toJSON());const r=[],p=s([a,r],n);for(const t of i(n))!e&&l(c(n[t]))||r.push([o(t),o(n[t])]);return p}case 3:return s([a,n.toISOString()],n);case 4:{const{source:e,flags:t}=n;return s([a,{source:e,flags:t}],n)}case 5:{const t=[],r=s([a,t],n);for(const[r,s]of n)(e||!l(c(r))&&!l(c(s)))&&t.push([o(r),o(s)]);return r}case 6:{const t=[],r=s([a,t],n);for(const r of n)!e&&l(c(r))||t.push(o(r));return r}}const{message:p}=n;return s([a,{name:u,message:p}],n)};return o})(!(t||r),!!t,new Map,n)(e),n},{parse:p,stringify:f}=JSON,d={json:!0,lossy:!0};var y=Object.freeze({__proto__:null,parse:e=>s(p(e)),stringify:e=>f(u(e,d))});const h="891249cd-eb53-4bc8-ae48-b0a5a277d24a",m="M"+h,g="T"+h;var w=e=>({value:new Promise((t=>{let r=new Worker("data:application/javascript,onmessage%3D(%7Bdata%3Ab%7D)%3D%3E(Atomics.wait(b%2C0)%2CpostMessage(0))");r.onmessage=t,r.postMessage(e)}))})
|
2
|
+
/*! (c) Andrea Giammarchi - ISC */;const{Int32Array:b,Map:v,SharedArrayBuffer:_,Uint16Array:E}=globalThis,{BYTES_PER_ELEMENT:A}=b,{BYTES_PER_ELEMENT:k}=E,{isArray:S}=Array,{notify:R,wait:x,waitAsync:P}=Atomics,{fromCharCode:j}=String,$=(e,t)=>e?(P||w)(t,0):(x(t,0),{value:{then:e=>e()}}),M=new WeakSet,W=new WeakMap;let T=0;const O=(e,{parse:t,stringify:r,transform:n}=JSON)=>{if(!W.has(e)){const s=(t,...r)=>e.postMessage({[h]:r},{transfer:t});let o=!1;W.set(e,new Proxy(new v,{has:(e,t)=>"string"==typeof t&&!t.startsWith("_"),get:(r,a)=>"then"===a?null:(...r)=>{const i=T++;let c=new b(new _(A)),l=[];M.has(r.at(-1)||l)&&M.delete(l=r.pop()),s(l,i,c,a,n?r.map(n):r);const u=e!==globalThis;let p=0;return o&&u&&(p=setTimeout(console.warn,1e3,`💀🔒 - Possible deadlock if proxy.${a}(...args) is awaited`)),$(u,c).value.then((()=>{clearTimeout(p);const e=c[0];if(!e)return;const r=k*e;return c=new b(new _(r+r%A)),s([],i,c),$(u,c).value.then((()=>t(j(...new E(c.buffer).slice(0,e)))))}))},set(t,n,s){if(!t.size){const n=new v;e.addEventListener("message",(async e=>{const s=e.data?.[h];if(S(s)){e.stopImmediatePropagation();const[a,i,...c]=s;if(c.length){const[e,s]=c;if(!t.has(e))throw new Error(`Unsupported action: ${e}`);o=!0;try{const o=await t.get(e)(...s);if(void 0!==o){const e=r(o);n.set(a,e),i[0]=e.length}}finally{o=!1}}else{const e=n.get(a);n.delete(a);for(let t=new E(i.buffer),r=0;r<e.length;r++)t[r]=e.charCodeAt(r)}R(i,0)}}))}return!!t.set(n,s)}}))}return W.get(e)};O.transfer=(...e)=>(M.add(e),e);const F="object",I="function",B="number",N="string",L="undefined",C="symbol",{defineProperty:J,getOwnPropertyDescriptor:D,getPrototypeOf:H,isExtensible:U,ownKeys:z,preventExtensions:q,set:Q,setPrototypeOf:Y}=Reflect,{assign:K,create:X}=Object,V=H(Int8Array),Z="isArray",G=(e,t)=>{const{get:r,set:n,value:s}=e;return r&&(e.get=t(r)),n&&(e.set=t(n)),s&&(e.value=t(s)),e},ee=(e,t)=>[e,t],te=e=>t=>{const r=typeof t;switch(r){case F:if(null==t)return ee("null",t);if(t===globalThis)return ee(F,null);case I:return e(r,t);case"boolean":case B:case N:case L:case"bigint":return ee(r,t);case C:if(re.has(t))return ee(r,re.get(t))}throw new Error(`Unable to handle this ${r} type`)},re=new Map(z(Symbol).filter((e=>typeof Symbol[e]===C)).map((e=>[Symbol[e],e]))),ne=e=>{for(const[t,r]of re)if(r===e)return t};function se(){return this}const oe="apply",ae="construct",ie="defineProperty",ce="deleteProperty",le="get",ue="getOwnPropertyDescriptor",pe="getPrototypeOf",fe="has",de="isExtensible",ye="ownKeys",he="preventExtensions",me="set",ge="setPrototypeOf",we="delete";var be=((e,t)=>{const r=t&&new WeakMap;if(t){const{addEventListener:e}=EventTarget.prototype;J(EventTarget.prototype,"addEventListener",{value(t,n,...s){return s.at(0)?.invoke&&(r.has(this)||r.set(this,new Map),r.get(this).set(t,[].concat(s[0].invoke)),delete s[0].invoke),e.call(this,t,n,...s)}})}const n=t&&(e=>{const{currentTarget:t,target:n,type:s}=e;for(const o of r.get(t||n)?.get(s)||[])e[o]()});return(r,s,o,...a)=>{let i=0;const c=new Map,l=new Map,{[o]:u}=r,p=a.length?K(X(globalThis),...a):globalThis,f=te(((e,t)=>{if(!c.has(t)){let e;for(;l.has(e=i++););c.set(t,e),l.set(e,t)}return ee(e,c.get(t))})),d=new FinalizationRegistry((e=>{u(we,ee(N,e))})),y=([e,r])=>{switch(e){case F:if(null==r)return p;if(typeof r===B)return l.get(r);if(!(r instanceof V))for(const e in r)r[e]=y(r[e]);return r;case I:if(typeof r===N){if(!l.has(r)){const e=function(...e){return t&&e.at(0)instanceof Event&&n(...e),u(oe,ee(I,r),f(this),e.map(f))},s=new WeakRef(e);l.set(r,s),d.register(e,r,s)}return l.get(r).deref()}return l.get(r);case C:return ne(r)}return r},h={[oe]:(e,t,r)=>f(e.apply(t,r)),[ae]:(e,t)=>f(new e(...t)),[ie]:(e,t,r)=>f(J(e,t,r)),[ce]:(e,t)=>f(delete e[t]),[pe]:e=>f(H(e)),[le]:(e,t)=>f(e[t]),[ue]:(e,t)=>{const r=D(e,t);return r?ee(F,G(r,f)):ee(L,r)},[fe]:(e,t)=>f(t in e),[de]:e=>f(U(e)),[ye]:e=>ee(F,z(e).map(f)),[he]:e=>f(q(e)),[me]:(e,t,r)=>f(Q(e,t,r)),[ge]:(e,t)=>f(Y(e,t)),[we](e){c.delete(l.get(e)),l.delete(e)}};return r[s]=(e,t,...r)=>{switch(e){case oe:r[0]=y(r[0]),r[1]=r[1].map(y);break;case ae:r[0]=r[0].map(y);break;case ie:{const[e,t]=r;r[0]=y(e);const{get:n,set:s,value:o}=t;n&&(t.get=y(n)),s&&(t.set=y(s)),o&&(t.value=y(o));break}default:r=r.map(y)}return h[e](y(t),...r)},{proxy:r,[e.toLowerCase()]:p,[`is${e}Proxy`]:()=>!1}}})("Window",!0),ve=(e=>{let t=0;const r=new Map,n=new Map,s=Symbol(),o=e=>typeof e===I?e():e,a=e=>typeof e===F&&!!e&&s in e,i=Array[Z],c=te(((e,a)=>{if(s in a)return o(a[s]);if(e===I){if(!n.has(a)){let e;for(;n.has(e=String(t++)););r.set(a,e),n.set(e,a)}return ee(e,r.get(a))}if(!(a instanceof V))for(const e in a)a[e]=c(a[e]);return ee(e,a)}));return(t,l,u)=>{const{[l]:p}=t,f=new Map,d=new FinalizationRegistry((e=>{f.delete(e),p(we,c(e))})),y=e=>{const[t,r]=e;if(!f.has(r)){const n=t===I?se.bind(e):e,s=new Proxy(n,g),o=new WeakRef(s);f.set(r,o),d.register(s,r,o)}return f.get(r).deref()},h=e=>{const[t,r]=e;switch(t){case F:return null===r?globalThis:typeof r===B?y(e):r;case I:return typeof r===N?n.get(r):y(e);case C:return ne(r)}return r},m=(e,t,...r)=>h(p(e,o(t),...r)),g={[oe]:(e,t,r)=>m(oe,e,c(t),r.map(c)),[ae]:(e,t)=>m(ae,e,t.map(c)),[ie]:(e,t,r)=>{const{get:n,set:s,value:o}=r;return typeof n===I&&(r.get=c(n)),typeof s===I&&(r.set=c(s)),typeof o===I&&(r.value=c(o)),m(ie,e,c(t),r)},[ce]:(e,t)=>m(ce,e,c(t)),[pe]:e=>m(pe,e),[le]:(e,t)=>t===s?e:m(le,e,c(t)),[ue]:(e,t)=>{const r=m(ue,e,c(t));return r&&G(r,h)},[fe]:(e,t)=>t===s||m(fe,e,c(t)),[de]:e=>m(de,e),[ye]:e=>m(ye,e).map(h),[he]:e=>m(he,e),[me]:(e,t,r)=>m(me,e,c(t),c(r)),[ge]:(e,t)=>m(ge,e,c(t))};t[u]=(e,t,s,o)=>{switch(e){case oe:return h(t).apply(h(s),o.map(h));case we:{const e=h(t);r.delete(n.get(e)),n.delete(e)}}};const w=new Proxy([F,null],g),b=w.Array[Z];return J(Array,Z,{value:e=>a(e)?b(e):i(e)}),{[e.toLowerCase()]:w,[`is${e}Proxy`]:a,proxy:t}}})("Window"),_e="function"==typeof Worker?Worker:class{};const Ee=new WeakMap,Ae=(e,...t)=>{const r=O(e,...t);if(!Ee.has(r)){const t=e instanceof _e?be:ve;Ee.set(r,t(r,m,g))}return Ee.get(r)};Ae.transfer=O.transfer;const{isArray:ke}=Array,{assign:Se,create:Re,defineProperties:xe,defineProperty:Pe,entries:je}=Object,{all:$e,resolve:Me}=new Proxy(Promise,{get:(e,t)=>e[t].bind(e)}),We=(e,t=location.href)=>new URL(e,t).href;let Te=0;const Oe=(e,t)=>({id:e.id||(e.id=`${t}-w${Te++}`),tag:e.tagName}),Fe=e=>e.arrayBuffer(),Ie=e=>e.json(),Be=e=>e.text(),Ne=[["beforeRun","codeBeforeRunWorker"],["beforeRunAsync","codeBeforeRunWorkerAsync"],["afterRun","codeAfterRunWorker"],["afterRunAsync","codeAfterRunWorkerAsync"]];class Le{constructor(e,t){this.interpreter=e,this.onWorkerReady=t.onWorkerReady;for(const[e,r]of Ne)this[e]=t[r]?.()}get stringHooks(){const e={};for(const[t]of Ne)this[t]&&(e[t]=this[t]);return e}}var Ce=(...e)=>function(t,r){const n=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))});const p="891249cd-eb53-4bc8-ae48-b0a5a277d24a",d="M"+p,g="T"+p;var y=e=>({value:new Promise((t=>{let r=new Worker("data:application/javascript,onmessage%3D(%7Bdata%3Ab%7D)%3D%3E(Atomics.wait(b%2C0)%2CpostMessage(0))");r.onmessage=t,r.postMessage(e)}))})\n/*! (c) Andrea Giammarchi - ISC */;const{Int32Array:w,Map:h,SharedArrayBuffer:m,Uint16Array:b}=globalThis,{BYTES_PER_ELEMENT:v}=w,{BYTES_PER_ELEMENT:S}=b,{isArray:P}=Array,{notify:A,wait:E,waitAsync:M}=Atomics,{fromCharCode:$}=String,j=(e,t)=>e?(M||y)(t,0):(E(t,0),{value:{then:e=>e()}}),T=new WeakSet,k=new WeakMap;let _=0;const x=(e,{parse:t,stringify:r,transform:n}=JSON)=>{if(!k.has(e)){const s=(t,...r)=>e.postMessage({[p]:r},{transfer:t});let o=!1;k.set(e,new Proxy(new h,{has:(e,t)=>"string"==typeof t&&!t.startsWith("_"),get:(r,a)=>"then"===a?null:(...r)=>{const i=_++;let c=new w(new m(v)),l=[];T.has(r.at(-1)||l)&&T.delete(l=r.pop()),s(l,i,c,a,n?r.map(n):r);const u=e!==globalThis;let f=0;return o&&u&&(f=setTimeout(console.warn,1e3,`💀🔒 - Possible deadlock if proxy.${a}(...args) is awaited`)),j(u,c).value.then((()=>{clearTimeout(f);const e=c[0];if(!e)return;const r=S*e;return c=new w(new m(r+r%v)),s([],i,c),j(u,c).value.then((()=>t($(...new b(c.buffer).slice(0,e)))))}))},set(t,n,s){if(!t.size){const n=new h;e.addEventListener("message",(async e=>{const s=e.data?.[p];if(P(s)){e.stopImmediatePropagation();const[a,i,...c]=s;if(c.length){const[e,s]=c;if(!t.has(e))throw new Error(`Unsupported action: ${e}`);o=!0;try{const o=await t.get(e)(...s);if(void 0!==o){const e=r(o);n.set(a,e),i[0]=e.length}}finally{o=!1}}else{const e=n.get(a);n.delete(a);for(let t=new b(i.buffer),r=0;r<e.length;r++)t[r]=e.charCodeAt(r)}A(i,0)}}))}return!!t.set(n,s)}}))}return k.get(e)};x.transfer=(...e)=>(T.add(e),e);const O="object",F="function",W="number",R="string",B="undefined",J="symbol",{defineProperty:I,getOwnPropertyDescriptor:L,getPrototypeOf:C,isExtensible:H,ownKeys:D,preventExtensions:N,set:U,setPrototypeOf:z}=Reflect,{assign:q,create:K}=Object,Y=C(Int8Array),G="isArray",V=(e,t)=>{const{get:r,set:n,value:s}=e;return r&&(e.get=t(r)),n&&(e.set=t(n)),s&&(e.value=t(s)),e},Q=(e,t)=>[e,t],X=e=>t=>{const r=typeof t;switch(r){case O:if(null==t)return Q("null",t);if(t===globalThis)return Q(O,null);case F:return e(r,t);case"boolean":case W:case R:case B:case"bigint":return Q(r,t);case J:if(Z.has(t))return Q(r,Z.get(t))}throw new Error(`Unable to handle this ${r} type`)},Z=new Map(D(Symbol).filter((e=>typeof Symbol[e]===J)).map((e=>[Symbol[e],e]))),ee=e=>{for(const[t,r]of Z)if(r===e)return t};function te(){return this}const re="apply",ne="construct",se="defineProperty",oe="deleteProperty",ae="get",ie="getOwnPropertyDescriptor",ce="getPrototypeOf",le="has",ue="isExtensible",fe="ownKeys",pe="preventExtensions",de="set",ge="setPrototypeOf",ye="delete";var we=((e,t)=>{const r=t&&new WeakMap;if(t){const{addEventListener:e}=EventTarget.prototype;I(EventTarget.prototype,"addEventListener",{value(t,n,...s){return s.at(0)?.invoke&&(r.has(this)||r.set(this,new Map),r.get(this).set(t,[].concat(s[0].invoke)),delete s[0].invoke),e.call(this,t,n,...s)}})}const n=t&&(e=>{const{currentTarget:t,target:n,type:s}=e;for(const o of r.get(t||n)?.get(s)||[])e[o]()});return(r,s,o,...a)=>{let i=0;const c=new Map,l=new Map,{[o]:u}=r,f=a.length?q(K(globalThis),...a):globalThis,p=X(((e,t)=>{if(!c.has(t)){let e;for(;l.has(e=i++););c.set(t,e),l.set(e,t)}return Q(e,c.get(t))})),d=new FinalizationRegistry((e=>{u(ye,Q(R,e))})),g=([e,r])=>{switch(e){case O:if(null==r)return f;if(typeof r===W)return l.get(r);if(!(r instanceof Y))for(const e in r)r[e]=g(r[e]);return r;case F:if(typeof r===R){if(!l.has(r)){const e=function(...e){return t&&e.at(0)instanceof Event&&n(...e),u(re,Q(F,r),p(this),e.map(p))},s=new WeakRef(e);l.set(r,s),d.register(e,r,s)}return l.get(r).deref()}return l.get(r);case J:return ee(r)}return r},y={[re]:(e,t,r)=>p(e.apply(t,r)),[ne]:(e,t)=>p(new e(...t)),[se]:(e,t,r)=>p(I(e,t,r)),[oe]:(e,t)=>p(delete e[t]),[ce]:e=>p(C(e)),[ae]:(e,t)=>p(e[t]),[ie]:(e,t)=>{const r=L(e,t);return r?Q(O,V(r,p)):Q(B,r)},[le]:(e,t)=>p(t in e),[ue]:e=>p(H(e)),[fe]:e=>Q(O,D(e).map(p)),[pe]:e=>p(N(e)),[de]:(e,t,r)=>p(U(e,t,r)),[ge]:(e,t)=>p(z(e,t)),[ye](e){c.delete(l.get(e)),l.delete(e)}};return r[s]=(e,t,...r)=>{switch(e){case re:r[0]=g(r[0]),r[1]=r[1].map(g);break;case ne:r[0]=r[0].map(g);break;case se:{const[e,t]=r;r[0]=g(e);const{get:n,set:s,value:o}=t;n&&(t.get=g(n)),s&&(t.set=g(s)),o&&(t.value=g(o));break}default:r=r.map(g)}return y[e](g(t),...r)},{proxy:r,[e.toLowerCase()]:f,[`is${e}Proxy`]:()=>!1}}})("Window",!0),he=(e=>{let t=0;const r=new Map,n=new Map,s=Symbol(),o=e=>typeof e===F?e():e,a=e=>typeof e===O&&!!e&&s in e,i=Array[G],c=X(((e,a)=>{if(s in a)return o(a[s]);if(e===F){if(!n.has(a)){let e;for(;n.has(e=String(t++)););r.set(a,e),n.set(e,a)}return Q(e,r.get(a))}if(!(a instanceof Y))for(const e in a)a[e]=c(a[e]);return Q(e,a)}));return(t,l,u)=>{const{[l]:f}=t,p=new Map,d=new FinalizationRegistry((e=>{p.delete(e),f(ye,c(e))})),g=e=>{const[t,r]=e;if(!p.has(r)){const n=t===F?te.bind(e):e,s=new Proxy(n,h),o=new WeakRef(s);p.set(r,o),d.register(s,r,o)}return p.get(r).deref()},y=e=>{const[t,r]=e;switch(t){case O:return null===r?globalThis:typeof r===W?g(e):r;case F:return typeof r===R?n.get(r):g(e);case J:return ee(r)}return r},w=(e,t,...r)=>y(f(e,o(t),...r)),h={[re]:(e,t,r)=>w(re,e,c(t),r.map(c)),[ne]:(e,t)=>w(ne,e,t.map(c)),[se]:(e,t,r)=>{const{get:n,set:s,value:o}=r;return typeof n===F&&(r.get=c(n)),typeof s===F&&(r.set=c(s)),typeof o===F&&(r.value=c(o)),w(se,e,c(t),r)},[oe]:(e,t)=>w(oe,e,c(t)),[ce]:e=>w(ce,e),[ae]:(e,t)=>t===s?e:w(ae,e,c(t)),[ie]:(e,t)=>{const r=w(ie,e,c(t));return r&&V(r,y)},[le]:(e,t)=>t===s||w(le,e,c(t)),[ue]:e=>w(ue,e),[fe]:e=>w(fe,e).map(y),[pe]:e=>w(pe,e),[de]:(e,t,r)=>w(de,e,c(t),c(r)),[ge]:(e,t)=>w(ge,e,c(t))};t[u]=(e,t,s,o)=>{switch(e){case re:return y(t).apply(y(s),o.map(y));case ye:{const e=y(t);r.delete(n.get(e)),n.delete(e)}}};const m=new Proxy([O,null],h),b=m.Array[G];return I(Array,G,{value:e=>a(e)?b(e):i(e)}),{[e.toLowerCase()]:m,[`is${e}Proxy`]:a,proxy:t}}})("Window"),me="function"==typeof Worker?Worker:class{};const be=new WeakMap,ve=(e,...t)=>{const r=x(e,...t);if(!be.has(r)){const t=e instanceof me?we:he;be.set(r,t(r,d,g))}return be.get(r)};ve.transfer=x.transfer;const{isArray:Se}=Array,{assign:Pe,create:Ae,defineProperties:Ee,defineProperty:Me,entries:$e}=Object,{all:je,resolve:Te}=new Proxy(Promise,{get:(e,t)=>e[t].bind(e)}),ke=(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 _e=e=>e.arrayBuffer(),xe=e=>e.json(),Oe=e=>e.text(),Fe=e=>e.replace(/^[^\\r\\n]+$/,(e=>e.trim())),We=new WeakMap,Re=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 We.set(t,r),t}}},Be=({FS:e,PATH:t,PATH_FS:r},n,s)=>{const o=r.resolve(n);return e.mkdirTree(t.dirname(o)),e.writeFile(o,new Uint8Array(s),{canOwn:!0})},Je=e=>{const t=e.split("/");return t.pop(),t.join("/")},Ie=(e,t)=>{const r=[];for(const n of t.split("/"))"."!==n&&(r.push(n),n&&e.mkdir(r.join("/")))},Le=(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(/^\\/+/,"/")},Ce=e=>{const t=e.map((e=>e.trim().replace(/(^[/]*|[/]*$)/g,""))).filter((e=>""!==e&&"."!==e)).join("/");return e[0].startsWith("/")?`/${t}`:t},He=new WeakMap,De=(e,t,r)=>je((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(Se(n))return n.map((r=>({url:Ce([e,r]),path:Ce([t,r])})));const s=r||e.slice(1+e.lastIndexOf("/"));return[{url:e,path:Ce([t,s])}]}))})(r).map((({url:n,path:s})=>((e,t)=>fetch(ke(t,He.get(e))))(r,n).then(_e).then((r=>e.writeFile(t,s,r)))))),Ne=(e,t,r)=>{e.registerJsModule(t,r)},Ue=(e,t,...r)=>{try{return e.runPython(Fe(t),...r)}catch(t){We.get(e).stderr(t)}},ze=async(e,t,...r)=>{try{return await e.runPythonAsync(Fe(t),...r)}catch(t){We.get(e).stderr(t)}},qe=async(e,t,r)=>{const[n,...s]=t.split(".");let o,a=e.globals.get(n);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,r)}catch(t){We.get(e).stderr(t)}};var Ke={type:"micropython",module:(e="1.20.0-297")=>`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}=Re();r=r.replace(/\\.m?js$/,".wasm");const a=await o(e({stderr:n,stdout:s,url:r}));return t.fetch&&await De(this,a,t.fetch),a},registerJSModule:Ne,run:Ue,runAsync:ze,runEvent:qe,transform:(e,t)=>t,writeFile:({FS:e,_module:{PATH:t,PATH_FS:r}},n,s)=>Be({FS:e,PATH:t,PATH_FS:r},n,s)};const Ye={dict_converter:Object.fromEntries};var Ge={type:"pyodide",module:(e="0.23.4")=>`https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs`,async engine({loadPyodide:e},t,r){const{stderr:n,stdout:s,get:o}=Re(),a=r.slice(0,r.lastIndexOf("/")),i=await o(e({stderr:n,stdout:s,indexURL:a}));if(t.fetch&&await De(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},registerJSModule:Ne,run:Ue,runAsync:ze,runEvent:qe,transform:(e,t)=>t instanceof e.ffi.PyProxy?t.toJs(Ye):t,writeFile:({FS:e,PATH:t,_module:{PATH_FS:r}},n,s)=>Be({FS:e,PATH:t,PATH_FS:r},n,s)};const Ve="ruby-wasm-wasi",Qe=Ve.replace(/\\W+/g,"_");var Xe={type:Ve,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 De(this,o,t.fetch),o},registerJSModule(e,t,r){const n=`__module_${Qe}_${t}`;globalThis[n]=r,this.run(e,`require "js";$${t}=JS.global[:${n}]`),delete globalThis[n]},run:(e,t,...r)=>e.eval(Fe(t),...r),runAsync:(e,t,...r)=>e.evalAsync(Fe(t),...r),async runEvent(e,t,r){if(/^xworker\\.(on\\w+)$/.test(t)){const{$1:t}=RegExp,n=`__module_${Qe}_event`;globalThis[n]=r,this.run(e,`require "js";$xworker.call("${t}",JS.global[:${n}])`),delete globalThis[n]}else{const n=this.run(e,`method(:${t})`);await n.call(t,e.wrap(r))}},transform:(e,t)=>t,writeFile:()=>{throw new Error(`writeFile is not supported in ${Ve}`)}};var Ze={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}=Re(),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 De(this,a,r.fetch),a},registerJSModule:(e,t,r)=>{e.global.set(t,r)},run:(e,t,...r)=>{try{return e.doStringSync(Fe(t),...r)}catch(t){We.get(e).stderr(t)}},runAsync:async(e,t,...r)=>{try{return await e.doString(Fe(t),...r)}catch(t){We.get(e).stderr(t)}},runEvent:async(e,t,r)=>{const[n,...s]=t.split(".");let o,a=e.global.get(n);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,r)}catch(t){We.get(e).stderr(t)}},transform:(e,t)=>t,writeFile:({cmodule:{module:{FS:e}}},t,r)=>((e,t,r)=>(Ie(e,Je(t)),t=Le(e,t),e.writeFile(t,new Uint8Array(r),{canOwn:!0})))(e,t,r)};const et=new Map,tt=new Map,rt=new Proxy(new Map,{get(e,t){if(!e.has(t)){const[r,...n]=t.split("@"),s=et.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=>{tt.set(t,e);const a=e?.fetch;return a&&He.set(a,o),s(n,e,r)}))}}),nt=e=>{for(const t of[].concat(e.type))et.set(t,e)};for(const e of[Ke,Ge,Xe,Ze])nt(e);const st=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 ot,at,it;const ct=(e,t)=>{addEventListener(e,t||(async t=>{try{await ot,at(`xworker.on${e}`,t)}catch(e){postMessage(e)}}),!!t&&{once:!0})},{parse:lt,stringify:ut}=f,{proxy:ft,window:pt,isWindowProxy:dt}=ve(self,{parse:lt,stringify:ut,transform:e=>it?it(e):e}),gt={sync:ft,window:pt,isWindowProxy:dt,onmessage:console.info,onerror:console.error,onmessageerror:console.warn,postMessage:postMessage.bind(self)};ct("message",(({data:{options:e,config:t,code:r,hooks:n}})=>{ot=(async()=>{try{const{id:s,tag:o,type:a,custom:i,version:c,config:l,async:u}=e,f=await((e,t,r={})=>{if(t)if(t.endsWith(".json"))r=fetch(t).then(xe),t=ke(t);else if(t.endsWith(".toml"))r=fetch(t).then(Oe).then(st),t=ke(t);else if(!t.endsWith(".txt")){try{r=JSON.parse(t)}catch(e){r=st(t)}t=ke("./config.txt")}return Te(r).then((r=>rt[e](r,t)))})(((e,t="")=>`${e}@${t}`.replace(/@$/,""))(a,c),t,l),p=Ae(et.get(a)),d="run"+(u?"Async":"");if(n){const{beforeRun:e,beforeRunAsync:t,afterRun:r,afterRunAsync:s}=n,o=r||s,a=e||t;if(o){const e=p[d].bind(p);p[d]=(t,r,...n)=>e(t,`${r}\\n${o}`,...n)}if(a){const e=p[d].bind(p);p[d]=(t,r,...n)=>e(t,`${a}\\n${r}`,...n)}}let g="";return p.registerJSModule(f,"polyscript",{xworker:gt,get target(){if(!g){const{document:e}=gt.window,t=e.getElementById(s);"SCRIPT"===o?t.after(Pe(e.createElement(`script-${i||a}`),{id:g=`${s}-target`})):(g=s,t.replaceChildren(),t.style.display="block")}return g}}),at=p.runEvent.bind(p,f),it=p.transform.bind(p,f),await p[d](f,r),f}catch(e){postMessage(e)}})(),ct("error"),ct("message"),ct("messageerror")}));\n'],{type:"application/javascript"})),{type:"module"}),{postMessage:s}=n,o=this instanceof Le;if(e.length){const[t,n]=e;(r=Se({},r||{type:t,version:n})).type||(r.type=t)}const{config:a}=r,i=We(a&&"string"==typeof a?a:"./config.txt"),c=fetch(t).then(Be).then((e=>{const t=o?this.stringHooks:void 0;s.call(n,{options:r,config:i,code:e,hooks:t})}));return xe(n,{postMessage:{value:(e,...t)=>c.then((()=>s.call(n,e,...t)))},sync:{value:Ae(n,y).proxy},onerror:{writable:!0,configurable:!0,value:console.error}}),o&&this.onWorkerReady?.(this.interpreter,n),n.addEventListener("message",(e=>{const{data:t}=e;t instanceof Error&&(e.stopImmediatePropagation(),n.onerror(Object.create(e,{type:{value:"error"},error:{value:t}})))})),n},Je=e=>{const{worker:t}=e.attributes;if(t){let{value:r}=t;if(!r){if(e.childElementCount){const{innerHTML:t,localName:n,type:s}=e,o=s||n.replace(/-script$/,"");console.warn(`Deprecated: use <script type="${o}"> for an always safe content parsing:\n`,t),r=t}else r=e.textContent;for(const e of r.split(/[\r\n]+/))if(e.trim().length){if(/^(\s+)/.test(e)){const e=`^${RegExp.$1}`;r=r.replace(new RegExp(e,"gm"),"")}break}return URL.createObjectURL(new Blob([r],{type:"text/plain"}))}return r}};const De=e=>e.replace(/^[^\r\n]+$/,(e=>e.trim())),He=new WeakMap,Ue=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 He.set(t,r),t}}},ze=({FS:e,PATH:t,PATH_FS:r},n,s)=>{const o=r.resolve(n);return e.mkdirTree(t.dirname(o)),e.writeFile(o,new Uint8Array(s),{canOwn:!0})},qe=e=>{const t=e.split("/");return t.pop(),t.join("/")},Qe=(e,t)=>{const r=[];for(const n of t.split("/"))"."!==n&&(r.push(n),n&&e.mkdir(r.join("/")))},Ye=(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(/^\/+/,"/")},Ke=e=>{const t=e.map((e=>e.trim().replace(/(^[/]*|[/]*$)/g,""))).filter((e=>""!==e&&"."!==e)).join("/");return e[0].startsWith("/")?`/${t}`:t},Xe=new WeakMap,Ve=(e,t,r)=>$e((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(ke(n))return n.map((r=>({url:Ke([e,r]),path:Ke([t,r])})));const s=r||e.slice(1+e.lastIndexOf("/"));return[{url:e,path:Ke([t,s])}]}))})(r).map((({url:n,path:s})=>((e,t)=>fetch(We(t,Xe.get(e))))(r,n).then(Fe).then((r=>e.writeFile(t,s,r)))))),Ze=(e,t,r)=>{e.registerJsModule(t,r)},Ge=(e,t,...r)=>{try{return e.runPython(De(t),...r)}catch(t){He.get(e).stderr(t)}},et=async(e,t,...r)=>{try{return await e.runPythonAsync(De(t),...r)}catch(t){He.get(e).stderr(t)}},tt=async(e,t,r)=>{const[n,...s]=t.split(".");let o,a=e.globals.get(n);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,r)}catch(t){He.get(e).stderr(t)}};var rt={type:"micropython",module:(e="1.20.0-297")=>`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}=Ue();r=r.replace(/\.m?js$/,".wasm");const a=await o(e({stderr:n,stdout:s,url:r}));return t.fetch&&await Ve(this,a,t.fetch),a},registerJSModule:Ze,run:Ge,runAsync:et,runEvent:tt,transform:(e,t)=>t,writeFile:({FS:e,_module:{PATH:t,PATH_FS:r}},n,s)=>ze({FS:e,PATH:t,PATH_FS:r},n,s)};const nt={dict_converter:Object.fromEntries};var st={type:"pyodide",module:(e="0.23.4")=>`https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs`,async engine({loadPyodide:e},t,r){const{stderr:n,stdout:s,get:o}=Ue(),a=r.slice(0,r.lastIndexOf("/")),i=await o(e({stderr:n,stdout:s,indexURL:a}));if(t.fetch&&await Ve(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},registerJSModule:Ze,run:Ge,runAsync:et,runEvent:tt,transform:(e,t)=>t instanceof e.ffi.PyProxy?t.toJs(nt):t,writeFile:({FS:e,PATH:t,_module:{PATH_FS:r}},n,s)=>ze({FS:e,PATH:t,PATH_FS:r},n,s)};const ot="ruby-wasm-wasi",at=ot.replace(/\W+/g,"_");var it={type:ot,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 Ve(this,o,t.fetch),o},registerJSModule(e,t,r){const n=`__module_${at}_${t}`;globalThis[n]=r,this.run(e,`require "js";$${t}=JS.global[:${n}]`),delete globalThis[n]},run:(e,t,...r)=>e.eval(De(t),...r),runAsync:(e,t,...r)=>e.evalAsync(De(t),...r),async runEvent(e,t,r){if(/^xworker\.(on\w+)$/.test(t)){const{$1:t}=RegExp,n=`__module_${at}_event`;globalThis[n]=r,this.run(e,`require "js";$xworker.call("${t}",JS.global[:${n}])`),delete globalThis[n]}else{const n=this.run(e,`method(:${t})`);await n.call(t,e.wrap(r))}},transform:(e,t)=>t,writeFile:()=>{throw new Error(`writeFile is not supported in ${ot}`)}};var ct={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}=Ue(),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 Ve(this,a,r.fetch),a},registerJSModule:(e,t,r)=>{e.global.set(t,r)},run:(e,t,...r)=>{try{return e.doStringSync(De(t),...r)}catch(t){He.get(e).stderr(t)}},runAsync:async(e,t,...r)=>{try{return await e.doString(De(t),...r)}catch(t){He.get(e).stderr(t)}},runEvent:async(e,t,r)=>{const[n,...s]=t.split(".");let o,a=e.global.get(n);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,r)}catch(t){He.get(e).stderr(t)}},transform:(e,t)=>t,writeFile:({cmodule:{module:{FS:e}}},t,r)=>((e,t,r)=>(Qe(e,qe(t)),t=Ye(e,t),e.writeFile(t,new Uint8Array(r),{canOwn:!0})))(e,t,r)};const lt=new Map,ut=new Map,pt=[],ft=[],dt=new Proxy(new Map,{get(e,t){if(!e.has(t)){const[r,...n]=t.split("@"),s=lt.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=>{ut.set(t,e);const a=e?.fetch;return a&&Xe.set(a,o),s(n,e,r)}))}}),yt=e=>{for(const t of[].concat(e.type))lt.set(t,e),pt.push(`script[type="${t}"]`),ft.push(`${t}-`)};for(const e of[rt,st,it,ct])yt(e);const ht=async e=>(await import("https://cdn.jsdelivr.net/npm/basic-toml@0.3.1/es.js")).parse(e),mt=(e,t,r={})=>{if(t)if(t.endsWith(".json"))r=fetch(t).then(Ie),t=We(t);else if(t.endsWith(".toml"))r=fetch(t).then(Be).then(ht),t=We(t);else if(!t.endsWith(".txt")){try{r=JSON.parse(t)}catch(e){r=ht(t)}t=We("./config.txt")}return Me(r).then((r=>dt[e](r,t)))},gt=(e,t="")=>`${e}@${t}`.replace(/@$/,""),wt=(t,r)=>{const n=(e=>{let t=e;for(;t.parentNode;)t=t.parentNode;return t})(t);return n.getElementById(r)||e(r,n)},bt=new WeakMap,vt={get(){let e=bt.get(this);return e||(e=document.createElement(`${this.type}-script`),bt.set(this,e),St(this)),e},set(e){"string"==typeof e?bt.set(this,wt(this,e)):(bt.set(this,e),St(this))}},_t=new WeakMap,Et=new Map,At=(e,t)=>{const r=e?.value;return r?t+r:""},kt=(e,t,r,n,s,o=e)=>{if(!Et.has(t)){const a={interpreter:mt(r,s),queue:Me(),XWorker:Ce(e,n)};Et.set(t,a),Et.has(e)||Et.set(e,a),Et.has(o)||Et.set(o,a)}return Et.get(t)},St=async e=>{if(_t.has(e)){const{target:t}=e;t&&(e.closest("head")?document.body.append(t):e.after(t))}else{const{attributes:{async:t,config:r,env:n,target:s,version:o},src:a,type:i}=e,c=o?.value,l=gt(i,c);let u=At(r,"|");const p=At(n,"")||`${l}${u}`;u=u.slice(1);const f=Je(e);if(f){const r=new(Ce(i,c))(f,{...Oe(e,i),async:!!t,config:u});return void _t.set(Pe(e,"xworker",{value:r}),{xworker:r})}const d=At(s,""),y=kt(i,p,l,c,u);_t.set(Pe(e,"target",vt),y),d&&bt.set(e,wt(e,d));const h=a?fetch(a).then(Be):e.textContent;y.queue=y.queue.then((()=>(async(e,t,r,n)=>{const s=lt.get(e.type);s.experimental&&console.warn(`The ${e.type} interpreter is experimental`);const[o,a]=await $e([_t.get(e).interpreter,t]);try{return Pe(document,"currentScript",{configurable:!0,get:()=>e}),s.registerJSModule(o,"polyscript",{XWorker:r}),s[n?"runAsync":"run"](o,a)}finally{delete document.currentScript}})(e,h,y.XWorker,!!t)))}};new Proxy(Re(null),{get:(e,t)=>Rt(t)});const Rt=async e=>{if(Et.has(e)){const{interpreter:t,queue:r}=Et.get(e);return(await $e([t,r]))[0]}const t=Et.size?`Available interpreters are: ${[...Et.keys()].map((e=>`"${e}"`)).join(", ")}.`:"There are no interpreters in this page.";throw new Error(`The interpreter "${e}" was not found. ${t}`)},xt=async e=>{const{type:t,currentTarget:n}=e;for(let{name:s,value:o,ownerElement:a}of r(`./@*[${ft.map((e=>`name()="${e}${t}"`)).join(" or ")}]`,n)){s=s.slice(0,-(t.length+1));const r=await Rt(a.getAttribute(`${s}-env`)||s);lt.get(s).runEvent(r,o,e)}},Pt=e=>{for(let{name:t,ownerElement:n}of r(`.//@*[${ft.map((e=>`starts-with(name(),"${e}")`)).join(" or ")}]`,e))t=t.slice(t.lastIndexOf("-")+1),"env"!==t&&n.addEventListener(t,xt)},jt=[],$t=new Map,Mt=new Map,Wt=e=>{for(const t of jt)if(e.matches(t)){const r=$t.get(t),{resolve:n}=Mt.get(r),{options:s,known:o}=Tt.get(r);if(!o.has(e)){o.add(e);const{interpreter:t,config:a,version:i,env:c,onInterpreterReady:l}=s,u=Je(e);if(u){const o=It.call(new Le(null,s),u,{...Oe(e,r),version:i,type:t,custom:r,config:a||{},async:e.hasAttribute("async")});return Pe(e,"xworker",{value:o}),void n({type:r,xworker:o})}const p=gt(t,i),f=c||`${p}${a?`|${a}`:""}`,{interpreter:d,XWorker:y}=kt(r,f,p,i,a,t);d.then((o=>{const a=Re(lt.get(t)),{onBeforeRun:i,onBeforeRunAsync:c,onAfterRun:u,onAfterRunAsync:f}=s,d=new Le(o,s),h=function(...e){return y.apply(d,e)};for(const[t,[r,n]]of[["run",[i,u]]]){const s=a[t];a[t]=function(t,o,...a){r&&r.call(this,m,e);const i=s.call(this,t,o,...a);return n&&n.call(this,m,e),i}}for(const[t,[r,n]]of[["runAsync",[c,f]]]){const s=a[t];a[t]=async function(t,o,...a){r&&await r.call(this,m,e);const i=await s.call(this,t,o,...a);return n&&await n.call(this,m,e),i}}a.registerJSModule(o,"polyscript",{XWorker:h});const m={type:r,interpreter:o,XWorker:h,io:He.get(o),config:structuredClone(ut.get(p)),run:a.run.bind(a,o),runAsync:a.runAsync.bind(a,o),runEvent:a.runEvent.bind(a,o)};n(m),l?.(m,e)}))}}},Tt=new Map;let Ot=0;const Ft=e=>(Mt.has(e)||Mt.set(e,Promise.withResolvers()),Mt.get(e).promise),It=Ce(),Bt=pt.join(","),Nt=new MutationObserver((e=>{for(const{type:r,target:n,attributeName:s,addedNodes:o}of e)if("attributes"!==r){for(const e of o)if(1===e.nodeType)if(Pt(e),e.matches(Bt))St(e);else{if(t(Bt,e).forEach(St),!jt.length)continue;Wt(e),t(jt.join(","),e).forEach(Wt)}}else{const e=s.lastIndexOf("-")+1;if(e){const t=s.slice(0,e);for(const r of ft)if(t===r){const t=s.slice(e);if("env"!==t){const e=n.hasAttribute(s)?"add":"remove";n[`${e}EventListener`](t,xt)}break}}}})),Lt=e=>(Nt.observe(e,{childList:!0,subtree:!0,attributes:!0}),e),{attachShadow:Ct}=Element.prototype;Se(Element.prototype,{attachShadow(e){return Lt(Ct.call(this,e))}}),Pt(Lt(document)),t(Bt,document).forEach(St);const Jt={"<":"<",">":">"},Dt=e=>{return(new DOMParser).parseFromString((t=e,t.replace(/[<>]/g,(e=>Jt[e]))),"text/html").documentElement.textContent;var t};var Ht={sleep:e=>new Promise((t=>setTimeout(t,1e3*e)))};const{entries:Ut}=Object,zt=["from pathlib import Path as _Path"],qt=(e,t)=>{for(const[r,n]of Ut(t)){const t=`_Path("${e}/${r}")`;if("string"==typeof n){const e=JSON.stringify(n);zt.push(`${t}.write_text(${e})`)}else zt.push(`${t}.mkdir(parents=True, exist_ok=True)`),qt(`${e}/${r}`,n)}};qt(".",{_pyscript:{"__init__.py":'import js as window\n\nIS_WORKER = not hasattr(window, "document")\n\nif IS_WORKER:\n from polyscript import xworker as _xworker\n\n window = _xworker.window\n document = window.document\n sync = _xworker.sync\nelse:\n document = window.document\n',"display.py":'import base64\nimport html\nimport io\nimport re\n\nfrom . import document, window\n\n_MIME_METHODS = {\n "__repr__": "text/plain",\n "_repr_html_": "text/html",\n "_repr_markdown_": "text/markdown",\n "_repr_svg_": "image/svg+xml",\n "_repr_png_": "image/png",\n "_repr_pdf_": "application/pdf",\n "_repr_jpeg_": "image/jpeg",\n "_repr_latex": "text/latex",\n "_repr_json_": "application/json",\n "_repr_javascript_": "application/javascript",\n "savefig": "image/png",\n}\n\n\ndef _render_image(mime, value, meta):\n # If the image value is using bytes we should convert it to base64\n # otherwise it will return raw bytes and the browser will not be able to\n # render it.\n if isinstance(value, bytes):\n value = base64.b64encode(value).decode("utf-8")\n\n # This is the pattern of base64 strings\n base64_pattern = re.compile(\n r"^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"\n )\n # If value doesn\'t match the base64 pattern we should encode it to base64\n if len(value) > 0 and not base64_pattern.match(value):\n value = base64.b64encode(value.encode("utf-8")).decode("utf-8")\n\n data = f"data:{mime};charset=utf-8;base64,{value}"\n attrs = " ".join([\'{k}="{v}"\' for k, v in meta.items()])\n return f\'<img src="{data}" {attrs}></img>\'\n\n\ndef _identity(value, meta):\n return value\n\n\n_MIME_RENDERERS = {\n "text/plain": html.escape,\n "text/html": _identity,\n "image/png": lambda value, meta: _render_image("image/png", value, meta),\n "image/jpeg": lambda value, meta: _render_image("image/jpeg", value, meta),\n "image/svg+xml": _identity,\n "application/json": _identity,\n "application/javascript": lambda value, meta: f"<script>{value}<\\\\/script>",\n}\n\n\ndef _eval_formatter(obj, print_method):\n """\n Evaluates a formatter method.\n """\n if print_method == "__repr__":\n return repr(obj)\n elif hasattr(obj, print_method):\n if print_method == "savefig":\n buf = io.BytesIO()\n obj.savefig(buf, format="png")\n buf.seek(0)\n return base64.b64encode(buf.read()).decode("utf-8")\n return getattr(obj, print_method)()\n elif print_method == "_repr_mimebundle_":\n return {}, {}\n return None\n\n\ndef _format_mime(obj):\n """\n Formats object using _repr_x_ methods.\n """\n if isinstance(obj, str):\n return html.escape(obj), "text/plain"\n\n mimebundle = _eval_formatter(obj, "_repr_mimebundle_")\n if isinstance(mimebundle, tuple):\n format_dict, _ = mimebundle\n else:\n format_dict = mimebundle\n\n output, not_available = None, []\n for method, mime_type in reversed(_MIME_METHODS.items()):\n if mime_type in format_dict:\n output = format_dict[mime_type]\n else:\n output = _eval_formatter(obj, method)\n\n if output is None:\n continue\n elif mime_type not in _MIME_RENDERERS:\n not_available.append(mime_type)\n continue\n break\n if output is None:\n if not_available:\n window.console.warn(\n f"Rendered object requested unavailable MIME renderers: {not_available}"\n )\n output = repr(output)\n mime_type = "text/plain"\n elif isinstance(output, tuple):\n output, meta = output\n else:\n meta = {}\n return _MIME_RENDERERS[mime_type](output, meta), mime_type\n\n\ndef _write(element, value, append=False):\n html, mime_type = _format_mime(value)\n if html == "\\\\n":\n return\n\n if append:\n out_element = document.createElement("div")\n element.append(out_element)\n else:\n out_element = element.lastElementChild\n if out_element is None:\n out_element = element\n\n if mime_type in ("application/javascript", "text/html"):\n script_element = document.createRange().createContextualFragment(html)\n out_element.append(script_element)\n else:\n out_element.innerHTML = html\n\n\ndef display(*values, target=None, append=True):\n element = document.getElementById(target)\n for v in values:\n _write(element, v, append=append)\n'},"pyscript.py":"# export only what we want to expose as `pyscript` module\n# but not what is WORKER/MAIN dependent\nfrom _pyscript import window, document, IS_WORKER\nfrom _pyscript.display import display as _display\n\n# this part is needed to disambiguate between MAIN and WORKER\nif IS_WORKER:\n # in workers the display does not have a default ID\n # but there is a sync utility from xworker\n import polyscript as _polyscript\n from _pyscript import sync\n\n def current_target():\n return _polyscript.target\n\nelse:\n # in MAIN both PyWorker and current element target exist\n # so these are both exposed and the display will use,\n # if not specified otherwise, such current element target\n import _pyscript_js\n\n PyWorker = _pyscript_js.PyWorker\n\n def current_target():\n return _pyscript_js.target\n\n\n# the display provides a handy default target either in MAIN or WORKER\ndef display(*values, target=None, append=True):\n if target is None:\n target = current_target()\n\n return _display(*values, target=target, append=append)\n"}),zt.push("del _Path"),zt.push("\n");var Qt=zt.join("\n"),Yt={error:()=>import("./error-f33e3b18.js")};const Kt="PY0001",Xt="PY0401",Vt="PY0403",Zt="PY0404",Gt="PY0500",er="PY0503";class tr extends Error{constructor(e,t="",r="text"){super(`(${e}): ${t}`),this.errorCode=e,this.messageType=r,this.name="UserError"}}class rr extends tr{constructor(e,t){super(e,t),this.name="FetchError"}}async function nr(e,t){let r;try{r=await fetch(e,t)}catch(t){const r=t;let n;throw n=e.startsWith("http")?`Fetching from URL ${e} failed with error '${r.message}'. Are your filename and path correct?`:'Polyscript: Access to local files\n (using [[fetch]] configurations in <py-config>)\n is not available when directly opening a HTML file;\n you must use a webserver to serve the additional files.\n See <a style="text-decoration: underline;" href="https://github.com/pyscript/pyscript/issues/257#issuecomment-1119595062">this reference</a>\n on starting a simple webserver with Python.\n ',new rr(Kt,n)}if(!r.ok){const t=`Fetching from URL ${e} failed with error ${r.status} (${r.statusText}). Are your filename and path correct?`;switch(r.status){case 404:throw new rr(Zt,t);case 401:throw new rr(Xt,t);case 403:throw new rr(Vt,t);case 500:throw new rr(Gt,t);case 503:throw new rr(er,t);default:throw new rr(Kt,t)}}return r}const{assign:sr,defineProperty:or,entries:ar}=Object,ir=e=>e.text();let cr,lr=0;const ur=(e="py")=>`${e}-${lr++}`;let pr,fr=e("py-config");fr?pr=fr.getAttribute("src")||fr.textContent:(fr=e('script[type="py"]'),pr=fr?.getAttribute("config")),/^https?:\/\//.test(pr)&&(pr=await nr(pr).then(ir));const dr=({tagName:e})=>"SCRIPT"===e,yr=e=>{or(document,"currentScript",{configurable:!0,get:()=>e})},hr=()=>{delete document.currentScript},mr=async(e,t,r)=>{if(e.hasAttribute("src"))try{return await nr(e.getAttribute("src")).then(ir)}catch(e){t.stderr(e)}return r?e.textContent:(console.warn('Deprecated: use <script type="py"> for an always safe content parsing:\n',e.innerHTML),Dt(e.innerHTML))},gr=(e,t,r,n)=>{dr(t)&&r(t);for(const r of br[n])r(e,t)};let wr=!0;const br={onBeforeRun:new Set,onBeforeRunAync:new Set,onAfterRun:new Set,onAfterRunAsync:new Set,onInterpreterReady:new Set,codeBeforeRunWorker:new Set,codeBeforeRunWorkerAsync:new Set,codeAfterRunWorker:new Set,codeAfterRunWorkerAsync:new Set},vr={codeBeforeRunWorker:()=>[Qt,...br.codeBeforeRunWorker].join("\n"),codeBeforeRunWorkerAsync:()=>[Qt,...br.codeBeforeRunWorkerAsync].join("\n"),codeAfterRunWorker:()=>[...br.codeAfterRunWorker].join("\n"),codeAfterRunWorkerAsync:()=>[...br.codeAfterRunWorkerAsync].join("\n")};((e,r)=>{let n=null==e;if(n)e="_ps"+Ot++;else if(lt.has(e)||Tt.has(e))throw new Error(`<script type="${e}"> already registered`);if(!lt.has(r?.interpreter))throw new Error("Unspecified interpreter");lt.set(e,lt.get(r.interpreter));const s=[`script[type="${e}"]`];if(Ft(e),n){const{onInterpreterReady:t}=r;r={...r,onInterpreterReady(r,n){jt.splice(jt.indexOf(e),1),lt.delete(e),Tt.delete(e),Mt.delete(e),n.remove(),t?.(r)}},document.head.append(Se(document.createElement("script"),{type:e}))}else s.push(`${e}-script`),ft.push(`${e}-`);for(const t of s)$t.set(t,e);jt.push(...s),Tt.set(e,{options:Se({env:e},r),known:new WeakSet}),n||Pt(document),t(s.join(",")).forEach(Wt)})("py",{config:pr,env:"py-script",interpreter:"pyodide",...vr,onWorkerReady(e,t){sr(t.sync,Ht)},onBeforeRun(e,t){cr=t,gr(e,t,yr,"onBeforeRun")},onBeforeRunAync(e,t){cr=t,gr(e,t,yr,"onBeforeRunAync")},onAfterRun(e,t){gr(e,t,hr,"onAfterRun")},onAfterRunAsync(e,t){gr(e,t,hr,"onAfterRunAsync")},async onInterpreterReady(e,t){wr&&(wr=!1,(({XWorker:e,interpreter:t,io:r})=>{t.registerJsModule("_pyscript_js",{PyWorker:function(...t){const n=e(...t);return n.onerror=({error:e})=>r.stderr(e),n},get target(){return dr(cr)?cr.target.id:cr.id}}),t.runPython(Qt,{globals:t.runPython("{}")})})(e));const r=[];for(const[t,n]of ar(Yt))e.config?.plugins?.includes(`!${t}`)||r.push(n());r.length&&await Promise.all(r);for(const r of br.onInterpreterReady)r(e,t);if(dr(t)){const{attributes:{async:r,target:n}}=t,s=!!n?.value,o=s?wt(n.value):document.createElement("script-py");if(!s){const{head:e,body:r}=document;e.contains(t)?r.append(o):t.after(o)}o.id||(o.id=ur()),or(t,"target",{value:o}),e["run"+(r?"Async":"")](await mr(t,e.io,!0))}else t._pyodide.resolve(e);console.debug("[pyscript/main] PyScript Ready")}});class _r extends HTMLElement{constructor(){sr(super(),{_pyodide:Promise.withResolvers(),srcCode:"",executed:!1})}get id(){return super.id||(super.id=ur())}set id(e){super.id=e}async connectedCallback(){if(!this.executed){this.executed=!0;const{io:e,run:t,runAsync:r}=await this._pyodide.promise,n=this.hasAttribute("async")?r:t;this.srcCode=await mr(this,e,!this.childElementCount),this.replaceChildren(),n(this.srcCode),this.style.display="block"}}}function Er(e,t){const r=It.call(new Le(null,vr),e,{...t,type:"pyodide"});return sr(r.sync,Ht),r}customElements.define("py-script",_r);export{Er as PyWorker,br as hooks};
|
@@ -0,0 +1 @@
|
|
1
|
+
import{hooks as e}from"./core.js";e.onBeforeRun.add((function n(o){e.onBeforeRun.delete(n);const{stderr:r}=o.io;o.io.stderr=(...e)=>{const[{message:n}]=e;return function(e){const n=document.createElement("div");n.className="py-error",n.textContent=e,n.style.cssText="\n border: 1px solid red;\n background: #ffdddd;\n color: black;\n font-family: courier, monospace;\n white-space: pre;\n overflow-x: auto;\n padding: 8px;\n margin-top: 8px;\n ",document.body.append(n)}(n),r(...e)}}));
|
package/package.json
CHANGED
@@ -1,27 +1,23 @@
|
|
1
1
|
{
|
2
2
|
"name": "@pyscript/core",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.8",
|
4
4
|
"type": "module",
|
5
5
|
"description": "PyScript",
|
6
|
-
"
|
7
|
-
"
|
8
|
-
"unpkg": "./core.js",
|
6
|
+
"module": "./dist/core.js",
|
7
|
+
"unpkg": "./dist/core.js",
|
9
8
|
"exports": {
|
10
9
|
".": {
|
11
|
-
"types": "./types/
|
12
|
-
"import": "./
|
13
|
-
},
|
14
|
-
"./js": {
|
15
|
-
"import": "./core.js"
|
10
|
+
"types": "./types/core.d.ts",
|
11
|
+
"import": "./src/core.js"
|
16
12
|
},
|
17
13
|
"./css": {
|
18
|
-
"import": "./core.css"
|
14
|
+
"import": "./dist/core.css"
|
19
15
|
},
|
20
16
|
"./package.json": "./package.json"
|
21
17
|
},
|
22
18
|
"scripts": {
|
23
19
|
"server": "npx static-handler --cors --coep --coop --corp .",
|
24
|
-
"build": "rollup
|
20
|
+
"build": "node rollup/stdlib.cjs && node rollup/plugins.cjs && rollup --config rollup/core.config.js && npm run ts",
|
25
21
|
"ts": "tsc -p ."
|
26
22
|
},
|
27
23
|
"keywords": [
|
@@ -33,12 +29,12 @@
|
|
33
29
|
"dependencies": {
|
34
30
|
"@ungap/with-resolvers": "^0.1.0",
|
35
31
|
"basic-devtools": "^0.1.6",
|
36
|
-
"polyscript": "^0.
|
32
|
+
"polyscript": "^0.3.0"
|
37
33
|
},
|
38
34
|
"devDependencies": {
|
39
35
|
"@rollup/plugin-node-resolve": "^15.2.1",
|
40
36
|
"@rollup/plugin-terser": "^0.4.3",
|
41
|
-
"rollup": "^3.
|
37
|
+
"rollup": "^3.29.0",
|
42
38
|
"rollup-plugin-postcss": "^4.0.2",
|
43
39
|
"rollup-plugin-string": "^3.0.0",
|
44
40
|
"static-handler": "^0.4.2",
|
package/src/core.js
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
import "@ungap/with-resolvers";
|
2
2
|
import { $ } from "basic-devtools";
|
3
3
|
import { define, XWorker } from "polyscript";
|
4
|
+
import { htmlDecode } from "./utils.js";
|
5
|
+
import sync from "./sync.js";
|
4
6
|
|
5
|
-
|
6
|
-
import
|
7
|
+
import stdlib from "./stdlib.js";
|
8
|
+
import plugins from "./plugins.js";
|
7
9
|
|
8
10
|
// TODO: this is not strictly polyscript related but handy ... not sure
|
9
11
|
// we should factor this utility out a part but this works anyway.
|
@@ -12,7 +14,7 @@ import { Hook } from "../node_modules/polyscript/esm/worker/hooks.js";
|
|
12
14
|
|
13
15
|
import { robustFetch as fetch } from "./fetch.js";
|
14
16
|
|
15
|
-
const { defineProperty } = Object;
|
17
|
+
const { assign, defineProperty, entries } = Object;
|
16
18
|
|
17
19
|
const getText = (body) => body.text();
|
18
20
|
|
@@ -35,7 +37,7 @@ else {
|
|
35
37
|
if (/^https?:\/\//.test(config)) config = await fetch(config).then(getText);
|
36
38
|
|
37
39
|
// generic helper to disambiguate between custom element and script
|
38
|
-
const isScript = (
|
40
|
+
const isScript = ({ tagName }) => tagName === "SCRIPT";
|
39
41
|
|
40
42
|
// helper for all script[type="py"] out there
|
41
43
|
const before = (script) => {
|
@@ -54,7 +56,7 @@ const after = () => {
|
|
54
56
|
* It either throws an error if the 'src' can't be fetched or it returns a fallback
|
55
57
|
* content as source.
|
56
58
|
*/
|
57
|
-
const fetchSource = async (tag, io) => {
|
59
|
+
const fetchSource = async (tag, io, asText) => {
|
58
60
|
if (tag.hasAttribute("src")) {
|
59
61
|
try {
|
60
62
|
return await fetch(tag.getAttribute("src")).then(getText);
|
@@ -62,7 +64,15 @@ const fetchSource = async (tag, io) => {
|
|
62
64
|
io.stderr(error);
|
63
65
|
}
|
64
66
|
}
|
65
|
-
|
67
|
+
|
68
|
+
if (asText) return tag.textContent;
|
69
|
+
|
70
|
+
console.warn(
|
71
|
+
'Deprecated: use <script type="py"> for an always safe content parsing:\n',
|
72
|
+
tag.innerHTML,
|
73
|
+
);
|
74
|
+
|
75
|
+
return htmlDecode(tag.innerHTML);
|
66
76
|
};
|
67
77
|
|
68
78
|
// common life-cycle handlers for any node
|
@@ -71,6 +81,7 @@ const bootstrapNodeAndPlugins = (pyodide, element, callback, hook) => {
|
|
71
81
|
for (const fn of hooks[hook]) fn(pyodide, element);
|
72
82
|
};
|
73
83
|
|
84
|
+
let shouldRegister = true;
|
74
85
|
const registerModule = ({ XWorker: $XWorker, interpreter, io }) => {
|
75
86
|
// automatically use the pyscript stderr (when/if defined)
|
76
87
|
// this defaults to console.error
|
@@ -79,43 +90,18 @@ const registerModule = ({ XWorker: $XWorker, interpreter, io }) => {
|
|
79
90
|
worker.onerror = ({ error }) => io.stderr(error);
|
80
91
|
return worker;
|
81
92
|
}
|
82
|
-
|
83
|
-
//
|
84
|
-
|
85
|
-
[
|
86
|
-
"import js as window",
|
87
|
-
"document=window.document",
|
88
|
-
display,
|
89
|
-
"display",
|
90
|
-
].join("\n"),
|
91
|
-
// avoid leaking on global
|
92
|
-
{ globals: interpreter.runPython("{}") },
|
93
|
-
);
|
94
|
-
interpreter.registerJsModule("pyscript", {
|
93
|
+
|
94
|
+
// enrich the Python env with some JS utility for main
|
95
|
+
interpreter.registerJsModule("_pyscript_js", {
|
95
96
|
PyWorker,
|
96
|
-
|
97
|
-
|
98
|
-
// a getter to ensure if multiple scripts with same
|
99
|
-
// env (py) runs, their execution code will have the correct
|
100
|
-
// display reference with automatic target
|
101
|
-
get display() {
|
102
|
-
const id = isScript(currentElement)
|
97
|
+
get target() {
|
98
|
+
return isScript(currentElement)
|
103
99
|
? currentElement.target.id
|
104
100
|
: currentElement.id;
|
105
|
-
|
106
|
-
return (...args) => {
|
107
|
-
const last = args.at(-1);
|
108
|
-
let kw = { target: id, append: false };
|
109
|
-
if (
|
110
|
-
typeof last === "object" &&
|
111
|
-
last &&
|
112
|
-
("target" in last || "append" in last)
|
113
|
-
)
|
114
|
-
kw = { ...kw, ...args.pop() };
|
115
|
-
pyDisplay.callKwargs(...args, kw);
|
116
|
-
};
|
117
101
|
},
|
118
102
|
});
|
103
|
+
|
104
|
+
interpreter.runPython(stdlib, { globals: interpreter.runPython("{}") });
|
119
105
|
};
|
120
106
|
|
121
107
|
export const hooks = {
|
@@ -140,25 +126,11 @@ export const hooks = {
|
|
140
126
|
codeAfterRunWorkerAsync: new Set(),
|
141
127
|
};
|
142
128
|
|
143
|
-
const workerPyScriptModule = [
|
144
|
-
"from pathlib import Path as _Path",
|
145
|
-
`_Path("./pyscript.py").write_text(${JSON.stringify(
|
146
|
-
[
|
147
|
-
"from polyscript import xworker as _xworker",
|
148
|
-
"window=_xworker.window",
|
149
|
-
"document=window.document",
|
150
|
-
"sync=_xworker.sync",
|
151
|
-
display,
|
152
|
-
].join("\n"),
|
153
|
-
)})`,
|
154
|
-
"del _Path",
|
155
|
-
].join("\n");
|
156
|
-
|
157
129
|
const workerHooks = {
|
158
130
|
codeBeforeRunWorker: () =>
|
159
|
-
[
|
131
|
+
[stdlib, ...hooks.codeBeforeRunWorker].join("\n"),
|
160
132
|
codeBeforeRunWorkerAsync: () =>
|
161
|
-
[
|
133
|
+
[stdlib, ...hooks.codeBeforeRunWorkerAsync].join("\n"),
|
162
134
|
codeAfterRunWorker: () => [...hooks.codeAfterRunWorker].join("\n"),
|
163
135
|
codeAfterRunWorkerAsync: () =>
|
164
136
|
[...hooks.codeAfterRunWorkerAsync].join("\n"),
|
@@ -170,6 +142,9 @@ define("py", {
|
|
170
142
|
env: "py-script",
|
171
143
|
interpreter: "pyodide",
|
172
144
|
...workerHooks,
|
145
|
+
onWorkerReady(_, xworker) {
|
146
|
+
assign(xworker.sync, sync);
|
147
|
+
},
|
173
148
|
onBeforeRun(pyodide, element) {
|
174
149
|
currentElement = element;
|
175
150
|
bootstrapNodeAndPlugins(pyodide, element, before, "onBeforeRun");
|
@@ -185,7 +160,20 @@ define("py", {
|
|
185
160
|
bootstrapNodeAndPlugins(pyodide, element, after, "onAfterRunAsync");
|
186
161
|
},
|
187
162
|
async onInterpreterReady(pyodide, element) {
|
188
|
-
|
163
|
+
if (shouldRegister) {
|
164
|
+
shouldRegister = false;
|
165
|
+
registerModule(pyodide);
|
166
|
+
}
|
167
|
+
|
168
|
+
// load plugins unless specified otherwise
|
169
|
+
const toBeAwaited = [];
|
170
|
+
for (const [key, value] of entries(plugins)) {
|
171
|
+
if (!pyodide.config?.plugins?.includes(`!${key}`))
|
172
|
+
toBeAwaited.push(value());
|
173
|
+
}
|
174
|
+
|
175
|
+
if (toBeAwaited.length) await Promise.all(toBeAwaited);
|
176
|
+
|
189
177
|
// allows plugins to do whatever they want with the element
|
190
178
|
// before regular stuff happens in here
|
191
179
|
for (const callback of hooks.onInterpreterReady)
|
@@ -199,7 +187,11 @@ define("py", {
|
|
199
187
|
? queryTarget(target.value)
|
200
188
|
: document.createElement("script-py");
|
201
189
|
|
202
|
-
if (!hasTarget)
|
190
|
+
if (!hasTarget) {
|
191
|
+
const { head, body } = document;
|
192
|
+
if (head.contains(element)) body.append(show);
|
193
|
+
else element.after(show);
|
194
|
+
}
|
203
195
|
if (!show.id) show.id = getID();
|
204
196
|
|
205
197
|
// allows the code to retrieve the target element via
|
@@ -207,29 +199,38 @@ define("py", {
|
|
207
199
|
defineProperty(element, "target", { value: show });
|
208
200
|
|
209
201
|
pyodide[`run${isAsync ? "Async" : ""}`](
|
210
|
-
await fetchSource(element, pyodide.io),
|
202
|
+
await fetchSource(element, pyodide.io, true),
|
211
203
|
);
|
212
204
|
} else {
|
213
205
|
// resolve PyScriptElement to allow connectedCallback
|
214
206
|
element._pyodide.resolve(pyodide);
|
215
207
|
}
|
208
|
+
console.debug("[pyscript/main] PyScript Ready");
|
216
209
|
},
|
217
210
|
});
|
218
211
|
|
219
212
|
class PyScriptElement extends HTMLElement {
|
220
213
|
constructor() {
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
214
|
+
assign(super(), {
|
215
|
+
_pyodide: Promise.withResolvers(),
|
216
|
+
srcCode: "",
|
217
|
+
executed: false,
|
218
|
+
});
|
219
|
+
}
|
220
|
+
get id() {
|
221
|
+
return super.id || (super.id = getID());
|
222
|
+
}
|
223
|
+
set id(value) {
|
224
|
+
super.id = value;
|
225
225
|
}
|
226
226
|
async connectedCallback() {
|
227
227
|
if (!this.executed) {
|
228
228
|
this.executed = true;
|
229
|
-
const { io, run } = await this._pyodide.promise;
|
230
|
-
this.
|
231
|
-
this.
|
232
|
-
|
229
|
+
const { io, run, runAsync } = await this._pyodide.promise;
|
230
|
+
const runner = this.hasAttribute("async") ? runAsync : run;
|
231
|
+
this.srcCode = await fetchSource(this, io, !this.childElementCount);
|
232
|
+
this.replaceChildren();
|
233
|
+
runner(this.srcCode);
|
233
234
|
this.style.display = "block";
|
234
235
|
}
|
235
236
|
}
|
@@ -249,8 +250,10 @@ export function PyWorker(file, options) {
|
|
249
250
|
// as the interpreter to use in the worker, as all hooks assume that
|
250
251
|
// and as `pyodide` is the only default interpreter that can deal with
|
251
252
|
// all the features we need to deliver pyscript out there.
|
252
|
-
|
253
|
+
const xworker = XWorker.call(new Hook(null, workerHooks), file, {
|
253
254
|
...options,
|
254
255
|
type: "pyodide",
|
255
256
|
});
|
257
|
+
assign(xworker.sync, sync);
|
258
|
+
return xworker;
|
256
259
|
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// PyScript Error Plugin
|
2
|
+
import { hooks } from "../core.js";
|
3
|
+
|
4
|
+
hooks.onBeforeRun.add(function override(pyScript) {
|
5
|
+
// be sure this override happens only once
|
6
|
+
hooks.onBeforeRun.delete(override);
|
7
|
+
|
8
|
+
// trap generic `stderr` to propagate to it regardless
|
9
|
+
const { stderr } = pyScript.io;
|
10
|
+
|
11
|
+
// override it with our own logic
|
12
|
+
pyScript.io.stderr = (...args) => {
|
13
|
+
// grab the message of the first argument (Error)
|
14
|
+
const [{ message }] = args;
|
15
|
+
// show it
|
16
|
+
notify(message);
|
17
|
+
// still let other plugins or PyScript itself do the rest
|
18
|
+
return stderr(...args);
|
19
|
+
};
|
20
|
+
});
|
21
|
+
|
22
|
+
// Error hook utilities
|
23
|
+
|
24
|
+
// Custom function to show notifications
|
25
|
+
function notify(message) {
|
26
|
+
const div = document.createElement("div");
|
27
|
+
div.className = "py-error";
|
28
|
+
div.textContent = message;
|
29
|
+
div.style.cssText = `
|
30
|
+
border: 1px solid red;
|
31
|
+
background: #ffdddd;
|
32
|
+
color: black;
|
33
|
+
font-family: courier, monospace;
|
34
|
+
white-space: pre;
|
35
|
+
overflow-x: auto;
|
36
|
+
padding: 8px;
|
37
|
+
margin-top: 8px;
|
38
|
+
`;
|
39
|
+
document.body.append(div);
|
40
|
+
}
|
package/src/plugins.js
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
// ⚠️ This file is an artifact: DO NOT MODIFY
|
2
|
+
export default {
|
3
|
+
"_pyscript": {
|
4
|
+
"__init__.py": "import js as window\n\nIS_WORKER = not hasattr(window, \"document\")\n\nif IS_WORKER:\n from polyscript import xworker as _xworker\n\n window = _xworker.window\n document = window.document\n sync = _xworker.sync\nelse:\n document = window.document\n",
|
5
|
+
"display.py": "import base64\nimport html\nimport io\nimport re\n\nfrom . import document, window\n\n_MIME_METHODS = {\n \"__repr__\": \"text/plain\",\n \"_repr_html_\": \"text/html\",\n \"_repr_markdown_\": \"text/markdown\",\n \"_repr_svg_\": \"image/svg+xml\",\n \"_repr_png_\": \"image/png\",\n \"_repr_pdf_\": \"application/pdf\",\n \"_repr_jpeg_\": \"image/jpeg\",\n \"_repr_latex\": \"text/latex\",\n \"_repr_json_\": \"application/json\",\n \"_repr_javascript_\": \"application/javascript\",\n \"savefig\": \"image/png\",\n}\n\n\ndef _render_image(mime, value, meta):\n # If the image value is using bytes we should convert it to base64\n # otherwise it will return raw bytes and the browser will not be able to\n # render it.\n if isinstance(value, bytes):\n value = base64.b64encode(value).decode(\"utf-8\")\n\n # This is the pattern of base64 strings\n base64_pattern = re.compile(\n r\"^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$\"\n )\n # If value doesn't match the base64 pattern we should encode it to base64\n if len(value) > 0 and not base64_pattern.match(value):\n value = base64.b64encode(value.encode(\"utf-8\")).decode(\"utf-8\")\n\n data = f\"data:{mime};charset=utf-8;base64,{value}\"\n attrs = \" \".join(['{k}=\"{v}\"' for k, v in meta.items()])\n return f'<img src=\"{data}\" {attrs}></img>'\n\n\ndef _identity(value, meta):\n return value\n\n\n_MIME_RENDERERS = {\n \"text/plain\": html.escape,\n \"text/html\": _identity,\n \"image/png\": lambda value, meta: _render_image(\"image/png\", value, meta),\n \"image/jpeg\": lambda value, meta: _render_image(\"image/jpeg\", value, meta),\n \"image/svg+xml\": _identity,\n \"application/json\": _identity,\n \"application/javascript\": lambda value, meta: f\"<script>{value}<\\\\/script>\",\n}\n\n\ndef _eval_formatter(obj, print_method):\n \"\"\"\n Evaluates a formatter method.\n \"\"\"\n if print_method == \"__repr__\":\n return repr(obj)\n elif hasattr(obj, print_method):\n if print_method == \"savefig\":\n buf = io.BytesIO()\n obj.savefig(buf, format=\"png\")\n buf.seek(0)\n return base64.b64encode(buf.read()).decode(\"utf-8\")\n return getattr(obj, print_method)()\n elif print_method == \"_repr_mimebundle_\":\n return {}, {}\n return None\n\n\ndef _format_mime(obj):\n \"\"\"\n Formats object using _repr_x_ methods.\n \"\"\"\n if isinstance(obj, str):\n return html.escape(obj), \"text/plain\"\n\n mimebundle = _eval_formatter(obj, \"_repr_mimebundle_\")\n if isinstance(mimebundle, tuple):\n format_dict, _ = mimebundle\n else:\n format_dict = mimebundle\n\n output, not_available = None, []\n for method, mime_type in reversed(_MIME_METHODS.items()):\n if mime_type in format_dict:\n output = format_dict[mime_type]\n else:\n output = _eval_formatter(obj, method)\n\n if output is None:\n continue\n elif mime_type not in _MIME_RENDERERS:\n not_available.append(mime_type)\n continue\n break\n if output is None:\n if not_available:\n window.console.warn(\n f\"Rendered object requested unavailable MIME renderers: {not_available}\"\n )\n output = repr(output)\n mime_type = \"text/plain\"\n elif isinstance(output, tuple):\n output, meta = output\n else:\n meta = {}\n return _MIME_RENDERERS[mime_type](output, meta), mime_type\n\n\ndef _write(element, value, append=False):\n html, mime_type = _format_mime(value)\n if html == \"\\\\n\":\n return\n\n if append:\n out_element = document.createElement(\"div\")\n element.append(out_element)\n else:\n out_element = element.lastElementChild\n if out_element is None:\n out_element = element\n\n if mime_type in (\"application/javascript\", \"text/html\"):\n script_element = document.createRange().createContextualFragment(html)\n out_element.append(script_element)\n else:\n out_element.innerHTML = html\n\n\ndef display(*values, target=None, append=True):\n element = document.getElementById(target)\n for v in values:\n _write(element, v, append=append)\n"
|
6
|
+
},
|
7
|
+
"pyscript.py": "# export only what we want to expose as `pyscript` module\n# but not what is WORKER/MAIN dependent\nfrom _pyscript import window, document, IS_WORKER\nfrom _pyscript.display import display as _display\n\n# this part is needed to disambiguate between MAIN and WORKER\nif IS_WORKER:\n # in workers the display does not have a default ID\n # but there is a sync utility from xworker\n import polyscript as _polyscript\n from _pyscript import sync\n\n def current_target():\n return _polyscript.target\n\nelse:\n # in MAIN both PyWorker and current element target exist\n # so these are both exposed and the display will use,\n # if not specified otherwise, such current element target\n import _pyscript_js\n\n PyWorker = _pyscript_js.PyWorker\n\n def current_target():\n return _pyscript_js.target\n\n\n# the display provides a handy default target either in MAIN or WORKER\ndef display(*values, target=None, append=True):\n if target is None:\n target = current_target()\n\n return _display(*values, target=target, append=append)\n"
|
8
|
+
};
|
package/src/stdlib.js
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
/**
|
2
|
+
* Create through Python the pyscript module through
|
3
|
+
* the artifact generated at build time.
|
4
|
+
* This the returned value is a string that must be used
|
5
|
+
* either before a worker execute code or when the module
|
6
|
+
* is registered on the main thread.
|
7
|
+
*/
|
8
|
+
|
9
|
+
import pyscript from "./stdlib/pyscript.js";
|
10
|
+
|
11
|
+
const { entries } = Object;
|
12
|
+
|
13
|
+
const python = ["from pathlib import Path as _Path"];
|
14
|
+
|
15
|
+
const write = (base, literal) => {
|
16
|
+
for (const [key, value] of entries(literal)) {
|
17
|
+
const path = `_Path("${base}/${key}")`;
|
18
|
+
if (typeof value === "string") {
|
19
|
+
const code = JSON.stringify(value);
|
20
|
+
python.push(`${path}.write_text(${code})`);
|
21
|
+
} else {
|
22
|
+
python.push(`${path}.mkdir(parents=True, exist_ok=True)`);
|
23
|
+
write(`${base}/${key}`, value);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
write(".", pyscript);
|
29
|
+
|
30
|
+
python.push("del _Path");
|
31
|
+
python.push("\n");
|
32
|
+
|
33
|
+
export default python.join("\n");
|
package/src/sync.js
ADDED
package/src/utils.js
ADDED
package/types/core.d.ts
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/types/sync.d.ts
ADDED
package/types/utils.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export function htmlDecode(html: any): string;
|