quickjs-emscripten-sync 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +36 -34
  2. package/dist/index.d.ts +17 -15
  3. package/dist/quickjs-emscripten-sync.es.js +146 -135
  4. package/dist/quickjs-emscripten-sync.umd.js +6 -6
  5. package/package.json +3 -3
  6. package/src/index.test.ts +146 -60
  7. package/src/index.ts +40 -26
  8. package/src/marshal/function.test.ts +61 -53
  9. package/src/marshal/function.ts +7 -6
  10. package/src/marshal/index.test.ts +73 -65
  11. package/src/marshal/index.ts +12 -11
  12. package/src/marshal/json.test.ts +30 -30
  13. package/src/marshal/json.ts +4 -3
  14. package/src/marshal/object.test.ts +55 -50
  15. package/src/marshal/object.ts +6 -5
  16. package/src/marshal/primitive.test.ts +21 -17
  17. package/src/marshal/primitive.ts +10 -9
  18. package/src/marshal/promise.test.ts +14 -14
  19. package/src/marshal/promise.ts +3 -3
  20. package/src/marshal/properties.test.ts +17 -15
  21. package/src/marshal/properties.ts +10 -9
  22. package/src/marshal/symbol.test.ts +6 -6
  23. package/src/marshal/symbol.ts +5 -4
  24. package/src/unmarshal/function.test.ts +45 -43
  25. package/src/unmarshal/function.ts +9 -8
  26. package/src/unmarshal/index.test.ts +41 -40
  27. package/src/unmarshal/index.ts +9 -8
  28. package/src/unmarshal/object.test.ts +33 -31
  29. package/src/unmarshal/object.ts +12 -11
  30. package/src/unmarshal/primitive.test.ts +18 -15
  31. package/src/unmarshal/primitive.ts +9 -9
  32. package/src/unmarshal/promise.test.ts +11 -11
  33. package/src/unmarshal/promise.ts +9 -11
  34. package/src/unmarshal/properties.test.ts +6 -6
  35. package/src/unmarshal/properties.ts +47 -44
  36. package/src/unmarshal/symbol.test.ts +6 -6
  37. package/src/unmarshal/symbol.ts +4 -4
  38. package/src/util.test.ts +1 -0
  39. package/src/vmmap.test.ts +72 -88
  40. package/src/vmmap.ts +16 -16
  41. package/src/vmutil.test.ts +71 -73
  42. package/src/vmutil.ts +22 -18
  43. package/src/wrapper.test.ts +111 -88
  44. package/src/wrapper.ts +31 -27
@@ -1,4 +1,4 @@
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";class w{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.vm=e;const r=e.unwrapResult(e.evalCode(`() => {
1
+ (function(h,v){typeof exports=="object"&&typeof module!="undefined"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(h=typeof globalThis!="undefined"?globalThis:h||self,v(h.QuickjsEmscriptenSync={}))})(this,function(h){"use strict";class v{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
2
  const mapSym = new Map();
3
3
  let map = new WeakMap();
4
4
  let map2 = new WeakMap();
@@ -21,19 +21,19 @@
21
21
  map2 = new WeakMap();
22
22
  }
23
23
  };
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.vm.newNumber(o).consume(a=>{this._call(this._mapSet,void 0,r,a,n!=null?n:this.vm.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.vm.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.vm.unwrapResult(this.vm.callFunction(e,typeof r=="undefined"?this.vm.undefined:r,...i))}}function E(t){return typeof t=="function"&&/^class\s/.test(Function.prototype.toString.call(t))}function m(t){return typeof t=="function"||typeof t=="object"&&t!==null}function v(t,e){const r=new Set,i=n=>{if(!(!m(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 I(t,e){return v(t,e?(r,i)=>i.size<e:void 0).size}function U(){let t=()=>{},e=()=>{};return{promise:new Promise((i,n)=>{t=i,e=n}),resolve:t,reject:e}}function J(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 y(t,e,r,...i){const n=J(t,e);try{return n(r,...i)}finally{n.dispose()}}function R(t,e,r){return t.dump(y(t,"Object.is",void 0,e,r))}function W(t,e,r){return t.dump(y(t,"(a, b) => a instanceof b",void 0,e,r))}function M(t,e){return t.dump(y(t,'a => typeof a === "object" && a !== null || typeof a === "function"',void 0,e))}function k(t,e){const r=JSON.stringify(e);return r?y(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 z([t,e],r){try{return r(t)}finally{e&&t.dispose()}}function O(t,e){try{return e(...t.map(r=>r[0]))}finally{for(const[r,i]of t)i&&r.dispose()}}function G(t){return"handle"in t}function q(t){return G(t)?t.handle:t}function F(t,e,r,i){const n=t.newObject(),s=(u,a)=>{const p=i(u),f=typeof a.value=="undefined"?void 0:i(a.value),c=typeof a.get=="undefined"?void 0:i(a.get),d=typeof a.set=="undefined"?void 0:i(a.set);t.newObject().consume(_=>{Object.entries(a).forEach(([l,b])=>{const g=l==="value"?f:l==="get"?c:l==="set"?d:b?t.true:t.false;g&&t.setProp(_,l,g)}),t.setProp(n,p,_)})},o=Object.getOwnPropertyDescriptors(e);Object.entries(o).forEach(([u,a])=>s(u,a)),Object.getOwnPropertySymbols(o).forEach(u=>s(u,o[u])),y(t,"Object.defineProperties",void 0,r,n).dispose(),n.dispose()}function Q(t,e,r,i,n,s){var a;if(typeof e!="function")return;const o=t.newFunction(e.name,function(...p){const f=i(this),c=p.map(d=>i(d));if(E(e)&&m(f)){const d=new e(...c);return Object.entries(d).forEach(([_,l])=>{t.setProp(this,_,r(l))}),this}return r(s?s(e,f,c):e.apply(f,c))}).consume(p=>y(t,`Cls => {
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.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 E(t){return typeof t=="function"&&/^class\s/.test(Function.prototype.toString.call(t))}function _(t){return typeof t=="function"||typeof t=="object"&&t!==null}function j(t,e){const r=new Set,i=n=>{if(!(!_(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 T(t,e){return j(t,e?(r,i)=>i.size<e:void 0).size}function I(){let t=()=>{},e=()=>{};return{promise:new Promise((i,n)=>{t=i,e=n}),resolve:t,reject:e}}function U(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 m(t,e,r,...i){const n=U(t,e);try{return n(r,...i)}finally{n.dispose()}}function R(t,e,r){return t.dump(m(t,"Object.is",void 0,e,r))}function W(t,e,r){return t.dump(m(t,"(a, b) => a instanceof b",void 0,e,r))}function M(t,e){return t.dump(m(t,'a => typeof a === "object" && a !== null || typeof a === "function"',void 0,e))}function k(t,e){const r=JSON.stringify(e);return r?m(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 z([t,e],r){try{return r(t)}finally{e&&t.dispose()}}function P(t,e){try{return e(...t.map(r=>r[0]))}finally{for(const[r,i]of t)i&&r.dispose()}}function G(t){return"handle"in t}function q(t){return G(t)?t.handle:t}function F(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),d=typeof a.set=="undefined"?void 0:i(a.set);t.newObject().consume(y=>{Object.entries(a).forEach(([c,b])=>{const w=c==="value"?l:c==="get"?f:c==="set"?d:b?t.true:t.false;w&&t.setProp(y,c,w)}),t.setProp(n,p,y)})},o=Object.getOwnPropertyDescriptors(e);Object.entries(o).forEach(([u,a])=>s(u,a)),Object.getOwnPropertySymbols(o).forEach(u=>s(u,o[u])),m(t,"Object.defineProperties",void 0,r,n).dispose(),n.dispose()}function Q(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(d=>i(d));if(E(e)&&_(l)){const d=new e(...f);return Object.entries(d).forEach(([y,c])=>{t.setProp(this,y,r(c))}),this}return r(s?s(e,l,f):e.apply(l,f))}).consume(p=>m(t,`Cls => {
25
25
  const fn = function(...args) { return Cls.apply(this, args); };
26
26
  fn.name = Cls.name;
27
27
  fn.length = Cls.length;
28
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) => {
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&&m(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=m(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 O(t,e){var l,f,d,y;const{ctx:r,unmarshal:i,isMarshalable:n,find:s,pre:o}=e;{const c=$(r,t);if(c)return c}{const c=s(t);if(c)return c}const u=n==null?void 0:n(t);if(u===!1)return r.undefined;const a=(c,b)=>o(c,b,u);if(u==="json")return X(r,t,a);const p=c=>O(c,e);return(y=(d=(f=(l=L(r,t,a))!=null?l:Y(r,t,p,a))!=null?f:Q(r,t,p,i,a,e.preApply))!=null?d:V(r,t,p,a))!=null?y: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,l])=>{const f=t.getProp(s,p),d=t.typeof(f);if(d==="undefined")return a;if(!l&&d==="boolean")return a[p]=t.dump(t.getProp(s,p)),a;const[y,c]=i(f);return c&&f.dispose(),a[p]=y,a},{});Object.defineProperty(r,o,u)}).consume(n=>{m(t,`(o, fn) => {
30
30
  const descs = Object.getOwnPropertyDescriptors(o);
31
31
  Object.entries(descs).forEach(([k, v]) => fn(k, v));
32
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 => {
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 P([r(this),...a.map(p=>r(p))],(p,...l)=>{if(new.target){const[c]=i(m(t,"(Cls, ...args) => new Cls(...args)",p,e,...l));return Object.defineProperties(this,Object.getOwnPropertyDescriptors(c)),this}const f=t.unwrapResult(t.callFunction(e,p,...l)),[d,y]=i(f);return y&&f.dispose(),d})},o=(u=n(s,e))!=null?u:s;return A(t,e,s,i),o}function K(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=m(t,"Array.isArray",void 0,e).consume(a=>t.dump(a))?[]:{},s=(u=i(n,e))!=null?u:n,o=m(t,`o => {
34
34
  const p = Object.getPrototypeOf(o);
35
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
+ }`,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 x(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(t,e))return;const n=I(),[s,o]=r(n.resolve),[u,a]=r(n.reject);return m(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,e){return e.owner?t.unwrapResult(t.evalCode("Promise")).consume(r=>e.owner?W(t,e,r):!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,l;const{ctx:r,marshal:i,find:n,pre:s}=e;{const[f,d]=x(r,t);if(d)return[f,!1]}{const f=n(t);if(f)return[f,!0]}const o=f=>D(f,e);return[(l=(p=(a=re(r,t,s))!=null?a:ee(r,t,i,s))!=null?p:Z(r,t,i,o,s))!=null?l:K(r,t,o,s),!1]}function ne(t,e,r,i,n,s){if(!_(e)||e instanceof Promise)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,l){var y;const f=g(p,r),d=(y=s==null?void 0:s(l))!=null?y:"host";return d!=="vm"&&!Reflect.set(u,a,f,l)||d==="host"||!t.alive||P([n(l),n(a),n(f)],(c,b,w)=>{const[J,ue]=S(t,c,i);ue?J.consume(ae=>t.setProp(ae,b,w)):t.setProp(J,b,w)}),!0},deleteProperty(u,a){var l;const p=(l=s==null?void 0:s(o))!=null?l:"host";return P([n(o),n(a)],(f,d)=>{const[y,c]=S(t,f,i);if(p==="vm"||Reflect.deleteProperty(u,a)){if(p==="host"||!t.alive)return!0;c?y.consume(b=>m(t,"(a, b) => delete a[b]",void 0,b,d)):m(t,"(a, b) => delete a[b]",void 0,y,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 l=n(u);if(l==="__proto__")return;const f=n(a);g(p,r)[l]=f}),t.newFunction("deleter",(o,u)=>{const a=n(o);if(!a)return;const p=n(u);delete g(a,r)[p]})],o=>[m(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,...o),!0]):[void 0,!1]}function j(t,e){var r;return m(t)&&(r=t[e])!=null?r:t}function P(t,e,r){return B(t,e,r)?[t.getProp(e,r),!0]:[e,!1]}function ie(t,e){return m(t)&&!!t[e]}function B(t,e,r){return!!t.dump(y(t,'(a, s) => (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]',void 0,e,r))}const N=[[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}`])];class oe{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,q(s),this._map))==null?void 0:u[1]},this._marshalPreApply=(n,s,o)=>{const u=m(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;const s=this._registeredMap.get(n);if(s)return[s,!1];const o=S((u=this._wrap(n))!=null?u:n,{vm:this.vm,unmarshal:this._unmarshal,isMarshalable:this._isMarshalable,find:this._marshalFind,pre:this._marshalPre,preApply:this._marshalPreApply});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=>{const s=this._registeredMap.getByHandle(n);if(typeof s!="undefined")return s;const[o]=this._wrapHandle(n);return C(o!=null?o:n,{vm:this.vm,marshal:this._marshal,find:this._unmarshalFind,pre:this._preUnmarshal})},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 this._sync.has(s)?n:s},this.vm=e,this._options=r,this._symbolHandle=e.unwrapResult(e.evalCode("Symbol()")),this._map=new w(e),this._registeredMap=new w(e),this.registerAll((i=r==null?void 0:r.registeredObjects)!=null?i:N)}dispose(){this._map.dispose(),this._registeredMap.dispose(),this._symbolHandle.dispose()}evalCode(e){const r=this.vm.evalCode(e);return this._unwrapResultAndUnmarshal(r)}executePendingJobs(e){const r=this.vm.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))z(this._marshal(i),n=>{this.vm.setProp(this.vm.global,r,n)})}sync(e){const r=this._wrap(e);return typeof r=="undefined"?e:(v(r,i=>{this._sync.add(this._unwrap(i))}),r)}register(e,r){if(this._registeredMap.has(e))return;const i=typeof r=="string"?this._unwrapResult(this.vm.evalCode(r)):r;R(this.vm,i,this.vm.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){!m(e)||this._sync.add(this._unwrap(e))}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;const s=this._wrap(e),[o]=this._wrapHandle(r);if(!s||!o)return;const u=this._unwrap(e),[a,p]=this._unwrapHandle(r);if(i.set(s,o,u,a))n&&this._sync.add(u);else throw p&&a.dispose(),new Error("already registered");return[s,o]}_wrap(e){return ne(this.vm,e,this._symbol,this._symbolHandle,this._marshal,this._syncMode)}_unwrap(e){return j(e,this._symbol)}_wrapHandle(e){return se(this.vm,e,this._symbol,this._symbolHandle,this._unmarshal,this._syncMode)}_unwrapHandle(e){return P(this.vm,e,this._symbolHandle)}}h.Arena=oe,h.VMMap=w,h.call=y,h.complexity=I,h.consumeAll=H,h.defaultRegisteredObjects=N,h.eq=R,h.isES2015Class=E,h.isHandleObject=M,h.isObject=m,h.json=k,h.marshal=S,h.unmarshal=C,h.walkObject=v,Object.defineProperties(h,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
64
+ }`,void 0,e,i,...o),!0]):[void 0,!1]}function g(t,e){var r;return _(t)&&(r=t[e])!=null?r:t}function S(t,e,r){return B(t,e,r)?[t.getProp(e,r),!0]:[e,!1]}function ie(t,e){return _(t)&&!!t[e]}function B(t,e,r){return!!t.dump(m(t,'(a, s) => (a instanceof Promise) || (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]',void 0,e,r))}const N=[[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}`])];class oe{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,q(s),this._map))==null?void 0:u[1]},this._marshalPreApply=(n,s,o)=>{const u=_(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;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});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=>{const s=this._registeredMap.getByHandle(n);if(typeof s!="undefined")return s;const[o]=this._wrapHandle(n);return C(o!=null?o:n,{ctx:this.context,marshal:this._marshal,find:this._unmarshalFind,pre:this._preUnmarshal})},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 v(e),this._registeredMap=new v(e),this.registerAll((i=r==null?void 0:r.registeredObjects)!=null?i:N)}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))z(this._marshal(i),n=>{this.context.setProp(this.context.global,r,n)})}sync(e){const r=this._wrap(e);return typeof r=="undefined"?e:(j(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;R(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(!_(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){return ne(this.context,e,this._symbol,this._symbolHandle,this._marshal,this._syncMode)}_unwrap(e){return g(e,this._symbol)}_wrapHandle(e){return se(this.context,e,this._symbol,this._symbolHandle,this._unmarshal,this._syncMode)}_unwrapHandle(e){return S(this.context,e,this._symbolHandle)}}h.Arena=oe,h.VMMap=v,h.call=m,h.complexity=T,h.consumeAll=H,h.defaultRegisteredObjects=N,h.eq=R,h.isES2015Class=E,h.isHandleObject=M,h.isObject=_,h.json=k,h.marshal=O,h.unmarshal=C,h.walkObject=j,Object.defineProperties(h,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quickjs-emscripten-sync",
3
3
  "author": "rot1024",
4
- "version": "1.3.0",
4
+ "version": "1.4.0",
5
5
  "license": "MIT",
6
6
  "source": "./src/index.ts",
7
7
  "main": "./dist/quickjs-emscripten-sync.umd.js",
@@ -44,10 +44,10 @@
44
44
  "eslint-config-prettier": "^8.5.0",
45
45
  "eslint-plugin-prettier": "^4.2.1",
46
46
  "prettier": "^2.7.1",
47
- "quickjs-emscripten": "^0.15.0",
47
+ "quickjs-emscripten": "^0.21.0",
48
48
  "typescript": "^4.7.4",
49
49
  "vite": "^2.9.14",
50
- "vite-plugin-dts": "^1.2.1",
50
+ "vite-plugin-dts": "^1.3.0",
51
51
  "vitest": "^0.18.0"
52
52
  }
53
53
  }
package/src/index.test.ts CHANGED
@@ -2,6 +2,7 @@ import { getQuickJS } from "quickjs-emscripten";
2
2
  import { describe, expect, test, vi } from "vitest";
3
3
 
4
4
  import { Arena } from ".";
5
+ import { isWrapped } from "./wrapper";
5
6
 
6
7
  describe("readme", () => {
7
8
  test("first", async () => {
@@ -13,8 +14,8 @@ describe("readme", () => {
13
14
  }
14
15
  }
15
16
 
16
- const vm = (await getQuickJS()).createVm();
17
- const arena = new Arena(vm, { isMarshalable: true });
17
+ const ctx = (await getQuickJS()).newContext();
18
+ const arena = new Arena(ctx, { isMarshalable: true });
18
19
 
19
20
  // We can pass objects to the VM and run code safely
20
21
  const exposed = {
@@ -34,17 +35,17 @@ describe("readme", () => {
34
35
  expect(arena.evalCode(`syncedCls.field`)).toBe(1);
35
36
 
36
37
  arena.dispose();
37
- vm.dispose();
38
+ ctx.dispose();
38
39
  });
39
40
 
40
41
  test("usage", async () => {
41
42
  const quickjs = await getQuickJS();
42
- const vm = quickjs.createVm();
43
+ const ctx = quickjs.newContext();
43
44
 
44
45
  // init Arena
45
46
  // ⚠️ Marshaling is opt-in for security reasons.
46
47
  // ⚠️ Be careful when activating marshalling.
47
- const arena = new Arena(vm, { isMarshalable: true });
48
+ const arena = new Arena(ctx, { isMarshalable: true });
48
49
 
49
50
  // expose objects as global objects in QuickJS VM
50
51
  const log = vi.fn();
@@ -67,14 +68,14 @@ describe("readme", () => {
67
68
 
68
69
  // Don't forget calling arena.dispose() before disposing QuickJS VM!
69
70
  arena.dispose();
70
- vm.dispose();
71
+ ctx.dispose();
71
72
  });
72
73
  });
73
74
 
74
75
  describe("evalCode", () => {
75
76
  test("simple object and function", async () => {
76
- const vm = (await getQuickJS()).createVm();
77
- const arena = new Arena(vm, { isMarshalable: true });
77
+ const ctx = (await getQuickJS()).newContext();
78
+ const arena = new Arena(ctx, { isMarshalable: true });
78
79
 
79
80
  const result = arena.evalCode(
80
81
  `({
@@ -106,23 +107,23 @@ describe("evalCode", () => {
106
107
  expect(result.e).toStrictEqual({ a: 1 });
107
108
 
108
109
  arena.dispose();
109
- vm.dispose();
110
+ ctx.dispose();
110
111
  });
111
112
 
112
113
  test("Math", async () => {
113
- const vm = (await getQuickJS()).createVm();
114
- const arena = new Arena(vm, { isMarshalable: true });
114
+ const ctx = (await getQuickJS()).newContext();
115
+ const arena = new Arena(ctx, { isMarshalable: true });
115
116
 
116
117
  const VMMath = arena.evalCode(`Math`) as Math;
117
118
  expect(VMMath.floor(1.1)).toBe(1);
118
119
 
119
120
  arena.dispose();
120
- vm.dispose();
121
+ ctx.dispose();
121
122
  });
122
123
 
123
124
  test("class", async () => {
124
- const vm = (await getQuickJS()).createVm();
125
- const arena = new Arena(vm, { isMarshalable: true });
125
+ const ctx = (await getQuickJS()).newContext();
126
+ const arena = new Arena(ctx, { isMarshalable: true });
126
127
 
127
128
  const instance = arena.evalCode(`{
128
129
  globalThis.Cls = class D {
@@ -143,12 +144,12 @@ describe("evalCode", () => {
143
144
  expect(instance.a).toBe(102);
144
145
 
145
146
  arena.dispose();
146
- vm.dispose();
147
+ ctx.dispose();
147
148
  });
148
149
 
149
150
  test("obj", async () => {
150
- const vm = (await getQuickJS()).createVm();
151
- const arena = new Arena(vm, { isMarshalable: true });
151
+ const ctx = (await getQuickJS()).newContext();
152
+ const arena = new Arena(ctx, { isMarshalable: true });
152
153
 
153
154
  const obj = arena.evalCode(`globalThis.AAA = { a: 1 }`);
154
155
 
@@ -159,14 +160,60 @@ describe("evalCode", () => {
159
160
  expect(arena.evalCode(`AAA.a`)).toBe(2);
160
161
 
161
162
  arena.dispose();
162
- vm.dispose();
163
+ ctx.dispose();
164
+ });
165
+
166
+ test("promise", async () => {
167
+ const ctx = (await getQuickJS()).newContext();
168
+ const arena = new Arena(ctx, { isMarshalable: true });
169
+
170
+ const [promise, resolve] = arena.evalCode<
171
+ [Promise<string>, (d: string) => void]
172
+ >(`
173
+ let resolve;
174
+ const promise = new Promise(r => {
175
+ resolve = r;
176
+ }).then(d => d + "!");
177
+ [promise, resolve]
178
+ `);
179
+ expect(promise).instanceOf(Promise);
180
+ expect(isWrapped(arena._unwrapIfNotSynced(promise), arena._symbol)).toBe(
181
+ false
182
+ );
183
+
184
+ resolve("hoge");
185
+ expect(arena.executePendingJobs()).toBe(2);
186
+ expect(await promise).toBe("hoge!");
187
+
188
+ arena.dispose();
189
+ ctx.dispose();
190
+ });
191
+
192
+ test("promise2", async () => {
193
+ const ctx = (await getQuickJS()).newContext();
194
+ const arena = new Arena(ctx, { isMarshalable: true });
195
+
196
+ const deferred: { resolve?: (s: string) => void } = {};
197
+ const promise = new Promise((resolve) => {
198
+ deferred.resolve = resolve;
199
+ });
200
+ const res = vi.fn();
201
+ arena.evalCode(`(p, r) => { p.then(d => { r(d + "!"); }); }`)(promise, res);
202
+
203
+ deferred.resolve?.("hoge");
204
+ await promise;
205
+ expect(arena.executePendingJobs()).toBe(1);
206
+ expect(res).toBeCalledWith("hoge!");
207
+
208
+ arena.dispose();
209
+ ctx.dispose();
163
210
  });
164
211
  });
165
212
 
166
213
  describe("expose without sync", () => {
167
214
  test("simple object and function", async () => {
168
- const vm = (await getQuickJS()).createVm();
169
- const arena = new Arena(vm, { isMarshalable: true });
215
+ const ctx = (await getQuickJS()).newContext();
216
+ const arena = new Arena(ctx, { isMarshalable: true });
170
217
 
171
218
  const obj = {
172
219
  a: 1,
@@ -197,12 +244,12 @@ describe("expose without sync", () => {
197
244
  expect(arena.evalCode(`obj.e`)).toStrictEqual({ a: 1 });
198
245
 
199
246
  arena.dispose();
200
- vm.dispose();
247
+ ctx.dispose();
201
248
  });
202
249
 
203
250
  test("Math", async () => {
204
- const vm = (await getQuickJS()).createVm();
205
- const arena = new Arena(vm, { isMarshalable: true });
251
+ const ctx = (await getQuickJS()).newContext();
252
+ const arena = new Arena(ctx, { isMarshalable: true });
206
253
 
207
254
  arena.expose({ Math2: Math });
208
255
  expect(arena.evalCode(`Math`)).not.toBe(Math);
@@ -210,12 +257,12 @@ describe("expose without sync", () => {
210
257
  expect(arena.evalCode(`Math2.floor(1.1)`)).toBe(1);
211
258
 
212
259
  arena.dispose();
213
- vm.dispose();
260
+ ctx.dispose();
214
261
  });
215
262
 
216
263
  test("class", async () => {
217
- const vm = (await getQuickJS()).createVm();
218
- const arena = new Arena(vm, { isMarshalable: true });
264
+ const ctx = (await getQuickJS()).newContext();
265
+ const arena = new Arena(ctx, { isMarshalable: true });
219
266
 
220
267
  class D {
221
268
  a: number;
@@ -239,12 +286,12 @@ describe("expose without sync", () => {
239
286
  expect(arena.evalCode(`d.a`)).toBe(102);
240
287
 
241
288
  arena.dispose();
242
- vm.dispose();
289
+ ctx.dispose();
243
290
  });
244
291
 
245
292
  test("object and function", async () => {
246
- const vm = (await getQuickJS()).createVm();
247
- const arena = new Arena(vm, { isMarshalable: true });
293
+ const ctx = (await getQuickJS()).newContext();
294
+ const arena = new Arena(ctx, { isMarshalable: true });
248
295
 
249
296
  const obj = {
250
297
  a: 1,
@@ -276,14 +323,14 @@ describe("expose without sync", () => {
276
323
  expect(arena.evalCode(`obj.a`)).toBe(100);
277
324
 
278
325
  arena.dispose();
279
- vm.dispose();
326
+ ctx.dispose();
280
327
  });
281
328
  });
282
329
 
283
330
  describe("expose with sync", () => {
284
331
  test("sync before expose", async () => {
285
- const vm = (await getQuickJS()).createVm();
286
- const arena = new Arena(vm, { isMarshalable: true });
332
+ const ctx = (await getQuickJS()).newContext();
333
+ const arena = new Arena(ctx, { isMarshalable: true });
287
334
 
288
335
  const obj = {
289
336
  a: 1,
@@ -322,12 +369,12 @@ describe("expose with sync", () => {
322
369
  expect(arena.evalCode(`obj.a`)).toBe(100);
323
370
 
324
371
  arena.dispose();
325
- vm.dispose();
372
+ ctx.dispose();
326
373
  });
327
374
 
328
375
  test("sync after expose", async () => {
329
- const vm = (await getQuickJS()).createVm();
330
- const arena = new Arena(vm, { isMarshalable: true });
376
+ const ctx = (await getQuickJS()).newContext();
377
+ const arena = new Arena(ctx, { isMarshalable: true });
331
378
 
332
379
  const obj = {
333
380
  a: 1,
@@ -367,13 +414,13 @@ describe("expose with sync", () => {
367
414
  expect(arena.evalCode(`obj.a`)).toBe(100);
368
415
 
369
416
  arena.dispose();
370
- vm.dispose();
417
+ ctx.dispose();
371
418
  });
372
419
  });
373
420
 
374
421
  test("evalCode -> expose", async () => {
375
- const vm = (await getQuickJS()).createVm();
376
- const arena = new Arena(vm, { isMarshalable: true });
422
+ const ctx = (await getQuickJS()).newContext();
423
+ const arena = new Arena(ctx, { isMarshalable: true });
377
424
 
378
425
  const obj = arena.evalCode(`({ a: 1, b: 1 })`);
379
426
  arena.expose({ obj });
@@ -399,12 +446,12 @@ test("evalCode -> expose", async () => {
399
446
  expect(arena.evalCode(`obj.b`)).toBe(2);
400
447
 
401
448
  arena.dispose();
402
- vm.dispose();
449
+ ctx.dispose();
403
450
  });
404
451
 
405
452
  test("expose -> evalCode", async () => {
406
- const vm = (await getQuickJS()).createVm();
407
- const arena = new Arena(vm, { isMarshalable: true });
453
+ const ctx = (await getQuickJS()).newContext();
454
+ const arena = new Arena(ctx, { isMarshalable: true });
408
455
 
409
456
  const obj = { a: 1 };
410
457
  arena.expose({ obj });
@@ -421,12 +468,12 @@ test("expose -> evalCode", async () => {
421
468
  expect(arena.evalCode(`obj.a`)).toBe(3);
422
469
 
423
470
  arena.dispose();
424
- vm.dispose();
471
+ ctx.dispose();
425
472
  });
426
473
 
427
474
  test("evalCode -> expose -> evalCode", async () => {
428
- const vm = (await getQuickJS()).createVm();
429
- const arena = new Arena(vm, { isMarshalable: true });
475
+ const ctx = (await getQuickJS()).newContext();
476
+ const arena = new Arena(ctx, { isMarshalable: true });
430
477
 
431
478
  const obj = [1];
432
479
  expect(arena.evalCode("a => a[0] + 10")(obj)).toBe(11);
@@ -434,12 +481,12 @@ test("evalCode -> expose -> evalCode", async () => {
434
481
  expect(arena.evalCode("obj")).toBe(obj);
435
482
 
436
483
  arena.dispose();
437
- vm.dispose();
484
+ ctx.dispose();
438
485
  });
439
486
 
440
487
  test("register and unregister", async () => {
441
- const vm = (await getQuickJS()).createVm();
442
- const arena = new Arena(vm, { isMarshalable: true, registeredObjects: [] });
488
+ const ctx = (await getQuickJS()).newContext();
489
+ const arena = new Arena(ctx, { isMarshalable: true, registeredObjects: [] });
443
490
 
444
491
  arena.register(Math, `Math`);
445
492
  expect(arena.evalCode(`Math`)).toBe(Math);
@@ -454,12 +501,12 @@ test("register and unregister", async () => {
454
501
  expect(arena.evalCode(`new Error()`)).toBeInstanceOf(Error);
455
502
 
456
503
  arena.dispose();
457
- vm.dispose();
504
+ ctx.dispose();
458
505
  });
459
506
 
460
507
  test("registeredObjects option", async () => {
461
- const vm = (await getQuickJS()).createVm();
462
- const arena = new Arena(vm, {
508
+ const ctx = (await getQuickJS()).newContext();
509
+ const arena = new Arena(ctx, {
463
510
  isMarshalable: true,
464
511
  registeredObjects: [[Symbol.iterator, "Symbol.iterator"]],
465
512
  });
@@ -470,13 +517,13 @@ test("registeredObjects option", async () => {
470
517
  );
471
518
 
472
519
  arena.dispose();
473
- vm.dispose();
520
+ ctx.dispose();
474
521
  });
475
522
 
476
523
  describe("isMarshalable option", () => {
477
524
  test("false", async () => {
478
- const vm = (await getQuickJS()).createVm();
479
- const arena = new Arena(vm, { isMarshalable: false });
525
+ const ctx = (await getQuickJS()).newContext();
526
+ const arena = new Arena(ctx, { isMarshalable: false });
480
527
 
481
528
  expect(arena.evalCode(`s => s === undefined`)(globalThis)).toBe(true);
482
529
  expect(arena.evalCode(`s => s === undefined`)({})).toBe(true);
@@ -484,12 +531,12 @@ describe("isMarshalable option", () => {
484
531
  expect(arena.evalCode(`aaa`)).toBeUndefined();
485
532
 
486
533
  arena.dispose();
487
- vm.dispose();
534
+ ctx.dispose();
488
535
  });
489
536
 
490
537
  test("json", async () => {
491
- const vm = (await getQuickJS()).createVm();
492
- const arena = new Arena(vm, { isMarshalable: "json" });
538
+ const ctx = (await getQuickJS()).newContext();
539
+ const arena = new Arena(ctx, { isMarshalable: "json" });
493
540
 
494
541
  const obj = { a: () => {}, b: new Date(), c: [() => {}, 1] };
495
542
  const objJSON = { b: obj.b.toISOString(), c: [null, 1] };
@@ -501,12 +548,12 @@ describe("isMarshalable option", () => {
501
548
  expect(exposedObj).not.toBe(objJSON2);
502
549
 
503
550
  arena.dispose();
504
- vm.dispose();
551
+ ctx.dispose();
505
552
  });
506
553
 
507
554
  test("conditional", async () => {
508
- const vm = (await getQuickJS()).createVm();
509
- const arena = new Arena(vm, {
555
+ const ctx = (await getQuickJS()).newContext();
556
+ const arena = new Arena(ctx, {
510
557
  isMarshalable: (o) => o !== globalThis,
511
558
  });
512
559
 
@@ -518,6 +565,45 @@ describe("isMarshalable option", () => {
518
565
  expect(arena.evalCode(`bbb`)).toBe(obj);
519
566
 
520
567
  arena.dispose();
521
- vm.dispose();
568
+ ctx.dispose();
569
+ });
570
+ });
571
+
572
+ describe("edge cases", () => {
573
+ test("getter", async () => {
574
+ const ctx = (await getQuickJS()).newContext();
575
+ const arena = new Arena(ctx, { isMarshalable: true });
576
+
577
+ const called: string[] = [];
578
+ const obj = { c: 0 };
579
+ const exposed = {
580
+ get a() {
581
+ called.push("a");
582
+ return {
583
+ get b() {
584
+ called.push("b");
585
+ return obj;
586
+ },
587
+ };
588
+ },
589
+ };
590
+ const cb: { current?: () => any } = {};
591
+ const register = (fn: () => any) => {
592
+ cb.current = fn;
593
+ };
594
+
595
+ arena.expose({ exposed, register });
596
+ expect(called).toEqual([]);
597
+
598
+ arena.evalCode(`register(() => exposed.a.b.c);`);
599
+ expect(cb.current?.()).toBe(0);
600
+ expect(called).toEqual(["a", "b"]);
601
+
602
+ obj.c = 1;
603
+ expect(cb.current?.()).toBe(1); // this line causes an error when context is disposed
604
+ expect(called).toEqual(["a", "b", "a", "b"]);
605
+
606
+ arena.dispose();
607
+ // ctx.dispose(); // reports an error
522
608
  });
523
609
  });