@ricsam/isolate-daemon 0.1.5 → 0.1.6
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 +27 -0
- package/dist/cjs/callback-fs-handler.cjs +68 -37
- package/dist/cjs/callback-fs-handler.cjs.map +3 -3
- package/dist/cjs/connection.cjs +255 -69
- package/dist/cjs/connection.cjs.map +3 -3
- package/dist/cjs/index.cjs +4 -2
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/callback-fs-handler.mjs +68 -37
- package/dist/mjs/callback-fs-handler.mjs.map +3 -3
- package/dist/mjs/connection.mjs +255 -70
- package/dist/mjs/connection.mjs.map +3 -3
- package/dist/mjs/index.mjs +4 -2
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/callback-fs-handler.d.ts +3 -3
- package/dist/types/types.d.ts +37 -1
- package/package.json +1 -1
package/dist/cjs/connection.cjs
CHANGED
|
@@ -83,18 +83,26 @@ function handleConnection(socket, state) {
|
|
|
83
83
|
for (const isolateId of connection.isolates) {
|
|
84
84
|
const instance = state.isolates.get(isolateId);
|
|
85
85
|
if (instance) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
if (instance.namespaceId != null && !instance.isDisposed) {
|
|
87
|
+
softDeleteRuntime(instance, state);
|
|
88
|
+
} else if (!instance.isDisposed) {
|
|
89
|
+
try {
|
|
90
|
+
if (instance.playwrightHandle) {
|
|
91
|
+
instance.playwrightHandle.dispose();
|
|
92
|
+
}
|
|
93
|
+
instance.runtime.dispose();
|
|
94
|
+
} catch {}
|
|
95
|
+
state.isolates.delete(isolateId);
|
|
96
|
+
}
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
for (const [, pending] of connection.pendingCallbacks) {
|
|
100
|
+
if (pending.timeoutId) {
|
|
101
|
+
clearTimeout(pending.timeoutId);
|
|
102
|
+
}
|
|
96
103
|
pending.reject(new Error("Connection closed"));
|
|
97
104
|
}
|
|
105
|
+
connection.pendingCallbacks.clear();
|
|
98
106
|
state.connections.delete(socket);
|
|
99
107
|
});
|
|
100
108
|
socket.on("error", (err) => {
|
|
@@ -220,10 +228,147 @@ async function handleMessage(message, connection, state) {
|
|
|
220
228
|
sendError(connection.socket, message.requestId ?? 0, import_isolate_protocol.ErrorCode.UNKNOWN_MESSAGE_TYPE, `Unknown message type: ${message.type}`);
|
|
221
229
|
}
|
|
222
230
|
}
|
|
231
|
+
function softDeleteRuntime(instance, state) {
|
|
232
|
+
instance.isDisposed = true;
|
|
233
|
+
instance.disposedAt = Date.now();
|
|
234
|
+
instance.ownerConnection = null;
|
|
235
|
+
instance.callbacks.clear();
|
|
236
|
+
instance.runtime.timers.clearAll();
|
|
237
|
+
instance.runtime.console.reset();
|
|
238
|
+
instance.pendingCallbacks.length = 0;
|
|
239
|
+
instance.returnedCallbacks?.clear();
|
|
240
|
+
instance.returnedPromises?.clear();
|
|
241
|
+
instance.returnedIterators?.clear();
|
|
242
|
+
}
|
|
243
|
+
function reuseNamespacedRuntime(instance, connection, message, state) {
|
|
244
|
+
instance.ownerConnection = connection.socket;
|
|
245
|
+
instance.isDisposed = false;
|
|
246
|
+
instance.disposedAt = undefined;
|
|
247
|
+
instance.lastActivity = Date.now();
|
|
248
|
+
connection.isolates.add(instance.isolateId);
|
|
249
|
+
const callbacks = message.options.callbacks;
|
|
250
|
+
if (instance.callbackContext) {
|
|
251
|
+
instance.callbackContext.connection = connection;
|
|
252
|
+
instance.callbackContext.consoleOnEntry = callbacks?.console?.onEntry?.callbackId;
|
|
253
|
+
instance.callbackContext.fetch = callbacks?.fetch?.callbackId;
|
|
254
|
+
instance.callbackContext.moduleLoader = callbacks?.moduleLoader?.callbackId;
|
|
255
|
+
instance.callbackContext.fs = {
|
|
256
|
+
readFile: callbacks?.fs?.readFile?.callbackId,
|
|
257
|
+
writeFile: callbacks?.fs?.writeFile?.callbackId,
|
|
258
|
+
stat: callbacks?.fs?.stat?.callbackId,
|
|
259
|
+
readdir: callbacks?.fs?.readdir?.callbackId,
|
|
260
|
+
unlink: callbacks?.fs?.unlink?.callbackId,
|
|
261
|
+
mkdir: callbacks?.fs?.mkdir?.callbackId,
|
|
262
|
+
rmdir: callbacks?.fs?.rmdir?.callbackId
|
|
263
|
+
};
|
|
264
|
+
instance.callbackContext.custom.clear();
|
|
265
|
+
if (callbacks?.custom) {
|
|
266
|
+
for (const [name, reg] of Object.entries(callbacks.custom)) {
|
|
267
|
+
if (reg) {
|
|
268
|
+
instance.callbackContext.custom.set(name, reg.callbackId);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
instance.callbacks.clear();
|
|
274
|
+
if (callbacks?.console?.onEntry) {
|
|
275
|
+
instance.callbacks.set(callbacks.console.onEntry.callbackId, {
|
|
276
|
+
...callbacks.console.onEntry,
|
|
277
|
+
name: "onEntry"
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
if (callbacks?.fetch) {
|
|
281
|
+
instance.callbacks.set(callbacks.fetch.callbackId, callbacks.fetch);
|
|
282
|
+
}
|
|
283
|
+
if (callbacks?.fs) {
|
|
284
|
+
for (const [name, reg] of Object.entries(callbacks.fs)) {
|
|
285
|
+
if (reg) {
|
|
286
|
+
instance.callbacks.set(reg.callbackId, { ...reg, name });
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (callbacks?.moduleLoader) {
|
|
291
|
+
instance.moduleLoaderCallbackId = callbacks.moduleLoader.callbackId;
|
|
292
|
+
instance.callbacks.set(callbacks.moduleLoader.callbackId, callbacks.moduleLoader);
|
|
293
|
+
}
|
|
294
|
+
if (callbacks?.custom) {
|
|
295
|
+
for (const [name, reg] of Object.entries(callbacks.custom)) {
|
|
296
|
+
if (reg) {
|
|
297
|
+
instance.callbacks.set(reg.callbackId, { ...reg, name });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
instance.returnedCallbacks = new Map;
|
|
302
|
+
instance.returnedPromises = new Map;
|
|
303
|
+
instance.returnedIterators = new Map;
|
|
304
|
+
instance.nextLocalCallbackId = 1e6;
|
|
305
|
+
if (callbacks?.custom) {
|
|
306
|
+
const newCallbackIdMap = {};
|
|
307
|
+
for (const [name, reg] of Object.entries(callbacks.custom)) {
|
|
308
|
+
if (reg) {
|
|
309
|
+
newCallbackIdMap[name] = reg.callbackId;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
instance.runtime.context.global.setSync("__customFnCallbackIds", new import_isolated_vm.default.ExternalCopy(newCallbackIdMap).copyInto());
|
|
314
|
+
} catch {}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function evictOldestDisposedRuntime(state) {
|
|
318
|
+
let oldest = null;
|
|
319
|
+
let oldestTime = Infinity;
|
|
320
|
+
for (const [, instance] of state.isolates) {
|
|
321
|
+
if (instance.isDisposed && instance.disposedAt !== undefined) {
|
|
322
|
+
if (instance.disposedAt < oldestTime) {
|
|
323
|
+
oldestTime = instance.disposedAt;
|
|
324
|
+
oldest = instance;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (oldest) {
|
|
329
|
+
try {
|
|
330
|
+
if (oldest.playwrightHandle) {
|
|
331
|
+
oldest.playwrightHandle.dispose();
|
|
332
|
+
}
|
|
333
|
+
oldest.runtime.dispose();
|
|
334
|
+
} catch {}
|
|
335
|
+
state.isolates.delete(oldest.isolateId);
|
|
336
|
+
if (oldest.namespaceId != null) {
|
|
337
|
+
state.namespacedRuntimes.delete(oldest.namespaceId);
|
|
338
|
+
}
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
223
343
|
async function handleCreateRuntime(message, connection, state) {
|
|
344
|
+
const namespaceId = message.options.namespaceId;
|
|
345
|
+
if (namespaceId != null) {
|
|
346
|
+
const existing = state.namespacedRuntimes.get(namespaceId);
|
|
347
|
+
if (existing) {
|
|
348
|
+
if (!existing.isDisposed) {
|
|
349
|
+
if (existing.ownerConnection === connection.socket) {
|
|
350
|
+
sendOk(connection.socket, message.requestId, {
|
|
351
|
+
isolateId: existing.isolateId,
|
|
352
|
+
reused: true
|
|
353
|
+
});
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, `Namespace "${namespaceId}" already has an active runtime`);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
reuseNamespacedRuntime(existing, connection, message, state);
|
|
360
|
+
sendOk(connection.socket, message.requestId, {
|
|
361
|
+
isolateId: existing.isolateId,
|
|
362
|
+
reused: true
|
|
363
|
+
});
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
224
367
|
if (state.isolates.size >= state.options.maxIsolates) {
|
|
225
|
-
|
|
226
|
-
|
|
368
|
+
if (!evictOldestDisposedRuntime(state)) {
|
|
369
|
+
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_MEMORY_LIMIT, `Maximum isolates (${state.options.maxIsolates}) reached`);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
227
372
|
}
|
|
228
373
|
try {
|
|
229
374
|
const isolateId = import_node_crypto.randomUUID();
|
|
@@ -233,32 +378,61 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
233
378
|
const moduleLoaderCallback = message.options.callbacks?.moduleLoader;
|
|
234
379
|
const customCallbacks = message.options.callbacks?.custom;
|
|
235
380
|
const pendingCallbacks = [];
|
|
381
|
+
const callbackContext = {
|
|
382
|
+
connection,
|
|
383
|
+
consoleOnEntry: consoleCallbacks?.onEntry?.callbackId,
|
|
384
|
+
fetch: fetchCallback?.callbackId,
|
|
385
|
+
moduleLoader: moduleLoaderCallback?.callbackId,
|
|
386
|
+
fs: {
|
|
387
|
+
readFile: fsCallbacks?.readFile?.callbackId,
|
|
388
|
+
writeFile: fsCallbacks?.writeFile?.callbackId,
|
|
389
|
+
stat: fsCallbacks?.stat?.callbackId,
|
|
390
|
+
readdir: fsCallbacks?.readdir?.callbackId,
|
|
391
|
+
unlink: fsCallbacks?.unlink?.callbackId,
|
|
392
|
+
mkdir: fsCallbacks?.mkdir?.callbackId,
|
|
393
|
+
rmdir: fsCallbacks?.rmdir?.callbackId
|
|
394
|
+
},
|
|
395
|
+
custom: new Map(customCallbacks ? Object.entries(customCallbacks).map(([name, reg]) => [name, reg.callbackId]) : [])
|
|
396
|
+
};
|
|
236
397
|
const runtime = await import_isolate_runtime.createInternalRuntime({
|
|
237
398
|
memoryLimitMB: message.options.memoryLimitMB ?? state.options.defaultMemoryLimitMB,
|
|
238
399
|
cwd: message.options.cwd,
|
|
239
|
-
console:
|
|
400
|
+
console: {
|
|
240
401
|
onEntry: (entry) => {
|
|
241
|
-
const
|
|
402
|
+
const conn = callbackContext.connection;
|
|
403
|
+
const callbackId = callbackContext.consoleOnEntry;
|
|
404
|
+
if (!conn || callbackId === undefined)
|
|
405
|
+
return;
|
|
406
|
+
const promise = invokeClientCallback(conn, callbackId, [entry]).catch(() => {});
|
|
242
407
|
pendingCallbacks.push(promise);
|
|
243
408
|
}
|
|
244
|
-
}
|
|
245
|
-
fetch:
|
|
409
|
+
},
|
|
410
|
+
fetch: {
|
|
246
411
|
onFetch: async (request) => {
|
|
412
|
+
const conn = callbackContext.connection;
|
|
413
|
+
const callbackId = callbackContext.fetch;
|
|
414
|
+
if (!conn || callbackId === undefined) {
|
|
415
|
+
throw new Error("Fetch callback not available");
|
|
416
|
+
}
|
|
247
417
|
const serialized = await serializeRequest(request);
|
|
248
|
-
const result = await invokeClientCallback(
|
|
418
|
+
const result = await invokeClientCallback(conn, callbackId, [serialized]);
|
|
249
419
|
return deserializeResponse(result);
|
|
250
420
|
}
|
|
251
|
-
}
|
|
252
|
-
fs:
|
|
421
|
+
},
|
|
422
|
+
fs: {
|
|
253
423
|
getDirectory: async (path) => {
|
|
424
|
+
const conn = callbackContext.connection;
|
|
425
|
+
if (!conn) {
|
|
426
|
+
throw new Error("FS callbacks not available");
|
|
427
|
+
}
|
|
254
428
|
return import_callback_fs_handler.createCallbackFileSystemHandler({
|
|
255
|
-
connection,
|
|
256
|
-
|
|
429
|
+
connection: conn,
|
|
430
|
+
callbackContext,
|
|
257
431
|
invokeClientCallback,
|
|
258
432
|
basePath: path
|
|
259
433
|
});
|
|
260
434
|
}
|
|
261
|
-
}
|
|
435
|
+
}
|
|
262
436
|
});
|
|
263
437
|
const instance = {
|
|
264
438
|
isolateId,
|
|
@@ -271,7 +445,10 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
271
445
|
returnedCallbacks: new Map,
|
|
272
446
|
returnedPromises: new Map,
|
|
273
447
|
returnedIterators: new Map,
|
|
274
|
-
nextLocalCallbackId: 1e6
|
|
448
|
+
nextLocalCallbackId: 1e6,
|
|
449
|
+
namespaceId,
|
|
450
|
+
isDisposed: false,
|
|
451
|
+
callbackContext
|
|
275
452
|
};
|
|
276
453
|
if (moduleLoaderCallback) {
|
|
277
454
|
instance.moduleLoaderCallbackId = moduleLoaderCallback.callbackId;
|
|
@@ -356,6 +533,9 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
356
533
|
state.isolates.set(isolateId, instance);
|
|
357
534
|
connection.isolates.add(isolateId);
|
|
358
535
|
state.stats.totalIsolatesCreated++;
|
|
536
|
+
if (namespaceId != null) {
|
|
537
|
+
state.namespacedRuntimes.set(namespaceId, instance);
|
|
538
|
+
}
|
|
359
539
|
instance.runtime.fetch.onWebSocketCommand((cmd) => {
|
|
360
540
|
let data;
|
|
361
541
|
if (cmd.data instanceof ArrayBuffer) {
|
|
@@ -376,7 +556,7 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
376
556
|
};
|
|
377
557
|
sendMessage(connection.socket, wsCommandMsg);
|
|
378
558
|
});
|
|
379
|
-
sendOk(connection.socket, message.requestId, { isolateId });
|
|
559
|
+
sendOk(connection.socket, message.requestId, { isolateId, reused: false });
|
|
380
560
|
} catch (err) {
|
|
381
561
|
const error = err;
|
|
382
562
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
@@ -393,12 +573,16 @@ async function handleDisposeRuntime(message, connection, state) {
|
|
|
393
573
|
return;
|
|
394
574
|
}
|
|
395
575
|
try {
|
|
396
|
-
if (instance.playwrightHandle) {
|
|
397
|
-
instance.playwrightHandle.dispose();
|
|
398
|
-
}
|
|
399
|
-
instance.runtime.dispose();
|
|
400
|
-
state.isolates.delete(message.isolateId);
|
|
401
576
|
connection.isolates.delete(message.isolateId);
|
|
577
|
+
if (instance.namespaceId != null) {
|
|
578
|
+
softDeleteRuntime(instance, state);
|
|
579
|
+
} else {
|
|
580
|
+
if (instance.playwrightHandle) {
|
|
581
|
+
instance.playwrightHandle.dispose();
|
|
582
|
+
}
|
|
583
|
+
instance.runtime.dispose();
|
|
584
|
+
state.isolates.delete(message.isolateId);
|
|
585
|
+
}
|
|
402
586
|
sendOk(connection.socket, message.requestId);
|
|
403
587
|
} catch (err) {
|
|
404
588
|
const error = err;
|
|
@@ -455,22 +639,21 @@ async function handleDispatchRequest(message, connection, state) {
|
|
|
455
639
|
body: requestBody
|
|
456
640
|
});
|
|
457
641
|
const response = await instance.runtime.fetch.dispatchRequest(request);
|
|
458
|
-
|
|
459
|
-
const knownSize = contentLength ? parseInt(contentLength, 10) : null;
|
|
460
|
-
if (knownSize !== null && knownSize > import_isolate_protocol.STREAM_THRESHOLD) {
|
|
642
|
+
if (response.body) {
|
|
461
643
|
await sendStreamedResponse(connection, message.requestId, response);
|
|
462
644
|
} else {
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
645
|
+
const headers = [];
|
|
646
|
+
response.headers.forEach((value, key) => {
|
|
647
|
+
headers.push([key, value]);
|
|
648
|
+
});
|
|
649
|
+
sendOk(connection.socket, message.requestId, {
|
|
650
|
+
response: {
|
|
651
|
+
status: response.status,
|
|
652
|
+
statusText: response.statusText,
|
|
653
|
+
headers,
|
|
654
|
+
body: null
|
|
470
655
|
}
|
|
471
|
-
}
|
|
472
|
-
await sendStreamedResponse(connection, message.requestId, clonedResponse);
|
|
473
|
-
}
|
|
656
|
+
});
|
|
474
657
|
}
|
|
475
658
|
} catch (err) {
|
|
476
659
|
const error = err;
|
|
@@ -1045,7 +1228,8 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
|
|
|
1045
1228
|
}
|
|
1046
1229
|
result = await callback(...args);
|
|
1047
1230
|
} else {
|
|
1048
|
-
|
|
1231
|
+
const conn = instance.callbackContext?.connection || connection;
|
|
1232
|
+
result = await invokeClientCallback(conn, callbackId, args);
|
|
1049
1233
|
}
|
|
1050
1234
|
const ctx = createMarshalContext();
|
|
1051
1235
|
const marshalledResult = await import_isolate_protocol.marshalValue({ ok: true, value: result }, ctx);
|
|
@@ -1061,6 +1245,11 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
|
|
|
1061
1245
|
});
|
|
1062
1246
|
global.setSync("__customFn_invoke", invokeCallbackRef);
|
|
1063
1247
|
context.evalSync(ISOLATE_MARSHAL_CODE);
|
|
1248
|
+
const callbackIdMap = {};
|
|
1249
|
+
for (const [name, registration] of Object.entries(customCallbacks)) {
|
|
1250
|
+
callbackIdMap[name] = registration.callbackId;
|
|
1251
|
+
}
|
|
1252
|
+
global.setSync("__customFnCallbackIds", new import_isolated_vm.default.ExternalCopy(callbackIdMap).copyInto());
|
|
1064
1253
|
for (const [name, registration] of Object.entries(customCallbacks)) {
|
|
1065
1254
|
if (name.includes(":")) {
|
|
1066
1255
|
continue;
|
|
@@ -1068,10 +1257,11 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
|
|
|
1068
1257
|
if (registration.type === "sync") {
|
|
1069
1258
|
context.evalSync(`
|
|
1070
1259
|
globalThis.${name} = function(...args) {
|
|
1260
|
+
const callbackId = globalThis.__customFnCallbackIds["${name}"];
|
|
1071
1261
|
const argsJson = JSON.stringify(__marshalForHost(args));
|
|
1072
1262
|
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1073
1263
|
undefined,
|
|
1074
|
-
[
|
|
1264
|
+
[callbackId, argsJson]
|
|
1075
1265
|
);
|
|
1076
1266
|
const result = JSON.parse(resultJson);
|
|
1077
1267
|
if (result.ok) {
|
|
@@ -1094,10 +1284,11 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
|
|
|
1094
1284
|
context.evalSync(`
|
|
1095
1285
|
globalThis.${name} = function(...args) {
|
|
1096
1286
|
// Start the iterator and get the iteratorId
|
|
1287
|
+
const startCallbackId = globalThis.__customFnCallbackIds["${name}:start"];
|
|
1097
1288
|
const argsJson = JSON.stringify(__marshalForHost(args));
|
|
1098
1289
|
const startResultJson = __customFn_invoke.applySyncPromise(
|
|
1099
1290
|
undefined,
|
|
1100
|
-
[
|
|
1291
|
+
[startCallbackId, argsJson]
|
|
1101
1292
|
);
|
|
1102
1293
|
const startResult = JSON.parse(startResultJson);
|
|
1103
1294
|
if (!startResult.ok) {
|
|
@@ -1110,10 +1301,11 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
|
|
|
1110
1301
|
return {
|
|
1111
1302
|
[Symbol.asyncIterator]() { return this; },
|
|
1112
1303
|
async next() {
|
|
1304
|
+
const nextCallbackId = globalThis.__customFnCallbackIds["${name}:next"];
|
|
1113
1305
|
const argsJson = JSON.stringify(__marshalForHost([iteratorId]));
|
|
1114
1306
|
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1115
1307
|
undefined,
|
|
1116
|
-
[
|
|
1308
|
+
[nextCallbackId, argsJson]
|
|
1117
1309
|
);
|
|
1118
1310
|
const result = JSON.parse(resultJson);
|
|
1119
1311
|
if (!result.ok) {
|
|
@@ -1125,19 +1317,21 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
|
|
|
1125
1317
|
return { done: val.done, value: val.value };
|
|
1126
1318
|
},
|
|
1127
1319
|
async return(v) {
|
|
1320
|
+
const returnCallbackId = globalThis.__customFnCallbackIds["${name}:return"];
|
|
1128
1321
|
const argsJson = JSON.stringify(__marshalForHost([iteratorId, v]));
|
|
1129
1322
|
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1130
1323
|
undefined,
|
|
1131
|
-
[
|
|
1324
|
+
[returnCallbackId, argsJson]
|
|
1132
1325
|
);
|
|
1133
1326
|
const result = JSON.parse(resultJson);
|
|
1134
1327
|
return { done: true, value: result.ok ? __unmarshalFromHost(result.value) : undefined };
|
|
1135
1328
|
},
|
|
1136
1329
|
async throw(e) {
|
|
1330
|
+
const throwCallbackId = globalThis.__customFnCallbackIds["${name}:throw"];
|
|
1137
1331
|
const argsJson = JSON.stringify(__marshalForHost([iteratorId, { message: e?.message, name: e?.name }]));
|
|
1138
1332
|
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1139
1333
|
undefined,
|
|
1140
|
-
[
|
|
1334
|
+
[throwCallbackId, argsJson]
|
|
1141
1335
|
);
|
|
1142
1336
|
const result = JSON.parse(resultJson);
|
|
1143
1337
|
if (!result.ok) {
|
|
@@ -1154,10 +1348,11 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
|
|
|
1154
1348
|
} else if (registration.type === "async") {
|
|
1155
1349
|
context.evalSync(`
|
|
1156
1350
|
globalThis.${name} = async function(...args) {
|
|
1351
|
+
const callbackId = globalThis.__customFnCallbackIds["${name}"];
|
|
1157
1352
|
const argsJson = JSON.stringify(__marshalForHost(args));
|
|
1158
1353
|
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1159
1354
|
undefined,
|
|
1160
|
-
[
|
|
1355
|
+
[callbackId, argsJson]
|
|
1161
1356
|
);
|
|
1162
1357
|
const result = JSON.parse(resultJson);
|
|
1163
1358
|
if (result.ok) {
|
|
@@ -1206,22 +1401,6 @@ async function serializeRequest(request) {
|
|
|
1206
1401
|
body
|
|
1207
1402
|
};
|
|
1208
1403
|
}
|
|
1209
|
-
async function serializeResponse(response) {
|
|
1210
|
-
const headers = [];
|
|
1211
|
-
response.headers.forEach((value, key) => {
|
|
1212
|
-
headers.push([key, value]);
|
|
1213
|
-
});
|
|
1214
|
-
let body = null;
|
|
1215
|
-
if (response.body) {
|
|
1216
|
-
body = new Uint8Array(await response.arrayBuffer());
|
|
1217
|
-
}
|
|
1218
|
-
return {
|
|
1219
|
-
status: response.status,
|
|
1220
|
-
statusText: response.statusText,
|
|
1221
|
-
headers,
|
|
1222
|
-
body
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
1404
|
function deserializeResponse(data) {
|
|
1226
1405
|
return new Response(data.body, {
|
|
1227
1406
|
status: data.status,
|
|
@@ -1382,14 +1561,21 @@ async function handleRunTests(message, connection, state) {
|
|
|
1382
1561
|
instance.lastActivity = Date.now();
|
|
1383
1562
|
try {
|
|
1384
1563
|
const timeout = message.timeout ?? 30000;
|
|
1564
|
+
let timeoutId;
|
|
1385
1565
|
const timeoutPromise = new Promise((_, reject) => {
|
|
1386
|
-
setTimeout(() => reject(new Error("Test timeout")), timeout);
|
|
1566
|
+
timeoutId = setTimeout(() => reject(new Error("Test timeout")), timeout);
|
|
1387
1567
|
});
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1568
|
+
try {
|
|
1569
|
+
const results = await Promise.race([
|
|
1570
|
+
import_isolate_test_environment.runTests(instance.runtime.context),
|
|
1571
|
+
timeoutPromise
|
|
1572
|
+
]);
|
|
1573
|
+
sendOk(connection.socket, message.requestId, results);
|
|
1574
|
+
} finally {
|
|
1575
|
+
if (timeoutId) {
|
|
1576
|
+
clearTimeout(timeoutId);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1393
1579
|
} catch (err) {
|
|
1394
1580
|
const error = err;
|
|
1395
1581
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
@@ -1502,4 +1688,4 @@ async function handleClearCollectedData(message, connection, state) {
|
|
|
1502
1688
|
}
|
|
1503
1689
|
})
|
|
1504
1690
|
|
|
1505
|
-
//# debugId=
|
|
1691
|
+
//# debugId=4B3FAD2EB54DBE6A64756E2164756E21
|