quickjs-emscripten-sync 1.4.0 → 1.5.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 (50) hide show
  1. package/README.md +28 -7
  2. package/dist/index.d.ts +12 -7
  3. package/dist/quickjs-emscripten-sync.mjs +842 -0
  4. package/dist/quickjs-emscripten-sync.umd.js +15 -15
  5. package/package.json +9 -18
  6. package/src/default.ts +2 -2
  7. package/src/index.test.ts +21 -13
  8. package/src/index.ts +30 -43
  9. package/src/marshal/custom.test.ts +50 -0
  10. package/src/marshal/custom.ts +36 -0
  11. package/src/marshal/function.test.ts +17 -37
  12. package/src/marshal/function.ts +8 -12
  13. package/src/marshal/index.test.ts +35 -39
  14. package/src/marshal/index.ts +6 -9
  15. package/src/marshal/json.test.ts +9 -15
  16. package/src/marshal/json.ts +1 -4
  17. package/src/marshal/object.test.ts +19 -51
  18. package/src/marshal/object.ts +3 -11
  19. package/src/marshal/primitive.test.ts +4 -13
  20. package/src/marshal/primitive.ts +1 -1
  21. package/src/marshal/promise.test.ts +9 -10
  22. package/src/marshal/promise.ts +4 -11
  23. package/src/marshal/properties.test.ts +7 -14
  24. package/src/marshal/properties.ts +6 -9
  25. package/src/unmarshal/custom.test.ts +50 -0
  26. package/src/unmarshal/custom.ts +31 -0
  27. package/src/unmarshal/function.test.ts +20 -44
  28. package/src/unmarshal/function.ts +7 -17
  29. package/src/unmarshal/index.test.ts +30 -23
  30. package/src/unmarshal/index.ts +4 -6
  31. package/src/unmarshal/object.test.ts +9 -17
  32. package/src/unmarshal/object.ts +7 -12
  33. package/src/unmarshal/primitive.test.ts +1 -4
  34. package/src/unmarshal/primitive.ts +3 -10
  35. package/src/unmarshal/promise.test.ts +3 -3
  36. package/src/unmarshal/promise.ts +3 -10
  37. package/src/unmarshal/properties.test.ts +2 -2
  38. package/src/unmarshal/properties.ts +4 -8
  39. package/src/util.test.ts +1 -7
  40. package/src/util.ts +3 -8
  41. package/src/vmmap.ts +13 -31
  42. package/src/vmutil.test.ts +15 -29
  43. package/src/vmutil.ts +12 -39
  44. package/src/wrapper.test.ts +27 -90
  45. package/src/wrapper.ts +43 -50
  46. package/dist/quickjs-emscripten-sync.es.js +0 -962
  47. package/src/marshal/symbol.test.ts +0 -24
  48. package/src/marshal/symbol.ts +0 -21
  49. package/src/unmarshal/symbol.test.ts +0 -25
  50. package/src/unmarshal/symbol.ts +0 -12
@@ -1,16 +1,15 @@
1
1
  import { getQuickJS, QuickJSHandle } from "quickjs-emscripten";
2
+ import { expect, test, vi } from "vitest";
2
3
 
3
4
  import { json, eq, call } from "../vmutil";
5
+
4
6
  import marshalFunction from "./function";
5
- import { expect, test, vi } from "vitest";
6
7
 
7
8
  test("normal func", async () => {
8
9
  const ctx = (await getQuickJS()).newContext();
9
10
 
10
- const marshal = vi.fn((v) => json(ctx, v));
11
- const unmarshal = vi.fn((v) =>
12
- eq(ctx, v, ctx.global) ? undefined : ctx.dump(v)
13
- );
11
+ const marshal = vi.fn(v => json(ctx, v));
12
+ const unmarshal = vi.fn(v => (eq(ctx, v, ctx.global) ? undefined : ctx.dump(v)));
14
13
  const preMarshal = vi.fn((_, a) => a);
15
14
  const innerfn = vi.fn((..._args: any[]) => "hoge");
16
15
  const fn = (...args: any[]) => innerfn(...args);
@@ -25,7 +24,7 @@ test("normal func", async () => {
25
24
  expect(ctx.dump(ctx.getProp(handle, "name"))).toBe("fn");
26
25
 
27
26
  const result = ctx.unwrapResult(
28
- ctx.callFunction(handle, ctx.undefined, ctx.newNumber(1), ctx.true)
27
+ ctx.callFunction(handle, ctx.undefined, ctx.newNumber(1), ctx.true),
29
28
  );
30
29
 
31
30
  expect(ctx.dump(result)).toBe("hoge");
@@ -42,7 +41,7 @@ test("normal func", async () => {
42
41
 
43
42
  test("func which has properties", async () => {
44
43
  const ctx = (await getQuickJS()).newContext();
45
- const marshal = vi.fn((v) => json(ctx, v));
44
+ const marshal = vi.fn(v => json(ctx, v));
46
45
 
47
46
  const fn = () => {};
48
47
  fn.hoge = "foo";
@@ -51,8 +50,8 @@ test("func which has properties", async () => {
51
50
  ctx,
52
51
  fn,
53
52
  marshal,
54
- (v) => ctx.dump(v),
55
- (_, a) => a
53
+ v => ctx.dump(v),
54
+ (_, a) => a,
56
55
  );
57
56
  if (!handle) throw new Error("handle is undefined");
58
57
 
@@ -92,20 +91,16 @@ test("class", async () => {
92
91
  if (!handle) throw new Error("handle is undefined");
93
92
 
94
93
  const newA = ctx.unwrapResult(ctx.evalCode(`A => new A(100)`));
95
- const instance = ctx.unwrapResult(
96
- ctx.callFunction(newA, ctx.undefined, handle)
97
- );
94
+ const instance = ctx.unwrapResult(ctx.callFunction(newA, ctx.undefined, handle));
98
95
 
99
96
  expect(ctx.dump(ctx.getProp(handle, "name"))).toBe("A");
100
97
  expect(ctx.dump(ctx.getProp(handle, "length"))).toBe(1);
101
- expect(
102
- ctx.dump(
103
- call(ctx, "(cls, i) => i instanceof cls", undefined, handle, instance)
104
- )
105
- ).toBe(true);
98
+ expect(ctx.dump(call(ctx, "(cls, i) => i instanceof cls", undefined, handle, instance))).toBe(
99
+ true,
100
+ );
106
101
  expect(ctx.dump(ctx.getProp(instance, "a"))).toBe(100);
107
102
 
108
- disposables.forEach((d) => d.dispose());
103
+ disposables.forEach(d => d.dispose());
109
104
  instance.dispose();
110
105
  newA.dispose();
111
106
  handle.dispose();
@@ -120,34 +115,19 @@ test("preApply", async () => {
120
115
  if (typeof v === "number") return ctx.newNumber(v);
121
116
  return ctx.null;
122
117
  };
123
- const unmarshal = (v: QuickJSHandle) =>
124
- ctx.typeof(v) === "object" ? that : ctx.dump(v);
125
- const preApply = vi.fn(
126
- (a: Function, b: any, c: any[]) => a.apply(b, c) + "!"
127
- );
118
+ const unmarshal = (v: QuickJSHandle) => (ctx.typeof(v) === "object" ? that : ctx.dump(v));
119
+ const preApply = vi.fn((a: Function, b: any, c: any[]) => a.apply(b, c) + "!");
128
120
  const that = {};
129
121
  const thatHandle = ctx.newObject();
130
122
 
131
123
  const fn = () => "foo";
132
- const handle = marshalFunction(
133
- ctx,
134
- fn,
135
- marshal,
136
- unmarshal,
137
- (_, a) => a,
138
- preApply
139
- );
124
+ const handle = marshalFunction(ctx, fn, marshal, unmarshal, (_, a) => a, preApply);
140
125
  if (!handle) throw new Error("handle is undefined");
141
126
 
142
127
  expect(preApply).toBeCalledTimes(0);
143
128
 
144
129
  const res = ctx.unwrapResult(
145
- ctx.callFunction(
146
- handle,
147
- thatHandle,
148
- ctx.newNumber(100),
149
- ctx.newString("hoge")
150
- )
130
+ ctx.callFunction(handle, thatHandle, ctx.newNumber(100), ctx.newString("hoge")),
151
131
  );
152
132
 
153
133
  expect(preApply).toBeCalledTimes(1);
@@ -2,6 +2,7 @@ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
2
 
3
3
  import { isES2015Class, isObject } from "../util";
4
4
  import { call } from "../vmutil";
5
+
5
6
  import marshalProperties from "./properties";
6
7
 
7
8
  export default function marshalFunction(
@@ -9,18 +10,15 @@ export default function marshalFunction(
9
10
  target: unknown,
10
11
  marshal: (target: unknown) => QuickJSHandle,
11
12
  unmarshal: (handle: QuickJSHandle) => unknown,
12
- preMarshal: (
13
- target: unknown,
14
- handle: QuickJSHandle
15
- ) => QuickJSHandle | undefined,
16
- preApply?: (target: Function, thisArg: unknown, args: unknown[]) => any
13
+ preMarshal: (target: unknown, handle: QuickJSHandle) => QuickJSHandle | undefined,
14
+ preApply?: (target: Function, thisArg: unknown, args: unknown[]) => any,
17
15
  ): QuickJSHandle | undefined {
18
16
  if (typeof target !== "function") return;
19
17
 
20
18
  const raw = ctx
21
19
  .newFunction(target.name, function (...argHandles) {
22
20
  const that = unmarshal(this);
23
- const args = argHandles.map((a) => unmarshal(a));
21
+ const args = argHandles.map(a => unmarshal(a));
24
22
 
25
23
  if (isES2015Class(target) && isObject(that)) {
26
24
  // Class constructors cannot be invoked without new expression, and new.target is not changed
@@ -31,11 +29,9 @@ export default function marshalFunction(
31
29
  return this;
32
30
  }
33
31
 
34
- return marshal(
35
- preApply ? preApply(target, that, args) : target.apply(that, args)
36
- );
32
+ return marshal(preApply ? preApply(target, that, args) : target.apply(that, args));
37
33
  })
38
- .consume((handle2) =>
34
+ .consume(handle2 =>
39
35
  // fucntions created by vm.newFunction are not callable as a class constrcutor
40
36
  call(
41
37
  ctx,
@@ -46,8 +42,8 @@ export default function marshalFunction(
46
42
  return fn;
47
43
  }`,
48
44
  undefined,
49
- handle2
50
- )
45
+ handle2,
46
+ ),
51
47
  );
52
48
 
53
49
  const handle = preMarshal(target, raw) ?? raw;
@@ -1,10 +1,11 @@
1
1
  import { getQuickJS } from "quickjs-emscripten";
2
2
  import { expect, test, vi } from "vitest";
3
3
 
4
+ import { newDeferred } from "../util";
4
5
  import VMMap from "../vmmap";
5
6
  import { instanceOf, call, handleFrom, fn } from "../vmutil";
7
+
6
8
  import marshal from ".";
7
- import { newDeferred } from "../util";
8
9
 
9
10
  test("primitive, array, object", async () => {
10
11
  const { ctx, map, marshal, dispose } = await setup();
@@ -36,11 +37,9 @@ test("object with symbol key", async () => {
36
37
  };
37
38
  const handle = marshal(target);
38
39
  expect(ctx.dump(call(ctx, `a => a.foo`, undefined, handle))).toBe("hoge");
39
- expect(
40
- ctx.dump(
41
- call(ctx, `a => a[Object.getOwnPropertySymbols(a)[0]]`, undefined, handle)
42
- )
43
- ).toBe(1);
40
+ expect(ctx.dump(call(ctx, `a => a[Object.getOwnPropertySymbols(a)[0]]`, undefined, handle))).toBe(
41
+ 1,
42
+ );
44
43
 
45
44
  dispose();
46
45
  });
@@ -56,9 +55,7 @@ test("arrow function", async () => {
56
55
  expect(ctx.dump(ctx.getProp(handle, "name"))).toBe("hoge");
57
56
  const foo = ctx.getProp(handle, "foo");
58
57
  expect(ctx.dump(foo)).toEqual({ bar: 1 });
59
- expect(
60
- ctx.dump(ctx.unwrapResult(ctx.callFunction(handle, ctx.undefined)))
61
- ).toBe("foo");
58
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(handle, ctx.undefined)))).toBe("foo");
62
59
  expect(map.size).toBe(2);
63
60
  expect(map.get(hoge)).toBe(handle);
64
61
  expect(map.has(hoge.foo)).toBe(true);
@@ -84,11 +81,7 @@ test("function", async () => {
84
81
 
85
82
  const b = ctx.unwrapResult(ctx.evalCode(`({ hoge: 2 })`));
86
83
  expect(
87
- ctx.dump(
88
- ctx.unwrapResult(
89
- ctx.callFunction(handle, ctx.undefined, ctx.newNumber(1), b)
90
- )
91
- )
84
+ ctx.dump(ctx.unwrapResult(ctx.callFunction(handle, ctx.undefined, ctx.newNumber(1), b))),
92
85
  ).toBe(3);
93
86
 
94
87
  b.dispose();
@@ -99,15 +92,15 @@ test("promise", async () => {
99
92
  const { ctx, marshal, dispose } = await setup();
100
93
  const register = fn(
101
94
  ctx,
102
- `promise => { promise.then(d => notify("resolve", d), d => notify("reject", d)); }`
95
+ `promise => { promise.then(d => notify("resolve", d), d => notify("reject", d)); }`,
103
96
  );
104
97
 
105
98
  let notified: any;
106
99
  ctx
107
100
  .newFunction("notify", (...handles) => {
108
- notified = handles.map((h) => ctx.dump(h));
101
+ notified = handles.map(h => ctx.dump(h));
109
102
  })
110
- .consume((h) => {
103
+ .consume(h => {
111
104
  ctx.setProp(ctx.global, "notify", h);
112
105
  });
113
106
 
@@ -169,12 +162,8 @@ test("class", async () => {
169
162
  expect(map.has(A.prototype)).toBe(true);
170
163
  expect(map.has(A.a)).toBe(true);
171
164
  expect(map.has(A.prototype.hoge)).toBe(true);
172
- expect(
173
- map.has(Object.getOwnPropertyDescriptor(A.prototype, "foo")?.get)
174
- ).toBe(true);
175
- expect(
176
- map.has(Object.getOwnPropertyDescriptor(A.prototype, "foo")?.set)
177
- ).toBe(true);
165
+ expect(map.has(Object.getOwnPropertyDescriptor(A.prototype, "foo")?.get)).toBe(true);
166
+ expect(map.has(Object.getOwnPropertyDescriptor(A.prototype, "foo")?.set)).toBe(true);
178
167
 
179
168
  expect(ctx.typeof(handle)).toBe("function");
180
169
  expect(ctx.dump(ctx.getProp(handle, "length"))).toBe(1);
@@ -185,28 +174,20 @@ test("class", async () => {
185
174
  expect(ctx.dump(ctx.getProp(staticA, "b"))).toBe("a!");
186
175
 
187
176
  const newA = ctx.unwrapResult(ctx.evalCode(`A => new A("foo")`));
188
- const instance = ctx.unwrapResult(
189
- ctx.callFunction(newA, ctx.undefined, handle)
190
- );
177
+ const instance = ctx.unwrapResult(ctx.callFunction(newA, ctx.undefined, handle));
191
178
  expect(instanceOf(ctx, instance, handle)).toBe(true);
192
179
  expect(ctx.dump(ctx.getProp(instance, "a"))).toBe(100);
193
180
  expect(ctx.dump(ctx.getProp(instance, "b"))).toBe("foo!");
194
181
  const methodHoge = ctx.getProp(instance, "hoge");
195
- expect(
196
- ctx.dump(ctx.unwrapResult(ctx.callFunction(methodHoge, instance)))
197
- ).toBe(101);
182
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(methodHoge, instance)))).toBe(101);
198
183
  expect(ctx.dump(ctx.getProp(instance, "a"))).toBe(100); // not synced
199
184
 
200
185
  const getter = ctx.unwrapResult(ctx.evalCode(`a => a.foo`));
201
186
  const setter = ctx.unwrapResult(ctx.evalCode(`(a, b) => a.foo = b`));
202
- expect(
203
- ctx.dump(
204
- ctx.unwrapResult(ctx.callFunction(getter, ctx.undefined, instance))
205
- )
206
- ).toBe("foo!");
207
- ctx.unwrapResult(
208
- ctx.callFunction(setter, ctx.undefined, instance, ctx.newString("b"))
187
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(getter, ctx.undefined, instance)))).toBe(
188
+ "foo!",
209
189
  );
190
+ ctx.unwrapResult(ctx.callFunction(setter, ctx.undefined, instance, ctx.newString("b")));
210
191
  expect(ctx.dump(ctx.getProp(instance, "b"))).toBe("foo!"); // not synced
211
192
 
212
193
  staticA.dispose();
@@ -215,7 +196,22 @@ test("class", async () => {
215
196
  methodHoge.dispose();
216
197
  getter.dispose();
217
198
  setter.dispose();
218
- map.dispose();
199
+ dispose();
200
+ });
201
+
202
+ test("date", async () => {
203
+ const { ctx, map, marshal, dispose } = await setup();
204
+
205
+ const date = new Date(2022, 7, 26);
206
+ const handle = marshal(date);
207
+ if (!map) throw new Error("map is undefined");
208
+
209
+ expect(map.size).toBe(1);
210
+ expect(map.get(date)).toBe(handle);
211
+
212
+ expect(ctx.dump(call(ctx, "d => d instanceof Date", undefined, handle))).toBe(true);
213
+ expect(ctx.dump(call(ctx, "d => d.getTime()", undefined, handle))).toBe(date.getTime());
214
+
219
215
  dispose();
220
216
  });
221
217
 
@@ -271,14 +267,14 @@ const setup = async ({
271
267
  marshal: (v: any) =>
272
268
  marshal(v, {
273
269
  ctx: ctx,
274
- unmarshal: (h) => map.getByHandle(h) ?? ctx.dump(h),
270
+ unmarshal: h => map.getByHandle(h) ?? ctx.dump(h),
275
271
  isMarshalable,
276
272
  pre: (t, d) => {
277
273
  const h = handleFrom(d);
278
274
  map.set(t, h);
279
275
  return h;
280
276
  },
281
- find: (t) => map.get(t),
277
+ find: t => map.get(t),
282
278
  }),
283
279
  dispose: () => {
284
280
  map.dispose();
@@ -1,14 +1,10 @@
1
- import type {
2
- QuickJSDeferredPromise,
3
- QuickJSHandle,
4
- QuickJSContext,
5
- } from "quickjs-emscripten";
1
+ import type { QuickJSDeferredPromise, QuickJSHandle, QuickJSContext } from "quickjs-emscripten";
6
2
 
3
+ import marshalCustom, { defaultCustom } from "./custom";
7
4
  import marshalFunction from "./function";
5
+ import marshalJSON from "./json";
8
6
  import marshalObject from "./object";
9
7
  import marshalPrimitive from "./primitive";
10
- import marshalSymbol from "./symbol";
11
- import marshalJSON from "./json";
12
8
  import marshalPromise from "./promise";
13
9
 
14
10
  export type Options = {
@@ -19,9 +15,10 @@ export type Options = {
19
15
  pre: (
20
16
  target: unknown,
21
17
  handle: QuickJSHandle | QuickJSDeferredPromise,
22
- mode: true | "json" | undefined
18
+ mode: true | "json" | undefined,
23
19
  ) => QuickJSHandle | undefined;
24
20
  preApply?: (target: Function, thisArg: unknown, args: unknown[]) => any;
21
+ custom?: Iterable<(obj: unknown, ctx: QuickJSContext) => QuickJSHandle | undefined>;
25
22
  };
26
23
 
27
24
  export function marshal(target: unknown, options: Options): QuickJSHandle {
@@ -52,7 +49,7 @@ export function marshal(target: unknown, options: Options): QuickJSHandle {
52
49
 
53
50
  const marshal2 = (t: unknown) => marshal(t, options);
54
51
  return (
55
- marshalSymbol(ctx, target, pre2) ??
52
+ marshalCustom(ctx, target, pre2, [...defaultCustom, ...(options.custom ?? [])]) ??
56
53
  marshalPromise(ctx, target, marshal2, pre2) ??
57
54
  marshalFunction(ctx, target, marshal2, unmarshal, pre2, options.preApply) ??
58
55
  marshalObject(ctx, target, marshal2, pre2) ??
@@ -6,7 +6,7 @@ import marshalJSON from "./json";
6
6
  test("empty object", async () => {
7
7
  const ctx = (await getQuickJS()).newContext();
8
8
  const prototypeCheck = ctx.unwrapResult(
9
- ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
9
+ ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`),
10
10
  );
11
11
 
12
12
  const obj = {};
@@ -19,11 +19,9 @@ test("empty object", async () => {
19
19
  expect(preMarshal).toBeCalledTimes(1);
20
20
  expect(preMarshal.mock.calls[0][0]).toBe(obj);
21
21
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
22
- expect(
23
- ctx.dump(
24
- ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle))
25
- )
26
- ).toBe(true);
22
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle)))).toBe(
23
+ true,
24
+ );
27
25
 
28
26
  handle.dispose();
29
27
  prototypeCheck.dispose();
@@ -33,7 +31,7 @@ test("empty object", async () => {
33
31
  test("normal object", async () => {
34
32
  const ctx = (await getQuickJS()).newContext();
35
33
  const prototypeCheck = ctx.unwrapResult(
36
- ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
34
+ ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`),
37
35
  );
38
36
  const entries = ctx.unwrapResult(ctx.evalCode(`Object.entries`));
39
37
 
@@ -49,11 +47,9 @@ test("normal object", async () => {
49
47
  expect(preMarshal).toBeCalledTimes(1);
50
48
  expect(preMarshal.mock.calls[0][0]).toBe(obj);
51
49
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
52
- expect(
53
- ctx.dump(
54
- ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle))
55
- )
56
- ).toBe(true);
50
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle)))).toBe(
51
+ true,
52
+ );
57
53
  const e = ctx.unwrapResult(ctx.callFunction(entries, ctx.undefined, handle));
58
54
  expect(ctx.dump(e)).toEqual([
59
55
  ["a", 100],
@@ -84,9 +80,7 @@ test("array", async () => {
84
80
  expect(preMarshal).toBeCalledTimes(1);
85
81
  expect(preMarshal.mock.calls[0][0]).toBe(array);
86
82
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
87
- expect(
88
- ctx.dump(ctx.unwrapResult(ctx.callFunction(isArray, ctx.undefined, handle)))
89
- ).toBe(true);
83
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(isArray, ctx.undefined, handle)))).toBe(true);
90
84
 
91
85
  handle.dispose();
92
86
  isArray.dispose();
@@ -5,10 +5,7 @@ import { json } from "../vmutil";
5
5
  export default function marshalJSON(
6
6
  ctx: QuickJSContext,
7
7
  target: unknown,
8
- preMarshal: (
9
- target: unknown,
10
- handle: QuickJSHandle
11
- ) => QuickJSHandle | undefined
8
+ preMarshal: (target: unknown, handle: QuickJSHandle) => QuickJSHandle | undefined,
12
9
  ): QuickJSHandle {
13
10
  const raw = json(ctx, target);
14
11
  const handle = preMarshal(target, raw) ?? raw;
@@ -2,12 +2,13 @@ import { getQuickJS } from "quickjs-emscripten";
2
2
  import { expect, test, vi } from "vitest";
3
3
 
4
4
  import { call } from "../vmutil";
5
+
5
6
  import marshalObject from "./object";
6
7
 
7
8
  test("empty object", async () => {
8
9
  const ctx = (await getQuickJS()).newContext();
9
10
  const prototypeCheck = ctx.unwrapResult(
10
- ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
11
+ ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`),
11
12
  );
12
13
 
13
14
  const obj = {};
@@ -22,11 +23,9 @@ test("empty object", async () => {
22
23
  expect(preMarshal).toBeCalledTimes(1);
23
24
  expect(preMarshal.mock.calls[0][0]).toBe(obj);
24
25
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
25
- expect(
26
- ctx.dump(
27
- ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle))
28
- )
29
- ).toBe(true);
26
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle)))).toBe(
27
+ true,
28
+ );
30
29
 
31
30
  handle.dispose();
32
31
  prototypeCheck.dispose();
@@ -36,17 +35,13 @@ test("empty object", async () => {
36
35
  test("normal object", async () => {
37
36
  const ctx = (await getQuickJS()).newContext();
38
37
  const prototypeCheck = ctx.unwrapResult(
39
- ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`)
38
+ ctx.evalCode(`o => Object.getPrototypeOf(o) === Object.prototype`),
40
39
  );
41
40
  const entries = ctx.unwrapResult(ctx.evalCode(`Object.entries`));
42
41
 
43
42
  const obj = { a: 100, b: "hoge" };
44
- const marshal = vi.fn((v) =>
45
- typeof v === "number"
46
- ? ctx.newNumber(v)
47
- : typeof v === "string"
48
- ? ctx.newString(v)
49
- : ctx.null
43
+ const marshal = vi.fn(v =>
44
+ typeof v === "number" ? ctx.newNumber(v) : typeof v === "string" ? ctx.newString(v) : ctx.null,
50
45
  );
51
46
  const preMarshal = vi.fn((_, a) => a);
52
47
 
@@ -60,11 +55,9 @@ test("normal object", async () => {
60
55
  expect(preMarshal).toBeCalledTimes(1);
61
56
  expect(preMarshal.mock.calls[0][0]).toBe(obj);
62
57
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
63
- expect(
64
- ctx.dump(
65
- ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle))
66
- )
67
- ).toBe(true);
58
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(prototypeCheck, ctx.undefined, handle)))).toBe(
59
+ true,
60
+ );
68
61
  const e = ctx.unwrapResult(ctx.callFunction(entries, ctx.undefined, handle));
69
62
  expect(ctx.dump(e)).toEqual([
70
63
  ["a", 100],
@@ -83,12 +76,8 @@ test("array", async () => {
83
76
  const isArray = ctx.unwrapResult(ctx.evalCode(`Array.isArray`));
84
77
 
85
78
  const array = [1, "aa"];
86
- const marshal = vi.fn((v) =>
87
- typeof v === "number"
88
- ? ctx.newNumber(v)
89
- : typeof v === "string"
90
- ? ctx.newString(v)
91
- : ctx.null
79
+ const marshal = vi.fn(v =>
80
+ typeof v === "number" ? ctx.newNumber(v) : typeof v === "string" ? ctx.newString(v) : ctx.null,
92
81
  );
93
82
  const preMarshal = vi.fn((_, a) => a);
94
83
 
@@ -99,20 +88,11 @@ test("array", async () => {
99
88
  expect(ctx.getNumber(ctx.getProp(handle, 0))).toBe(1);
100
89
  expect(ctx.getString(ctx.getProp(handle, 1))).toBe("aa");
101
90
  expect(ctx.getNumber(ctx.getProp(handle, "length"))).toBe(2);
102
- expect(marshal.mock.calls).toEqual([
103
- ["0"],
104
- [1],
105
- ["1"],
106
- ["aa"],
107
- ["length"],
108
- [2],
109
- ]);
91
+ expect(marshal.mock.calls).toEqual([["0"], [1], ["1"], ["aa"], ["length"], [2]]);
110
92
  expect(preMarshal).toBeCalledTimes(1);
111
93
  expect(preMarshal.mock.calls[0][0]).toBe(array);
112
94
  expect(preMarshal.mock.calls[0][1] === handle).toBe(true); // avoid freeze
113
- expect(
114
- ctx.dump(ctx.unwrapResult(ctx.callFunction(isArray, ctx.undefined, handle)))
115
- ).toBe(true);
95
+ expect(ctx.dump(ctx.unwrapResult(ctx.callFunction(isArray, ctx.undefined, handle)))).toBe(true);
116
96
 
117
97
  handle.dispose();
118
98
  isArray.dispose();
@@ -132,13 +112,8 @@ test("prototype", async () => {
132
112
  const handle = marshalObject(
133
113
  ctx,
134
114
  obj,
135
- (v) =>
136
- v === proto
137
- ? protoHandle
138
- : typeof v === "string"
139
- ? ctx.newString(v)
140
- : ctx.null,
141
- preMarshal
115
+ v => (v === proto ? protoHandle : typeof v === "string" ? ctx.newString(v) : ctx.null),
116
+ preMarshal,
142
117
  );
143
118
  if (!handle) throw new Error("handle is undefined");
144
119
 
@@ -150,15 +125,8 @@ test("prototype", async () => {
150
125
  expect(ctx.getString(ctx.getProp(handle, "b"))).toBe("hoge");
151
126
  const e = call(ctx, "Object.entries", undefined, handle);
152
127
  expect(ctx.dump(e)).toEqual([["b", "hoge"]]);
153
- const protoHandle2 = call(
154
- ctx,
155
- "Object.getPrototypeOf",
156
- ctx.undefined,
157
- handle
158
- );
159
- expect(
160
- ctx.dump(call(ctx, `Object.is`, undefined, protoHandle, protoHandle2))
161
- ).toBe(true);
128
+ const protoHandle2 = call(ctx, "Object.getPrototypeOf", ctx.undefined, handle);
129
+ expect(ctx.dump(call(ctx, `Object.is`, undefined, protoHandle, protoHandle2))).toBe(true);
162
130
 
163
131
  protoHandle2.dispose();
164
132
  e.dispose();
@@ -1,16 +1,14 @@
1
1
  import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
2
 
3
3
  import { call } from "../vmutil";
4
+
4
5
  import marshalProperties from "./properties";
5
6
 
6
7
  export default function marshalObject(
7
8
  ctx: QuickJSContext,
8
9
  target: unknown,
9
10
  marshal: (target: unknown) => QuickJSHandle,
10
- preMarshal: (
11
- target: unknown,
12
- handle: QuickJSHandle
13
- ) => QuickJSHandle | undefined
11
+ preMarshal: (target: unknown, handle: QuickJSHandle) => QuickJSHandle | undefined,
14
12
  ): QuickJSHandle | undefined {
15
13
  if (typeof target !== "object" || target === null) return;
16
14
 
@@ -24,13 +22,7 @@ export default function marshalObject(
24
22
  ? marshal(prototype)
25
23
  : undefined;
26
24
  if (prototypeHandle) {
27
- call(
28
- ctx,
29
- "Object.setPrototypeOf",
30
- undefined,
31
- handle,
32
- prototypeHandle
33
- ).dispose();
25
+ call(ctx, "Object.setPrototypeOf", undefined, handle, prototypeHandle).dispose();
34
26
  }
35
27
 
36
28
  marshalProperties(ctx, target, raw, marshal);
@@ -2,6 +2,7 @@ import { getQuickJS } from "quickjs-emscripten";
2
2
  import { expect, test } from "vitest";
3
3
 
4
4
  import { eq } from "../vmutil";
5
+
5
6
  import marshalPrimitive from "./primitive";
6
7
 
7
8
  test("works", async () => {
@@ -11,19 +12,9 @@ test("works", async () => {
11
12
  expect(marshalPrimitive(ctx, null)).toBe(ctx.null);
12
13
  expect(marshalPrimitive(ctx, false)).toBe(ctx.false);
13
14
  expect(marshalPrimitive(ctx, true)).toBe(ctx.true);
14
- expect(
15
- eq(ctx, marshalPrimitive(ctx, 1) ?? ctx.undefined, ctx.newNumber(1))
16
- ).toBe(true);
17
- expect(
18
- eq(ctx, marshalPrimitive(ctx, -100) ?? ctx.undefined, ctx.newNumber(-100))
19
- ).toBe(true);
20
- expect(
21
- eq(
22
- ctx,
23
- marshalPrimitive(ctx, "hoge") ?? ctx.undefined,
24
- ctx.newString("hoge")
25
- )
26
- ).toBe(true);
15
+ expect(eq(ctx, marshalPrimitive(ctx, 1) ?? ctx.undefined, ctx.newNumber(1))).toBe(true);
16
+ expect(eq(ctx, marshalPrimitive(ctx, -100) ?? ctx.undefined, ctx.newNumber(-100))).toBe(true);
17
+ expect(eq(ctx, marshalPrimitive(ctx, "hoge") ?? ctx.undefined, ctx.newString("hoge"))).toBe(true);
27
18
  // expect(
28
19
  // eq(
29
20
  // ctx,
@@ -4,7 +4,7 @@ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
4
4
 
5
5
  export default function marshalPrimitive(
6
6
  ctx: QuickJSContext,
7
- target: unknown
7
+ target: unknown,
8
8
  ): QuickJSHandle | undefined {
9
9
  switch (typeof target) {
10
10
  case "undefined":