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.
- package/README.md +28 -7
- package/dist/index.d.ts +12 -7
- package/dist/quickjs-emscripten-sync.mjs +842 -0
- package/dist/quickjs-emscripten-sync.umd.js +15 -15
- package/package.json +9 -18
- package/src/default.ts +2 -2
- package/src/index.test.ts +21 -13
- package/src/index.ts +30 -43
- package/src/marshal/custom.test.ts +50 -0
- package/src/marshal/custom.ts +36 -0
- package/src/marshal/function.test.ts +17 -37
- package/src/marshal/function.ts +8 -12
- package/src/marshal/index.test.ts +35 -39
- package/src/marshal/index.ts +6 -9
- package/src/marshal/json.test.ts +9 -15
- package/src/marshal/json.ts +1 -4
- package/src/marshal/object.test.ts +19 -51
- package/src/marshal/object.ts +3 -11
- package/src/marshal/primitive.test.ts +4 -13
- package/src/marshal/primitive.ts +1 -1
- package/src/marshal/promise.test.ts +9 -10
- package/src/marshal/promise.ts +4 -11
- package/src/marshal/properties.test.ts +7 -14
- package/src/marshal/properties.ts +6 -9
- package/src/unmarshal/custom.test.ts +50 -0
- package/src/unmarshal/custom.ts +31 -0
- package/src/unmarshal/function.test.ts +20 -44
- package/src/unmarshal/function.ts +7 -17
- package/src/unmarshal/index.test.ts +30 -23
- package/src/unmarshal/index.ts +4 -6
- package/src/unmarshal/object.test.ts +9 -17
- package/src/unmarshal/object.ts +7 -12
- package/src/unmarshal/primitive.test.ts +1 -4
- package/src/unmarshal/primitive.ts +3 -10
- package/src/unmarshal/promise.test.ts +3 -3
- package/src/unmarshal/promise.ts +3 -10
- package/src/unmarshal/properties.test.ts +2 -2
- package/src/unmarshal/properties.ts +4 -8
- package/src/util.test.ts +1 -7
- package/src/util.ts +3 -8
- package/src/vmmap.ts +13 -31
- package/src/vmutil.test.ts +15 -29
- package/src/vmutil.ts +12 -39
- package/src/wrapper.test.ts +27 -90
- package/src/wrapper.ts +43 -50
- package/dist/quickjs-emscripten-sync.es.js +0 -962
- package/src/marshal/symbol.test.ts +0 -24
- package/src/marshal/symbol.ts +0 -21
- package/src/unmarshal/symbol.test.ts +0 -25
- package/src/unmarshal/symbol.ts +0 -12
package/src/wrapper.test.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { QuickJSHandle, getQuickJS } from "quickjs-emscripten";
|
|
2
2
|
import { expect, test, vi } from "vitest";
|
|
3
3
|
|
|
4
|
+
import { call, eq, json } from "./vmutil";
|
|
4
5
|
import {
|
|
5
6
|
wrap,
|
|
6
7
|
unwrap,
|
|
@@ -10,7 +11,6 @@ import {
|
|
|
10
11
|
isHandleWrapped,
|
|
11
12
|
SyncMode,
|
|
12
13
|
} from "./wrapper";
|
|
13
|
-
import { call, eq, json } from "./vmutil";
|
|
14
14
|
|
|
15
15
|
test("wrap, unwrap, isWrapped", async () => {
|
|
16
16
|
const ctx = (await getQuickJS()).newContext();
|
|
@@ -24,34 +24,18 @@ test("wrap, unwrap, isWrapped", async () => {
|
|
|
24
24
|
expect(isWrapped(target, proxyKeySymbol)).toBe(false);
|
|
25
25
|
expect(unwrap(target, proxyKeySymbol)).toBe(target);
|
|
26
26
|
|
|
27
|
-
const wrapped = wrap(
|
|
28
|
-
ctx,
|
|
29
|
-
target,
|
|
30
|
-
proxyKeySymbol,
|
|
31
|
-
proxyKeySymbolHandle,
|
|
32
|
-
marshal,
|
|
33
|
-
syncMode
|
|
34
|
-
);
|
|
27
|
+
const wrapped = wrap(ctx, target, proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode);
|
|
35
28
|
if (!wrapped) throw new Error("wrapped is undefined");
|
|
36
29
|
|
|
37
30
|
expect(wrapped).toEqual(target);
|
|
38
31
|
expect(isWrapped(wrapped, proxyKeySymbol)).toBe(true);
|
|
39
32
|
expect(unwrap(wrapped, proxyKeySymbol)).toBe(target);
|
|
40
33
|
|
|
41
|
-
expect(
|
|
42
|
-
wrap(ctx, wrapped, proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode)
|
|
43
|
-
).toBe(wrapped);
|
|
34
|
+
expect(wrap(ctx, wrapped, proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode)).toBe(wrapped);
|
|
44
35
|
|
|
45
36
|
// promise cannot be wrapped
|
|
46
37
|
expect(
|
|
47
|
-
wrap(
|
|
48
|
-
ctx,
|
|
49
|
-
Promise.resolve(1),
|
|
50
|
-
proxyKeySymbol,
|
|
51
|
-
proxyKeySymbolHandle,
|
|
52
|
-
marshal,
|
|
53
|
-
syncMode
|
|
54
|
-
)
|
|
38
|
+
wrap(ctx, Promise.resolve(1), proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode),
|
|
55
39
|
).toBeUndefined();
|
|
56
40
|
|
|
57
41
|
proxyKeySymbolHandle.dispose();
|
|
@@ -68,14 +52,7 @@ test("wrap without sync", async () => {
|
|
|
68
52
|
const marshal = vi.fn();
|
|
69
53
|
const syncMode = vi.fn();
|
|
70
54
|
|
|
71
|
-
const wrapped = wrap(
|
|
72
|
-
ctx,
|
|
73
|
-
target,
|
|
74
|
-
proxyKeySymbol,
|
|
75
|
-
proxyKeySymbolHandle,
|
|
76
|
-
marshal,
|
|
77
|
-
syncMode
|
|
78
|
-
);
|
|
55
|
+
const wrapped = wrap(ctx, target, proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode);
|
|
79
56
|
if (!wrapped) throw new Error("wrapped is undefined");
|
|
80
57
|
|
|
81
58
|
expect(marshal).toBeCalledTimes(0);
|
|
@@ -109,14 +86,7 @@ test("wrap with both sync", async () => {
|
|
|
109
86
|
]);
|
|
110
87
|
const syncMode = vi.fn((): SyncMode => "both");
|
|
111
88
|
|
|
112
|
-
const wrapped = wrap(
|
|
113
|
-
ctx,
|
|
114
|
-
target,
|
|
115
|
-
proxyKeySymbol,
|
|
116
|
-
proxyKeySymbolHandle,
|
|
117
|
-
marshal,
|
|
118
|
-
syncMode
|
|
119
|
-
);
|
|
89
|
+
const wrapped = wrap(ctx, target, proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode);
|
|
120
90
|
if (!wrapped) throw new Error("wrapped is undefined");
|
|
121
91
|
|
|
122
92
|
expect(marshal).toBeCalledTimes(0);
|
|
@@ -156,14 +126,7 @@ test("wrap with vm sync", async () => {
|
|
|
156
126
|
]);
|
|
157
127
|
const syncMode = vi.fn((): SyncMode => "vm");
|
|
158
128
|
|
|
159
|
-
const wrapped = wrap(
|
|
160
|
-
ctx,
|
|
161
|
-
target,
|
|
162
|
-
proxyKeySymbol,
|
|
163
|
-
proxyKeySymbolHandle,
|
|
164
|
-
marshal,
|
|
165
|
-
syncMode
|
|
166
|
-
);
|
|
129
|
+
const wrapped = wrap(ctx, target, proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode);
|
|
167
130
|
if (!wrapped) throw new Error("wrapped is undefined");
|
|
168
131
|
|
|
169
132
|
expect(marshal).toBeCalledTimes(0);
|
|
@@ -201,10 +164,7 @@ test("wrapHandle, unwrapHandle, isHandleWrapped", async () => {
|
|
|
201
164
|
const syncMode = vi.fn();
|
|
202
165
|
|
|
203
166
|
expect(isHandleWrapped(ctx, handle, proxyKeySymbolHandle)).toBe(false);
|
|
204
|
-
expect(unwrapHandle(ctx, handle, proxyKeySymbolHandle)).toEqual([
|
|
205
|
-
handle,
|
|
206
|
-
false,
|
|
207
|
-
]);
|
|
167
|
+
expect(unwrapHandle(ctx, handle, proxyKeySymbolHandle)).toEqual([handle, false]);
|
|
208
168
|
|
|
209
169
|
const [wrapped, w] = wrapHandle(
|
|
210
170
|
ctx,
|
|
@@ -212,7 +172,7 @@ test("wrapHandle, unwrapHandle, isHandleWrapped", async () => {
|
|
|
212
172
|
proxyKeySymbol,
|
|
213
173
|
proxyKeySymbolHandle,
|
|
214
174
|
unmarshal,
|
|
215
|
-
syncMode
|
|
175
|
+
syncMode,
|
|
216
176
|
);
|
|
217
177
|
if (!wrapped || !w) throw new Error("wrapped is undefined");
|
|
218
178
|
|
|
@@ -220,13 +180,9 @@ test("wrapHandle, unwrapHandle, isHandleWrapped", async () => {
|
|
|
220
180
|
expect(ctx.dump(ctx.getProp(wrapped, "a"))).toBe(1);
|
|
221
181
|
expect(isHandleWrapped(ctx, wrapped, proxyKeySymbolHandle)).toBe(true);
|
|
222
182
|
|
|
223
|
-
const [handle2, unwrapped2] = unwrapHandle(
|
|
224
|
-
ctx,
|
|
225
|
-
wrapped,
|
|
226
|
-
proxyKeySymbolHandle
|
|
227
|
-
);
|
|
183
|
+
const [handle2, unwrapped2] = unwrapHandle(ctx, wrapped, proxyKeySymbolHandle);
|
|
228
184
|
expect(unwrapped2).toBe(true);
|
|
229
|
-
handle2.consume(
|
|
185
|
+
handle2.consume(h => {
|
|
230
186
|
expect(eq(ctx, handle, h)).toBe(true);
|
|
231
187
|
});
|
|
232
188
|
|
|
@@ -236,15 +192,13 @@ test("wrapHandle, unwrapHandle, isHandleWrapped", async () => {
|
|
|
236
192
|
proxyKeySymbol,
|
|
237
193
|
proxyKeySymbolHandle,
|
|
238
194
|
unmarshal,
|
|
239
|
-
syncMode
|
|
195
|
+
syncMode,
|
|
240
196
|
);
|
|
241
197
|
expect(wrapped2 === wrapped).toBe(true);
|
|
242
198
|
|
|
243
199
|
// promise cannot be wrapped
|
|
244
200
|
const deferred = ctx.newPromise();
|
|
245
|
-
expect(isHandleWrapped(ctx, deferred.handle, proxyKeySymbolHandle)).toBe(
|
|
246
|
-
true
|
|
247
|
-
);
|
|
201
|
+
expect(isHandleWrapped(ctx, deferred.handle, proxyKeySymbolHandle)).toBe(true);
|
|
248
202
|
|
|
249
203
|
deferred.dispose();
|
|
250
204
|
wrapped.dispose();
|
|
@@ -260,7 +214,7 @@ test("wrapHandle without sync", async () => {
|
|
|
260
214
|
const proxyKeySymbol = Symbol();
|
|
261
215
|
const proxyKeySymbolHandle = ctx.unwrapResult(ctx.evalCode(`Symbol()`));
|
|
262
216
|
const unmarshal = vi.fn((h: QuickJSHandle) =>
|
|
263
|
-
wrapped && eq(ctx, h, wrapped) ? target : ctx.dump(h)
|
|
217
|
+
wrapped && eq(ctx, h, wrapped) ? target : ctx.dump(h),
|
|
264
218
|
);
|
|
265
219
|
const syncMode = vi.fn();
|
|
266
220
|
|
|
@@ -270,7 +224,7 @@ test("wrapHandle without sync", async () => {
|
|
|
270
224
|
proxyKeySymbol,
|
|
271
225
|
proxyKeySymbolHandle,
|
|
272
226
|
unmarshal,
|
|
273
|
-
syncMode
|
|
227
|
+
syncMode,
|
|
274
228
|
);
|
|
275
229
|
if (!wrapped || !w) throw new Error("wrapped is undefined");
|
|
276
230
|
|
|
@@ -309,7 +263,7 @@ test("wrapHandle with both sync", async () => {
|
|
|
309
263
|
proxyKeySymbol,
|
|
310
264
|
proxyKeySymbolHandle,
|
|
311
265
|
unmarshal,
|
|
312
|
-
syncMode
|
|
266
|
+
syncMode,
|
|
313
267
|
);
|
|
314
268
|
if (!wrapped || !w) throw new Error("wrapped is undefined");
|
|
315
269
|
|
|
@@ -333,9 +287,7 @@ test("wrapHandle with both sync", async () => {
|
|
|
333
287
|
|
|
334
288
|
// changing __proto__ will be blocked
|
|
335
289
|
call(ctx, `a => { a.__proto__ = null; }`, undefined, wrapped);
|
|
336
|
-
expect(ctx.dump(call(ctx, `Object.getPrototypeOf`, undefined, handle))).toBe(
|
|
337
|
-
null
|
|
338
|
-
);
|
|
290
|
+
expect(ctx.dump(call(ctx, `Object.getPrototypeOf`, undefined, handle))).toBe(null);
|
|
339
291
|
expect(Object.getPrototypeOf(target)).toBe(Object.prototype); // not changed
|
|
340
292
|
|
|
341
293
|
wrapped.dispose();
|
|
@@ -351,7 +303,7 @@ test("wrapHandle with host sync", async () => {
|
|
|
351
303
|
const proxyKeySymbol = Symbol();
|
|
352
304
|
const proxyKeySymbolHandle = ctx.unwrapResult(ctx.evalCode(`Symbol()`));
|
|
353
305
|
const unmarshal = vi.fn((handle: QuickJSHandle) =>
|
|
354
|
-
wrapped && eq(ctx, handle, wrapped) ? target : ctx.dump(handle)
|
|
306
|
+
wrapped && eq(ctx, handle, wrapped) ? target : ctx.dump(handle),
|
|
355
307
|
);
|
|
356
308
|
const syncMode = vi.fn((): SyncMode => "host");
|
|
357
309
|
|
|
@@ -361,7 +313,7 @@ test("wrapHandle with host sync", async () => {
|
|
|
361
313
|
proxyKeySymbol,
|
|
362
314
|
proxyKeySymbolHandle,
|
|
363
315
|
unmarshal,
|
|
364
|
-
syncMode
|
|
316
|
+
syncMode,
|
|
365
317
|
);
|
|
366
318
|
if (!wrapped || !w) throw new Error("wrapped is undefined");
|
|
367
319
|
|
|
@@ -400,18 +352,11 @@ test("wrap and wrapHandle", async () => {
|
|
|
400
352
|
false,
|
|
401
353
|
]);
|
|
402
354
|
const unmarshal = vi.fn((handle: QuickJSHandle) =>
|
|
403
|
-
wrappedHandle && eq(ctx, handle, wrappedHandle) ? wrapped : ctx.dump(handle)
|
|
355
|
+
wrappedHandle && eq(ctx, handle, wrappedHandle) ? wrapped : ctx.dump(handle),
|
|
404
356
|
);
|
|
405
357
|
const syncMode = vi.fn((): SyncMode => "both");
|
|
406
358
|
|
|
407
|
-
const wrapped = wrap(
|
|
408
|
-
ctx,
|
|
409
|
-
target,
|
|
410
|
-
proxyKeySymbol,
|
|
411
|
-
proxyKeySymbolHandle,
|
|
412
|
-
marshal,
|
|
413
|
-
syncMode
|
|
414
|
-
);
|
|
359
|
+
const wrapped = wrap(ctx, target, proxyKeySymbol, proxyKeySymbolHandle, marshal, syncMode);
|
|
415
360
|
if (!wrapped) throw new Error("wrapped is undefined");
|
|
416
361
|
const [wrappedHandle, w] = wrapHandle(
|
|
417
362
|
ctx,
|
|
@@ -419,7 +364,7 @@ test("wrap and wrapHandle", async () => {
|
|
|
419
364
|
proxyKeySymbol,
|
|
420
365
|
proxyKeySymbolHandle,
|
|
421
366
|
unmarshal,
|
|
422
|
-
syncMode
|
|
367
|
+
syncMode,
|
|
423
368
|
);
|
|
424
369
|
if (!wrappedHandle || !w) throw new Error("wrappedHandle is undefined");
|
|
425
370
|
|
|
@@ -459,20 +404,12 @@ test("non object", async () => {
|
|
|
459
404
|
const proxyKeySymbol = Symbol();
|
|
460
405
|
const proxyKeySymbolHandle = ctx.unwrapResult(ctx.evalCode(`Symbol()`));
|
|
461
406
|
|
|
462
|
-
expect(
|
|
463
|
-
wrap(ctx, target, proxyKeySymbol, proxyKeySymbolHandle, vi.fn(), vi.fn())
|
|
464
|
-
).toBe(undefined);
|
|
407
|
+
expect(wrap(ctx, target, proxyKeySymbol, proxyKeySymbolHandle, vi.fn(), vi.fn())).toBe(undefined);
|
|
465
408
|
|
|
466
|
-
expect(
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
proxyKeySymbol,
|
|
471
|
-
proxyKeySymbolHandle,
|
|
472
|
-
vi.fn(),
|
|
473
|
-
vi.fn()
|
|
474
|
-
)
|
|
475
|
-
).toEqual([undefined, false]);
|
|
409
|
+
expect(wrapHandle(ctx, handle, proxyKeySymbol, proxyKeySymbolHandle, vi.fn(), vi.fn())).toEqual([
|
|
410
|
+
undefined,
|
|
411
|
+
false,
|
|
412
|
+
]);
|
|
476
413
|
|
|
477
414
|
proxyKeySymbolHandle.dispose();
|
|
478
415
|
ctx.dispose();
|
package/src/wrapper.ts
CHANGED
|
@@ -13,10 +13,18 @@ export function wrap<T = any>(
|
|
|
13
13
|
proxyKeySymbol: symbol,
|
|
14
14
|
proxyKeySymbolHandle: QuickJSHandle,
|
|
15
15
|
marshal: (target: any) => [QuickJSHandle, boolean],
|
|
16
|
-
syncMode?: (target: T) => SyncMode | undefined
|
|
16
|
+
syncMode?: (target: T) => SyncMode | undefined,
|
|
17
|
+
wrappable?: (target: unknown) => boolean,
|
|
17
18
|
): Wrapped<T> | undefined {
|
|
18
|
-
// promise cannot be wrapped
|
|
19
|
-
if (
|
|
19
|
+
// promise and date cannot be wrapped
|
|
20
|
+
if (
|
|
21
|
+
!isObject(target) ||
|
|
22
|
+
target instanceof Promise ||
|
|
23
|
+
target instanceof Date ||
|
|
24
|
+
(wrappable && !wrappable(target))
|
|
25
|
+
)
|
|
26
|
+
return undefined;
|
|
27
|
+
|
|
20
28
|
if (isWrapped(target, proxyKeySymbol)) return target;
|
|
21
29
|
|
|
22
30
|
const rec = new Proxy(target as any, {
|
|
@@ -26,56 +34,39 @@ export function wrap<T = any>(
|
|
|
26
34
|
set(obj, key, value, receiver) {
|
|
27
35
|
const v = unwrap(value, proxyKeySymbol);
|
|
28
36
|
const sync = syncMode?.(receiver) ?? "host";
|
|
29
|
-
if (
|
|
30
|
-
(sync !== "vm" && !Reflect.set(obj, key, v, receiver)) ||
|
|
31
|
-
sync === "host" ||
|
|
32
|
-
!ctx.alive
|
|
33
|
-
)
|
|
37
|
+
if ((sync !== "vm" && !Reflect.set(obj, key, v, receiver)) || sync === "host" || !ctx.alive)
|
|
34
38
|
return true;
|
|
35
39
|
|
|
36
40
|
mayConsumeAll(
|
|
37
41
|
[marshal(receiver), marshal(key), marshal(v)],
|
|
38
42
|
(receiverHandle, keyHandle, valueHandle) => {
|
|
39
|
-
const [handle2, unwrapped] = unwrapHandle(
|
|
40
|
-
ctx,
|
|
41
|
-
receiverHandle,
|
|
42
|
-
proxyKeySymbolHandle
|
|
43
|
-
);
|
|
43
|
+
const [handle2, unwrapped] = unwrapHandle(ctx, receiverHandle, proxyKeySymbolHandle);
|
|
44
44
|
if (unwrapped) {
|
|
45
|
-
handle2.consume(
|
|
45
|
+
handle2.consume(h => ctx.setProp(h, keyHandle, valueHandle));
|
|
46
46
|
} else {
|
|
47
47
|
ctx.setProp(handle2, keyHandle, valueHandle);
|
|
48
48
|
}
|
|
49
|
-
}
|
|
49
|
+
},
|
|
50
50
|
);
|
|
51
51
|
|
|
52
52
|
return true;
|
|
53
53
|
},
|
|
54
54
|
deleteProperty(obj, key) {
|
|
55
55
|
const sync = syncMode?.(rec) ?? "host";
|
|
56
|
-
return mayConsumeAll(
|
|
57
|
-
[
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (sync === "host" || !ctx.alive) return true;
|
|
67
|
-
|
|
68
|
-
if (unwrapped) {
|
|
69
|
-
handle2.consume((h) =>
|
|
70
|
-
call(ctx, `(a, b) => delete a[b]`, undefined, h, keyHandle)
|
|
71
|
-
);
|
|
72
|
-
} else {
|
|
73
|
-
call(ctx, `(a, b) => delete a[b]`, undefined, handle2, keyHandle);
|
|
74
|
-
}
|
|
56
|
+
return mayConsumeAll([marshal(rec), marshal(key)], (recHandle, keyHandle) => {
|
|
57
|
+
const [handle2, unwrapped] = unwrapHandle(ctx, recHandle, proxyKeySymbolHandle);
|
|
58
|
+
|
|
59
|
+
if (sync === "vm" || Reflect.deleteProperty(obj, key)) {
|
|
60
|
+
if (sync === "host" || !ctx.alive) return true;
|
|
61
|
+
|
|
62
|
+
if (unwrapped) {
|
|
63
|
+
handle2.consume(h => call(ctx, `(a, b) => delete a[b]`, undefined, h, keyHandle));
|
|
64
|
+
} else {
|
|
65
|
+
call(ctx, `(a, b) => delete a[b]`, undefined, handle2, keyHandle);
|
|
75
66
|
}
|
|
76
|
-
return true;
|
|
77
67
|
}
|
|
78
|
-
|
|
68
|
+
return true;
|
|
69
|
+
});
|
|
79
70
|
},
|
|
80
71
|
}) as Wrapped<T>;
|
|
81
72
|
return rec;
|
|
@@ -87,15 +78,17 @@ export function wrapHandle(
|
|
|
87
78
|
proxyKeySymbol: symbol,
|
|
88
79
|
proxyKeySymbolHandle: QuickJSHandle,
|
|
89
80
|
unmarshal: (handle: QuickJSHandle) => any,
|
|
90
|
-
syncMode?: (target: QuickJSHandle) => SyncMode | undefined
|
|
81
|
+
syncMode?: (target: QuickJSHandle) => SyncMode | undefined,
|
|
82
|
+
wrappable?: (target: QuickJSHandle, ctx: QuickJSContext) => boolean,
|
|
91
83
|
): [Wrapped<QuickJSHandle> | undefined, boolean] {
|
|
92
|
-
if (!isHandleObject(ctx, handle)
|
|
93
|
-
|
|
94
|
-
|
|
84
|
+
if (!isHandleObject(ctx, handle) || (wrappable && !wrappable(handle, ctx)))
|
|
85
|
+
return [undefined, false];
|
|
86
|
+
|
|
87
|
+
if (isHandleWrapped(ctx, handle, proxyKeySymbolHandle)) return [handle, false];
|
|
95
88
|
|
|
96
89
|
return consumeAll(
|
|
97
90
|
[
|
|
98
|
-
ctx.newFunction("getSyncMode",
|
|
91
|
+
ctx.newFunction("getSyncMode", h => {
|
|
99
92
|
const res = syncMode?.(unmarshal(h));
|
|
100
93
|
if (typeof res === "string") return ctx.newString(res);
|
|
101
94
|
return ctx.undefined;
|
|
@@ -115,7 +108,7 @@ export function wrapHandle(
|
|
|
115
108
|
delete unwrap(target, proxyKeySymbol)[key];
|
|
116
109
|
}),
|
|
117
110
|
],
|
|
118
|
-
|
|
111
|
+
args => [
|
|
119
112
|
call(
|
|
120
113
|
ctx,
|
|
121
114
|
`(target, sym, getSyncMode, setter, deleter) => {
|
|
@@ -150,10 +143,10 @@ export function wrapHandle(
|
|
|
150
143
|
undefined,
|
|
151
144
|
handle,
|
|
152
145
|
proxyKeySymbolHandle,
|
|
153
|
-
...args
|
|
146
|
+
...args,
|
|
154
147
|
) as Wrapped<QuickJSHandle>,
|
|
155
148
|
true,
|
|
156
|
-
]
|
|
149
|
+
],
|
|
157
150
|
);
|
|
158
151
|
}
|
|
159
152
|
|
|
@@ -164,7 +157,7 @@ export function unwrap<T>(obj: T, key: string | symbol): T {
|
|
|
164
157
|
export function unwrapHandle(
|
|
165
158
|
ctx: QuickJSContext,
|
|
166
159
|
handle: QuickJSHandle,
|
|
167
|
-
key: QuickJSHandle
|
|
160
|
+
key: QuickJSHandle,
|
|
168
161
|
): [QuickJSHandle, boolean] {
|
|
169
162
|
if (!isHandleWrapped(ctx, handle, key)) return [handle, false];
|
|
170
163
|
return [ctx.getProp(handle, key), true];
|
|
@@ -177,16 +170,16 @@ export function isWrapped<T>(obj: T, key: string | symbol): obj is Wrapped<T> {
|
|
|
177
170
|
export function isHandleWrapped(
|
|
178
171
|
ctx: QuickJSContext,
|
|
179
172
|
handle: QuickJSHandle,
|
|
180
|
-
key: QuickJSHandle
|
|
173
|
+
key: QuickJSHandle,
|
|
181
174
|
): handle is Wrapped<QuickJSHandle> {
|
|
182
175
|
return !!ctx.dump(
|
|
183
176
|
call(
|
|
184
177
|
ctx,
|
|
185
|
-
// promise cannot be wrapped
|
|
186
|
-
`(a, s) => (a instanceof Promise) || (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]`,
|
|
178
|
+
// promise and date cannot be wrapped
|
|
179
|
+
`(a, s) => (a instanceof Promise) || (a instanceof Date) || (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]`,
|
|
187
180
|
undefined,
|
|
188
181
|
handle,
|
|
189
|
-
key
|
|
190
|
-
)
|
|
182
|
+
key,
|
|
183
|
+
),
|
|
191
184
|
);
|
|
192
185
|
}
|