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,16 +1,18 @@
1
1
  import { getQuickJS, QuickJSHandle } from "quickjs-emscripten";
2
+ import { expect, test, vi } from "vitest";
3
+
2
4
  import unmarshalObject from "./object";
3
5
 
4
6
  test("normal object", async () => {
5
- const vm = (await getQuickJS()).createVm();
6
- const unmarshal = jest.fn((v: QuickJSHandle): [unknown, boolean] => [
7
- vm.dump(v),
7
+ const ctx = (await getQuickJS()).newContext();
8
+ const unmarshal = vi.fn((v: QuickJSHandle): [unknown, boolean] => [
9
+ ctx.dump(v),
8
10
  false,
9
11
  ]);
10
- const preUnmarshal = jest.fn(a => a);
12
+ const preUnmarshal = vi.fn((a) => a);
11
13
 
12
- const handle = vm.unwrapResult(vm.evalCode(`({ a: 1, b: true })`));
13
- const obj = unmarshalObject(vm, handle, unmarshal, preUnmarshal);
14
+ const handle = ctx.unwrapResult(ctx.evalCode(`({ a: 1, b: true })`));
15
+ const obj = unmarshalObject(ctx, handle, unmarshal, preUnmarshal);
14
16
  if (!obj) throw new Error("obj is undefined");
15
17
  expect(obj).toEqual({ a: 1, b: true });
16
18
  expect(unmarshal).toReturnTimes(4);
@@ -22,20 +24,20 @@ test("normal object", async () => {
22
24
  expect(preUnmarshal).toBeCalledWith(obj, handle);
23
25
 
24
26
  handle.dispose();
25
- vm.dispose();
27
+ ctx.dispose();
26
28
  });
27
29
 
28
30
  test("properties", async () => {
29
- const vm = (await getQuickJS()).createVm();
31
+ const ctx = (await getQuickJS()).newContext();
30
32
  const disposables: QuickJSHandle[] = [];
31
- const unmarshal = jest.fn((v: QuickJSHandle): [unknown, boolean] => {
33
+ const unmarshal = vi.fn((v: QuickJSHandle): [unknown, boolean] => {
32
34
  disposables.push(v);
33
- return [vm.typeof(v) === "function" ? () => {} : vm.dump(v), false];
35
+ return [ctx.typeof(v) === "function" ? () => {} : ctx.dump(v), false];
34
36
  });
35
- const preUnmarshal = jest.fn(a => a);
37
+ const preUnmarshal = vi.fn((a) => a);
36
38
 
37
- const handle = vm.unwrapResult(
38
- vm.evalCode(`{
39
+ const handle = ctx.unwrapResult(
40
+ ctx.evalCode(`{
39
41
  const obj = {};
40
42
  Object.defineProperties(obj, {
41
43
  a: { value: 1, writable: true, configurable: true, enumerable: true },
@@ -45,7 +47,7 @@ test("properties", async () => {
45
47
  obj
46
48
  }`)
47
49
  );
48
- const obj = unmarshalObject(vm, handle, unmarshal, preUnmarshal);
50
+ const obj = unmarshalObject(ctx, handle, unmarshal, preUnmarshal);
49
51
  if (!obj) throw new Error("obj is undefined");
50
52
  expect(obj).toEqual({
51
53
  a: 1,
@@ -70,21 +72,21 @@ test("properties", async () => {
70
72
  expect(preUnmarshal).toBeCalledTimes(1);
71
73
  expect(preUnmarshal).toBeCalledWith(obj, handle);
72
74
 
73
- disposables.forEach(d => d.dispose());
75
+ disposables.forEach((d) => d.dispose());
74
76
  handle.dispose();
75
- vm.dispose();
77
+ ctx.dispose();
76
78
  });
77
79
 
78
80
  test("array", async () => {
79
- const vm = (await getQuickJS()).createVm();
80
- const unmarshal = jest.fn((v: QuickJSHandle): [unknown, boolean] => [
81
- vm.dump(v),
81
+ const ctx = (await getQuickJS()).newContext();
82
+ const unmarshal = vi.fn((v: QuickJSHandle): [unknown, boolean] => [
83
+ ctx.dump(v),
82
84
  false,
83
85
  ]);
84
- const preUnmarshal = jest.fn(a => a);
86
+ const preUnmarshal = vi.fn((a) => a);
85
87
 
86
- const handle = vm.unwrapResult(vm.evalCode(`[1, true, "a"]`));
87
- const array = unmarshalObject(vm, handle, unmarshal, preUnmarshal);
88
+ const handle = ctx.unwrapResult(ctx.evalCode(`[1, true, "a"]`));
89
+ const array = unmarshalObject(ctx, handle, unmarshal, preUnmarshal);
88
90
  expect((array as any)[0]).toEqual(1);
89
91
  expect(Array.isArray(array)).toBe(true);
90
92
  expect(unmarshal.mock.results[0].value).toEqual(["0", false]);
@@ -98,19 +100,21 @@ test("array", async () => {
98
100
  expect(preUnmarshal).toBeCalledWith(array, handle);
99
101
 
100
102
  handle.dispose();
101
- vm.dispose();
103
+ ctx.dispose();
102
104
  });
103
105
 
104
106
  test("prototype", async () => {
105
- const vm = (await getQuickJS()).createVm();
106
- const unmarshal = jest.fn((v: QuickJSHandle): [unknown, boolean] => [
107
- vm.typeof(v) === "object" ? { a: () => 1 } : vm.dump(v),
107
+ const ctx = (await getQuickJS()).newContext();
108
+ const unmarshal = vi.fn((v: QuickJSHandle): [unknown, boolean] => [
109
+ ctx.typeof(v) === "object" ? { a: () => 1 } : ctx.dump(v),
108
110
  false,
109
111
  ]);
110
- const preUnmarshal = jest.fn(a => a);
112
+ const preUnmarshal = vi.fn((a) => a);
111
113
 
112
- const handle = vm.unwrapResult(vm.evalCode(`Object.create({ a: () => 1 })`));
113
- const obj = unmarshalObject(vm, handle, unmarshal, preUnmarshal) as any;
114
+ const handle = ctx.unwrapResult(
115
+ ctx.evalCode(`Object.create({ a: () => 1 })`)
116
+ );
117
+ const obj = unmarshalObject(ctx, handle, unmarshal, preUnmarshal) as any;
114
118
  if (!obj) throw new Error("obj is undefined");
115
119
  expect(Object.getPrototypeOf(obj)).toEqual({ a: expect.any(Function) });
116
120
  expect(obj.a()).toBe(1);
@@ -120,25 +124,25 @@ test("prototype", async () => {
120
124
  expect(preUnmarshal).toBeCalledWith(obj, handle);
121
125
 
122
126
  handle.dispose();
123
- vm.dispose();
127
+ ctx.dispose();
124
128
  });
125
129
 
126
130
  test("undefined", async () => {
127
- const vm = (await getQuickJS()).createVm();
128
- const f = jest.fn();
131
+ const ctx = (await getQuickJS()).newContext();
132
+ const f = vi.fn();
129
133
 
130
- expect(unmarshalObject(vm, vm.undefined, f, f)).toEqual(undefined);
131
- expect(unmarshalObject(vm, vm.true, f, f)).toEqual(undefined);
132
- expect(unmarshalObject(vm, vm.false, f, f)).toEqual(undefined);
133
- expect(unmarshalObject(vm, vm.null, f, f)).toEqual(undefined);
134
- expect(unmarshalObject(vm, vm.newString("hoge"), f, f)).toEqual(undefined);
135
- expect(unmarshalObject(vm, vm.newNumber(-10), f, f)).toEqual(undefined);
134
+ expect(unmarshalObject(ctx, ctx.undefined, f, f)).toEqual(undefined);
135
+ expect(unmarshalObject(ctx, ctx.true, f, f)).toEqual(undefined);
136
+ expect(unmarshalObject(ctx, ctx.false, f, f)).toEqual(undefined);
137
+ expect(unmarshalObject(ctx, ctx.null, f, f)).toEqual(undefined);
138
+ expect(unmarshalObject(ctx, ctx.newString("hoge"), f, f)).toEqual(undefined);
139
+ expect(unmarshalObject(ctx, ctx.newNumber(-10), f, f)).toEqual(undefined);
136
140
 
137
- const func = vm.newFunction("", () => {});
138
- expect(unmarshalObject(vm, func, f, f)).toEqual(undefined);
141
+ const func = ctx.newFunction("", () => {});
142
+ expect(unmarshalObject(ctx, func, f, f)).toEqual(undefined);
139
143
 
140
144
  expect(f).toBeCalledTimes(0);
141
145
 
142
146
  func.dispose();
143
- vm.dispose();
147
+ ctx.dispose();
144
148
  });
@@ -1,41 +1,42 @@
1
- import { QuickJSVm, QuickJSHandle } from "quickjs-emscripten";
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+
2
3
  import unmarshalProperties from "./properties";
3
4
  import { call } from "../vmutil";
4
5
 
5
6
  export default function unmarshalObject(
6
- vm: QuickJSVm,
7
+ ctx: QuickJSContext,
7
8
  handle: QuickJSHandle,
8
9
  unmarshal: (handle: QuickJSHandle) => [unknown, boolean],
9
10
  preUnmarshal: <T>(target: T, handle: QuickJSHandle) => T | undefined
10
11
  ): object | undefined {
11
12
  if (
12
- vm.typeof(handle) !== "object" ||
13
+ ctx.typeof(handle) !== "object" ||
13
14
  // null check
14
- vm
15
- .unwrapResult(vm.evalCode("o => o === null"))
16
- .consume(n =>
17
- vm.dump(vm.unwrapResult(vm.callFunction(n, vm.undefined, handle)))
15
+ ctx
16
+ .unwrapResult(ctx.evalCode("o => o === null"))
17
+ .consume((n) =>
18
+ ctx.dump(ctx.unwrapResult(ctx.callFunction(n, ctx.undefined, handle)))
18
19
  )
19
20
  )
20
21
  return;
21
22
 
22
- const raw = call(vm, "Array.isArray", undefined, handle).consume(r =>
23
- vm.dump(r)
23
+ const raw = call(ctx, "Array.isArray", undefined, handle).consume((r) =>
24
+ ctx.dump(r)
24
25
  )
25
26
  ? []
26
27
  : {};
27
28
  const obj = preUnmarshal(raw, handle) ?? raw;
28
29
 
29
30
  const prototype = call(
30
- vm,
31
+ ctx,
31
32
  `o => {
32
33
  const p = Object.getPrototypeOf(o);
33
34
  return !p || p === Object.prototype || p === Array.prototype ? undefined : p;
34
35
  }`,
35
36
  undefined,
36
37
  handle
37
- ).consume(prototype => {
38
- if (vm.typeof(prototype) === "undefined") return;
38
+ ).consume((prototype) => {
39
+ if (ctx.typeof(prototype) === "undefined") return;
39
40
  const [proto] = unmarshal(prototype);
40
41
  return proto;
41
42
  });
@@ -43,7 +44,7 @@ export default function unmarshalObject(
43
44
  Object.setPrototypeOf(obj, prototype);
44
45
  }
45
46
 
46
- unmarshalProperties(vm, handle, raw, unmarshal);
47
+ unmarshalProperties(ctx, handle, raw, unmarshal);
47
48
 
48
49
  return obj;
49
50
  }
@@ -1,28 +1,33 @@
1
1
  import { getQuickJS } from "quickjs-emscripten";
2
+ import { expect, test } from "vitest";
3
+
2
4
  import unmarshalPrimitive from "./primitive";
3
5
 
4
6
  test("works", async () => {
5
- const vm = (await getQuickJS()).createVm();
7
+ const ctx = (await getQuickJS()).newContext();
6
8
 
7
- expect(unmarshalPrimitive(vm, vm.undefined)).toEqual([undefined, true]);
8
- expect(unmarshalPrimitive(vm, vm.true)).toEqual([true, true]);
9
- expect(unmarshalPrimitive(vm, vm.false)).toEqual([false, true]);
10
- expect(unmarshalPrimitive(vm, vm.null)).toEqual([null, true]);
11
- expect(unmarshalPrimitive(vm, vm.newString("hoge"))).toEqual(["hoge", true]);
12
- expect(unmarshalPrimitive(vm, vm.newNumber(-10))).toEqual([-10, true]);
9
+ expect(unmarshalPrimitive(ctx, ctx.undefined)).toEqual([undefined, true]);
10
+ expect(unmarshalPrimitive(ctx, ctx.true)).toEqual([true, true]);
11
+ expect(unmarshalPrimitive(ctx, ctx.false)).toEqual([false, true]);
12
+ expect(unmarshalPrimitive(ctx, ctx.null)).toEqual([null, true]);
13
+ expect(unmarshalPrimitive(ctx, ctx.newString("hoge"))).toEqual([
14
+ "hoge",
15
+ true,
16
+ ]);
17
+ expect(unmarshalPrimitive(ctx, ctx.newNumber(-10))).toEqual([-10, true]);
13
18
  // expect(
14
- // unmarshalPrimitive(vm, vm.unwrapResult(vm.evalCode(`BigInt(1)`)))
19
+ // unmarshalPrimitive(ctx, ctx.unwrapResult(vm.evalCode(`BigInt(1)`)))
15
20
  // ).toEqual([BigInt(1), true]);
16
21
 
17
- const obj = vm.newObject();
18
- expect(unmarshalPrimitive(vm, obj)).toEqual([undefined, false]);
19
- const array = vm.newArray();
20
- expect(unmarshalPrimitive(vm, array)).toEqual([undefined, false]);
21
- const func = vm.newFunction("", () => {});
22
- expect(unmarshalPrimitive(vm, func)).toEqual([undefined, false]);
22
+ const obj = ctx.newObject();
23
+ expect(unmarshalPrimitive(ctx, obj)).toEqual([undefined, false]);
24
+ const array = ctx.newArray();
25
+ expect(unmarshalPrimitive(ctx, array)).toEqual([undefined, false]);
26
+ const func = ctx.newFunction("", () => {});
27
+ expect(unmarshalPrimitive(ctx, func)).toEqual([undefined, false]);
23
28
 
24
29
  obj.dispose();
25
30
  array.dispose();
26
31
  func.dispose();
27
- vm.dispose();
32
+ ctx.dispose();
28
33
  });
@@ -1,22 +1,22 @@
1
- import { QuickJSVm, QuickJSHandle } from "quickjs-emscripten";
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
2
 
3
3
  export default function unmarshalPrimitive(
4
- vm: QuickJSVm,
4
+ ctx: QuickJSContext,
5
5
  handle: QuickJSHandle
6
6
  ): [any, boolean] {
7
- const ty = vm.typeof(handle);
7
+ const ty = ctx.typeof(handle);
8
8
  if (
9
9
  ty === "undefined" ||
10
10
  ty === "number" ||
11
11
  ty === "string" ||
12
12
  ty === "boolean"
13
13
  ) {
14
- return [vm.dump(handle), true];
14
+ return [ctx.dump(handle), true];
15
15
  } else if (ty === "object") {
16
- const isNull = vm
17
- .unwrapResult(vm.evalCode("a => a === null"))
18
- .consume(n =>
19
- vm.dump(vm.unwrapResult(vm.callFunction(n, vm.undefined, handle)))
16
+ const isNull = ctx
17
+ .unwrapResult(ctx.evalCode("a => a === null"))
18
+ .consume((n) =>
19
+ ctx.dump(ctx.unwrapResult(ctx.callFunction(n, ctx.undefined, handle)))
20
20
  );
21
21
  if (isNull) {
22
22
  return [null, true];
@@ -25,10 +25,10 @@ export default function unmarshalPrimitive(
25
25
 
26
26
  // BigInt is not supported by quickjs-emscripten
27
27
  // if (ty === "bigint") {
28
- // const str = vm
28
+ // const str = ctx
29
29
  // .getProp(handle, "toString")
30
30
  // .consume(toString => vm.unwrapResult(vm.callFunction(toString, handle)))
31
- // .consume(str => vm.getString(str));
31
+ // .consume(str => ctx.getString(str));
32
32
  // const bi = BigInt(str);
33
33
  // return [bi, true];
34
34
  // }
@@ -0,0 +1,44 @@
1
+ import { Disposable, getQuickJS, type QuickJSHandle } from "quickjs-emscripten";
2
+ import { expect, test, vi } from "vitest";
3
+
4
+ import unmarshalPromise from "./promise";
5
+
6
+ const testPromise = (reject: boolean) => async () => {
7
+ const ctx = (await getQuickJS()).newContext();
8
+ const disposables: Disposable[] = [];
9
+ const marshal = vi.fn((v): [QuickJSHandle, boolean] => {
10
+ const f = ctx.newFunction(v.name, (h) => {
11
+ v(ctx.dump(h));
12
+ });
13
+ disposables.push(f);
14
+ return [f, false];
15
+ });
16
+ const preUnmarshal = vi.fn((a) => a);
17
+
18
+ const deferred = ctx.newPromise();
19
+ disposables.push(deferred);
20
+ const promise = unmarshalPromise(ctx, deferred.handle, marshal, preUnmarshal);
21
+
22
+ expect(marshal).toBeCalledTimes(2);
23
+ expect(preUnmarshal).toBeCalledTimes(1);
24
+ expect(ctx.runtime.hasPendingJob()).toBe(false);
25
+
26
+ if (reject) {
27
+ deferred.reject(ctx.newString("hoge"));
28
+ } else {
29
+ deferred.resolve(ctx.newString("hoge"));
30
+ }
31
+ expect(ctx.runtime.hasPendingJob()).toBe(true);
32
+ expect(ctx.unwrapResult(ctx.runtime.executePendingJobs())).toBe(1);
33
+ if (reject) {
34
+ expect(promise).rejects.toThrow("hoge");
35
+ } else {
36
+ expect(promise).resolves.toBe("hoge");
37
+ }
38
+
39
+ disposables.forEach((d) => d.dispose());
40
+ ctx.dispose();
41
+ };
42
+
43
+ test("resolve", testPromise(false));
44
+ test("reject", testPromise(true));
@@ -0,0 +1,38 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+
3
+ import { newDeferred } from "../util";
4
+ import { call, instanceOf } from "../vmutil";
5
+
6
+ export default function unmarshalPromise<T = unknown>(
7
+ ctx: QuickJSContext,
8
+ handle: QuickJSHandle,
9
+ /** marshal returns handle and boolean indicates that the handle should be disposed after use */
10
+ marshal: (value: unknown) => [QuickJSHandle, boolean],
11
+ preUnmarshal: <T>(target: T, handle: QuickJSHandle) => T | undefined
12
+ ): Promise<T> | undefined {
13
+ if (!isPromiseHandle(ctx, handle)) return;
14
+
15
+ const deferred = newDeferred<T>();
16
+ const [resHandle, resShouldBeDisposed] = marshal(deferred.resolve);
17
+ const [rejHandle, rejShouldBeDisposed] = marshal(deferred.reject);
18
+ call(
19
+ ctx,
20
+ "(p, res, rej) => { p.then(res, rej); }",
21
+ undefined,
22
+ handle,
23
+ resHandle,
24
+ rejHandle
25
+ );
26
+ if (resShouldBeDisposed) resHandle.dispose();
27
+ if (rejShouldBeDisposed) rejHandle.dispose();
28
+
29
+ return preUnmarshal(deferred.promise, handle) ?? deferred.promise;
30
+ }
31
+
32
+ function isPromiseHandle(ctx: QuickJSContext, handle: QuickJSHandle): boolean {
33
+ if (!handle.owner) return false;
34
+ return ctx.unwrapResult(ctx.evalCode("Promise")).consume((promise) => {
35
+ if (!handle.owner) return false;
36
+ return instanceOf(ctx, handle, promise);
37
+ });
38
+ }
@@ -1,17 +1,19 @@
1
1
  import { getQuickJS, QuickJSHandle } from "quickjs-emscripten";
2
+ import { expect, test, vi } from "vitest";
3
+
2
4
  import unmarshalProperties from "./properties";
3
5
 
4
6
  test("works", async () => {
5
- const vm = (await getQuickJS()).createVm();
7
+ const ctx = (await getQuickJS()).newContext();
6
8
  const disposables: QuickJSHandle[] = [];
7
- const unmarshal = jest.fn((v: QuickJSHandle): [unknown, boolean] => {
9
+ const unmarshal = vi.fn((v: QuickJSHandle): [unknown, boolean] => {
8
10
  disposables.push(v);
9
- return [vm.typeof(v) === "function" ? () => {} : vm.dump(v), false];
11
+ return [ctx.typeof(v) === "function" ? () => {} : ctx.dump(v), false];
10
12
  });
11
13
  const obj = {};
12
14
 
13
- const handle = vm.unwrapResult(
14
- vm.evalCode(`{
15
+ const handle = ctx.unwrapResult(
16
+ ctx.evalCode(`{
15
17
  const obj = {};
16
18
  Object.defineProperties(obj, {
17
19
  a: { value: 1, writable: true, configurable: true, enumerable: true },
@@ -22,7 +24,7 @@ test("works", async () => {
22
24
  }`)
23
25
  );
24
26
 
25
- unmarshalProperties(vm, handle, obj, unmarshal);
27
+ unmarshalProperties(ctx, handle, obj, unmarshal);
26
28
 
27
29
  expect(obj).toEqual({
28
30
  a: 1,
@@ -45,7 +47,7 @@ test("works", async () => {
45
47
  expect(unmarshal).toReturnWith(["c", false]);
46
48
  expect(unmarshal).toReturnWith([expect.any(Function), false]); // get, set
47
49
 
48
- disposables.forEach(d => d.dispose());
50
+ disposables.forEach((d) => d.dispose());
49
51
  handle.dispose();
50
- vm.dispose();
52
+ ctx.dispose();
51
53
  });
@@ -1,59 +1,64 @@
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 unmarshalProperties(
5
- vm: QuickJSVm,
6
+ ctx: QuickJSContext,
6
7
  handle: QuickJSHandle,
7
8
  target: object | Function,
8
9
  unmarshal: (handle: QuickJSHandle) => [unknown, boolean]
9
10
  ) {
10
- vm.newFunction("", (key, value) => {
11
- const [keyName] = unmarshal(key);
12
- if (
13
- typeof keyName !== "string" &&
14
- typeof keyName !== "number" &&
15
- typeof keyName !== "symbol"
16
- )
17
- return;
11
+ ctx
12
+ .newFunction("", (key, value) => {
13
+ const [keyName] = unmarshal(key);
14
+ if (
15
+ typeof keyName !== "string" &&
16
+ typeof keyName !== "number" &&
17
+ typeof keyName !== "symbol"
18
+ )
19
+ return;
18
20
 
19
- const desc = ([
20
- ["value", true],
21
- ["get", true],
22
- ["set", true],
23
- ["configurable", false],
24
- ["enumerable", false],
25
- ["writable", false],
26
- ] as const).reduce<PropertyDescriptor>((desc, [key, unmarshable]) => {
27
- const h = vm.getProp(value, key);
28
- const ty = vm.typeof(h);
21
+ const desc = (
22
+ [
23
+ ["value", true],
24
+ ["get", true],
25
+ ["set", true],
26
+ ["configurable", false],
27
+ ["enumerable", false],
28
+ ["writable", false],
29
+ ] as const
30
+ ).reduce<PropertyDescriptor>((desc, [key, unmarshable]) => {
31
+ const h = ctx.getProp(value, key);
32
+ const ty = ctx.typeof(h);
29
33
 
30
- if (ty === "undefined") return desc;
31
- if (!unmarshable && ty === "boolean") {
32
- desc[key] = vm.dump(vm.getProp(value, key));
33
- return desc;
34
- }
34
+ if (ty === "undefined") return desc;
35
+ if (!unmarshable && ty === "boolean") {
36
+ desc[key] = ctx.dump(ctx.getProp(value, key));
37
+ return desc;
38
+ }
35
39
 
36
- const [v, alreadyExists] = unmarshal(h);
37
- if (alreadyExists) {
38
- h.dispose();
39
- }
40
- desc[key] = v;
40
+ const [v, alreadyExists] = unmarshal(h);
41
+ if (alreadyExists) {
42
+ h.dispose();
43
+ }
44
+ desc[key] = v;
41
45
 
42
- return desc;
43
- }, {});
46
+ return desc;
47
+ }, {});
44
48
 
45
- Object.defineProperty(target, keyName, desc);
46
- }).consume(fn => {
47
- call(
48
- vm,
49
- `(o, fn) => {
49
+ Object.defineProperty(target, keyName, desc);
50
+ })
51
+ .consume((fn) => {
52
+ call(
53
+ ctx,
54
+ `(o, fn) => {
50
55
  const descs = Object.getOwnPropertyDescriptors(o);
51
56
  Object.entries(descs).forEach(([k, v]) => fn(k, v));
52
57
  Object.getOwnPropertySymbols(descs).forEach(k => fn(k, descs[k]));
53
58
  }`,
54
- undefined,
55
- handle,
56
- fn
57
- ).dispose();
58
- });
59
+ undefined,
60
+ handle,
61
+ fn
62
+ ).dispose();
63
+ });
59
64
  }
@@ -1,16 +1,18 @@
1
1
  import { getQuickJS } from "quickjs-emscripten";
2
+ import { expect, test, vi } from "vitest";
3
+
2
4
  import unmarshalSymbol from "./symbol";
3
5
 
4
6
  test("works", async () => {
5
- const vm = (await getQuickJS()).createVm();
6
- const pre = jest.fn();
7
- const obj = vm.newObject();
8
- const handle = vm.unwrapResult(vm.evalCode(`Symbol("foobar")`));
7
+ const ctx = (await getQuickJS()).newContext();
8
+ const pre = vi.fn();
9
+ const obj = ctx.newObject();
10
+ const handle = ctx.unwrapResult(ctx.evalCode(`Symbol("foobar")`));
9
11
 
10
- expect(unmarshalSymbol(vm, obj, pre)).toBe(undefined);
12
+ expect(unmarshalSymbol(ctx, obj, pre)).toBe(undefined);
11
13
  expect(pre).toBeCalledTimes(0);
12
14
 
13
- const sym = unmarshalSymbol(vm, handle, pre);
15
+ const sym = unmarshalSymbol(ctx, handle, pre);
14
16
  expect(typeof sym).toBe("symbol");
15
17
  expect((sym as any).description).toBe("foobar");
16
18
  expect(pre).toReturnTimes(1);
@@ -19,5 +21,5 @@ test("works", async () => {
19
21
 
20
22
  handle.dispose();
21
23
  obj.dispose();
22
- vm.dispose();
24
+ ctx.dispose();
23
25
  });
@@ -1,12 +1,12 @@
1
- import { QuickJSVm, QuickJSHandle } from "quickjs-emscripten";
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
2
 
3
3
  export default function unmarshalSymbol(
4
- vm: QuickJSVm,
4
+ ctx: QuickJSContext,
5
5
  handle: QuickJSHandle,
6
6
  preUnmarshal: <T>(target: T, handle: QuickJSHandle) => T | undefined
7
7
  ): symbol | undefined {
8
- if (vm.typeof(handle) !== "symbol") return;
9
- const desc = vm.getString(vm.getProp(handle, "description"));
8
+ if (ctx.typeof(handle) !== "symbol") return;
9
+ const desc = ctx.getString(ctx.getProp(handle, "description"));
10
10
  const sym = Symbol(desc);
11
11
  return preUnmarshal(sym, handle) ?? sym;
12
12
  }
package/src/util.test.ts CHANGED
@@ -1,9 +1,17 @@
1
- import { isES2015Class, isObject, walkObject, complexity } from "./util";
1
+ import { expect, test, vi } from "vitest";
2
+
3
+ import {
4
+ isES2015Class,
5
+ isObject,
6
+ walkObject,
7
+ complexity,
8
+ newDeferred,
9
+ } from "./util";
2
10
 
3
11
  test("isES2015Class", () => {
4
12
  expect(isES2015Class(class {})).toBe(true);
5
13
  expect(isES2015Class(class A {})).toBe(true);
6
- expect(isES2015Class(function() {})).toBe(false);
14
+ expect(isES2015Class(function () {})).toBe(false);
7
15
  expect(isES2015Class(function A() {})).toBe(false);
8
16
  expect(isES2015Class(() => {})).toBe(false);
9
17
  expect(isES2015Class({})).toBe(false);
@@ -14,7 +22,7 @@ test("isES2015Class", () => {
14
22
  test("isObject", () => {
15
23
  expect(isObject({})).toBe(true);
16
24
  expect(isObject(Object.create(null))).toBe(true);
17
- expect(isObject(function() {})).toBe(true);
25
+ expect(isObject(function () {})).toBe(true);
18
26
  expect(isObject(function A() {})).toBe(true);
19
27
  expect(isObject(() => {})).toBe(true);
20
28
  expect(isObject(class {})).toBe(true);
@@ -25,7 +33,7 @@ test("isObject", () => {
25
33
  });
26
34
 
27
35
  test("walkObject", () => {
28
- const cb = jest.fn();
36
+ const cb = vi.fn();
29
37
  const obj = { a: { b: 1, c: () => {} } };
30
38
  const set = new Set<any>([obj, obj.a, obj.a.c]);
31
39
  expect(walkObject(obj, cb)).toEqual(set);
@@ -47,8 +55,18 @@ test("complexity", () => {
47
55
  expect(complexity({ a: 1 })).toBe(1);
48
56
  expect(complexity(() => {})).toBe(1);
49
57
  expect(complexity([{}])).toBe(2);
50
- expect(complexity(function() {})).toBe(2);
58
+ expect(complexity(function () {})).toBe(2);
51
59
  expect(complexity(class {})).toBe(2);
52
60
  expect(complexity({ a: {} })).toBe(2);
53
61
  expect(complexity({ a: {} }, 1)).toBe(1);
54
62
  });
63
+
64
+ test("newDeferred", () => {
65
+ const deferred = newDeferred();
66
+ deferred.resolve("foo");
67
+ expect(deferred.promise).resolves.toBe("foo");
68
+
69
+ const deferred2 = newDeferred();
70
+ deferred2.reject("bar");
71
+ expect(deferred2.promise).rejects.toBe("bar");
72
+ });