quickjs-emscripten-sync 1.3.0 → 1.5.1
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 +60 -37
- package/dist/index.d.ts +29 -22
- package/dist/quickjs-emscripten-sync.mjs +842 -0
- package/dist/quickjs-emscripten-sync.umd.js +15 -15
- package/package.json +12 -21
- package/src/default.ts +2 -2
- package/src/index.test.ts +159 -65
- package/src/index.ts +67 -66
- package/src/marshal/custom.test.ts +50 -0
- package/src/marshal/custom.ts +36 -0
- package/src/marshal/function.test.ts +60 -72
- package/src/marshal/function.ts +15 -18
- package/src/marshal/index.test.ts +88 -84
- package/src/marshal/index.ts +16 -18
- package/src/marshal/json.test.ts +32 -38
- package/src/marshal/json.ts +5 -7
- package/src/marshal/object.test.ts +52 -79
- package/src/marshal/object.ts +8 -15
- package/src/marshal/primitive.test.ts +16 -21
- package/src/marshal/primitive.ts +11 -10
- package/src/marshal/promise.test.ts +21 -22
- package/src/marshal/promise.ts +6 -13
- package/src/marshal/properties.test.ts +21 -26
- package/src/marshal/properties.ts +15 -17
- package/src/unmarshal/custom.test.ts +50 -0
- package/src/unmarshal/custom.ts +31 -0
- package/src/unmarshal/function.test.ts +52 -74
- package/src/unmarshal/function.ts +13 -22
- package/src/unmarshal/index.test.ts +58 -50
- package/src/unmarshal/index.ts +12 -13
- package/src/unmarshal/object.test.ts +37 -43
- package/src/unmarshal/object.ts +16 -20
- package/src/unmarshal/primitive.test.ts +15 -15
- package/src/unmarshal/primitive.ts +11 -18
- package/src/unmarshal/promise.test.ts +13 -13
- package/src/unmarshal/promise.ts +10 -19
- package/src/unmarshal/properties.test.ts +8 -8
- package/src/unmarshal/properties.ts +44 -45
- package/src/util.test.ts +2 -7
- package/src/util.ts +3 -8
- package/src/vmmap.test.ts +72 -88
- package/src/vmmap.ts +26 -44
- package/src/vmutil.test.ts +73 -89
- package/src/vmutil.ts +24 -47
- package/src/wrapper.test.ts +108 -148
- package/src/wrapper.ts +59 -62
- package/dist/quickjs-emscripten-sync.es.js +0 -951
- package/src/marshal/symbol.test.ts +0 -24
- package/src/marshal/symbol.ts +0 -20
- package/src/unmarshal/symbol.test.ts +0 -25
- package/src/unmarshal/symbol.ts +0 -12
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
(function(h,w){typeof exports=="object"&&typeof module!="undefined"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(h=typeof globalThis!="undefined"?globalThis:h||self,w(h.QuickjsEmscriptenSync={}))})(this,function(h){"use strict";
|
|
1
|
+
(function(h,w){typeof exports=="object"&&typeof module!="undefined"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(h=typeof globalThis!="undefined"?globalThis:h||self,w(h.QuickjsEmscriptenSync={}))})(this,function(h){"use strict";const w=[[Symbol,"Symbol"],[Symbol.prototype,"Symbol.prototype"],[Object,"Object"],[Object.prototype,"Object.prototype"],[Function,"Function"],[Function.prototype,"Function.prototype"],[Boolean,"Boolean"],[Boolean.prototype,"Boolean.prototype"],[Array,"Array"],[Array.prototype,"Array.prototype"],[Error,"Error"],[Error.prototype,"Error.prototype"],[EvalError,"EvalError"],[EvalError.prototype,"EvalError.prototype"],[RangeError,"RangeError"],[RangeError.prototype,"RangeError.prototype"],[ReferenceError,"ReferenceError"],[ReferenceError.prototype,"ReferenceError.prototype"],[SyntaxError,"SyntaxError"],[SyntaxError.prototype,"SyntaxError.prototype"],[TypeError,"TypeError"],[TypeError.prototype,"TypeError.prototype"],[URIError,"URIError"],[URIError.prototype,"URIError.prototype"],...Object.getOwnPropertyNames(Symbol).filter(t=>typeof Symbol[t]=="symbol").map(t=>[Symbol[t],`Symbol.${t}`])];function I(t,e){const r=t.unwrapResult(t.evalCode(e)),i=(n,...s)=>t.unwrapResult(t.callFunction(r,n!=null?n:t.undefined,...s));return i.dispose=()=>r.dispose(),i.alive=!0,Object.defineProperty(i,"alive",{get:()=>r.alive}),i}function d(t,e,r,...i){const n=I(t,e);try{return n(r,...i)}finally{n.dispose()}}function M(t,e,r){return t.dump(d(t,"Object.is",void 0,e,r))}function U(t,e,r){return t.dump(d(t,"(a, b) => a instanceof b",void 0,e,r))}function R(t,e){return t.dump(d(t,'a => typeof a === "object" && a !== null || typeof a === "function"',void 0,e))}function k(t,e){const r=JSON.stringify(e);return r?d(t,"JSON.parse",void 0,t.newString(r)):t.undefined}function H(t,e){try{return e(t)}finally{for(const r of t)r.alive&&r.dispose()}}function W([t,e],r){try{return r(t)}finally{e&&t.dispose()}}function j(t,e){try{return e(...t.map(r=>r[0]))}finally{for(const[r,i]of t)i&&r.dispose()}}function z(t){return"handle"in t}function $(t){return z(t)?t.handle:t}function G(t,e,r,i){var s;let n;for(const o of i)if(n=o(e,t),n)break;return n?(s=r(e,n))!=null?s:n:void 0}function q(t,e){return typeof t!="symbol"?void 0:d(e,"d => Symbol(d)",void 0,t.description?e.newString(t.description):e.undefined)}function Q(t,e){return t instanceof Date?d(e,"d => new Date(d)",void 0,e.newNumber(t.getTime())):void 0}const V=[q,Q];function C(t){return typeof t=="function"&&/^class\s/.test(Function.prototype.toString.call(t))}function v(t){return typeof t=="function"||typeof t=="object"&&t!==null}function P(t,e){const r=new Set,i=n=>{if(!(!v(n)||r.has(n)||(e==null?void 0:e(n,r))===!1)){if(r.add(n),Array.isArray(n)){for(const s of n)i(s);return}if(typeof n=="object"){const s=Object.getPrototypeOf(n);s&&s!==Object.prototype&&i(s)}for(const s of Object.values(Object.getOwnPropertyDescriptors(n)))"value"in s&&i(s.value),"get"in s&&i(s.get),"set"in s&&i(s.set)}};return i(t),r}function L(t,e){return P(t,e?(r,i)=>i.size<e:void 0).size}function X(){let t=()=>{},e=()=>{};return{promise:new Promise((i,n)=>{t=i,e=n}),resolve:t,reject:e}}function D(t,e,r,i){const n=t.newObject(),s=(u,a)=>{const p=i(u),l=typeof a.value=="undefined"?void 0:i(a.value),f=typeof a.get=="undefined"?void 0:i(a.get),c=typeof a.set=="undefined"?void 0:i(a.set);t.newObject().consume(m=>{Object.entries(a).forEach(([y,_])=>{const b=y==="value"?l:y==="get"?f:y==="set"?c:_?t.true:t.false;b&&t.setProp(m,y,b)}),t.setProp(n,p,m)})},o=Object.getOwnPropertyDescriptors(e);Object.entries(o).forEach(([u,a])=>s(u,a)),Object.getOwnPropertySymbols(o).forEach(u=>s(u,o[u])),d(t,"Object.defineProperties",void 0,r,n).dispose(),n.dispose()}function Y(t,e,r,i,n,s){var a;if(typeof e!="function")return;const o=t.newFunction(e.name,function(...p){const l=i(this),f=p.map(c=>i(c));if(C(e)&&v(l)){const c=new e(...f);return Object.entries(c).forEach(([m,y])=>{t.setProp(this,m,r(y))}),this}return r(s?s(e,l,f):e.apply(l,f))}).consume(p=>d(t,`Cls => {
|
|
2
|
+
const fn = function(...args) { return Cls.apply(this, args); };
|
|
3
|
+
fn.name = Cls.name;
|
|
4
|
+
fn.length = Cls.length;
|
|
5
|
+
return fn;
|
|
6
|
+
}`,void 0,p)),u=(a=n(e,o))!=null?a:o;return D(t,e,o,r),u}function Z(t,e,r){var s;const i=k(t,e);return(s=r(e,i))!=null?s:i}function K(t,e,r,i){var a;if(typeof e!="object"||e===null)return;const n=Array.isArray(e)?t.newArray():t.newObject(),s=(a=i(e,n))!=null?a:n,o=Object.getPrototypeOf(e),u=o&&o!==Object.prototype&&o!==Array.prototype?r(o):void 0;return u&&d(t,"Object.setPrototypeOf",void 0,s,u).dispose(),D(t,e,n,r),s}function x(t,e){switch(typeof e){case"undefined":return t.undefined;case"number":return t.newNumber(e);case"string":return t.newString(e);case"boolean":return e?t.true:t.false;case"object":return e===null?t.null:void 0}}function ee(t,e,r,i){var s;if(!(e instanceof Promise))return;const n=t.newPromise();return e.then(o=>n.resolve(r(o)),o=>n.reject(r(o))),(s=i(e,n))!=null?s:n.handle}function O(t,e){var l,f,c,m,y;const{ctx:r,unmarshal:i,isMarshalable:n,find:s,pre:o}=e;{const _=x(r,t);if(_)return _}{const _=s(t);if(_)return _}const u=n==null?void 0:n(t);if(u===!1)return r.undefined;const a=(_,b)=>o(_,b,u);if(u==="json")return Z(r,t,a);const p=_=>O(_,e);return(y=(m=(c=(f=G(r,t,a,[...V,...(l=e.custom)!=null?l:[]]))!=null?f:ee(r,t,p,a))!=null?c:Y(r,t,p,i,a,e.preApply))!=null?m:K(r,t,p,a))!=null?y:r.undefined}function te(t,e,r,i){var s;let n;for(const o of i)if(n=o(e,t),n)break;return n?(s=r(n,e))!=null?s:n:void 0}function re(t,e){if(e.typeof(t)!=="symbol")return;const r=e.getString(e.getProp(t,"description"));return Symbol(r)}function ne(t,e){if(!e.dump(d(e,"a => a instanceof Date",void 0,t)))return;const r=e.getNumber(d(e,"a => a.getTime()",void 0,t));return new Date(r)}const se=[re,ne];function F(t,e,r,i){t.newFunction("",(n,s)=>{const[o]=i(n);if(typeof o!="string"&&typeof o!="number"&&typeof o!="symbol")return;const u=[["value",!0],["get",!0],["set",!0],["configurable",!1],["enumerable",!1],["writable",!1]].reduce((a,[p,l])=>{const f=t.getProp(s,p),c=t.typeof(f);if(c==="undefined")return a;if(!l&&c==="boolean")return a[p]=t.dump(t.getProp(s,p)),a;const[m,y]=i(f);return y&&f.dispose(),a[p]=m,a},{});Object.defineProperty(r,o,u)}).consume(n=>{d(t,`(o, fn) => {
|
|
7
|
+
const descs = Object.getOwnPropertyDescriptors(o);
|
|
8
|
+
Object.entries(descs).forEach(([k, v]) => fn(k, v));
|
|
9
|
+
Object.getOwnPropertySymbols(descs).forEach(k => fn(k, descs[k]));
|
|
10
|
+
}`,void 0,e,n).dispose()})}function ie(t,e,r,i,n){var u;if(t.typeof(e)!=="function")return;const s=function(...a){return j([r(this),...a.map(p=>r(p))],(p,...l)=>{if(new.target){const[y]=i(d(t,"(Cls, ...args) => new Cls(...args)",p,e,...l));return Object.defineProperties(this,Object.getOwnPropertyDescriptors(y)),this}const f=t.unwrapResult(t.callFunction(e,p,...l)),[c,m]=i(f);return m&&f.dispose(),c})},o=(u=n(s,e))!=null?u:s;return F(t,e,s,i),o}function oe(t,e,r,i){var u;if(t.typeof(e)!=="object"||t.unwrapResult(t.evalCode("o => o === null")).consume(a=>t.dump(t.unwrapResult(t.callFunction(a,t.undefined,e)))))return;const n=d(t,"Array.isArray",void 0,e).consume(a=>t.dump(a))?[]:{},s=(u=i(n,e))!=null?u:n,o=d(t,`o => {
|
|
11
|
+
const p = Object.getPrototypeOf(o);
|
|
12
|
+
return !p || p === Object.prototype || p === Array.prototype ? undefined : p;
|
|
13
|
+
}`,void 0,e).consume(a=>{if(t.typeof(a)==="undefined")return;const[p]=r(a);return p});return typeof o=="object"&&Object.setPrototypeOf(s,o),F(t,e,n,r),s}function ue(t,e){const r=t.typeof(e);return r==="undefined"||r==="number"||r==="string"||r==="boolean"?[t.dump(e),!0]:r==="object"&&t.unwrapResult(t.evalCode("a => a === null")).consume(n=>t.dump(t.unwrapResult(t.callFunction(n,t.undefined,e))))?[null,!0]:[void 0,!1]}function ae(t,e,r,i){var p;if(!pe(t,e))return;const n=X(),[s,o]=r(n.resolve),[u,a]=r(n.reject);return d(t,"(p, res, rej) => { p.then(res, rej); }",void 0,e,s,u),o&&s.dispose(),a&&u.dispose(),(p=i(n.promise,e))!=null?p:n.promise}function pe(t,e){return e.owner?t.unwrapResult(t.evalCode("Promise")).consume(r=>e.owner?U(t,e,r):!1):!1}function A(t,e){const[r]=N(t,e);return r}function N(t,e){var a,p,l,f;const{ctx:r,marshal:i,find:n,pre:s}=e;{const[c,m]=ue(r,t);if(m)return[c,!1]}{const c=n(t);if(c)return[c,!0]}const o=c=>N(c,e);return[(f=(l=(p=te(r,t,s,[...se,...(a=e.custom)!=null?a:[]]))!=null?p:ae(r,t,i,s))!=null?l:ie(r,t,i,o,s))!=null?f:oe(r,t,o,s),!1]}class S{constructor(e){this._map1=new Map,this._map2=new Map,this._map3=new Map,this._map4=new Map,this._counterMap=new Map,this._disposables=new Set,this._counter=0,this.ctx=e;const r=e.unwrapResult(e.evalCode(`() => {
|
|
2
14
|
const mapSym = new Map();
|
|
3
15
|
let map = new WeakMap();
|
|
4
16
|
let map2 = new WeakMap();
|
|
@@ -21,19 +33,7 @@
|
|
|
21
33
|
map2 = new WeakMap();
|
|
22
34
|
}
|
|
23
35
|
};
|
|
24
|
-
}`)).consume(i=>this._call(i,void 0));this._mapGet=e.getProp(r,"get"),this._mapSet=e.getProp(r,"set"),this._mapDelete=e.getProp(r,"delete"),this._mapClear=e.getProp(r,"clear"),r.dispose(),this._disposables.add(this._mapGet),this._disposables.add(this._mapSet),this._disposables.add(this._mapDelete),this._disposables.add(this._mapClear)}set(e,r,i,n){var u;if(!r.alive||n&&!n.alive)return!1;const s=(u=this.get(e))!=null?u:this.get(i);if(s)return s===r||s===n;const o=this._counter++;return this._map1.set(e,o),this._map3.set(o,r),this._counterMap.set(o,e),i&&(this._map2.set(i,o),n&&this._map4.set(o,n)),this.
|
|
25
|
-
const fn = function(...args) { return Cls.apply(this, args); };
|
|
26
|
-
fn.name = Cls.name;
|
|
27
|
-
fn.length = Cls.length;
|
|
28
|
-
return fn;
|
|
29
|
-
}`,void 0,p)),u=(a=n(e,o))!=null?a:o;return F(t,e,o,r),u}function V(t,e,r,i){var a;if(typeof e!="object"||e===null)return;const n=Array.isArray(e)?t.newArray():t.newObject(),s=(a=i(e,n))!=null?a:n,o=Object.getPrototypeOf(e),u=o&&o!==Object.prototype&&o!==Array.prototype?r(o):void 0;return u&&y(t,"Object.setPrototypeOf",void 0,s,u).dispose(),F(t,e,n,r),s}function $(t,e){switch(typeof e){case"undefined":return t.undefined;case"number":return t.newNumber(e);case"string":return t.newString(e);case"boolean":return e?t.true:t.false;case"object":return e===null?t.null:void 0}}function L(t,e,r){var n;if(typeof e!="symbol")return;const i=y(t,"d => Symbol(d)",void 0,e.description?t.newString(e.description):t.undefined);return(n=r(e,i))!=null?n:i}function X(t,e,r){var s;const i=k(t,e);return(s=r(e,i))!=null?s:i}function Y(t,e,r,i){var s;if(!(e instanceof Promise))return;const n=t.newPromise();return e.then(o=>n.resolve(r(o)),o=>n.reject(r(o))),(s=i(e,n))!=null?s:n.handle}function S(t,e){var f,c,d,_;const{vm:r,unmarshal:i,isMarshalable:n,find:s,pre:o}=e;{const l=$(r,t);if(l)return l}{const l=s(t);if(l)return l}const u=n==null?void 0:n(t);if(u===!1)return r.undefined;const a=(l,b)=>o(l,b,u);if(u==="json")return X(r,t,a);const p=l=>S(l,e);return(_=(d=(c=(f=L(r,t,a))!=null?f:Y(r,t,p,a))!=null?c:Q(r,t,p,i,a,e.preApply))!=null?d:V(r,t,p,a))!=null?_:r.undefined}function A(t,e,r,i){t.newFunction("",(n,s)=>{const[o]=i(n);if(typeof o!="string"&&typeof o!="number"&&typeof o!="symbol")return;const u=[["value",!0],["get",!0],["set",!0],["configurable",!1],["enumerable",!1],["writable",!1]].reduce((a,[p,f])=>{const c=t.getProp(s,p),d=t.typeof(c);if(d==="undefined")return a;if(!f&&d==="boolean")return a[p]=t.dump(t.getProp(s,p)),a;const[_,l]=i(c);return l&&c.dispose(),a[p]=_,a},{});Object.defineProperty(r,o,u)}).consume(n=>{y(t,`(o, fn) => {
|
|
30
|
-
const descs = Object.getOwnPropertyDescriptors(o);
|
|
31
|
-
Object.entries(descs).forEach(([k, v]) => fn(k, v));
|
|
32
|
-
Object.getOwnPropertySymbols(descs).forEach(k => fn(k, descs[k]));
|
|
33
|
-
}`,void 0,e,n).dispose()})}function Z(t,e,r,i,n){var u;if(t.typeof(e)!=="function")return;const s=function(...a){return O([r(this),...a.map(p=>r(p))],(p,...f)=>{if(new.target){const[l]=i(y(t,"(Cls, ...args) => new Cls(...args)",p,e,...f));return Object.defineProperties(this,Object.getOwnPropertyDescriptors(l)),this}const c=t.unwrapResult(t.callFunction(e,p,...f)),[d,_]=i(c);return _&&c.dispose(),d})},o=(u=n(s,e))!=null?u:s;return A(t,e,s,i),o}function x(t,e,r,i){var u;if(t.typeof(e)!=="object"||t.unwrapResult(t.evalCode("o => o === null")).consume(a=>t.dump(t.unwrapResult(t.callFunction(a,t.undefined,e)))))return;const n=y(t,"Array.isArray",void 0,e).consume(a=>t.dump(a))?[]:{},s=(u=i(n,e))!=null?u:n,o=y(t,`o => {
|
|
34
|
-
const p = Object.getPrototypeOf(o);
|
|
35
|
-
return !p || p === Object.prototype || p === Array.prototype ? undefined : p;
|
|
36
|
-
}`,void 0,e).consume(a=>{if(t.typeof(a)==="undefined")return;const[p]=r(a);return p});return typeof o=="object"&&Object.setPrototypeOf(s,o),A(t,e,n,r),s}function K(t,e){const r=t.typeof(e);return r==="undefined"||r==="number"||r==="string"||r==="boolean"?[t.dump(e),!0]:r==="object"&&t.unwrapResult(t.evalCode("a => a === null")).consume(n=>t.dump(t.unwrapResult(t.callFunction(n,t.undefined,e))))?[null,!0]:[void 0,!1]}function ee(t,e,r,i){var p;if(!te(e))return;const n=U(),[s,o]=r(n.resolve),[u,a]=r(n.reject);return y(t,"(p, res, rej) => { p.then(res, rej); }",void 0,e,s,u),o&&s.dispose(),a&&u.dispose(),(p=i(n.promise,e))!=null?p:n.promise}function te(t){return t.owner?t.owner.unwrapResult(t.owner.evalCode("Promise")).consume(e=>t.owner?W(t.owner,t,e):!1):!1}function re(t,e,r){var s;if(t.typeof(e)!=="symbol")return;const i=t.getString(t.getProp(e,"description")),n=Symbol(i);return(s=r(n,e))!=null?s:n}function C(t,e){const[r]=D(t,e);return r}function D(t,e){var a,p,f;const{vm:r,marshal:i,find:n,pre:s}=e;{const[c,d]=K(r,t);if(d)return[c,!1]}{const c=n(t);if(c)return[c,!0]}const o=c=>D(c,e);return[(f=(p=(a=re(r,t,s))!=null?a:ee(r,t,i,s))!=null?p:Z(r,t,i,o,s))!=null?f:x(r,t,o,s),!1]}function ne(t,e,r,i,n,s){if(!m(e))return;if(ie(e,r))return e;const o=new Proxy(e,{get(u,a){return a===r?u:Reflect.get(u,a)},set(u,a,p,f){var _;const c=j(p,r),d=(_=s==null?void 0:s(f))!=null?_:"host";return d!=="vm"&&!Reflect.set(u,a,c,f)||d==="host"||!t.alive||O([n(f),n(a),n(c)],(l,b,g)=>{const[T,ue]=P(t,l,i);ue?T.consume(ae=>t.setProp(ae,b,g)):t.setProp(T,b,g)}),!0},deleteProperty(u,a){var f;const p=(f=s==null?void 0:s(o))!=null?f:"host";return O([n(o),n(a)],(c,d)=>{const[_,l]=P(t,c,i);if(p==="vm"||Reflect.deleteProperty(u,a)){if(p==="host"||!t.alive)return!0;l?_.consume(b=>y(t,"(a, b) => delete a[b]",void 0,b,d)):y(t,"(a, b) => delete a[b]",void 0,_,d)}return!0})}});return o}function se(t,e,r,i,n,s){return M(t,e)?B(t,e,i)?[e,!1]:H([t.newFunction("getSyncMode",o=>{const u=s==null?void 0:s(n(o));return typeof u=="string"?t.newString(u):t.undefined}),t.newFunction("setter",(o,u,a)=>{const p=n(o);if(!p)return;const f=n(u);if(f==="__proto__")return;const c=n(a);j(p,r)[f]=c}),t.newFunction("deleter",(o,u)=>{const a=n(o);if(!a)return;const p=n(u);delete j(a,r)[p]})],o=>[y(t,`(target, sym, getSyncMode, setter, deleter) => {
|
|
36
|
+
}`)).consume(i=>this._call(i,void 0));this._mapGet=e.getProp(r,"get"),this._mapSet=e.getProp(r,"set"),this._mapDelete=e.getProp(r,"delete"),this._mapClear=e.getProp(r,"clear"),r.dispose(),this._disposables.add(this._mapGet),this._disposables.add(this._mapSet),this._disposables.add(this._mapDelete),this._disposables.add(this._mapClear)}set(e,r,i,n){var u;if(!r.alive||n&&!n.alive)return!1;const s=(u=this.get(e))!=null?u:this.get(i);if(s)return s===r||s===n;const o=this._counter++;return this._map1.set(e,o),this._map3.set(o,r),this._counterMap.set(o,e),i&&(this._map2.set(i,o),n&&this._map4.set(o,n)),this.ctx.newNumber(o).consume(a=>{this._call(this._mapSet,void 0,r,a,n!=null?n:this.ctx.undefined)}),!0}merge(e){if(!!e)for(const r of e)!r||r[1]&&this.set(r[0],r[1],r[2],r[3])}get(e){var n;const r=(n=this._map1.get(e))!=null?n:this._map2.get(e),i=typeof r=="number"?this._map3.get(r):void 0;if(!!i){if(!i.alive){this.delete(e);return}return i}}getByHandle(e){if(!!e.alive)return this._counterMap.get(this.ctx.getNumber(this._call(this._mapGet,void 0,e)))}has(e){return!!this.get(e)}hasHandle(e){return typeof this.getByHandle(e)!="undefined"}keys(){return this._map1.keys()}delete(e,r){var o;const i=(o=this._map1.get(e))!=null?o:this._map2.get(e);if(typeof i=="undefined")return;const n=this._map3.get(i),s=this._map4.get(i);this._call(this._mapDelete,void 0,...[n,s].filter(u=>!!(u!=null&&u.alive))),this._map1.delete(e),this._map2.delete(e),this._map3.delete(i),this._map4.delete(i);for(const[u,a]of this._map1)if(a===i){this._map1.delete(u);break}for(const[u,a]of this._map2)if(a===i){this._map2.delete(u);break}for(const[u,a]of this._counterMap)if(a===e){this._counterMap.delete(u);break}r&&(n!=null&&n.alive&&n.dispose(),s!=null&&s.alive&&s.dispose())}deleteByHandle(e,r){const i=this.getByHandle(e);typeof i!="undefined"&&this.delete(i,r)}clear(){this._counter=0,this._map1.clear(),this._map2.clear(),this._map3.clear(),this._map4.clear(),this._counterMap.clear(),this._mapClear.alive&&this._call(this._mapClear,void 0)}dispose(){for(const e of this._disposables.values())e.alive&&e.dispose();for(const e of this._map3.values())e.alive&&e.dispose();for(const e of this._map4.values())e.alive&&e.dispose();this._disposables.clear(),this.clear()}get size(){return this._map1.size}[Symbol.iterator](){const e=this._map1.keys();return{next:()=>{for(;;){const r=e.next();if(r.done)return{value:void 0,done:!0};const i=this._map1.get(r.value);if(typeof i=="undefined")continue;const n=this._map3.get(i),s=this._map4.get(i);if(!n)continue;const o=this._get2(i);return{value:[r.value,n,o,s],done:!1}}}}}_get2(e){for(const[r,i]of this._map2)if(i===e)return r}_call(e,r,...i){return this.ctx.unwrapResult(this.ctx.callFunction(e,typeof r=="undefined"?this.ctx.undefined:r,...i))}}function fe(t,e,r,i,n,s,o){if(!v(e)||e instanceof Promise||e instanceof Date||o&&!o(e))return;if(ce(e,r))return e;const u=new Proxy(e,{get(a,p){return p===r?a:Reflect.get(a,p)},set(a,p,l,f){var y;const c=g(l,r),m=(y=s==null?void 0:s(f))!=null?y:"host";return m!=="vm"&&!Reflect.set(a,p,c,f)||m==="host"||!t.alive||j([n(f),n(p),n(c)],(_,b,T)=>{const[J,he]=E(t,_,i);he?J.consume(me=>t.setProp(me,b,T)):t.setProp(J,b,T)}),!0},deleteProperty(a,p){var f;const l=(f=s==null?void 0:s(u))!=null?f:"host";return j([n(u),n(p)],(c,m)=>{const[y,_]=E(t,c,i);if(l==="vm"||Reflect.deleteProperty(a,p)){if(l==="host"||!t.alive)return!0;_?y.consume(b=>d(t,"(a, b) => delete a[b]",void 0,b,m)):d(t,"(a, b) => delete a[b]",void 0,y,m)}return!0})}});return u}function le(t,e,r,i,n,s,o){return!R(t,e)||o&&!o(e,t)?[void 0,!1]:B(t,e,i)?[e,!1]:H([t.newFunction("getSyncMode",u=>{const a=s==null?void 0:s(n(u));return typeof a=="string"?t.newString(a):t.undefined}),t.newFunction("setter",(u,a,p)=>{const l=n(u);if(!l)return;const f=n(a);if(f==="__proto__")return;const c=n(p);g(l,r)[f]=c}),t.newFunction("deleter",(u,a)=>{const p=n(u);if(!p)return;const l=n(a);delete g(p,r)[l]})],u=>[d(t,`(target, sym, getSyncMode, setter, deleter) => {
|
|
37
37
|
const rec = new Proxy(target, {
|
|
38
38
|
get(obj, key, receiver) {
|
|
39
39
|
return key === sym ? obj : Reflect.get(obj, key, receiver)
|
|
@@ -61,4 +61,4 @@
|
|
|
61
61
|
},
|
|
62
62
|
});
|
|
63
63
|
return rec;
|
|
64
|
-
}`,void 0,e,i,...
|
|
64
|
+
}`,void 0,e,i,...u),!0])}function g(t,e){var r;return v(t)&&(r=t[e])!=null?r:t}function E(t,e,r){return B(t,e,r)?[t.getProp(e,r),!0]:[e,!1]}function ce(t,e){return v(t)&&!!t[e]}function B(t,e,r){return!!t.dump(d(t,'(a, s) => (a instanceof Promise) || (a instanceof Date) || (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]',void 0,e,r))}class de{constructor(e,r){var i;this._registeredMapDispose=new Set,this._sync=new Set,this._temporalSync=new Set,this._symbol=Symbol(),this._isMarshalable=n=>{var o,u;const s=(o=this._options)==null?void 0:o.isMarshalable;return(u=typeof s=="function"?s(this._unwrap(n)):s)!=null?u:"json"},this._marshalFind=n=>{var u,a,p;const s=this._unwrap(n);return(p=(a=(u=this._registeredMap.get(n))!=null?u:s!==n?this._registeredMap.get(s):void 0)!=null?a:this._map.get(n))!=null?p:s!==n?this._map.get(s):void 0},this._marshalPre=(n,s,o)=>{var u;if(o!=="json")return(u=this._register(n,$(s),this._map))==null?void 0:u[1]},this._marshalPreApply=(n,s,o)=>{const u=v(s)?this._unwrap(s):void 0;u&&this._temporalSync.add(u);try{return n.apply(s,o)}finally{u&&this._temporalSync.delete(u)}},this._marshal=n=>{var u,a;const s=this._registeredMap.get(n);if(s)return[s,!1];const o=O((u=this._wrap(n))!=null?u:n,{ctx:this.context,unmarshal:this._unmarshal,isMarshalable:this._isMarshalable,find:this._marshalFind,pre:this._marshalPre,preApply:this._marshalPreApply,custom:(a=this._options)==null?void 0:a.customMarshaller});return[o,!this._map.hasHandle(o)]},this._preUnmarshal=(n,s)=>{var o;return(o=this._register(n,s,void 0,!0))==null?void 0:o[0]},this._unmarshalFind=n=>{var s;return(s=this._registeredMap.getByHandle(n))!=null?s:this._map.getByHandle(n)},this._unmarshal=n=>{var u;const s=this._registeredMap.getByHandle(n);if(typeof s!="undefined")return s;const[o]=this._wrapHandle(n);return A(o!=null?o:n,{ctx:this.context,marshal:this._marshal,find:this._unmarshalFind,pre:this._preUnmarshal,custom:(u=this._options)==null?void 0:u.customUnmarshaller})},this._syncMode=n=>{const s=this._unwrap(n);return this._sync.has(s)||this._temporalSync.has(s)?"both":void 0},this._unwrapIfNotSynced=n=>{const s=this._unwrap(n);return s instanceof Promise||!this._sync.has(s)?s:n},(r==null?void 0:r.compat)&&!("runtime"in e)&&(e.runtime={hasPendingJob:()=>e.hasPendingJob(),executePendingJobs:n=>e.executePendingJobs(n)}),this.context=e,this._options=r,this._symbolHandle=e.unwrapResult(e.evalCode("Symbol()")),this._map=new S(e),this._registeredMap=new S(e),this.registerAll((i=r==null?void 0:r.registeredObjects)!=null?i:w)}dispose(){this._map.dispose(),this._registeredMap.dispose(),this._symbolHandle.dispose()}evalCode(e){const r=this.context.evalCode(e);return this._unwrapResultAndUnmarshal(r)}executePendingJobs(e){const r=this.context.runtime.executePendingJobs(e);if("value"in r)return r.value;throw this._unwrapIfNotSynced(r.error.consume(this._unmarshal))}expose(e){for(const[r,i]of Object.entries(e))W(this._marshal(i),n=>{this.context.setProp(this.context.global,r,n)})}sync(e){const r=this._wrap(e);return typeof r=="undefined"?e:(P(r,i=>{const n=this._unwrap(i);this._sync.add(n)}),r)}register(e,r){if(this._registeredMap.has(e))return;const i=typeof r=="string"?this._unwrapResult(this.context.evalCode(r)):r;M(this.context,i,this.context.undefined)||(typeof r=="string"&&this._registeredMapDispose.add(e),this._registeredMap.set(e,i))}registerAll(e){for(const[r,i]of e)this.register(r,i)}unregister(e,r){this._registeredMap.delete(e,this._registeredMapDispose.has(e)||r),this._registeredMapDispose.delete(e)}unregisterAll(e,r){for(const i of e)this.unregister(i,r)}startSync(e){if(!v(e))return;const r=this._unwrap(e);this._sync.add(r)}endSync(e){this._sync.delete(this._unwrap(e))}_unwrapResult(e){if("value"in e)return e.value;throw this._unwrapIfNotSynced(e.error.consume(this._unmarshal))}_unwrapResultAndUnmarshal(e){if(!!e)return this._unwrapIfNotSynced(this._unwrapResult(e).consume(this._unmarshal))}_register(e,r,i=this._map,n){if(this._registeredMap.has(e)||this._registeredMap.hasHandle(r))return;let s=this._wrap(e);const[o]=this._wrapHandle(r),u=e instanceof Promise;if(!o||!s&&!u)return;u&&(s=e);const a=this._unwrap(e),[p,l]=this._unwrapHandle(r);if(i.set(s,o,a,p))n&&this._sync.add(a);else throw l&&p.dispose(),new Error("already registered");return[s,o]}_wrap(e){var r;return fe(this.context,e,this._symbol,this._symbolHandle,this._marshal,this._syncMode,(r=this._options)==null?void 0:r.isWrappable)}_unwrap(e){return g(e,this._symbol)}_wrapHandle(e){var r;return le(this.context,e,this._symbol,this._symbolHandle,this._unmarshal,this._syncMode,(r=this._options)==null?void 0:r.isHandleWrappable)}_unwrapHandle(e){return E(this.context,e,this._symbolHandle)}}h.Arena=de,h.VMMap=S,h.call=d,h.complexity=L,h.consumeAll=H,h.defaultRegisteredObjects=w,h.eq=M,h.isES2015Class=C,h.isHandleObject=R,h.isObject=v,h.json=k,h.marshal=O,h.unmarshal=A,h.walkObject=P,Object.defineProperties(h,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quickjs-emscripten-sync",
|
|
3
3
|
"author": "rot1024",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./dist/quickjs-emscripten-sync.umd.js",
|
|
8
|
-
"module": "./dist/quickjs-emscripten-sync.
|
|
8
|
+
"module": "./dist/quickjs-emscripten-sync.mjs",
|
|
9
9
|
"unpkg": "./dist/quickjs-emscripten-sync.umd.js",
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"sideEffects": false,
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"import": "./dist/quickjs-emscripten-sync.
|
|
14
|
+
"import": "./dist/quickjs-emscripten-sync.mjs",
|
|
15
15
|
"require": "./dist/quickjs-emscripten-sync.umd.js"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"src"
|
|
21
21
|
],
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=
|
|
23
|
+
"node": ">=12"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "tsc && vite build",
|
|
@@ -30,24 +30,15 @@
|
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"quickjs-emscripten": "*"
|
|
32
32
|
},
|
|
33
|
-
"prettier": {
|
|
34
|
-
"printWidth": 80,
|
|
35
|
-
"semi": true,
|
|
36
|
-
"singleQuote": false,
|
|
37
|
-
"trailingComma": "es5"
|
|
38
|
-
},
|
|
39
33
|
"devDependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"eslint": "^8.19.0",
|
|
44
|
-
"eslint-config-prettier": "^8.5.0",
|
|
45
|
-
"eslint-plugin-prettier": "^4.2.1",
|
|
34
|
+
"@vitest/coverage-c8": "^0.22.1",
|
|
35
|
+
"eslint": "^8.22.0",
|
|
36
|
+
"eslint-config-reearth": "^0.1.0",
|
|
46
37
|
"prettier": "^2.7.1",
|
|
47
|
-
"quickjs-emscripten": "^0.
|
|
48
|
-
"typescript": "^4.
|
|
49
|
-
"vite": "^
|
|
50
|
-
"vite-plugin-dts": "^1.
|
|
51
|
-
"vitest": "^0.
|
|
38
|
+
"quickjs-emscripten": "^0.21.0",
|
|
39
|
+
"typescript": "^4.8.2",
|
|
40
|
+
"vite": "^3.0.9",
|
|
41
|
+
"vite-plugin-dts": "^1.4.1",
|
|
42
|
+
"vitest": "^0.22.1"
|
|
52
43
|
}
|
|
53
44
|
}
|
package/src/default.ts
CHANGED
|
@@ -32,6 +32,6 @@ export const defaultRegisteredObjects: [any, string][] = [
|
|
|
32
32
|
[URIError.prototype, "URIError.prototype"],
|
|
33
33
|
// built-in symbols
|
|
34
34
|
...Object.getOwnPropertyNames(Symbol)
|
|
35
|
-
.filter(
|
|
36
|
-
.map<[any, string]>(
|
|
35
|
+
.filter(k => typeof (Symbol as any)[k] === "symbol")
|
|
36
|
+
.map<[any, string]>(k => [(Symbol as any)[k], `Symbol.${k}`]),
|
|
37
37
|
];
|
package/src/index.test.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getQuickJS } from "quickjs-emscripten";
|
|
2
2
|
import { describe, expect, test, vi } from "vitest";
|
|
3
3
|
|
|
4
|
+
import { isWrapped } from "./wrapper";
|
|
5
|
+
|
|
4
6
|
import { Arena } from ".";
|
|
5
7
|
|
|
6
8
|
describe("readme", () => {
|
|
@@ -13,8 +15,8 @@ describe("readme", () => {
|
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
const
|
|
17
|
-
const arena = new Arena(
|
|
18
|
+
const ctx = (await getQuickJS()).newContext();
|
|
19
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
18
20
|
|
|
19
21
|
// We can pass objects to the VM and run code safely
|
|
20
22
|
const exposed = {
|
|
@@ -34,17 +36,17 @@ describe("readme", () => {
|
|
|
34
36
|
expect(arena.evalCode(`syncedCls.field`)).toBe(1);
|
|
35
37
|
|
|
36
38
|
arena.dispose();
|
|
37
|
-
|
|
39
|
+
ctx.dispose();
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
test("usage", async () => {
|
|
41
43
|
const quickjs = await getQuickJS();
|
|
42
|
-
const
|
|
44
|
+
const ctx = quickjs.newContext();
|
|
43
45
|
|
|
44
46
|
// init Arena
|
|
45
47
|
// ⚠️ Marshaling is opt-in for security reasons.
|
|
46
48
|
// ⚠️ Be careful when activating marshalling.
|
|
47
|
-
const arena = new Arena(
|
|
49
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
48
50
|
|
|
49
51
|
// expose objects as global objects in QuickJS VM
|
|
50
52
|
const log = vi.fn();
|
|
@@ -67,14 +69,14 @@ describe("readme", () => {
|
|
|
67
69
|
|
|
68
70
|
// Don't forget calling arena.dispose() before disposing QuickJS VM!
|
|
69
71
|
arena.dispose();
|
|
70
|
-
|
|
72
|
+
ctx.dispose();
|
|
71
73
|
});
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
describe("evalCode", () => {
|
|
75
77
|
test("simple object and function", async () => {
|
|
76
|
-
const
|
|
77
|
-
const arena = new Arena(
|
|
78
|
+
const ctx = (await getQuickJS()).newContext();
|
|
79
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
78
80
|
|
|
79
81
|
const result = arena.evalCode(
|
|
80
82
|
`({
|
|
@@ -88,7 +90,7 @@ describe("evalCode", () => {
|
|
|
88
90
|
get e() {
|
|
89
91
|
return { a: 1 };
|
|
90
92
|
}
|
|
91
|
-
})
|
|
93
|
+
})`,
|
|
92
94
|
);
|
|
93
95
|
expect(result).toEqual({
|
|
94
96
|
a: 1,
|
|
@@ -106,23 +108,36 @@ describe("evalCode", () => {
|
|
|
106
108
|
expect(result.e).toStrictEqual({ a: 1 });
|
|
107
109
|
|
|
108
110
|
arena.dispose();
|
|
109
|
-
|
|
111
|
+
ctx.dispose();
|
|
110
112
|
});
|
|
111
113
|
|
|
112
114
|
test("Math", async () => {
|
|
113
|
-
const
|
|
114
|
-
const arena = new Arena(
|
|
115
|
+
const ctx = (await getQuickJS()).newContext();
|
|
116
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
115
117
|
|
|
116
118
|
const VMMath = arena.evalCode(`Math`) as Math;
|
|
117
119
|
expect(VMMath.floor(1.1)).toBe(1);
|
|
118
120
|
|
|
119
121
|
arena.dispose();
|
|
120
|
-
|
|
122
|
+
ctx.dispose();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("Date", async () => {
|
|
126
|
+
const ctx = (await getQuickJS()).newContext();
|
|
127
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
128
|
+
|
|
129
|
+
const date = new Date(2022, 7, 26);
|
|
130
|
+
expect(arena.evalCode("new Date(2022, 7, 26)")).toEqual(date);
|
|
131
|
+
expect(arena.evalCode("d => d instanceof Date")(date)).toBe(true);
|
|
132
|
+
expect(arena.evalCode("d => d.getTime()")(date)).toBe(date.getTime());
|
|
133
|
+
|
|
134
|
+
arena.dispose();
|
|
135
|
+
ctx.dispose();
|
|
121
136
|
});
|
|
122
137
|
|
|
123
138
|
test("class", async () => {
|
|
124
|
-
const
|
|
125
|
-
const arena = new Arena(
|
|
139
|
+
const ctx = (await getQuickJS()).newContext();
|
|
140
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
126
141
|
|
|
127
142
|
const instance = arena.evalCode(`{
|
|
128
143
|
globalThis.Cls = class D {
|
|
@@ -143,12 +158,12 @@ describe("evalCode", () => {
|
|
|
143
158
|
expect(instance.a).toBe(102);
|
|
144
159
|
|
|
145
160
|
arena.dispose();
|
|
146
|
-
|
|
161
|
+
ctx.dispose();
|
|
147
162
|
});
|
|
148
163
|
|
|
149
164
|
test("obj", async () => {
|
|
150
|
-
const
|
|
151
|
-
const arena = new Arena(
|
|
165
|
+
const ctx = (await getQuickJS()).newContext();
|
|
166
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
152
167
|
|
|
153
168
|
const obj = arena.evalCode(`globalThis.AAA = { a: 1 }`);
|
|
154
169
|
|
|
@@ -159,14 +174,56 @@ describe("evalCode", () => {
|
|
|
159
174
|
expect(arena.evalCode(`AAA.a`)).toBe(2);
|
|
160
175
|
|
|
161
176
|
arena.dispose();
|
|
162
|
-
|
|
177
|
+
ctx.dispose();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("promise", async () => {
|
|
181
|
+
const ctx = (await getQuickJS()).newContext();
|
|
182
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
183
|
+
|
|
184
|
+
const [promise, resolve] = arena.evalCode<[Promise<string>, (d: string) => void]>(`
|
|
185
|
+
let resolve;
|
|
186
|
+
const promise = new Promise(r => {
|
|
187
|
+
resolve = r;
|
|
188
|
+
}).then(d => d + "!");
|
|
189
|
+
[promise, resolve]
|
|
190
|
+
`);
|
|
191
|
+
expect(promise).instanceOf(Promise);
|
|
192
|
+
expect(isWrapped(arena._unwrapIfNotSynced(promise), arena._symbol)).toBe(false);
|
|
193
|
+
|
|
194
|
+
resolve("hoge");
|
|
195
|
+
expect(arena.executePendingJobs()).toBe(2);
|
|
196
|
+
expect(await promise).toBe("hoge!");
|
|
197
|
+
|
|
198
|
+
arena.dispose();
|
|
199
|
+
ctx.dispose();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("promise2", async () => {
|
|
203
|
+
const ctx = (await getQuickJS()).newContext();
|
|
204
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
205
|
+
|
|
206
|
+
const deferred: { resolve?: (s: string) => void } = {};
|
|
207
|
+
const promise = new Promise(resolve => {
|
|
208
|
+
deferred.resolve = resolve;
|
|
209
|
+
});
|
|
210
|
+
const res = vi.fn();
|
|
211
|
+
arena.evalCode(`(p, r) => { p.then(d => { r(d + "!"); }); }`)(promise, res);
|
|
212
|
+
|
|
213
|
+
deferred.resolve?.("hoge");
|
|
214
|
+
await promise;
|
|
215
|
+
expect(arena.executePendingJobs()).toBe(1);
|
|
216
|
+
expect(res).toBeCalledWith("hoge!");
|
|
217
|
+
|
|
218
|
+
arena.dispose();
|
|
219
|
+
ctx.dispose();
|
|
163
220
|
});
|
|
164
221
|
});
|
|
165
222
|
|
|
166
223
|
describe("expose without sync", () => {
|
|
167
224
|
test("simple object and function", async () => {
|
|
168
|
-
const
|
|
169
|
-
const arena = new Arena(
|
|
225
|
+
const ctx = (await getQuickJS()).newContext();
|
|
226
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
170
227
|
|
|
171
228
|
const obj = {
|
|
172
229
|
a: 1,
|
|
@@ -197,12 +254,12 @@ describe("expose without sync", () => {
|
|
|
197
254
|
expect(arena.evalCode(`obj.e`)).toStrictEqual({ a: 1 });
|
|
198
255
|
|
|
199
256
|
arena.dispose();
|
|
200
|
-
|
|
257
|
+
ctx.dispose();
|
|
201
258
|
});
|
|
202
259
|
|
|
203
260
|
test("Math", async () => {
|
|
204
|
-
const
|
|
205
|
-
const arena = new Arena(
|
|
261
|
+
const ctx = (await getQuickJS()).newContext();
|
|
262
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
206
263
|
|
|
207
264
|
arena.expose({ Math2: Math });
|
|
208
265
|
expect(arena.evalCode(`Math`)).not.toBe(Math);
|
|
@@ -210,12 +267,12 @@ describe("expose without sync", () => {
|
|
|
210
267
|
expect(arena.evalCode(`Math2.floor(1.1)`)).toBe(1);
|
|
211
268
|
|
|
212
269
|
arena.dispose();
|
|
213
|
-
|
|
270
|
+
ctx.dispose();
|
|
214
271
|
});
|
|
215
272
|
|
|
216
273
|
test("class", async () => {
|
|
217
|
-
const
|
|
218
|
-
const arena = new Arena(
|
|
274
|
+
const ctx = (await getQuickJS()).newContext();
|
|
275
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
219
276
|
|
|
220
277
|
class D {
|
|
221
278
|
a: number;
|
|
@@ -239,12 +296,12 @@ describe("expose without sync", () => {
|
|
|
239
296
|
expect(arena.evalCode(`d.a`)).toBe(102);
|
|
240
297
|
|
|
241
298
|
arena.dispose();
|
|
242
|
-
|
|
299
|
+
ctx.dispose();
|
|
243
300
|
});
|
|
244
301
|
|
|
245
302
|
test("object and function", async () => {
|
|
246
|
-
const
|
|
247
|
-
const arena = new Arena(
|
|
303
|
+
const ctx = (await getQuickJS()).newContext();
|
|
304
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
248
305
|
|
|
249
306
|
const obj = {
|
|
250
307
|
a: 1,
|
|
@@ -276,14 +333,14 @@ describe("expose without sync", () => {
|
|
|
276
333
|
expect(arena.evalCode(`obj.a`)).toBe(100);
|
|
277
334
|
|
|
278
335
|
arena.dispose();
|
|
279
|
-
|
|
336
|
+
ctx.dispose();
|
|
280
337
|
});
|
|
281
338
|
});
|
|
282
339
|
|
|
283
340
|
describe("expose with sync", () => {
|
|
284
341
|
test("sync before expose", async () => {
|
|
285
|
-
const
|
|
286
|
-
const arena = new Arena(
|
|
342
|
+
const ctx = (await getQuickJS()).newContext();
|
|
343
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
287
344
|
|
|
288
345
|
const obj = {
|
|
289
346
|
a: 1,
|
|
@@ -322,12 +379,12 @@ describe("expose with sync", () => {
|
|
|
322
379
|
expect(arena.evalCode(`obj.a`)).toBe(100);
|
|
323
380
|
|
|
324
381
|
arena.dispose();
|
|
325
|
-
|
|
382
|
+
ctx.dispose();
|
|
326
383
|
});
|
|
327
384
|
|
|
328
385
|
test("sync after expose", async () => {
|
|
329
|
-
const
|
|
330
|
-
const arena = new Arena(
|
|
386
|
+
const ctx = (await getQuickJS()).newContext();
|
|
387
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
331
388
|
|
|
332
389
|
const obj = {
|
|
333
390
|
a: 1,
|
|
@@ -367,13 +424,13 @@ describe("expose with sync", () => {
|
|
|
367
424
|
expect(arena.evalCode(`obj.a`)).toBe(100);
|
|
368
425
|
|
|
369
426
|
arena.dispose();
|
|
370
|
-
|
|
427
|
+
ctx.dispose();
|
|
371
428
|
});
|
|
372
429
|
});
|
|
373
430
|
|
|
374
431
|
test("evalCode -> expose", async () => {
|
|
375
|
-
const
|
|
376
|
-
const arena = new Arena(
|
|
432
|
+
const ctx = (await getQuickJS()).newContext();
|
|
433
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
377
434
|
|
|
378
435
|
const obj = arena.evalCode(`({ a: 1, b: 1 })`);
|
|
379
436
|
arena.expose({ obj });
|
|
@@ -399,12 +456,12 @@ test("evalCode -> expose", async () => {
|
|
|
399
456
|
expect(arena.evalCode(`obj.b`)).toBe(2);
|
|
400
457
|
|
|
401
458
|
arena.dispose();
|
|
402
|
-
|
|
459
|
+
ctx.dispose();
|
|
403
460
|
});
|
|
404
461
|
|
|
405
462
|
test("expose -> evalCode", async () => {
|
|
406
|
-
const
|
|
407
|
-
const arena = new Arena(
|
|
463
|
+
const ctx = (await getQuickJS()).newContext();
|
|
464
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
408
465
|
|
|
409
466
|
const obj = { a: 1 };
|
|
410
467
|
arena.expose({ obj });
|
|
@@ -421,12 +478,12 @@ test("expose -> evalCode", async () => {
|
|
|
421
478
|
expect(arena.evalCode(`obj.a`)).toBe(3);
|
|
422
479
|
|
|
423
480
|
arena.dispose();
|
|
424
|
-
|
|
481
|
+
ctx.dispose();
|
|
425
482
|
});
|
|
426
483
|
|
|
427
484
|
test("evalCode -> expose -> evalCode", async () => {
|
|
428
|
-
const
|
|
429
|
-
const arena = new Arena(
|
|
485
|
+
const ctx = (await getQuickJS()).newContext();
|
|
486
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
430
487
|
|
|
431
488
|
const obj = [1];
|
|
432
489
|
expect(arena.evalCode("a => a[0] + 10")(obj)).toBe(11);
|
|
@@ -434,12 +491,12 @@ test("evalCode -> expose -> evalCode", async () => {
|
|
|
434
491
|
expect(arena.evalCode("obj")).toBe(obj);
|
|
435
492
|
|
|
436
493
|
arena.dispose();
|
|
437
|
-
|
|
494
|
+
ctx.dispose();
|
|
438
495
|
});
|
|
439
496
|
|
|
440
497
|
test("register and unregister", async () => {
|
|
441
|
-
const
|
|
442
|
-
const arena = new Arena(
|
|
498
|
+
const ctx = (await getQuickJS()).newContext();
|
|
499
|
+
const arena = new Arena(ctx, { isMarshalable: true, registeredObjects: [] });
|
|
443
500
|
|
|
444
501
|
arena.register(Math, `Math`);
|
|
445
502
|
expect(arena.evalCode(`Math`)).toBe(Math);
|
|
@@ -454,29 +511,27 @@ test("register and unregister", async () => {
|
|
|
454
511
|
expect(arena.evalCode(`new Error()`)).toBeInstanceOf(Error);
|
|
455
512
|
|
|
456
513
|
arena.dispose();
|
|
457
|
-
|
|
514
|
+
ctx.dispose();
|
|
458
515
|
});
|
|
459
516
|
|
|
460
517
|
test("registeredObjects option", async () => {
|
|
461
|
-
const
|
|
462
|
-
const arena = new Arena(
|
|
518
|
+
const ctx = (await getQuickJS()).newContext();
|
|
519
|
+
const arena = new Arena(ctx, {
|
|
463
520
|
isMarshalable: true,
|
|
464
521
|
registeredObjects: [[Symbol.iterator, "Symbol.iterator"]],
|
|
465
522
|
});
|
|
466
523
|
|
|
467
524
|
expect(arena.evalCode(`Symbol.iterator`)).toBe(Symbol.iterator);
|
|
468
|
-
expect(arena.evalCode(`s => s === Symbol.iterator`)(Symbol.iterator)).toBe(
|
|
469
|
-
true
|
|
470
|
-
);
|
|
525
|
+
expect(arena.evalCode(`s => s === Symbol.iterator`)(Symbol.iterator)).toBe(true);
|
|
471
526
|
|
|
472
527
|
arena.dispose();
|
|
473
|
-
|
|
528
|
+
ctx.dispose();
|
|
474
529
|
});
|
|
475
530
|
|
|
476
531
|
describe("isMarshalable option", () => {
|
|
477
532
|
test("false", async () => {
|
|
478
|
-
const
|
|
479
|
-
const arena = new Arena(
|
|
533
|
+
const ctx = (await getQuickJS()).newContext();
|
|
534
|
+
const arena = new Arena(ctx, { isMarshalable: false });
|
|
480
535
|
|
|
481
536
|
expect(arena.evalCode(`s => s === undefined`)(globalThis)).toBe(true);
|
|
482
537
|
expect(arena.evalCode(`s => s === undefined`)({})).toBe(true);
|
|
@@ -484,12 +539,12 @@ describe("isMarshalable option", () => {
|
|
|
484
539
|
expect(arena.evalCode(`aaa`)).toBeUndefined();
|
|
485
540
|
|
|
486
541
|
arena.dispose();
|
|
487
|
-
|
|
542
|
+
ctx.dispose();
|
|
488
543
|
});
|
|
489
544
|
|
|
490
545
|
test("json", async () => {
|
|
491
|
-
const
|
|
492
|
-
const arena = new Arena(
|
|
546
|
+
const ctx = (await getQuickJS()).newContext();
|
|
547
|
+
const arena = new Arena(ctx, { isMarshalable: "json" });
|
|
493
548
|
|
|
494
549
|
const obj = { a: () => {}, b: new Date(), c: [() => {}, 1] };
|
|
495
550
|
const objJSON = { b: obj.b.toISOString(), c: [null, 1] };
|
|
@@ -501,13 +556,13 @@ describe("isMarshalable option", () => {
|
|
|
501
556
|
expect(exposedObj).not.toBe(objJSON2);
|
|
502
557
|
|
|
503
558
|
arena.dispose();
|
|
504
|
-
|
|
559
|
+
ctx.dispose();
|
|
505
560
|
});
|
|
506
561
|
|
|
507
562
|
test("conditional", async () => {
|
|
508
|
-
const
|
|
509
|
-
const arena = new Arena(
|
|
510
|
-
isMarshalable:
|
|
563
|
+
const ctx = (await getQuickJS()).newContext();
|
|
564
|
+
const arena = new Arena(ctx, {
|
|
565
|
+
isMarshalable: o => o !== globalThis,
|
|
511
566
|
});
|
|
512
567
|
|
|
513
568
|
const obj = { a: 1 };
|
|
@@ -518,6 +573,45 @@ describe("isMarshalable option", () => {
|
|
|
518
573
|
expect(arena.evalCode(`bbb`)).toBe(obj);
|
|
519
574
|
|
|
520
575
|
arena.dispose();
|
|
521
|
-
|
|
576
|
+
ctx.dispose();
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
describe("edge cases", () => {
|
|
581
|
+
test("getter", async () => {
|
|
582
|
+
const ctx = (await getQuickJS()).newContext();
|
|
583
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
584
|
+
|
|
585
|
+
const called: string[] = [];
|
|
586
|
+
const obj = { c: 0 };
|
|
587
|
+
const exposed = {
|
|
588
|
+
get a() {
|
|
589
|
+
called.push("a");
|
|
590
|
+
return {
|
|
591
|
+
get b() {
|
|
592
|
+
called.push("b");
|
|
593
|
+
return obj;
|
|
594
|
+
},
|
|
595
|
+
};
|
|
596
|
+
},
|
|
597
|
+
};
|
|
598
|
+
const cb: { current?: () => any } = {};
|
|
599
|
+
const register = (fn: () => any) => {
|
|
600
|
+
cb.current = fn;
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
arena.expose({ exposed, register });
|
|
604
|
+
expect(called).toEqual([]);
|
|
605
|
+
|
|
606
|
+
arena.evalCode(`register(() => exposed.a.b.c);`);
|
|
607
|
+
expect(cb.current?.()).toBe(0);
|
|
608
|
+
expect(called).toEqual(["a", "b"]);
|
|
609
|
+
|
|
610
|
+
obj.c = 1;
|
|
611
|
+
expect(cb.current?.()).toBe(1); // this line causes an error when context is disposed
|
|
612
|
+
expect(called).toEqual(["a", "b", "a", "b"]);
|
|
613
|
+
|
|
614
|
+
arena.dispose();
|
|
615
|
+
// ctx.dispose(); // reports an error
|
|
522
616
|
});
|
|
523
617
|
});
|