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
@@ -1,70 +1,72 @@
1
1
  import { getQuickJS } from "quickjs-emscripten";
2
+ import { expect, test, vi } from "vitest";
3
+
2
4
  import { call } from "../vmutil";
3
5
  import marshalObject from "./object";
4
6
 
5
7
  test("empty object", async () => {
6
- const vm = (await getQuickJS()).createVm();
7
- const prototypeCheck = vm.unwrapResult(
8
- vm.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
8
+ const ctx = (await getQuickJS()).newContext();
9
+ const prototypeCheck = ctx.unwrapResult(
10
+ ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
9
11
  );
10
12
 
11
13
  const obj = {};
12
- const marshal = jest.fn();
13
- const preMarshal = jest.fn((_, a) => a);
14
+ const marshal = vi.fn();
15
+ const preMarshal = vi.fn((_, a) => a);
14
16
 
15
- const handle = marshalObject(vm, obj, marshal, preMarshal);
17
+ const handle = marshalObject(ctx, obj, marshal, preMarshal);
16
18
  if (!handle) throw new Error("handle is undefined");
17
19
 
18
- expect(vm.typeof(handle)).toBe("object");
20
+ expect(ctx.typeof(handle)).toBe("object");
19
21
  expect(marshal).toBeCalledTimes(0);
20
22
  expect(preMarshal).toBeCalledTimes(1);
21
23
  expect(preMarshal.mock.calls[0][0]).toBe(obj);
22
24
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
23
25
  expect(
24
- vm.dump(
25
- vm.unwrapResult(vm.callFunction(prototypeCheck, vm.undefined, handle))
26
+ ctx.dump(
27
+ ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle))
26
28
  )
27
29
  ).toBe(true);
28
30
 
29
31
  handle.dispose();
30
32
  prototypeCheck.dispose();
31
- vm.dispose();
33
+ ctx.dispose();
32
34
  });
33
35
 
34
36
  test("normal object", async () => {
35
- const vm = (await getQuickJS()).createVm();
36
- const prototypeCheck = vm.unwrapResult(
37
- vm.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
37
+ const ctx = (await getQuickJS()).newContext();
38
+ const prototypeCheck = ctx.unwrapResult(
39
+ ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
38
40
  );
39
- const entries = vm.unwrapResult(vm.evalCode(`Object.entries`));
41
+ const entries = ctx.unwrapResult(ctx.evalCode(`Object.entries`));
40
42
 
41
43
  const obj = { a: 100, b: "hoge" };
42
- const marshal = jest.fn(v =>
44
+ const marshal = vi.fn((v) =>
43
45
  typeof v === "number"
44
- ? vm.newNumber(v)
46
+ ? ctx.newNumber(v)
45
47
  : typeof v === "string"
46
- ? vm.newString(v)
47
- : vm.null
48
+ ? ctx.newString(v)
49
+ : ctx.null
48
50
  );
49
- const preMarshal = jest.fn((_, a) => a);
51
+ const preMarshal = vi.fn((_, a) => a);
50
52
 
51
- const handle = marshalObject(vm, obj, marshal, preMarshal);
53
+ const handle = marshalObject(ctx, obj, marshal, preMarshal);
52
54
  if (!handle) throw new Error("handle is undefined");
53
55
 
54
- expect(vm.typeof(handle)).toBe("object");
55
- expect(vm.getNumber(vm.getProp(handle, "a"))).toBe(100);
56
- expect(vm.getString(vm.getProp(handle, "b"))).toBe("hoge");
56
+ expect(ctx.typeof(handle)).toBe("object");
57
+ expect(ctx.getNumber(ctx.getProp(handle, "a"))).toBe(100);
58
+ expect(ctx.getString(ctx.getProp(handle, "b"))).toBe("hoge");
57
59
  expect(marshal.mock.calls).toEqual([["a"], [100], ["b"], ["hoge"]]);
58
60
  expect(preMarshal).toBeCalledTimes(1);
59
61
  expect(preMarshal.mock.calls[0][0]).toBe(obj);
60
62
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
61
63
  expect(
62
- vm.dump(
63
- vm.unwrapResult(vm.callFunction(prototypeCheck, vm.undefined, handle))
64
+ ctx.dump(
65
+ ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle))
64
66
  )
65
67
  ).toBe(true);
66
- const e = vm.unwrapResult(vm.callFunction(entries, vm.undefined, handle));
67
- expect(vm.dump(e)).toEqual([
68
+ const e = ctx.unwrapResult(ctx.callFunction(entries, ctx.undefined, handle));
69
+ expect(ctx.dump(e)).toEqual([
68
70
  ["a", 100],
69
71
  ["b", "hoge"],
70
72
  ]);
@@ -73,30 +75,30 @@ test("normal object", async () => {
73
75
  handle.dispose();
74
76
  prototypeCheck.dispose();
75
77
  entries.dispose();
76
- vm.dispose();
78
+ ctx.dispose();
77
79
  });
78
80
 
79
81
  test("array", async () => {
80
- const vm = (await getQuickJS()).createVm();
81
- const isArray = vm.unwrapResult(vm.evalCode(`Array.isArray`));
82
+ const ctx = (await getQuickJS()).newContext();
83
+ const isArray = ctx.unwrapResult(ctx.evalCode(`Array.isArray`));
82
84
 
83
85
  const array = [1, "aa"];
84
- const marshal = jest.fn(v =>
86
+ const marshal = vi.fn((v) =>
85
87
  typeof v === "number"
86
- ? vm.newNumber(v)
88
+ ? ctx.newNumber(v)
87
89
  : typeof v === "string"
88
- ? vm.newString(v)
89
- : vm.null
90
+ ? ctx.newString(v)
91
+ : ctx.null
90
92
  );
91
- const preMarshal = jest.fn((_, a) => a);
93
+ const preMarshal = vi.fn((_, a) => a);
92
94
 
93
- const handle = marshalObject(vm, array, marshal, preMarshal);
95
+ const handle = marshalObject(ctx, array, marshal, preMarshal);
94
96
  if (!handle) throw new Error("handle is undefined");
95
97
 
96
- expect(vm.typeof(handle)).toBe("object");
97
- expect(vm.getNumber(vm.getProp(handle, 0))).toBe(1);
98
- expect(vm.getString(vm.getProp(handle, 1))).toBe("aa");
99
- expect(vm.getNumber(vm.getProp(handle, "length"))).toBe(2);
98
+ expect(ctx.typeof(handle)).toBe("object");
99
+ expect(ctx.getNumber(ctx.getProp(handle, 0))).toBe(1);
100
+ expect(ctx.getString(ctx.getProp(handle, 1))).toBe("aa");
101
+ expect(ctx.getNumber(ctx.getProp(handle, "length"))).toBe(2);
100
102
  expect(marshal.mock.calls).toEqual([
101
103
  ["0"],
102
104
  [1],
@@ -109,33 +111,33 @@ test("array", async () => {
109
111
  expect(preMarshal.mock.calls[0][0]).toBe(array);
110
112
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
111
113
  expect(
112
- vm.dump(vm.unwrapResult(vm.callFunction(isArray, vm.undefined, handle)))
114
+ ctx.dump(ctx.unwrapResult(ctx.callFunction(isArray, ctx.undefined, handle)))
113
115
  ).toBe(true);
114
116
 
115
117
  handle.dispose();
116
118
  isArray.dispose();
117
- vm.dispose();
119
+ ctx.dispose();
118
120
  });
119
121
 
120
122
  test("prototype", async () => {
121
- const vm = (await getQuickJS()).createVm();
123
+ const ctx = (await getQuickJS()).newContext();
122
124
 
123
125
  const proto = { a: 100 };
124
- const protoHandle = vm.newObject();
125
- vm.setProp(protoHandle, "a", vm.newNumber(100));
126
- const preMarshal = jest.fn((_, a) => a);
126
+ const protoHandle = ctx.newObject();
127
+ ctx.setProp(protoHandle, "a", ctx.newNumber(100));
128
+ const preMarshal = vi.fn((_, a) => a);
127
129
 
128
130
  const obj = Object.create(proto);
129
131
  obj.b = "hoge";
130
132
  const handle = marshalObject(
131
- vm,
133
+ ctx,
132
134
  obj,
133
- v =>
135
+ (v) =>
134
136
  v === proto
135
137
  ? protoHandle
136
138
  : typeof v === "string"
137
- ? vm.newString(v)
138
- : vm.null,
139
+ ? ctx.newString(v)
140
+ : ctx.null,
139
141
  preMarshal
140
142
  );
141
143
  if (!handle) throw new Error("handle is undefined");
@@ -143,19 +145,24 @@ test("prototype", async () => {
143
145
  expect(preMarshal).toBeCalledTimes(1);
144
146
  expect(preMarshal.mock.calls[0][0]).toBe(obj);
145
147
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
146
- expect(vm.typeof(handle)).toBe("object");
147
- expect(vm.getNumber(vm.getProp(handle, "a"))).toBe(100);
148
- expect(vm.getString(vm.getProp(handle, "b"))).toBe("hoge");
149
- const e = call(vm, "Object.entries", undefined, handle);
150
- expect(vm.dump(e)).toEqual([["b", "hoge"]]);
151
- const protoHandle2 = call(vm, "Object.getPrototypeOf", vm.undefined, handle);
148
+ expect(ctx.typeof(handle)).toBe("object");
149
+ expect(ctx.getNumber(ctx.getProp(handle, "a"))).toBe(100);
150
+ expect(ctx.getString(ctx.getProp(handle, "b"))).toBe("hoge");
151
+ const e = call(ctx, "Object.entries", undefined, handle);
152
+ expect(ctx.dump(e)).toEqual([["b", "hoge"]]);
153
+ const protoHandle2 = call(
154
+ ctx,
155
+ "Object.getPrototypeOf",
156
+ ctx.undefined,
157
+ handle
158
+ );
152
159
  expect(
153
- vm.dump(call(vm, `Object.is`, undefined, protoHandle, protoHandle2))
160
+ ctx.dump(call(ctx, `Object.is`, undefined, protoHandle, protoHandle2))
154
161
  ).toBe(true);
155
162
 
156
163
  protoHandle2.dispose();
157
164
  e.dispose();
158
165
  handle.dispose();
159
166
  protoHandle.dispose();
160
- vm.dispose();
167
+ ctx.dispose();
161
168
  });
@@ -1,9 +1,10 @@
1
- import { QuickJSVm, QuickJSHandle } from "quickjs-emscripten";
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+
2
3
  import { call } from "../vmutil";
3
4
  import marshalProperties from "./properties";
4
5
 
5
6
  export default function marshalObject(
6
- vm: QuickJSVm,
7
+ ctx: QuickJSContext,
7
8
  target: unknown,
8
9
  marshal: (target: unknown) => QuickJSHandle,
9
10
  preMarshal: (
@@ -13,7 +14,7 @@ export default function marshalObject(
13
14
  ): QuickJSHandle | undefined {
14
15
  if (typeof target !== "object" || target === null) return;
15
16
 
16
- const raw = Array.isArray(target) ? vm.newArray() : vm.newObject();
17
+ const raw = Array.isArray(target) ? ctx.newArray() : ctx.newObject();
17
18
  const handle = preMarshal(target, raw) ?? raw;
18
19
 
19
20
  // prototype
@@ -24,7 +25,7 @@ export default function marshalObject(
24
25
  : undefined;
25
26
  if (prototypeHandle) {
26
27
  call(
27
- vm,
28
+ ctx,
28
29
  "Object.setPrototypeOf",
29
30
  undefined,
30
31
  handle,
@@ -32,7 +33,7 @@ export default function marshalObject(
32
33
  ).dispose();
33
34
  }
34
35
 
35
- marshalProperties(vm, target, raw, marshal);
36
+ marshalProperties(ctx, target, raw, marshal);
36
37
 
37
38
  return handle;
38
39
  }
@@ -1,34 +1,40 @@
1
1
  import { getQuickJS } from "quickjs-emscripten";
2
+ import { expect, test } from "vitest";
3
+
2
4
  import { eq } from "../vmutil";
3
5
  import marshalPrimitive from "./primitive";
4
6
 
5
7
  test("works", async () => {
6
- const vm = (await getQuickJS()).createVm();
8
+ const ctx = (await getQuickJS()).newContext();
7
9
 
8
- expect(marshalPrimitive(vm, undefined)).toBe(vm.undefined);
9
- expect(marshalPrimitive(vm, null)).toBe(vm.null);
10
- expect(marshalPrimitive(vm, false)).toBe(vm.false);
11
- expect(marshalPrimitive(vm, true)).toBe(vm.true);
12
- expect(eq(vm, marshalPrimitive(vm, 1) ?? vm.undefined, vm.newNumber(1))).toBe(
13
- true
14
- );
10
+ expect(marshalPrimitive(ctx, undefined)).toBe(ctx.undefined);
11
+ expect(marshalPrimitive(ctx, null)).toBe(ctx.null);
12
+ expect(marshalPrimitive(ctx, false)).toBe(ctx.false);
13
+ expect(marshalPrimitive(ctx, true)).toBe(ctx.true);
14
+ expect(
15
+ eq(ctx, marshalPrimitive(ctx, 1) ?? ctx.undefined, ctx.newNumber(1))
16
+ ).toBe(true);
15
17
  expect(
16
- eq(vm, marshalPrimitive(vm, -100) ?? vm.undefined, vm.newNumber(-100))
18
+ eq(ctx, marshalPrimitive(ctx, -100) ?? ctx.undefined, ctx.newNumber(-100))
17
19
  ).toBe(true);
18
20
  expect(
19
- eq(vm, marshalPrimitive(vm, "hoge") ?? vm.undefined, vm.newString("hoge"))
21
+ eq(
22
+ ctx,
23
+ marshalPrimitive(ctx, "hoge") ?? ctx.undefined,
24
+ ctx.newString("hoge")
25
+ )
20
26
  ).toBe(true);
21
27
  // expect(
22
28
  // eq(
23
- // vm,
24
- // marshalPrimitive(vm, BigInt(1)) ?? vm.undefined,
25
- // vm.unwrapResult(vm.evalCode("BigInt(1)"))
29
+ // ctx,
30
+ // marshalPrimitive(ctx, BigInt(1)) ?? ctx.undefined,
31
+ // ctx.unwrapResult(ctx.evalCode("BigInt(1)"))
26
32
  // )
27
33
  // ).toBe(true);
28
34
 
29
- expect(marshalPrimitive(vm, () => {})).toBe(undefined);
30
- expect(marshalPrimitive(vm, [])).toBe(undefined);
31
- expect(marshalPrimitive(vm, {})).toBe(undefined);
35
+ expect(marshalPrimitive(ctx, () => {})).toBe(undefined);
36
+ expect(marshalPrimitive(ctx, [])).toBe(undefined);
37
+ expect(marshalPrimitive(ctx, {})).toBe(undefined);
32
38
 
33
- vm.dispose();
39
+ ctx.dispose();
34
40
  });
@@ -1,29 +1,30 @@
1
- import { QuickJSVm, QuickJSHandle } from "quickjs-emscripten";
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+
2
3
  // import { call } from "../vmutil";
3
4
 
4
5
  export default function marshalPrimitive(
5
- vm: QuickJSVm,
6
+ ctx: QuickJSContext,
6
7
  target: unknown
7
8
  ): QuickJSHandle | undefined {
8
9
  switch (typeof target) {
9
10
  case "undefined":
10
- return vm.undefined;
11
+ return ctx.undefined;
11
12
  case "number":
12
- return vm.newNumber(target);
13
+ return ctx.newNumber(target);
13
14
  case "string":
14
- return vm.newString(target);
15
+ return ctx.newString(target);
15
16
  case "boolean":
16
- return target ? vm.true : vm.false;
17
+ return target ? ctx.true : ctx.false;
17
18
  case "object":
18
- return target === null ? vm.null : undefined;
19
+ return target === null ? ctx.null : undefined;
19
20
 
20
21
  // BigInt is not supported by quickjs-emscripten
21
22
  // case "bigint":
22
23
  // return call(
23
- // vm,
24
+ // ctx,
24
25
  // `s => BigInt(s)`,
25
26
  // undefined,
26
- // vm.newString(target.toString())
27
+ // ctx.newString(target.toString())
27
28
  // );
28
29
  }
29
30
 
@@ -0,0 +1,86 @@
1
+ import {
2
+ getQuickJS,
3
+ type Disposable,
4
+ type QuickJSDeferredPromise,
5
+ type QuickJSHandle,
6
+ } from "quickjs-emscripten";
7
+ import { expect, test, vi } from "vitest";
8
+
9
+ import marshalPromise from "./promise";
10
+ import { newDeferred } from "../util";
11
+ import { fn, json } from "../vmutil";
12
+
13
+ const testPromise = (reject: boolean) => async () => {
14
+ const ctx = (await getQuickJS()).newContext();
15
+
16
+ const disposables: Disposable[] = [];
17
+ const marshal = vi.fn((v) => {
18
+ const handle = json(ctx, v);
19
+ disposables.push(handle);
20
+ return handle;
21
+ });
22
+ const preMarshal = vi.fn(
23
+ (_: any, a: QuickJSDeferredPromise): QuickJSHandle => {
24
+ disposables.push(a);
25
+ return a.handle;
26
+ }
27
+ );
28
+
29
+ const mockNotify = vi.fn();
30
+ const notify = ctx.newFunction("notify", (handle1, handle2) => {
31
+ const arg1 = ctx.dump(handle1);
32
+ const arg2 = ctx.dump(handle2);
33
+ mockNotify(arg1, arg2);
34
+ });
35
+ disposables.push(notify);
36
+
37
+ const notifier = fn(
38
+ ctx,
39
+ `(notify, promise) => { promise.then(d => notify("resolved", d), d => notify("rejected", d)); }`
40
+ );
41
+ disposables.push(notifier);
42
+
43
+ const deferred = newDeferred();
44
+ if (reject) {
45
+ deferred.promise.catch(() => {});
46
+ }
47
+ const handle = marshalPromise(ctx, deferred.promise, marshal, preMarshal);
48
+ if (!handle) throw new Error("handle is undefined");
49
+
50
+ expect(marshal).toBeCalledTimes(0);
51
+ expect(preMarshal).toBeCalledTimes(1);
52
+ expect(preMarshal.mock.calls[0][0]).toBe(deferred.promise);
53
+ expect(preMarshal.mock.calls[0][1].handle).toBe(handle);
54
+
55
+ notifier(undefined, notify, handle);
56
+
57
+ expect(mockNotify).toBeCalledTimes(0);
58
+ expect(deferred.resolve).not.toBeUndefined();
59
+ expect(ctx.runtime.hasPendingJob()).toBe(false);
60
+
61
+ if (reject) {
62
+ deferred.reject("hoge");
63
+ } else {
64
+ deferred.resolve("hoge");
65
+ }
66
+
67
+ expect(ctx.runtime.hasPendingJob()).toBe(false);
68
+ if (reject) {
69
+ await expect(deferred.promise).rejects.toBe("hoge");
70
+ } else {
71
+ await expect(deferred.promise).resolves.toBe("hoge");
72
+ }
73
+ expect(ctx.runtime.hasPendingJob()).toBe(true);
74
+ const executed = ctx.unwrapResult(ctx.runtime.executePendingJobs());
75
+ expect(executed).toBe(1);
76
+ expect(mockNotify).toBeCalledTimes(1);
77
+ expect(mockNotify).toBeCalledWith(reject ? "rejected" : "resolved", "hoge");
78
+ expect(marshal).toBeCalledTimes(1);
79
+ expect(marshal.mock.calls).toEqual([["hoge"]]);
80
+
81
+ disposables.forEach((h) => h.dispose());
82
+ ctx.dispose();
83
+ };
84
+
85
+ test("resolve", testPromise(false));
86
+ test("reject", testPromise(true));
@@ -0,0 +1,26 @@
1
+ import type {
2
+ QuickJSDeferredPromise,
3
+ QuickJSHandle,
4
+ QuickJSContext,
5
+ } from "quickjs-emscripten";
6
+
7
+ export default function marshalPromise(
8
+ ctx: QuickJSContext,
9
+ target: unknown,
10
+ marshal: (target: unknown) => QuickJSHandle,
11
+ preMarshal: (
12
+ target: unknown,
13
+ handle: QuickJSDeferredPromise
14
+ ) => QuickJSHandle | undefined
15
+ ) {
16
+ if (!(target instanceof Promise)) return;
17
+
18
+ const promise = ctx.newPromise();
19
+
20
+ target.then(
21
+ (d) => promise.resolve(marshal(d)),
22
+ (d) => promise.reject(marshal(d))
23
+ );
24
+
25
+ return preMarshal(target, promise) ?? promise.handle;
26
+ }
@@ -1,11 +1,13 @@
1
1
  import { getQuickJS, QuickJSHandle } from "quickjs-emscripten";
2
- import { send } from "../vmutil";
2
+ import { expect, test, vi } from "vitest";
3
+
4
+ import { json } from "../vmutil";
3
5
  import marshalProperties from "./properties";
4
6
 
5
7
  test("works", async () => {
6
- const vm = (await getQuickJS()).createVm();
7
- const descTester = vm.unwrapResult(
8
- vm.evalCode(`(obj, expected) => {
8
+ const ctx = (await getQuickJS()).newContext();
9
+ const descTester = ctx.unwrapResult(
10
+ ctx.evalCode(`(obj, expected) => {
9
11
  const descs = Object.getOwnPropertyDescriptors(obj);
10
12
  for (const [k, v] of Object.entries(expected)) {
11
13
  const d = descs[k];
@@ -20,14 +22,14 @@ test("works", async () => {
20
22
  );
21
23
 
22
24
  const disposables: QuickJSHandle[] = [];
23
- const marshal = jest.fn(t => {
24
- if (typeof t !== "function") return send(vm, t);
25
- const fn = vm.newFunction("", () => {});
25
+ const marshal = vi.fn((t) => {
26
+ if (typeof t !== "function") return json(ctx, t);
27
+ const fn = ctx.newFunction("", () => {});
26
28
  disposables.push(fn);
27
29
  return fn;
28
30
  });
29
31
 
30
- const handle = vm.newObject();
32
+ const handle = ctx.newObject();
31
33
  const obj = {};
32
34
  const bar = () => {};
33
35
  const fooGet = () => {};
@@ -47,7 +49,7 @@ test("works", async () => {
47
49
  },
48
50
  });
49
51
 
50
- marshalProperties(vm, obj, handle, marshal);
52
+ marshalProperties(ctx, obj, handle, marshal);
51
53
  expect(marshal.mock.calls).toEqual([
52
54
  ["bar"],
53
55
  [bar],
@@ -56,30 +58,32 @@ test("works", async () => {
56
58
  [fooSet],
57
59
  ]);
58
60
 
59
- const expected = vm.unwrapResult(
60
- vm.evalCode(`({
61
+ const expected = ctx.unwrapResult(
62
+ ctx.evalCode(`({
61
63
  bar: { valueType: "function", getType: "undefined", setType: "undefined", enumerable: true, configurable: true, writable: true },
62
64
  foo: { valueType: "undefined", getType: "function", setType: "function", enumerable: false, configurable: true }
63
65
  })`)
64
66
  );
65
- vm.unwrapResult(vm.callFunction(descTester, vm.undefined, handle, expected));
67
+ ctx.unwrapResult(
68
+ ctx.callFunction(descTester, ctx.undefined, handle, expected)
69
+ );
66
70
 
67
71
  expected.dispose();
68
- disposables.forEach(d => d.dispose());
72
+ disposables.forEach((d) => d.dispose());
69
73
  handle.dispose();
70
74
  descTester.dispose();
71
- vm.dispose();
75
+ ctx.dispose();
72
76
  });
73
77
 
74
78
  test("empty", async () => {
75
- const vm = (await getQuickJS()).createVm();
76
- const marshal = jest.fn();
77
- const handle = vm.newObject();
79
+ const ctx = (await getQuickJS()).newContext();
80
+ const marshal = vi.fn();
81
+ const handle = ctx.newObject();
78
82
  const obj = {};
79
83
 
80
- marshalProperties(vm, obj, handle, marshal);
84
+ marshalProperties(ctx, obj, handle, marshal);
81
85
  expect(marshal).toHaveBeenCalledTimes(0);
82
86
 
83
87
  handle.dispose();
84
- vm.dispose();
88
+ ctx.dispose();
85
89
  });
@@ -1,13 +1,14 @@
1
- import { QuickJSVm, QuickJSHandle } from "quickjs-emscripten";
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+
2
3
  import { call } from "../vmutil";
3
4
 
4
5
  export default function marshalProperties(
5
- vm: QuickJSVm,
6
+ ctx: QuickJSContext,
6
7
  target: object | Function,
7
8
  handle: QuickJSHandle,
8
9
  marshal: (target: unknown) => QuickJSHandle
9
10
  ): void {
10
- const descs = vm.newObject();
11
+ const descs = ctx.newObject();
11
12
  const cb = (key: string | number | symbol, desc: PropertyDescriptor) => {
12
13
  const keyHandle = marshal(key);
13
14
  const valueHandle =
@@ -17,7 +18,7 @@ export default function marshalProperties(
17
18
  const setHandle =
18
19
  typeof desc.set === "undefined" ? undefined : marshal(desc.set);
19
20
 
20
- vm.newObject().consume(descObj => {
21
+ ctx.newObject().consume((descObj) => {
21
22
  Object.entries(desc).forEach(([k, v]) => {
22
23
  const v2 =
23
24
  k === "value"
@@ -27,21 +28,21 @@ export default function marshalProperties(
27
28
  : k === "set"
28
29
  ? setHandle
29
30
  : v
30
- ? vm.true
31
- : vm.false;
31
+ ? ctx.true
32
+ : ctx.false;
32
33
  if (v2) {
33
- vm.setProp(descObj, k, v2);
34
+ ctx.setProp(descObj, k, v2);
34
35
  }
35
36
  });
36
- vm.setProp(descs, keyHandle, descObj);
37
+ ctx.setProp(descs, keyHandle, descObj);
37
38
  });
38
39
  };
39
40
 
40
41
  const desc = Object.getOwnPropertyDescriptors(target);
41
42
  Object.entries(desc).forEach(([k, v]) => cb(k, v));
42
- Object.getOwnPropertySymbols(desc).forEach(k => cb(k, (desc as any)[k]));
43
+ Object.getOwnPropertySymbols(desc).forEach((k) => cb(k, (desc as any)[k]));
43
44
 
44
- call(vm, `Object.defineProperties`, undefined, handle, descs).dispose();
45
+ call(ctx, `Object.defineProperties`, undefined, handle, descs).dispose();
45
46
 
46
47
  descs.dispose();
47
48
  }
@@ -1,22 +1,24 @@
1
1
  import { getQuickJS } from "quickjs-emscripten";
2
+ import { expect, test, vi } from "vitest";
3
+
2
4
  import marshalSymbol from "./symbol";
3
5
 
4
6
  test("works", async () => {
5
- const vm = (await getQuickJS()).createVm();
6
- const pre = jest.fn();
7
+ const ctx = (await getQuickJS()).newContext();
8
+ const pre = vi.fn();
7
9
  const sym = Symbol("foobar");
8
10
 
9
- expect(marshalSymbol(vm, {}, pre)).toBe(undefined);
11
+ expect(marshalSymbol(ctx, {}, pre)).toBe(undefined);
10
12
  expect(pre).toBeCalledTimes(0);
11
13
 
12
- const handle = marshalSymbol(vm, sym, pre);
14
+ const handle = marshalSymbol(ctx, sym, pre);
13
15
  if (!handle) throw new Error("handle is undefined");
14
- expect(vm.typeof(handle)).toBe("symbol");
15
- expect(vm.getString(vm.getProp(handle, "description"))).toBe("foobar");
16
+ expect(ctx.typeof(handle)).toBe("symbol");
17
+ expect(ctx.getString(ctx.getProp(handle, "description"))).toBe("foobar");
16
18
  expect(pre).toReturnTimes(1);
17
19
  expect(pre.mock.calls[0][0]).toBe(sym);
18
20
  expect(pre.mock.calls[0][1] === handle).toBe(true);
19
21
 
20
22
  handle.dispose();
21
- vm.dispose();
23
+ ctx.dispose();
22
24
  });
@@ -1,8 +1,9 @@
1
- import { QuickJSVm, QuickJSHandle } from "quickjs-emscripten";
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+
2
3
  import { call } from "../vmutil";
3
4
 
4
5
  export default function marshalSymbol(
5
- vm: QuickJSVm,
6
+ ctx: QuickJSContext,
6
7
  target: unknown,
7
8
  preMarshal: (
8
9
  target: unknown,
@@ -11,10 +12,10 @@ export default function marshalSymbol(
11
12
  ): QuickJSHandle | undefined {
12
13
  if (typeof target !== "symbol") return;
13
14
  const handle = call(
14
- vm,
15
+ ctx,
15
16
  "d => Symbol(d)",
16
17
  undefined,
17
- target.description ? vm.newString(target.description) : vm.undefined
18
+ target.description ? ctx.newString(target.description) : ctx.undefined
18
19
  );
19
20
  return preMarshal(target, handle) ?? handle;
20
21
  }