quickjs-emscripten-sync 1.0.0 → 1.3.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.
- package/LICENSE +2 -2
- package/README.md +303 -0
- package/dist/index.d.ts +129 -29
- package/dist/quickjs-emscripten-sync.es.js +951 -0
- package/dist/quickjs-emscripten-sync.umd.js +64 -0
- package/package.json +28 -40
- package/src/default.ts +6 -2
- package/src/index.test.ts +266 -51
- package/src/index.ts +123 -66
- package/src/marshal/function.test.ts +11 -10
- package/src/marshal/function.ts +3 -3
- package/src/marshal/index.test.ts +75 -10
- package/src/marshal/index.ts +28 -14
- package/src/marshal/json.test.ts +94 -0
- package/src/marshal/json.ts +15 -0
- package/src/marshal/object.test.ts +49 -6
- package/src/marshal/object.ts +2 -2
- package/src/marshal/primitive.test.ts +2 -0
- package/src/marshal/primitive.ts +8 -2
- package/src/marshal/promise.test.ts +86 -0
- package/src/marshal/promise.ts +26 -0
- package/src/marshal/properties.test.ts +7 -5
- package/src/marshal/properties.ts +2 -2
- package/src/marshal/symbol.test.ts +3 -1
- package/src/unmarshal/function.test.ts +28 -21
- package/src/unmarshal/function.ts +31 -23
- package/src/unmarshal/index.test.ts +86 -86
- package/src/unmarshal/index.ts +5 -4
- package/src/unmarshal/object.test.ts +36 -8
- package/src/unmarshal/object.ts +8 -4
- package/src/unmarshal/primitive.test.ts +2 -0
- package/src/unmarshal/primitive.ts +1 -2
- package/src/unmarshal/promise.test.ts +44 -0
- package/src/unmarshal/promise.ts +40 -0
- package/src/unmarshal/properties.test.ts +4 -2
- package/src/unmarshal/properties.ts +11 -9
- package/src/unmarshal/symbol.test.ts +3 -1
- package/src/util.test.ts +22 -5
- package/src/util.ts +15 -0
- package/src/vmmap.test.ts +22 -0
- package/src/vmmap.ts +6 -2
- package/src/vmutil.test.ts +116 -8
- package/src/vmutil.ts +76 -8
- package/src/wrapper.test.ts +44 -31
- package/src/wrapper.ts +47 -30
- package/dist/default.d.ts +0 -4
- package/dist/index.js +0 -8
- package/dist/marshal/array.d.ts +0 -2
- package/dist/marshal/function.d.ts +0 -2
- package/dist/marshal/index.d.ts +0 -11
- package/dist/marshal/object.d.ts +0 -2
- package/dist/marshal/primitive.d.ts +0 -2
- package/dist/marshal/properties.d.ts +0 -2
- package/dist/marshal/symbol.d.ts +0 -2
- package/dist/quickjs-emscripten-sync.cjs.development.js +0 -1302
- package/dist/quickjs-emscripten-sync.cjs.development.js.map +0 -1
- package/dist/quickjs-emscripten-sync.cjs.production.min.js +0 -2
- package/dist/quickjs-emscripten-sync.cjs.production.min.js.map +0 -1
- package/dist/quickjs-emscripten-sync.esm.js +0 -1285
- package/dist/quickjs-emscripten-sync.esm.js.map +0 -1
- package/dist/unmarshal/array.d.ts +0 -2
- package/dist/unmarshal/function.d.ts +0 -2
- package/dist/unmarshal/index.d.ts +0 -9
- package/dist/unmarshal/object.d.ts +0 -2
- package/dist/unmarshal/primitive.d.ts +0 -2
- package/dist/unmarshal/properties.d.ts +0 -2
- package/dist/unmarshal/symbol.d.ts +0 -2
- package/dist/util.d.ts +0 -7
- package/dist/vmmap.d.ts +0 -35
- package/dist/vmutil.d.ts +0 -7
- package/dist/wrapper.d.ts +0 -11
- package/src/marshal/array.test.ts +0 -40
- package/src/marshal/array.ts +0 -24
- package/src/unmarshal/array.test.ts +0 -45
- package/src/unmarshal/array.ts +0 -32
package/src/index.test.ts
CHANGED
|
@@ -1,21 +1,109 @@
|
|
|
1
1
|
import { getQuickJS } from "quickjs-emscripten";
|
|
2
|
-
import
|
|
2
|
+
import { describe, expect, test, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { Arena } from ".";
|
|
5
|
+
|
|
6
|
+
describe("readme", () => {
|
|
7
|
+
test("first", async () => {
|
|
8
|
+
class Cls {
|
|
9
|
+
field = 0;
|
|
10
|
+
|
|
11
|
+
method() {
|
|
12
|
+
return ++this.field;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const vm = (await getQuickJS()).createVm();
|
|
17
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
18
|
+
|
|
19
|
+
// We can pass objects to the VM and run code safely
|
|
20
|
+
const exposed = {
|
|
21
|
+
Cls,
|
|
22
|
+
cls: new Cls(),
|
|
23
|
+
syncedCls: arena.sync(new Cls()),
|
|
24
|
+
};
|
|
25
|
+
arena.expose(exposed);
|
|
26
|
+
|
|
27
|
+
expect(arena.evalCode(`cls instanceof Cls`)).toBe(true);
|
|
28
|
+
expect(arena.evalCode(`cls.field`)).toBe(0);
|
|
29
|
+
expect(arena.evalCode(`cls.method()`)).toBe(1);
|
|
30
|
+
expect(arena.evalCode(`cls.field`)).toBe(1);
|
|
31
|
+
|
|
32
|
+
expect(arena.evalCode(`syncedCls.field`)).toBe(0);
|
|
33
|
+
expect(exposed.syncedCls.method()).toBe(1);
|
|
34
|
+
expect(arena.evalCode(`syncedCls.field`)).toBe(1);
|
|
35
|
+
|
|
36
|
+
arena.dispose();
|
|
37
|
+
vm.dispose();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("usage", async () => {
|
|
41
|
+
const quickjs = await getQuickJS();
|
|
42
|
+
const vm = quickjs.createVm();
|
|
43
|
+
|
|
44
|
+
// init Arena
|
|
45
|
+
// ⚠️ Marshaling is opt-in for security reasons.
|
|
46
|
+
// ⚠️ Be careful when activating marshalling.
|
|
47
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
48
|
+
|
|
49
|
+
// expose objects as global objects in QuickJS VM
|
|
50
|
+
const log = vi.fn();
|
|
51
|
+
arena.expose({
|
|
52
|
+
console: { log },
|
|
53
|
+
});
|
|
54
|
+
arena.evalCode(`console.log("hello, world");`); // run console.log
|
|
55
|
+
expect(log).toBeCalledWith("hello, world");
|
|
56
|
+
arena.evalCode(`1 + 1`); // 2
|
|
57
|
+
|
|
58
|
+
// expose objects but also enable sync
|
|
59
|
+
const data = arena.sync({ hoge: "foo" });
|
|
60
|
+
arena.expose({ data });
|
|
61
|
+
|
|
62
|
+
arena.evalCode(`data.hoge = "bar"`);
|
|
63
|
+
// eval code and operations to exposed objects are automatically synced
|
|
64
|
+
expect(data.hoge).toBe("bar");
|
|
65
|
+
data.hoge = "changed!";
|
|
66
|
+
expect(arena.evalCode(`data.hoge`)).toBe("changed!");
|
|
67
|
+
|
|
68
|
+
// Don't forget calling arena.dispose() before disposing QuickJS VM!
|
|
69
|
+
arena.dispose();
|
|
70
|
+
vm.dispose();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
3
73
|
|
|
4
74
|
describe("evalCode", () => {
|
|
5
75
|
test("simple object and function", async () => {
|
|
6
76
|
const vm = (await getQuickJS()).createVm();
|
|
7
|
-
const arena = new Arena(vm);
|
|
77
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
8
78
|
|
|
9
79
|
const result = arena.evalCode(
|
|
10
|
-
`({
|
|
80
|
+
`({
|
|
81
|
+
a: 1,
|
|
82
|
+
b: a => Math.floor(a),
|
|
83
|
+
c: () => { throw new Error("hoge") },
|
|
84
|
+
d: (yourFavoriteNumber) => ({
|
|
85
|
+
myFavoriteNumber: 42,
|
|
86
|
+
yourFavoriteNumber,
|
|
87
|
+
}),
|
|
88
|
+
get e() {
|
|
89
|
+
return { a: 1 };
|
|
90
|
+
}
|
|
91
|
+
})`
|
|
11
92
|
);
|
|
12
93
|
expect(result).toEqual({
|
|
13
94
|
a: 1,
|
|
14
95
|
b: expect.any(Function),
|
|
15
96
|
c: expect.any(Function),
|
|
97
|
+
d: expect.any(Function),
|
|
98
|
+
e: { a: 1 },
|
|
16
99
|
});
|
|
17
100
|
expect(result.b(1.1)).toBe(1);
|
|
18
101
|
expect(() => result.c()).toThrow("hoge");
|
|
102
|
+
expect(result.d(1)).toStrictEqual({
|
|
103
|
+
myFavoriteNumber: 42,
|
|
104
|
+
yourFavoriteNumber: 1,
|
|
105
|
+
});
|
|
106
|
+
expect(result.e).toStrictEqual({ a: 1 });
|
|
19
107
|
|
|
20
108
|
arena.dispose();
|
|
21
109
|
vm.dispose();
|
|
@@ -23,7 +111,7 @@ describe("evalCode", () => {
|
|
|
23
111
|
|
|
24
112
|
test("Math", async () => {
|
|
25
113
|
const vm = (await getQuickJS()).createVm();
|
|
26
|
-
const arena = new Arena(vm);
|
|
114
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
27
115
|
|
|
28
116
|
const VMMath = arena.evalCode(`Math`) as Math;
|
|
29
117
|
expect(VMMath.floor(1.1)).toBe(1);
|
|
@@ -34,7 +122,7 @@ describe("evalCode", () => {
|
|
|
34
122
|
|
|
35
123
|
test("class", async () => {
|
|
36
124
|
const vm = (await getQuickJS()).createVm();
|
|
37
|
-
const arena = new Arena(vm);
|
|
125
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
38
126
|
|
|
39
127
|
const instance = arena.evalCode(`{
|
|
40
128
|
globalThis.Cls = class D {
|
|
@@ -45,7 +133,7 @@ describe("evalCode", () => {
|
|
|
45
133
|
return ++this.a;
|
|
46
134
|
}
|
|
47
135
|
};
|
|
48
|
-
|
|
136
|
+
|
|
49
137
|
new Cls(100);
|
|
50
138
|
}`);
|
|
51
139
|
const Cls = arena.evalCode(`globalThis.Cls`);
|
|
@@ -60,7 +148,7 @@ describe("evalCode", () => {
|
|
|
60
148
|
|
|
61
149
|
test("obj", async () => {
|
|
62
150
|
const vm = (await getQuickJS()).createVm();
|
|
63
|
-
const arena = new Arena(vm);
|
|
151
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
64
152
|
|
|
65
153
|
const obj = arena.evalCode(`globalThis.AAA = { a: 1 }`);
|
|
66
154
|
|
|
@@ -78,21 +166,35 @@ describe("evalCode", () => {
|
|
|
78
166
|
describe("expose without sync", () => {
|
|
79
167
|
test("simple object and function", async () => {
|
|
80
168
|
const vm = (await getQuickJS()).createVm();
|
|
81
|
-
const arena = new Arena(vm);
|
|
169
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
82
170
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
171
|
+
const obj = {
|
|
172
|
+
a: 1,
|
|
173
|
+
b: (a: number) => Math.floor(a),
|
|
174
|
+
c: () => {
|
|
175
|
+
throw new Error("hoge");
|
|
176
|
+
},
|
|
177
|
+
d: (yourFavoriteNumber: number) => ({
|
|
178
|
+
myFavoriteNumber: 42,
|
|
179
|
+
yourFavoriteNumber,
|
|
180
|
+
}),
|
|
181
|
+
get e() {
|
|
182
|
+
return { a: 1 };
|
|
90
183
|
},
|
|
184
|
+
};
|
|
185
|
+
arena.expose({
|
|
186
|
+
obj,
|
|
91
187
|
});
|
|
92
188
|
|
|
189
|
+
expect(arena.evalCode(`obj`)).toBe(obj);
|
|
93
190
|
expect(arena.evalCode(`obj.a`)).toBe(1);
|
|
94
191
|
expect(arena.evalCode(`obj.b(1.1)`)).toBe(1);
|
|
95
192
|
expect(() => arena.evalCode(`obj.c()`)).toThrow("hoge");
|
|
193
|
+
expect(arena.evalCode(`obj.d(1)`)).toStrictEqual({
|
|
194
|
+
myFavoriteNumber: 42,
|
|
195
|
+
yourFavoriteNumber: 1,
|
|
196
|
+
});
|
|
197
|
+
expect(arena.evalCode(`obj.e`)).toStrictEqual({ a: 1 });
|
|
96
198
|
|
|
97
199
|
arena.dispose();
|
|
98
200
|
vm.dispose();
|
|
@@ -100,10 +202,12 @@ describe("expose without sync", () => {
|
|
|
100
202
|
|
|
101
203
|
test("Math", async () => {
|
|
102
204
|
const vm = (await getQuickJS()).createVm();
|
|
103
|
-
const arena = new Arena(vm);
|
|
205
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
104
206
|
|
|
105
|
-
arena.expose({ Math });
|
|
106
|
-
expect(arena.evalCode(`Math
|
|
207
|
+
arena.expose({ Math2: Math });
|
|
208
|
+
expect(arena.evalCode(`Math`)).not.toBe(Math);
|
|
209
|
+
expect(arena.evalCode(`Math2`)).toBe(Math);
|
|
210
|
+
expect(arena.evalCode(`Math2.floor(1.1)`)).toBe(1);
|
|
107
211
|
|
|
108
212
|
arena.dispose();
|
|
109
213
|
vm.dispose();
|
|
@@ -111,7 +215,7 @@ describe("expose without sync", () => {
|
|
|
111
215
|
|
|
112
216
|
test("class", async () => {
|
|
113
217
|
const vm = (await getQuickJS()).createVm();
|
|
114
|
-
const arena = new Arena(vm);
|
|
218
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
115
219
|
|
|
116
220
|
class D {
|
|
117
221
|
a: number;
|
|
@@ -125,7 +229,10 @@ describe("expose without sync", () => {
|
|
|
125
229
|
}
|
|
126
230
|
}
|
|
127
231
|
|
|
128
|
-
|
|
232
|
+
const d = new D(100);
|
|
233
|
+
arena.expose({ D, d });
|
|
234
|
+
expect(arena.evalCode(`D`)).toBe(D);
|
|
235
|
+
expect(arena.evalCode(`d`)).toBe(d);
|
|
129
236
|
expect(arena.evalCode(`d instanceof D`)).toBe(true);
|
|
130
237
|
expect(arena.evalCode(`d.a`)).toBe(101);
|
|
131
238
|
expect(arena.evalCode(`d.foo()`)).toBe(102);
|
|
@@ -137,7 +244,7 @@ describe("expose without sync", () => {
|
|
|
137
244
|
|
|
138
245
|
test("object and function", async () => {
|
|
139
246
|
const vm = (await getQuickJS()).createVm();
|
|
140
|
-
const arena = new Arena(vm);
|
|
247
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
141
248
|
|
|
142
249
|
const obj = {
|
|
143
250
|
a: 1,
|
|
@@ -146,9 +253,13 @@ describe("expose without sync", () => {
|
|
|
146
253
|
return this.a++;
|
|
147
254
|
},
|
|
148
255
|
};
|
|
149
|
-
|
|
256
|
+
arena.expose({ obj });
|
|
150
257
|
|
|
258
|
+
expect(arena.evalCode(`obj`)).toBe(obj);
|
|
259
|
+
expect(arena.evalCode(`obj.a`)).toBe(1);
|
|
260
|
+
expect(arena.evalCode(`obj.b`)).toBe(obj.b);
|
|
151
261
|
expect(arena.evalCode(`obj.b(1.1)`)).toBe(1);
|
|
262
|
+
expect(arena.evalCode(`obj.c`)).toBe(obj.c);
|
|
152
263
|
expect(arena.evalCode(`obj.c()`)).toBe(1);
|
|
153
264
|
expect(arena.evalCode(`obj.a`)).toBe(2);
|
|
154
265
|
expect(obj.a).toBe(2);
|
|
@@ -156,8 +267,7 @@ describe("expose without sync", () => {
|
|
|
156
267
|
expect(arena.evalCode(`obj.a`)).toBe(3);
|
|
157
268
|
expect(obj.a).toBe(3);
|
|
158
269
|
|
|
159
|
-
|
|
160
|
-
obj2.obj.a = 10;
|
|
270
|
+
obj.a = 10;
|
|
161
271
|
expect(obj.a).toBe(10);
|
|
162
272
|
expect(arena.evalCode(`obj.a`)).toBe(3); // not affected
|
|
163
273
|
|
|
@@ -171,9 +281,9 @@ describe("expose without sync", () => {
|
|
|
171
281
|
});
|
|
172
282
|
|
|
173
283
|
describe("expose with sync", () => {
|
|
174
|
-
test("
|
|
284
|
+
test("sync before expose", async () => {
|
|
175
285
|
const vm = (await getQuickJS()).createVm();
|
|
176
|
-
const arena = new Arena(vm);
|
|
286
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
177
287
|
|
|
178
288
|
const obj = {
|
|
179
289
|
a: 1,
|
|
@@ -182,9 +292,64 @@ describe("expose with sync", () => {
|
|
|
182
292
|
return this.a++;
|
|
183
293
|
},
|
|
184
294
|
};
|
|
185
|
-
const obj2 = arena.
|
|
295
|
+
const obj2 = arena.sync(obj);
|
|
296
|
+
arena.expose({ obj: obj2 });
|
|
297
|
+
|
|
298
|
+
const obj3 = arena.evalCode(`obj`);
|
|
299
|
+
expect(obj3).toBe(obj2);
|
|
300
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj.c); // wrapped object
|
|
301
|
+
expect(arena.evalCode(`obj.b`)).not.toBe(obj2.b); // wrapped object
|
|
302
|
+
expect(arena.evalCode(`obj.b`)).not.toBe(obj3.b); // wrapped object
|
|
303
|
+
expect(arena.evalCode(`obj.b(1.1)`)).toBe(1);
|
|
304
|
+
expect(arena.evalCode(`obj.a`)).toBe(1);
|
|
305
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj.c); // wrapped object
|
|
306
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj2.c); // wrapped object
|
|
307
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj3.c); // wrapped object
|
|
308
|
+
expect(arena.evalCode(`obj.c()`)).toBe(1);
|
|
309
|
+
expect(arena.evalCode(`obj.a`)).toBe(2);
|
|
310
|
+
expect(obj.a).toBe(2);
|
|
311
|
+
expect(arena.evalCode(`obj.c()`)).toBe(2);
|
|
312
|
+
expect(arena.evalCode(`obj.a`)).toBe(3);
|
|
313
|
+
expect(obj.a).toBe(3);
|
|
314
|
+
|
|
315
|
+
expect(obj).not.toBe(obj2);
|
|
316
|
+
obj2.a = 10;
|
|
317
|
+
expect(obj.a).toBe(10);
|
|
318
|
+
expect(arena.evalCode(`obj.a`)).toBe(10); // affected
|
|
186
319
|
|
|
320
|
+
arena.evalCode(`obj.a = 100`);
|
|
321
|
+
expect(obj.a).toBe(100); // affected
|
|
322
|
+
expect(arena.evalCode(`obj.a`)).toBe(100);
|
|
323
|
+
|
|
324
|
+
arena.dispose();
|
|
325
|
+
vm.dispose();
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test("sync after expose", async () => {
|
|
329
|
+
const vm = (await getQuickJS()).createVm();
|
|
330
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
331
|
+
|
|
332
|
+
const obj = {
|
|
333
|
+
a: 1,
|
|
334
|
+
b: (a: number) => Math.floor(a),
|
|
335
|
+
c() {
|
|
336
|
+
return this.a++;
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
arena.expose({ obj });
|
|
340
|
+
const obj2 = arena.sync(obj);
|
|
341
|
+
|
|
342
|
+
const obj3 = arena.evalCode(`obj`);
|
|
343
|
+
expect(obj3).not.toBe(obj); // wrapped object
|
|
344
|
+
expect(obj3).not.toBe(obj2); // wrapped object
|
|
345
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj.c); // wrapped object
|
|
346
|
+
expect(arena.evalCode(`obj.b`)).not.toBe(obj2.b); // wrapped object
|
|
347
|
+
expect(arena.evalCode(`obj.b`)).not.toBe(obj3.b); // wrapped object
|
|
187
348
|
expect(arena.evalCode(`obj.b(1.1)`)).toBe(1);
|
|
349
|
+
expect(arena.evalCode(`obj.a`)).toBe(1);
|
|
350
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj.c); // wrapped object
|
|
351
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj2.c); // wrapped object
|
|
352
|
+
expect(arena.evalCode(`obj.c`)).not.toBe(obj3.c); // wrapped object
|
|
188
353
|
expect(arena.evalCode(`obj.c()`)).toBe(1);
|
|
189
354
|
expect(arena.evalCode(`obj.a`)).toBe(2);
|
|
190
355
|
expect(obj.a).toBe(2);
|
|
@@ -192,8 +357,8 @@ describe("expose with sync", () => {
|
|
|
192
357
|
expect(arena.evalCode(`obj.a`)).toBe(3);
|
|
193
358
|
expect(obj.a).toBe(3);
|
|
194
359
|
|
|
195
|
-
expect(obj).not.toBe(obj2
|
|
196
|
-
obj2.
|
|
360
|
+
expect(obj).not.toBe(obj2);
|
|
361
|
+
obj2.a = 10;
|
|
197
362
|
expect(obj.a).toBe(10);
|
|
198
363
|
expect(arena.evalCode(`obj.a`)).toBe(10); // affected
|
|
199
364
|
|
|
@@ -208,13 +373,12 @@ describe("expose with sync", () => {
|
|
|
208
373
|
|
|
209
374
|
test("evalCode -> expose", async () => {
|
|
210
375
|
const vm = (await getQuickJS()).createVm();
|
|
211
|
-
const arena = new Arena(vm);
|
|
376
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
212
377
|
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
true
|
|
216
|
-
);
|
|
378
|
+
const obj = arena.evalCode(`({ a: 1, b: 1 })`);
|
|
379
|
+
arena.expose({ obj });
|
|
217
380
|
|
|
381
|
+
expect(obj).toBe(obj);
|
|
218
382
|
expect(obj.a).toBe(1);
|
|
219
383
|
expect(arena.evalCode(`obj.a`)).toBe(1);
|
|
220
384
|
expect(obj.b).toBe(1);
|
|
@@ -240,21 +404,34 @@ test("evalCode -> expose", async () => {
|
|
|
240
404
|
|
|
241
405
|
test("expose -> evalCode", async () => {
|
|
242
406
|
const vm = (await getQuickJS()).createVm();
|
|
243
|
-
const arena = new Arena(vm);
|
|
407
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
244
408
|
|
|
245
409
|
const obj = { a: 1 };
|
|
246
|
-
|
|
247
|
-
const
|
|
410
|
+
arena.expose({ obj });
|
|
411
|
+
const obj2 = arena.evalCode(`obj`);
|
|
248
412
|
|
|
249
|
-
expect(
|
|
413
|
+
expect(obj2).toBe(obj);
|
|
250
414
|
|
|
251
|
-
|
|
415
|
+
obj2.a = 2;
|
|
252
416
|
expect(obj.a).toBe(2);
|
|
253
|
-
expect(arena.evalCode(`obj.a`)).toBe(
|
|
417
|
+
expect(arena.evalCode(`obj.a`)).toBe(1);
|
|
418
|
+
|
|
419
|
+
arena.evalCode("obj.a = 3");
|
|
420
|
+
expect(obj.a).toBe(2);
|
|
421
|
+
expect(arena.evalCode(`obj.a`)).toBe(3);
|
|
422
|
+
|
|
423
|
+
arena.dispose();
|
|
424
|
+
vm.dispose();
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
test("evalCode -> expose -> evalCode", async () => {
|
|
428
|
+
const vm = (await getQuickJS()).createVm();
|
|
429
|
+
const arena = new Arena(vm, { isMarshalable: true });
|
|
254
430
|
|
|
255
|
-
|
|
256
|
-
expect(
|
|
257
|
-
|
|
431
|
+
const obj = [1];
|
|
432
|
+
expect(arena.evalCode("a => a[0] + 10")(obj)).toBe(11);
|
|
433
|
+
arena.expose({ obj });
|
|
434
|
+
expect(arena.evalCode("obj")).toBe(obj);
|
|
258
435
|
|
|
259
436
|
arena.dispose();
|
|
260
437
|
vm.dispose();
|
|
@@ -262,7 +439,7 @@ test("expose -> evalCode", async () => {
|
|
|
262
439
|
|
|
263
440
|
test("register and unregister", async () => {
|
|
264
441
|
const vm = (await getQuickJS()).createVm();
|
|
265
|
-
const arena = new Arena(vm, { registeredObjects: [] });
|
|
442
|
+
const arena = new Arena(vm, { isMarshalable: true, registeredObjects: [] });
|
|
266
443
|
|
|
267
444
|
arena.register(Math, `Math`);
|
|
268
445
|
expect(arena.evalCode(`Math`)).toBe(Math);
|
|
@@ -283,6 +460,7 @@ test("register and unregister", async () => {
|
|
|
283
460
|
test("registeredObjects option", async () => {
|
|
284
461
|
const vm = (await getQuickJS()).createVm();
|
|
285
462
|
const arena = new Arena(vm, {
|
|
463
|
+
isMarshalable: true,
|
|
286
464
|
registeredObjects: [[Symbol.iterator, "Symbol.iterator"]],
|
|
287
465
|
});
|
|
288
466
|
|
|
@@ -295,14 +473,51 @@ test("registeredObjects option", async () => {
|
|
|
295
473
|
vm.dispose();
|
|
296
474
|
});
|
|
297
475
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
476
|
+
describe("isMarshalable option", () => {
|
|
477
|
+
test("false", async () => {
|
|
478
|
+
const vm = (await getQuickJS()).createVm();
|
|
479
|
+
const arena = new Arena(vm, { isMarshalable: false });
|
|
480
|
+
|
|
481
|
+
expect(arena.evalCode(`s => s === undefined`)(globalThis)).toBe(true);
|
|
482
|
+
expect(arena.evalCode(`s => s === undefined`)({})).toBe(true);
|
|
483
|
+
arena.expose({ aaa: globalThis });
|
|
484
|
+
expect(arena.evalCode(`aaa`)).toBeUndefined();
|
|
485
|
+
|
|
486
|
+
arena.dispose();
|
|
487
|
+
vm.dispose();
|
|
302
488
|
});
|
|
303
489
|
|
|
304
|
-
|
|
490
|
+
test("json", async () => {
|
|
491
|
+
const vm = (await getQuickJS()).createVm();
|
|
492
|
+
const arena = new Arena(vm, { isMarshalable: "json" });
|
|
305
493
|
|
|
306
|
-
|
|
307
|
-
|
|
494
|
+
const obj = { a: () => {}, b: new Date(), c: [() => {}, 1] };
|
|
495
|
+
const objJSON = { b: obj.b.toISOString(), c: [null, 1] };
|
|
496
|
+
const objJSON2 = arena.evalCode(`a => a`)(obj);
|
|
497
|
+
expect(objJSON2).toStrictEqual(objJSON);
|
|
498
|
+
arena.expose({ obj });
|
|
499
|
+
const exposedObj = arena.evalCode(`obj`);
|
|
500
|
+
expect(exposedObj).toStrictEqual(objJSON);
|
|
501
|
+
expect(exposedObj).not.toBe(objJSON2);
|
|
502
|
+
|
|
503
|
+
arena.dispose();
|
|
504
|
+
vm.dispose();
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test("conditional", async () => {
|
|
508
|
+
const vm = (await getQuickJS()).createVm();
|
|
509
|
+
const arena = new Arena(vm, {
|
|
510
|
+
isMarshalable: (o) => o !== globalThis,
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
const obj = { a: 1 };
|
|
514
|
+
expect(arena.evalCode(`s => s === undefined`)(globalThis)).toBe(true);
|
|
515
|
+
expect(arena.evalCode(`s => s === undefined`)(obj)).toBe(false);
|
|
516
|
+
arena.expose({ aaa: globalThis, bbb: obj });
|
|
517
|
+
expect(arena.evalCode(`aaa`)).toBeUndefined();
|
|
518
|
+
expect(arena.evalCode(`bbb`)).toBe(obj);
|
|
519
|
+
|
|
520
|
+
arena.dispose();
|
|
521
|
+
vm.dispose();
|
|
522
|
+
});
|
|
308
523
|
});
|