quickjs-emscripten-sync 1.1.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 (71) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +59 -49
  3. package/dist/index.d.ts +121 -26
  4. package/dist/quickjs-emscripten-sync.es.js +962 -0
  5. package/dist/quickjs-emscripten-sync.umd.js +64 -0
  6. package/package.json +28 -40
  7. package/src/default.ts +2 -2
  8. package/src/index.test.ts +371 -69
  9. package/src/index.ts +135 -72
  10. package/src/marshal/function.test.ts +70 -61
  11. package/src/marshal/function.ts +10 -9
  12. package/src/marshal/index.test.ts +135 -62
  13. package/src/marshal/index.ts +33 -16
  14. package/src/marshal/json.test.ts +94 -0
  15. package/src/marshal/json.ts +16 -0
  16. package/src/marshal/object.test.ts +65 -58
  17. package/src/marshal/object.ts +6 -5
  18. package/src/marshal/primitive.test.ts +23 -17
  19. package/src/marshal/primitive.ts +10 -9
  20. package/src/marshal/promise.test.ts +86 -0
  21. package/src/marshal/promise.ts +26 -0
  22. package/src/marshal/properties.test.ts +23 -19
  23. package/src/marshal/properties.ts +11 -10
  24. package/src/marshal/symbol.test.ts +9 -7
  25. package/src/marshal/symbol.ts +5 -4
  26. package/src/unmarshal/function.test.ts +70 -61
  27. package/src/unmarshal/function.ts +39 -30
  28. package/src/unmarshal/index.test.ts +101 -100
  29. package/src/unmarshal/index.ts +13 -9
  30. package/src/unmarshal/object.test.ts +45 -41
  31. package/src/unmarshal/object.ts +14 -13
  32. package/src/unmarshal/primitive.test.ts +20 -15
  33. package/src/unmarshal/primitive.ts +10 -10
  34. package/src/unmarshal/promise.test.ts +44 -0
  35. package/src/unmarshal/promise.ts +38 -0
  36. package/src/unmarshal/properties.test.ts +10 -8
  37. package/src/unmarshal/properties.ts +47 -42
  38. package/src/unmarshal/symbol.test.ts +9 -7
  39. package/src/unmarshal/symbol.ts +4 -4
  40. package/src/util.test.ts +23 -5
  41. package/src/util.ts +15 -0
  42. package/src/vmmap.test.ts +88 -82
  43. package/src/vmmap.ts +21 -17
  44. package/src/vmutil.test.ts +159 -53
  45. package/src/vmutil.ts +91 -19
  46. package/src/wrapper.test.ts +151 -115
  47. package/src/wrapper.ts +69 -48
  48. package/dist/default.d.ts +0 -4
  49. package/dist/index.js +0 -8
  50. package/dist/marshal/function.d.ts +0 -2
  51. package/dist/marshal/index.d.ts +0 -11
  52. package/dist/marshal/object.d.ts +0 -2
  53. package/dist/marshal/primitive.d.ts +0 -2
  54. package/dist/marshal/properties.d.ts +0 -2
  55. package/dist/marshal/symbol.d.ts +0 -2
  56. package/dist/quickjs-emscripten-sync.cjs.development.js +0 -1289
  57. package/dist/quickjs-emscripten-sync.cjs.development.js.map +0 -1
  58. package/dist/quickjs-emscripten-sync.cjs.production.min.js +0 -2
  59. package/dist/quickjs-emscripten-sync.cjs.production.min.js.map +0 -1
  60. package/dist/quickjs-emscripten-sync.esm.js +0 -1272
  61. package/dist/quickjs-emscripten-sync.esm.js.map +0 -1
  62. package/dist/unmarshal/function.d.ts +0 -2
  63. package/dist/unmarshal/index.d.ts +0 -9
  64. package/dist/unmarshal/object.d.ts +0 -2
  65. package/dist/unmarshal/primitive.d.ts +0 -2
  66. package/dist/unmarshal/properties.d.ts +0 -2
  67. package/dist/unmarshal/symbol.d.ts +0 -2
  68. package/dist/util.d.ts +0 -7
  69. package/dist/vmmap.d.ts +0 -35
  70. package/dist/vmutil.d.ts +0 -7
  71. package/dist/wrapper.d.ts +0 -11
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 rot1024
3
+ Copyright (c) 2022 rot1024
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # quickjs-emscripten-sync
2
2
 
3
- We can build a plugin system that works safely in the web browser!
3
+ [![CI](https://github.com/reearth/quickjs-emscripten-sync/actions/workflows/ci.yml/badge.svg)](https://github.com/reearth/quickjs-emscripten-sync/actions/workflows/main.yml) [![codecov](https://codecov.io/gh/reearth/quickjs-emscripten-sync/branch/main/graph/badge.svg)](https://codecov.io/gh/reearth/quickjs-emscripten-sync)
4
+
5
+ Build a secure plugin system in web browsers
4
6
 
5
7
  This library wraps [quickjs-emscripten](https://github.com/justjake/quickjs-emscripten) and provides a way to sync object state between the browser and sandboxed QuickJS.
6
8
 
@@ -10,6 +12,7 @@ This library wraps [quickjs-emscripten](https://github.com/justjake/quickjs-emsc
10
12
  - Functions
11
13
  - Classes and instances
12
14
  - Objects with prototypes and any property descriptors
15
+ - Promises
13
16
  - Expose objects as a global object in QuickJS
14
17
  - Marshaling limitation for specific objects
15
18
  - Register a pair of objects that will be considered the same between the browser and QuickJS
@@ -20,7 +23,7 @@ npm install quickjs-emscripten quickjs-emscripten-sync
20
23
 
21
24
  ```js
22
25
  import { getQuickJS } from "quickjs-emscripten";
23
- import Arena from "quickjs-emscripten-sync";
26
+ import { Arena } from "quickjs-emscripten-sync";
24
27
 
25
28
  class Cls {
26
29
  field = 0;
@@ -30,10 +33,10 @@ class Cls {
30
33
  }
31
34
  }
32
35
 
33
- const vm = (await getQuickJS()).createVm();
34
- const arena = new Arena(vm);
36
+ const ctx = (await getQuickJS()).newContext();
37
+ const arena = new Arena(ctx, { isMarshalable: true });
35
38
 
36
- // We can pass objects to the VM and run code safely
39
+ // We can pass objects to the context and run code safely
37
40
  const exposed = {
38
41
  Cls,
39
42
  cls: new Cls(),
@@ -41,22 +44,22 @@ const exposed = {
41
44
  };
42
45
  arena.expose(exposed);
43
46
 
44
- arena.evalCode(`cls instanceof Cls`)); // returns true
45
- arena.evalCode(`cls.field`)); // returns 0
46
- arena.evalCode(`cls.method()`)); // returns 1
47
- arena.evalCode(`cls.field`)); // returns 1
47
+ arena.evalCode(`cls instanceof Cls`); // returns true
48
+ arena.evalCode(`cls.field`); // returns 0
49
+ arena.evalCode(`cls.method()`); // returns 1
50
+ arena.evalCode(`cls.field`); // returns 1
48
51
 
49
- arena.evalCode(`syncedCls.field`); // returns 0
50
- exposed.syncedCls.method(); // returns 1
51
- arena.evalCode(`syncedCls.field`); // returns 1
52
+ arena.evalCode(`syncedCls.field`); // returns 0
53
+ exposed.syncedCls.method(); // returns 1
54
+ arena.evalCode(`syncedCls.field`); // returns 1
52
55
 
53
56
  arena.dispose();
54
- vm.dispose();
57
+ ctx.dispose();
55
58
  ```
56
59
 
57
60
  [Example code](src/index.test.ts) is available as the unit test code.
58
61
 
59
- ## Operating environment
62
+ ## Operating Environment
60
63
 
61
64
  - Web browsers that support WebAssembly
62
65
  - Node.js
@@ -67,16 +70,17 @@ If you want to run quickjs-emscripten and quickjs-emscripten-sync in a web brows
67
70
 
68
71
  ```js
69
72
  import { getQuickJS } from "quickjs-emscripten";
70
- import Arena from "quickjs-emscripten-sync";
73
+ import { Arena } from "quickjs-emscripten-sync";
71
74
 
72
75
  (async function() {
73
- const quickjs = await getQuickJS();
74
- const vm = quickjs.createVm();
76
+ const ctx = (await getQuickJS()).newContext();
75
77
 
76
78
  // init Arena
77
- const arena = new Arena(vm);
79
+ // ⚠️ Marshaling is opt-in for security reasons.
80
+ // ⚠️ Be careful when activating marshalling.
81
+ const arena = new Arena(ctx, { isMarshalable: true });
78
82
 
79
- // expose objects as global objects in QuickJS VM
83
+ // expose objects as global objects in QuickJS context
80
84
  arena.expose({
81
85
  console: {
82
86
  log: console.log
@@ -87,32 +91,32 @@ import Arena from "quickjs-emscripten-sync";
87
91
 
88
92
  // expose objects but also enable sync
89
93
  const data = arena.sync({ hoge: "foo" });
90
- const exposed = arena.expose({ data });
94
+ arena.expose({ data });
91
95
 
92
96
  arena.evalCode(`data.hoge = "bar"`);
93
97
  // eval code and operations to exposed objects are automatically synced
94
98
  console.log(data.hoge); // "bar"
95
- exposed.hoge = "changed!";
99
+ data.hoge = "changed!";
96
100
  console.log(arena.evalCode(`data.hoge`)); // "changed!"
97
101
 
98
- // Don't forget calling arena.dispose() before disposing QuickJS VM!
102
+ // Don't forget calling arena.dispose() before disposing QuickJS context!
99
103
  arena.dispose();
100
- vm.dispose();
104
+ ctx.dispose();
101
105
  })();
102
106
  ```
103
107
 
104
- ## Marshaling limitations
108
+ ## Marshaling Limitations
105
109
 
106
- Objects are automatically converted when they cross between the host and the QuickJS VM. The conversion of a host's object to a VM handle is called marshaling, and the conversion of a VM handle to a host's object is called unmarshaling.
110
+ Objects are automatically converted when they cross between the host and the QuickJS context. The conversion of a host's object to a handle is called marshaling, and the conversion of a handle to a host's object is called unmarshaling.
107
111
 
108
112
  And for marshalling, it is possible to control whether the conversion is performed or not.
109
113
 
110
114
  For example, exposing the host's global object to QuickJS is very heavy and dangerous. This exposure can be limited and controlled with the `isMarshalable` option. If `false` is returned, just `undefined` is passed to QuickJS.
111
115
 
112
116
  ```js
113
- import Arena, { complexity } from "quickjs-emscripten-sync";
117
+ import { Arena, complexity } from "quickjs-emscripten-sync";
114
118
 
115
- const arena = new Arena(vm, {
119
+ const arena = new Arena(ctx, {
116
120
  isMarshalable: (target: any) => {
117
121
  // prevent passing globalThis to QuickJS
118
122
  if (target === window) return false;
@@ -129,13 +133,13 @@ arena.evalCode(`a => a === undefined`)(document); // true
129
133
 
130
134
  The `complexity` function is useful to detect whether the object is too heavy to be passed to QuickJS.
131
135
 
132
- ## Security warning
136
+ ## Security Warning
133
137
 
134
138
  QuickJS has an environment isolated from the browser, so any code can be executed safely, but there are edge cases where some exposed objects by quickjs-emscripten-sync may break security.
135
139
 
136
140
  quickjs-emscripten-sync cannot prevent such dangerous case, so **PLEASE be very careful and deliberate about what you expose to QuickJS!**
137
141
 
138
- ### Case 1: Prototype pollution in browser
142
+ ### Case 1: Prototype pollution
139
143
 
140
144
  ```js
141
145
  import { set } from "lodash-es";
@@ -179,28 +183,34 @@ By default, quickjs-emscripten-sync doesn't prevent any marshaling, even in such
179
183
 
180
184
  ### `Arena`
181
185
 
182
- The Arena class manages all generated handles at once by quickjs-emscripten and automatically converts objects between the host and the QuickJS VM.
186
+ The Arena class manages all generated handles at once by quickjs-emscripten and automatically converts objects between the host and the QuickJS context.
183
187
 
184
- #### `new Arena(vm: QuickJSVm, options?: Options)`
188
+ #### `new Arena(ctx: QuickJSContext, options?: Options)`
185
189
 
186
- Constructs a new Arena instance. It requires a quickjs-emscripten VM initialized with `quickjs.createVM()`.
190
+ Constructs a new Arena instance. It requires a quickjs-emscripten context initialized with `quickjs.newContext()`.
187
191
 
188
192
  Options accepted:
189
193
 
190
194
  ```ts
191
195
  type Options = {
192
- isMarshalable?: (target: any) => boolean;
196
+ isMarshalable?: boolean | "json" | ((target: any) => boolean | "json");
193
197
  registeredObjects?: Iterable<[any, QuickJSHandle | string]>;
198
+ compat?: boolean;
194
199
  }
195
200
  ```
196
201
 
197
- - **`isMarshalable`**: A callback that returns a boolean value that determines whether an object is marshalled or not. If false, no marshaling will be done and undefined will be passed to the QuickJS VM, otherwise marshaling will be done. By default, all objects will be marshalled.
198
- - **`registeredObjects`**: You can pre-register a pair of objects that will be considered the same between the host and the QuickJS VM. This will be used automatically during the conversion. By default, it will be registered automatically with [`defaultRegisteredObjects`](src/default.ts). If you want to add a new pair to this, please do the following:
202
+ - **`isMarshalable`**: Determines how marshalling will be done when sending objects from the host to the context. **Make sure to set the marshalling to be the minimum necessary as it may reduce the security of your application.** [Please read the section on security above.](#security-warning)
203
+ - `"json"` (**default**, safety): Target object will be serialized as JSON in host and then parsed in context. Functions and classes will be lost in the process.
204
+ - `false` (safety): Target object will not be always marshalled as `undefined`.
205
+ - `(target: any) => boolean | "json"` (recoomended): You can control marshalling mode for each objects. If you want to do marshalling, usually use this method. Allow partial marshalling by returning `true` only for some objects.
206
+ - `true` (**risky and not recommended**): Target object will be always marshaled. This setting may reduce security.
207
+ - **`registeredObjects`**: You can pre-register a pair of objects that will be considered the same between the host and the QuickJS context. This will be used automatically during the conversion. By default, it will be registered automatically with [`defaultRegisteredObjects`](src/default.ts). If you want to add a new pair to this, please do the following:
208
+ - **`compat`**: If you want to use quickjs-emscripten v0.15 or older, enable this option to automatically inject code to the VM for compatibility.
199
209
 
200
210
  ```js
201
211
  import { defaultRegisteredObjects } from "quickjs-emscripten-sync";
202
212
 
203
- const arena = new Arena(vm, {
213
+ const arena = new Arena(ctx, {
204
214
  registeredObjects: [
205
215
  ...defaultRegisteredObjects,
206
216
  [Math, "Math"]
@@ -208,36 +218,36 @@ const arena = new Arena(vm, {
208
218
  });
209
219
  ```
210
220
 
211
- Instead of a string, you can also pass a QuickJSHandle directly. In that case, however, you have to dispose of them manually when destroying the VM.
221
+ Instead of a string, you can also pass a QuickJSHandle directly. In that case, however, you have to dispose of them manually when destroying the context.
212
222
 
213
223
  #### `dispose()`
214
224
 
215
- Dispose of the arena and managed handles. This method won't dispose the VM itself, so the VM has to be disposed of manually.
225
+ Dispose of the arena and managed handles. This method won't dispose the context itself, so the context has to be disposed of manually.
216
226
 
217
227
  #### `evalCode<T = any>(code: string): T | undefined`
218
228
 
219
- Evaluate JS code in the VM and get the result as an object on the host side. It also converts and re-throws error objects when an error is thrown during evaluation.
229
+ Evaluate JS code in the context and get the result as an object on the host side. It also converts and re-throws error objects when an error is thrown during evaluation.
220
230
 
221
231
  #### `executePendingJobs(): number`
222
232
 
223
- Almost same as `vm.executePendingJobs()`, but it converts and re-throws error objects when an error is thrown during evaluation.
233
+ Almost same as `ctx.runtime.executePendingJobs()`, but it converts and re-throws error objects when an error is thrown during evaluation.
224
234
 
225
235
  #### `expose(obj: { [k: string]: any })`
226
236
 
227
- Expose objects as global objects in the VM.
237
+ Expose objects as global objects in the context.
228
238
 
229
- By default, exposed objects are not synchronized between the host and the VM.
230
- If you want to sync an objects, first wrap the object with sync method, and then expose the wrapped object.
239
+ By default, exposed objects are not synchronized between the host and the context.
240
+ If you want to sync an objects, first wrap the object with `sync` method, and then expose the wrapped object.
231
241
 
232
242
  #### `sync<T>(target: T): T`
233
243
 
234
- Enables sync for the object between the host and the VM and returns objects wrapped with proxies.
244
+ Enables sync for the object between the host and the context and returns objects wrapped with proxies.
235
245
 
236
- The return value is necessary in order to reflect changes to the object from the host to the VM. Please note that setting a value in the field or deleting a field in the original object will not synchronize it.
246
+ The return value is necessary in order to reflect changes to the object from the host to the context. Please note that setting a value in the field or deleting a field in the original object will not synchronize it.
237
247
 
238
248
  #### `register(target: any, code: string | QuickJSHandle)`
239
249
 
240
- Register a pair of objects that will be considered the same between the host and the QuickJS VM.
250
+ Register a pair of objects that will be considered the same between the host and the QuickJS context.
241
251
 
242
252
  #### `unregisterAll(targets: Iterable<[any, string | QuickJSHandle]>)`
243
253
 
@@ -263,9 +273,9 @@ Measure the complexity of an object as you traverse the field and prototype chai
263
273
 
264
274
  ### How to work
265
275
 
266
- quickjs-emscripten can execute JS code safely, but it requires to deal with a lot of handles and lifetimes. Also, when destroying the VM, any un-destroyed handle will result in an error.
276
+ quickjs-emscripten can execute JS code safely, but it requires to deal with a lot of handles and lifetimes. Also, when destroying the context, any un-destroyed handle will result in an error.
267
277
 
268
- quickjs-emscripten-sync will automatically manage all handles once generated by QuickJS VM in an Arena class.
278
+ quickjs-emscripten-sync will automatically manage all handles once generated by QuickJS context in an Arena class.
269
279
  And it will automatically "marshal" objects as handles and "unmarshal" handles as objects to enable seamless data exchange between the browser and QuickJS. It recursively traverses the object properties and prototype chain to transform objects. A function is called after its arguments and this arg are automatically converted for the environment in which the function is defined. The return value will be automatically converted to match the environment of the caller.
270
280
  Most objects are wrapped by proxies during conversion, allowing "set" and "delete" operations on objects to be synchronized between the browser and QuickJS.
271
281
 
@@ -273,7 +283,7 @@ Most objects are wrapped by proxies during conversion, allowing "set" and "delet
273
283
 
274
284
  #### Class constructor
275
285
 
276
- When initializing a new instance, it is not possible to fully proxy this arg (a.k.a. `new.target`) inside the class constructor. Therefore, after the constructor call, the fields set for this are re-set to this on the VM side. Therefore, there may be some edge cases where the constructor may not work properly.
286
+ When initializing a new instance, it is not possible to fully proxy this arg (a.k.a. `new.target`) inside the class constructor. Therefore, after the constructor call, the fields set for this are re-set to this on the context side. Therefore, there may be some edge cases where the constructor may not work properly.
277
287
 
278
288
  ```js
279
289
  class Cls {
package/dist/index.d.ts CHANGED
@@ -1,27 +1,14 @@
1
- import { QuickJSHandle, QuickJSVm } from "quickjs-emscripten";
2
- import { SuccessOrFail, VmCallResult } from "quickjs-emscripten/dist/vm-interface";
3
- import VMMap from "./vmmap";
4
- import marshal from "./marshal";
5
- import unmarshal from "./unmarshal";
6
- import { Wrapped } from "./wrapper";
7
- import { complexity, isES2015Class, isObject, walkObject } from "./util";
8
- import { call, eq, isHandleObject, send, consumeAll } from "./vmutil";
9
- import { defaultRegisteredObjects } from "./default";
10
- export { Arena, VMMap, defaultRegisteredObjects, marshal, unmarshal, complexity, isES2015Class, isObject, walkObject, call, eq, isHandleObject, send, consumeAll, };
11
- export declare type Options = {
12
- /** A callback that returns a boolean value that determines whether an object is marshalled or not. If false, no marshaling will be done and undefined will be passed to the QuickJS VM, otherwise marshaling will be done. By default, all objects will be marshalled. */
13
- isMarshalable?: (target: any) => boolean;
14
- /** You can pre-register a pair of objects that will be considered the same between the host and the QuickJS VM. This will be used automatically during the conversion. By default, it will be registered automatically with `defaultRegisteredObjects`.
15
- *
16
- * Instead of a string, you can also pass a QuickJSHandle directly. In that case, however, you have to dispose of them manually when destroying the VM.
17
- */
18
- registeredObjects?: Iterable<[any, QuickJSHandle | string]>;
19
- };
1
+ import type { QuickJSContext } from 'quickjs-emscripten';
2
+ import type { QuickJSDeferredPromise } from 'quickjs-emscripten';
3
+ import type { QuickJSHandle } from 'quickjs-emscripten';
4
+ import type { SuccessOrFail } from 'quickjs-emscripten';
5
+ import type { VmCallResult } from 'quickjs-emscripten';
6
+
20
7
  /**
21
8
  * The Arena class manages all generated handles at once by quickjs-emscripten and automatically converts objects between the host and the QuickJS VM.
22
9
  */
23
- export default class Arena {
24
- vm: QuickJSVm;
10
+ export declare class Arena {
11
+ context: QuickJSContext;
25
12
  _map: VMMap;
26
13
  _registeredMap: VMMap;
27
14
  _registeredMapDispose: Set<any>;
@@ -30,8 +17,8 @@ export default class Arena {
30
17
  _symbol: symbol;
31
18
  _symbolHandle: QuickJSHandle;
32
19
  _options?: Options;
33
- /** Constructs a new Arena instance. It requires a quickjs-emscripten VM initialized with `quickjs.createVM()`. */
34
- constructor(vm: QuickJSVm, options?: Options);
20
+ /** Constructs a new Arena instance. It requires a quickjs-emscripten context initialized with `quickjs.newContext()`. */
21
+ constructor(ctx: QuickJSContext, options?: Options);
35
22
  /**
36
23
  * Dispose of the arena and managed handles. This method won't dispose the VM itself, so the VM has to be disposed of manually.
37
24
  */
@@ -81,12 +68,120 @@ export default class Arena {
81
68
  endSync(target: any): void;
82
69
  _unwrapResult<T>(result: SuccessOrFail<T, QuickJSHandle>): T;
83
70
  _unwrapResultAndUnmarshal(result: VmCallResult<QuickJSHandle> | undefined): any;
84
- _marshal(target: any): QuickJSHandle;
85
- _unmarshal(handle: QuickJSHandle): any;
71
+ _isMarshalable: (t: unknown) => boolean | "json";
72
+ _marshalFind: (t: unknown) => QuickJSHandle | undefined;
73
+ _marshalPre: (t: unknown, h: QuickJSHandle | QuickJSDeferredPromise, mode: true | "json" | undefined) => Wrapped<QuickJSHandle> | undefined;
74
+ _marshalPreApply: (target: Function, that: unknown, args: unknown[]) => void;
75
+ _marshal: (target: any) => [QuickJSHandle, boolean];
76
+ _preUnmarshal: (t: any, h: QuickJSHandle) => Wrapped<any>;
77
+ _unmarshalFind: (h: QuickJSHandle) => unknown;
78
+ _unmarshal: (handle: QuickJSHandle) => any;
86
79
  _register(t: any, h: QuickJSHandle, map?: VMMap, sync?: boolean): [Wrapped<any>, Wrapped<QuickJSHandle>] | undefined;
87
- _syncMode(obj: any): "both" | undefined;
80
+ _syncMode: (obj: any) => "both" | undefined;
88
81
  _wrap<T>(target: T): Wrapped<T> | undefined;
89
82
  _unwrap<T>(target: T): T;
83
+ _unwrapIfNotSynced: <T>(target: T) => T;
90
84
  _wrapHandle(handle: QuickJSHandle): [Wrapped<QuickJSHandle> | undefined, boolean];
91
85
  _unwrapHandle(target: QuickJSHandle): [QuickJSHandle, boolean];
92
86
  }
87
+
88
+ export declare function call(ctx: QuickJSContext, code: string, thisArg?: QuickJSHandle, ...args: QuickJSHandle[]): QuickJSHandle;
89
+
90
+ /**
91
+ * Measure the complexity of an object as you traverse the field and prototype chain. If max is specified, when the complexity reaches max, the traversal is terminated and it returns the max. In this function, one object and function are counted as a complexity of 1, and primitives are not counted as a complexity.
92
+ */
93
+ export declare function complexity(value: any, max?: number): number;
94
+
95
+ export declare function consumeAll<T extends QuickJSHandle[], K>(handles: T, cb: (handles: T) => K): K;
96
+
97
+ /**
98
+ * Default value of registeredObjects option of the Arena class constructor.
99
+ */
100
+ export declare const defaultRegisteredObjects: [any, string][];
101
+
102
+ export declare function eq(ctx: QuickJSContext, a: QuickJSHandle, b: QuickJSHandle): boolean;
103
+
104
+ export declare function isES2015Class(cls: any): cls is new (...args: any[]) => any;
105
+
106
+ export declare function isHandleObject(ctx: QuickJSContext, h: QuickJSHandle): boolean;
107
+
108
+ export declare function isObject(value: any): value is object | Function;
109
+
110
+ export declare function json(ctx: QuickJSContext, target: any): QuickJSHandle;
111
+
112
+ export declare function marshal(target: unknown, options: Options_2): QuickJSHandle;
113
+
114
+ export declare type Options = {
115
+ /** A callback that returns a boolean value that determines whether an object is marshalled or not. If false, no marshaling will be done and undefined will be passed to the QuickJS VM, otherwise marshaling will be done. By default, all objects will be marshalled. */
116
+ isMarshalable?: boolean | "json" | ((target: any) => boolean | "json");
117
+ /** You can pre-register a pair of objects that will be considered the same between the host and the QuickJS VM. This will be used automatically during the conversion. By default, it will be registered automatically with `defaultRegisteredObjects`.
118
+ *
119
+ * Instead of a string, you can also pass a QuickJSHandle directly. In that case, however, you have to dispose of them manually when destroying the VM.
120
+ */
121
+ registeredObjects?: Iterable<[any, QuickJSHandle | string]>;
122
+ /** Compatibility with quickjs-emscripten prior to v0.15. Inject code for compatibility into context at Arena class initialization time. */
123
+ compat?: boolean;
124
+ };
125
+
126
+ declare type Options_2 = {
127
+ ctx: QuickJSContext;
128
+ unmarshal: (handle: QuickJSHandle) => unknown;
129
+ isMarshalable?: (target: unknown) => boolean | "json";
130
+ find: (target: unknown) => QuickJSHandle | undefined;
131
+ pre: (target: unknown, handle: QuickJSHandle | QuickJSDeferredPromise, mode: true | "json" | undefined) => QuickJSHandle | undefined;
132
+ preApply?: (target: Function, thisArg: unknown, args: unknown[]) => any;
133
+ };
134
+
135
+ declare type Options_3 = {
136
+ ctx: QuickJSContext;
137
+ /** marshal returns handle and boolean indicates that the handle should be disposed after use */
138
+ marshal: (target: unknown) => [QuickJSHandle, boolean];
139
+ find: (handle: QuickJSHandle) => unknown | undefined;
140
+ pre: <T = unknown>(target: T, handle: QuickJSHandle) => T | undefined;
141
+ };
142
+
143
+ export declare function unmarshal(handle: QuickJSHandle, options: Options_3): any;
144
+
145
+ export declare class VMMap {
146
+ ctx: QuickJSContext;
147
+ _map1: Map<any, number>;
148
+ _map2: Map<any, number>;
149
+ _map3: Map<number, QuickJSHandle>;
150
+ _map4: Map<number, QuickJSHandle>;
151
+ _counterMap: Map<number, any>;
152
+ _disposables: Set<QuickJSHandle>;
153
+ _mapGet: QuickJSHandle;
154
+ _mapSet: QuickJSHandle;
155
+ _mapDelete: QuickJSHandle;
156
+ _mapClear: QuickJSHandle;
157
+ _counter: number;
158
+ constructor(ctx: QuickJSContext);
159
+ set(key: any, handle: QuickJSHandle, key2?: any, handle2?: QuickJSHandle): boolean;
160
+ merge(iteratable: Iterable<[any, QuickJSHandle | undefined] | [any, QuickJSHandle | undefined, any, QuickJSHandle | undefined]> | undefined): void;
161
+ get(key: any): QuickJSHandle | undefined;
162
+ getByHandle(handle: QuickJSHandle): any;
163
+ has(key: any): boolean;
164
+ hasHandle(handle: QuickJSHandle): boolean;
165
+ keys(): IterableIterator<any>;
166
+ delete(key: any, dispose?: boolean): void;
167
+ deleteByHandle(handle: QuickJSHandle, dispose?: boolean): void;
168
+ clear(): void;
169
+ dispose(): void;
170
+ get size(): number;
171
+ [Symbol.iterator](): Iterator<[
172
+ any,
173
+ QuickJSHandle,
174
+ any,
175
+ QuickJSHandle | undefined
176
+ ]>;
177
+ _get2(num: number): any;
178
+ _call(fn: QuickJSHandle, thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]): QuickJSHandle;
179
+ }
180
+
181
+ export declare function walkObject(value: any, callback?: (target: any, set: Set<any>) => boolean | void): Set<any>;
182
+
183
+ declare type Wrapped<T> = T & {
184
+ __qes_wrapped: never;
185
+ };
186
+
187
+ export { }