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.
Files changed (51) hide show
  1. package/README.md +60 -37
  2. package/dist/index.d.ts +29 -22
  3. package/dist/quickjs-emscripten-sync.mjs +842 -0
  4. package/dist/quickjs-emscripten-sync.umd.js +15 -15
  5. package/package.json +12 -21
  6. package/src/default.ts +2 -2
  7. package/src/index.test.ts +159 -65
  8. package/src/index.ts +67 -66
  9. package/src/marshal/custom.test.ts +50 -0
  10. package/src/marshal/custom.ts +36 -0
  11. package/src/marshal/function.test.ts +60 -72
  12. package/src/marshal/function.ts +15 -18
  13. package/src/marshal/index.test.ts +88 -84
  14. package/src/marshal/index.ts +16 -18
  15. package/src/marshal/json.test.ts +32 -38
  16. package/src/marshal/json.ts +5 -7
  17. package/src/marshal/object.test.ts +52 -79
  18. package/src/marshal/object.ts +8 -15
  19. package/src/marshal/primitive.test.ts +16 -21
  20. package/src/marshal/primitive.ts +11 -10
  21. package/src/marshal/promise.test.ts +21 -22
  22. package/src/marshal/promise.ts +6 -13
  23. package/src/marshal/properties.test.ts +21 -26
  24. package/src/marshal/properties.ts +15 -17
  25. package/src/unmarshal/custom.test.ts +50 -0
  26. package/src/unmarshal/custom.ts +31 -0
  27. package/src/unmarshal/function.test.ts +52 -74
  28. package/src/unmarshal/function.ts +13 -22
  29. package/src/unmarshal/index.test.ts +58 -50
  30. package/src/unmarshal/index.ts +12 -13
  31. package/src/unmarshal/object.test.ts +37 -43
  32. package/src/unmarshal/object.ts +16 -20
  33. package/src/unmarshal/primitive.test.ts +15 -15
  34. package/src/unmarshal/primitive.ts +11 -18
  35. package/src/unmarshal/promise.test.ts +13 -13
  36. package/src/unmarshal/promise.ts +10 -19
  37. package/src/unmarshal/properties.test.ts +8 -8
  38. package/src/unmarshal/properties.ts +44 -45
  39. package/src/util.test.ts +2 -7
  40. package/src/util.ts +3 -8
  41. package/src/vmmap.test.ts +72 -88
  42. package/src/vmmap.ts +26 -44
  43. package/src/vmutil.test.ts +73 -89
  44. package/src/vmutil.ts +24 -47
  45. package/src/wrapper.test.ts +108 -148
  46. package/src/wrapper.ts +59 -62
  47. package/dist/quickjs-emscripten-sync.es.js +0 -951
  48. package/src/marshal/symbol.test.ts +0 -24
  49. package/src/marshal/symbol.ts +0 -20
  50. package/src/unmarshal/symbol.test.ts +0 -25
  51. package/src/unmarshal/symbol.ts +0 -12
@@ -15,16 +15,15 @@ import {
15
15
  } from "./vmutil";
16
16
 
17
17
  test("fn", async () => {
18
- const quickjs = await getQuickJS();
19
- const vm = quickjs.createVm();
18
+ const ctx = (await getQuickJS()).newContext();
20
19
 
21
- const f = fn(vm, "(a, b) => a + b");
22
- expect(vm.getNumber(f(undefined, vm.newNumber(1), vm.newNumber(2)))).toBe(3);
20
+ const f = fn(ctx, "(a, b) => a + b");
21
+ expect(ctx.getNumber(f(undefined, ctx.newNumber(1), ctx.newNumber(2)))).toBe(3);
23
22
 
24
- const obj = vm.newObject();
25
- vm.setProp(obj, "a", vm.newNumber(2));
26
- const f2 = fn(vm, "(function() { return this.a + 1; })");
27
- expect(vm.getNumber(f2(obj))).toBe(3);
23
+ const obj = ctx.newObject();
24
+ ctx.setProp(obj, "a", ctx.newNumber(2));
25
+ const f2 = fn(ctx, "(function() { return this.a + 1; })");
26
+ expect(ctx.getNumber(f2(obj))).toBe(3);
28
27
 
29
28
  obj.dispose();
30
29
  expect(f.alive).toBe(true);
@@ -33,199 +32,184 @@ test("fn", async () => {
33
32
  f.dispose();
34
33
  expect(f.alive).toBe(false);
35
34
  expect(f2.alive).toBe(false);
36
- vm.dispose();
35
+ ctx.dispose();
37
36
  });
38
37
 
39
38
  test("call", async () => {
40
- const quickjs = await getQuickJS();
41
- const vm = quickjs.createVm();
39
+ const ctx = (await getQuickJS()).newContext();
42
40
 
43
41
  expect(
44
- vm.getNumber(
45
- call(vm, "(a, b) => a + b", undefined, vm.newNumber(1), vm.newNumber(2))
46
- )
42
+ ctx.getNumber(call(ctx, "(a, b) => a + b", undefined, ctx.newNumber(1), ctx.newNumber(2))),
47
43
  ).toBe(3);
48
44
 
49
- const obj = vm.newObject();
50
- vm.setProp(obj, "a", vm.newNumber(2));
51
- expect(
52
- vm.getNumber(call(vm, "(function() { return this.a + 1; })", obj))
53
- ).toBe(3);
45
+ const obj = ctx.newObject();
46
+ ctx.setProp(obj, "a", ctx.newNumber(2));
47
+ expect(ctx.getNumber(call(ctx, "(function() { return this.a + 1; })", obj))).toBe(3);
54
48
 
55
49
  obj.dispose();
56
- vm.dispose();
50
+ ctx.dispose();
57
51
  });
58
52
 
59
53
  test("eq", async () => {
60
- const quickjs = await getQuickJS();
61
- const vm = quickjs.createVm();
54
+ const ctx = (await getQuickJS()).newContext();
62
55
 
63
- const math1 = vm.unwrapResult(vm.evalCode("Math"));
64
- const math2 = vm.unwrapResult(vm.evalCode("Math"));
65
- const obj = vm.newObject();
56
+ const math1 = ctx.unwrapResult(ctx.evalCode("Math"));
57
+ const math2 = ctx.unwrapResult(ctx.evalCode("Math"));
58
+ const obj = ctx.newObject();
66
59
  expect(math1 === math2).toBe(false);
67
- expect(eq(vm, math1, math2)).toBe(true);
68
- expect(eq(vm, math1, obj)).toBe(false);
60
+ expect(eq(ctx, math1, math2)).toBe(true);
61
+ expect(eq(ctx, math1, obj)).toBe(false);
69
62
 
70
63
  math1.dispose();
71
64
  math2.dispose();
72
65
  obj.dispose();
73
- vm.dispose();
66
+ ctx.dispose();
74
67
  });
75
68
 
76
69
  test("instanceOf", async () => {
77
- const quickjs = await getQuickJS();
78
- const vm = quickjs.createVm();
70
+ const ctx = (await getQuickJS()).newContext();
79
71
 
80
- const pr = vm.unwrapResult(vm.evalCode("Promise"));
81
- const func = vm.unwrapResult(vm.evalCode("(function() {})"));
82
- const p = vm.unwrapResult(vm.evalCode("Promise.resolve()"));
83
- expect(instanceOf(vm, p, pr)).toBe(true);
84
- expect(instanceOf(vm, p, func)).toBe(false);
72
+ const pr = ctx.unwrapResult(ctx.evalCode("Promise"));
73
+ const func = ctx.unwrapResult(ctx.evalCode("(function() {})"));
74
+ const p = ctx.unwrapResult(ctx.evalCode("Promise.resolve()"));
75
+ expect(instanceOf(ctx, p, pr)).toBe(true);
76
+ expect(instanceOf(ctx, p, func)).toBe(false);
85
77
 
86
78
  p.dispose();
87
79
  pr.dispose();
88
80
  func.dispose();
89
- vm.dispose();
81
+ ctx.dispose();
90
82
  });
91
83
 
92
84
  test("isHandleObject", async () => {
93
- const quickjs = await getQuickJS();
94
- const vm = quickjs.createVm();
95
-
96
- const obj = vm.newObject();
97
- expect(isHandleObject(vm, obj)).toBe(true);
98
- const func = vm.newFunction("", () => {});
99
- expect(isHandleObject(vm, func)).toBe(true);
100
- const array = vm.newArray();
101
- expect(isHandleObject(vm, array)).toBe(true);
102
- const num = vm.newNumber(NaN);
103
- expect(isHandleObject(vm, num)).toBe(false);
85
+ const ctx = (await getQuickJS()).newContext();
86
+
87
+ const obj = ctx.newObject();
88
+ expect(isHandleObject(ctx, obj)).toBe(true);
89
+ const func = ctx.newFunction("", () => {});
90
+ expect(isHandleObject(ctx, func)).toBe(true);
91
+ const array = ctx.newArray();
92
+ expect(isHandleObject(ctx, array)).toBe(true);
93
+ const num = ctx.newNumber(NaN);
94
+ expect(isHandleObject(ctx, num)).toBe(false);
104
95
 
105
96
  obj.dispose();
106
97
  func.dispose();
107
98
  array.dispose();
108
- vm.dispose();
99
+ ctx.dispose();
109
100
  });
110
101
 
111
102
  test("json", async () => {
112
- const quickjs = await getQuickJS();
113
- const vm = quickjs.createVm();
103
+ const ctx = (await getQuickJS()).newContext();
114
104
 
115
- const handle = json(vm, {
105
+ const handle = json(ctx, {
116
106
  hoge: { foo: ["bar"] },
117
107
  });
118
- expect(
119
- vm.dump(call(vm, `a => a.hoge.foo[0] === "bar"`, undefined, handle))
120
- ).toBe(true);
121
- expect(vm.typeof(json(vm, undefined))).toBe("undefined");
108
+ expect(ctx.dump(call(ctx, `a => a.hoge.foo[0] === "bar"`, undefined, handle))).toBe(true);
109
+ expect(ctx.typeof(json(ctx, undefined))).toBe("undefined");
122
110
 
123
111
  handle.dispose();
124
- vm.dispose();
112
+ ctx.dispose();
125
113
  });
126
114
 
127
115
  test("consumeAll", async () => {
128
- const quickjs = await getQuickJS();
129
- const vm = quickjs.createVm();
116
+ const ctx = (await getQuickJS()).newContext();
130
117
 
131
118
  const o = {};
132
119
 
133
- const handles = [vm.newObject(), vm.newObject()];
120
+ const handles = [ctx.newObject(), ctx.newObject()];
134
121
  expect(
135
122
  consumeAll(
136
123
  handles,
137
- vi.fn(() => o)
138
- )
124
+ vi.fn(() => o),
125
+ ),
139
126
  ).toBe(o);
140
- expect(handles.every((h) => !h.alive)).toBe(true);
127
+ expect(handles.every(h => !h.alive)).toBe(true);
141
128
 
142
- const handles2 = [vm.newObject(), vm.newObject()];
129
+ const handles2 = [ctx.newObject(), ctx.newObject()];
143
130
  expect(() =>
144
131
  consumeAll(handles2, () => {
145
132
  throw new Error("qes error");
146
- })
133
+ }),
147
134
  ).toThrow("qes error");
148
- expect(handles2.every((h) => !h.alive)).toBe(true);
135
+ expect(handles2.every(h => !h.alive)).toBe(true);
149
136
 
150
- vm.dispose();
137
+ ctx.dispose();
151
138
  });
152
139
 
153
140
  test("mayConsume", async () => {
154
- const quickjs = await getQuickJS();
155
- const vm = quickjs.createVm();
141
+ const ctx = (await getQuickJS()).newContext();
156
142
 
157
143
  const o = {};
158
144
 
159
- const handle = vm.newArray();
145
+ const handle = ctx.newArray();
160
146
  expect(
161
147
  mayConsume(
162
148
  [handle, false],
163
- vi.fn(() => o)
164
- )
149
+ vi.fn(() => o),
150
+ ),
165
151
  ).toBe(o);
166
152
  expect(handle.alive).toBe(true);
167
153
 
168
154
  mayConsume([handle, true], () => {});
169
155
  expect(handle.alive).toBe(false);
170
156
 
171
- const handle2 = vm.newArray();
157
+ const handle2 = ctx.newArray();
172
158
  expect(() =>
173
159
  mayConsume([handle2, true], () => {
174
160
  throw new Error("qes error");
175
- })
161
+ }),
176
162
  ).toThrow("qes error");
177
163
  expect(handle.alive).toBe(false);
178
164
 
179
- vm.dispose();
165
+ ctx.dispose();
180
166
  });
181
167
 
182
168
  test("mayConsumeAll", async () => {
183
- const quickjs = await getQuickJS();
184
- const vm = quickjs.createVm();
169
+ const ctx = (await getQuickJS()).newContext();
185
170
 
186
171
  const o = {};
187
172
 
188
173
  const handles: [QuickJSHandle, boolean][] = [
189
- [vm.newObject(), false],
190
- [vm.newObject(), true],
174
+ [ctx.newObject(), false],
175
+ [ctx.newObject(), true],
191
176
  ];
192
177
  expect(
193
178
  mayConsumeAll(
194
179
  handles,
195
- vi.fn((..._: any[]) => o)
196
- )
180
+ vi.fn((..._: any[]) => o),
181
+ ),
197
182
  ).toBe(o);
198
183
  expect(handles[0][0].alive).toBe(true);
199
184
  expect(handles[1][0].alive).toBe(false);
200
185
 
201
186
  const handles2: [QuickJSHandle, boolean][] = [
202
- [vm.newObject(), false],
203
- [vm.newObject(), true],
187
+ [ctx.newObject(), false],
188
+ [ctx.newObject(), true],
204
189
  ];
205
190
  expect(() =>
206
191
  mayConsumeAll(handles2, (..._args) => {
207
192
  throw new Error("qes error");
208
- })
193
+ }),
209
194
  ).toThrow("qes error");
210
195
  expect(handles2[0][0].alive).toBe(true);
211
196
  expect(handles2[1][0].alive).toBe(false);
212
197
 
213
198
  handles[0][0].dispose();
214
199
  handles2[0][0].dispose();
215
- vm.dispose();
200
+ ctx.dispose();
216
201
  });
217
202
 
218
203
  test("handleFrom", async () => {
219
- const quickjs = await getQuickJS();
220
- const vm = quickjs.createVm();
204
+ const ctx = (await getQuickJS()).newContext();
221
205
 
222
- const handle = vm.newObject();
223
- const promise = vm.newPromise();
206
+ const handle = ctx.newObject();
207
+ const promise = ctx.newPromise();
224
208
 
225
209
  expect(handleFrom(handle) === handle).toBe(true);
226
210
  expect(handleFrom(promise) === promise.handle).toBe(true);
227
211
 
228
212
  handle.dispose();
229
213
  promise.dispose();
230
- vm.dispose();
214
+ ctx.dispose();
231
215
  });
package/src/vmutil.ts CHANGED
@@ -1,26 +1,17 @@
1
1
  import type {
2
2
  Disposable,
3
- QuickJSVm,
3
+ QuickJSContext,
4
4
  QuickJSHandle,
5
5
  QuickJSDeferredPromise,
6
6
  } from "quickjs-emscripten";
7
7
 
8
8
  export function fn(
9
- vm: QuickJSVm,
10
- code: string
11
- ): ((
12
- thisArg: QuickJSHandle | undefined,
13
- ...args: QuickJSHandle[]
14
- ) => QuickJSHandle) &
15
- Disposable {
16
- const handle = vm.unwrapResult(vm.evalCode(code));
17
- const f = (
18
- thisArg: QuickJSHandle | undefined,
19
- ...args: QuickJSHandle[]
20
- ): any => {
21
- return vm.unwrapResult(
22
- vm.callFunction(handle, thisArg ?? vm.undefined, ...args)
23
- );
9
+ ctx: QuickJSContext,
10
+ code: string,
11
+ ): ((thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]) => QuickJSHandle) & Disposable {
12
+ const handle = ctx.unwrapResult(ctx.evalCode(code));
13
+ const f = (thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]): any => {
14
+ return ctx.unwrapResult(ctx.callFunction(handle, thisArg ?? ctx.undefined, ...args));
24
15
  };
25
16
  f.dispose = () => handle.dispose();
26
17
  f.alive = true;
@@ -31,12 +22,12 @@ export function fn(
31
22
  }
32
23
 
33
24
  export function call(
34
- vm: QuickJSVm,
25
+ ctx: QuickJSContext,
35
26
  code: string,
36
27
  thisArg?: QuickJSHandle,
37
28
  ...args: QuickJSHandle[]
38
29
  ): QuickJSHandle {
39
- const f = fn(vm, code);
30
+ const f = fn(ctx, code);
40
31
  try {
41
32
  return f(thisArg, ...args);
42
33
  } finally {
@@ -44,39 +35,27 @@ export function call(
44
35
  }
45
36
  }
46
37
 
47
- export function eq(vm: QuickJSVm, a: QuickJSHandle, b: QuickJSHandle): boolean {
48
- return vm.dump(call(vm, "Object.is", undefined, a, b));
38
+ export function eq(ctx: QuickJSContext, a: QuickJSHandle, b: QuickJSHandle): boolean {
39
+ return ctx.dump(call(ctx, "Object.is", undefined, a, b));
49
40
  }
50
41
 
51
- export function instanceOf(
52
- vm: QuickJSVm,
53
- a: QuickJSHandle,
54
- b: QuickJSHandle
55
- ): boolean {
56
- return vm.dump(call(vm, "(a, b) => a instanceof b", undefined, a, b));
42
+ export function instanceOf(ctx: QuickJSContext, a: QuickJSHandle, b: QuickJSHandle): boolean {
43
+ return ctx.dump(call(ctx, "(a, b) => a instanceof b", undefined, a, b));
57
44
  }
58
45
 
59
- export function isHandleObject(vm: QuickJSVm, a: QuickJSHandle): boolean {
60
- return vm.dump(
61
- call(
62
- vm,
63
- `a => typeof a === "object" && a !== null || typeof a === "function"`,
64
- undefined,
65
- a
66
- )
46
+ export function isHandleObject(ctx: QuickJSContext, h: QuickJSHandle): boolean {
47
+ return ctx.dump(
48
+ call(ctx, `a => typeof a === "object" && a !== null || typeof a === "function"`, undefined, h),
67
49
  );
68
50
  }
69
51
 
70
- export function json(vm: QuickJSVm, target: any): QuickJSHandle {
52
+ export function json(ctx: QuickJSContext, target: any): QuickJSHandle {
71
53
  const json = JSON.stringify(target);
72
- if (!json) return vm.undefined;
73
- return call(vm, `JSON.parse`, undefined, vm.newString(json));
54
+ if (!json) return ctx.undefined;
55
+ return call(ctx, `JSON.parse`, undefined, ctx.newString(json));
74
56
  }
75
57
 
76
- export function consumeAll<T extends QuickJSHandle[], K>(
77
- handles: T,
78
- cb: (handles: T) => K
79
- ): K {
58
+ export function consumeAll<T extends QuickJSHandle[], K>(handles: T, cb: (handles: T) => K): K {
80
59
  try {
81
60
  return cb(handles);
82
61
  } finally {
@@ -88,7 +67,7 @@ export function consumeAll<T extends QuickJSHandle[], K>(
88
67
 
89
68
  export function mayConsume<T>(
90
69
  [handle, shouldBeDisposed]: [QuickJSHandle, boolean],
91
- fn: (h: QuickJSHandle) => T
70
+ fn: (h: QuickJSHandle) => T,
92
71
  ) {
93
72
  try {
94
73
  return fn(handle);
@@ -101,10 +80,10 @@ export function mayConsume<T>(
101
80
 
102
81
  export function mayConsumeAll<T, H extends QuickJSHandle[]>(
103
82
  handles: { [P in keyof H]: [QuickJSHandle, boolean] },
104
- fn: (...args: H) => T
83
+ fn: (...args: H) => T,
105
84
  ) {
106
85
  try {
107
- return fn(...(handles.map((h) => h[0]) as H));
86
+ return fn(...(handles.map(h => h[0]) as H));
108
87
  } finally {
109
88
  for (const [handle, shouldBeDisposed] of handles) {
110
89
  if (shouldBeDisposed) {
@@ -118,8 +97,6 @@ function isQuickJSDeferredPromise(d: Disposable): d is QuickJSDeferredPromise {
118
97
  return "handle" in d;
119
98
  }
120
99
 
121
- export function handleFrom(
122
- d: QuickJSDeferredPromise | QuickJSHandle
123
- ): QuickJSHandle {
100
+ export function handleFrom(d: QuickJSDeferredPromise | QuickJSHandle): QuickJSHandle {
124
101
  return isQuickJSDeferredPromise(d) ? d.handle : d;
125
102
  }