@ricsam/isolate-daemon 0.1.13 → 0.1.15
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 +1 -0
- package/dist/cjs/callback-fs-handler.cjs +18 -33
- package/dist/cjs/callback-fs-handler.cjs.map +3 -3
- package/dist/cjs/connection.cjs +547 -793
- package/dist/cjs/connection.cjs.map +3 -3
- package/dist/cjs/index.cjs +3 -2
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/callback-fs-handler.mjs +18 -33
- package/dist/mjs/callback-fs-handler.mjs.map +3 -3
- package/dist/mjs/connection.mjs +553 -795
- package/dist/mjs/connection.mjs.map +3 -3
- package/dist/mjs/index.mjs +3 -2
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/types.d.ts +15 -20
- package/package.json +1 -1
package/dist/cjs/connection.cjs
CHANGED
|
@@ -1,20 +1,7 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
3
1
|
var __defProp = Object.defineProperty;
|
|
4
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
-
for (let key of __getOwnPropNames(mod))
|
|
11
|
-
if (!__hasOwnProp.call(to, key))
|
|
12
|
-
__defProp(to, key, {
|
|
13
|
-
get: () => mod[key],
|
|
14
|
-
enumerable: true
|
|
15
|
-
});
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
5
|
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
19
6
|
var __toCommonJS = (from) => {
|
|
20
7
|
var entry = __moduleCache.get(from), desc;
|
|
@@ -46,14 +33,31 @@ __export(exports_connection, {
|
|
|
46
33
|
});
|
|
47
34
|
module.exports = __toCommonJS(exports_connection);
|
|
48
35
|
var import_node_crypto = require("node:crypto");
|
|
49
|
-
var import_node_path = __toESM(require("node:path"));
|
|
50
|
-
var import_isolated_vm = __toESM(require("isolated-vm"));
|
|
51
36
|
var import_isolate_protocol = require("@ricsam/isolate-protocol");
|
|
52
37
|
var import_callback_fs_handler = require("./callback-fs-handler.cjs");
|
|
53
|
-
var import_isolate_test_environment = require("@ricsam/isolate-test-environment");
|
|
54
|
-
var import_isolate_playwright = require("@ricsam/isolate-playwright");
|
|
55
38
|
var import_isolate_runtime = require("@ricsam/isolate-runtime");
|
|
56
|
-
var
|
|
39
|
+
var LINKER_CONFLICT_ERROR = "Module is currently being linked by another linker";
|
|
40
|
+
function getErrorText(error) {
|
|
41
|
+
if (error instanceof Error) {
|
|
42
|
+
const cause = error.cause;
|
|
43
|
+
const causeText = cause instanceof Error ? `${cause.name}: ${cause.message}
|
|
44
|
+
${cause.stack ?? ""}` : cause != null ? String(cause) : "";
|
|
45
|
+
return [error.name, error.message, error.stack, causeText].filter((part) => part != null && part !== "").join(`
|
|
46
|
+
`);
|
|
47
|
+
}
|
|
48
|
+
if (typeof error === "string") {
|
|
49
|
+
return error;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return JSON.stringify(error);
|
|
53
|
+
} catch {
|
|
54
|
+
return String(error ?? "");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function isLinkerConflictError(error) {
|
|
58
|
+
const text = getErrorText(error).toLowerCase();
|
|
59
|
+
return text.includes(LINKER_CONFLICT_ERROR.toLowerCase());
|
|
60
|
+
}
|
|
57
61
|
function handleConnection(socket, state) {
|
|
58
62
|
const connection = {
|
|
59
63
|
socket,
|
|
@@ -86,22 +90,17 @@ function handleConnection(socket, state) {
|
|
|
86
90
|
const instance = state.isolates.get(isolateId);
|
|
87
91
|
if (instance) {
|
|
88
92
|
if (instance.namespaceId != null && !instance.isDisposed) {
|
|
89
|
-
|
|
93
|
+
if (instance.isPoisoned) {
|
|
94
|
+
hardDeleteRuntime(instance, state).catch(() => {});
|
|
95
|
+
} else {
|
|
96
|
+
softDeleteRuntime(instance, state);
|
|
97
|
+
}
|
|
90
98
|
} else if (!instance.isDisposed) {
|
|
91
|
-
|
|
92
|
-
if (instance.playwrightHandle) {
|
|
93
|
-
instance.playwrightHandle.dispose();
|
|
94
|
-
}
|
|
95
|
-
instance.runtime.dispose();
|
|
96
|
-
} catch {}
|
|
97
|
-
state.isolates.delete(isolateId);
|
|
99
|
+
hardDeleteRuntime(instance, state).catch(() => {});
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
for (const [, pending] of connection.pendingCallbacks) {
|
|
102
|
-
if (pending.timeoutId) {
|
|
103
|
-
clearTimeout(pending.timeoutId);
|
|
104
|
-
}
|
|
105
104
|
pending.reject(new Error("Connection closed"));
|
|
106
105
|
}
|
|
107
106
|
connection.pendingCallbacks.clear();
|
|
@@ -199,12 +198,6 @@ async function handleMessage(message, connection, state) {
|
|
|
199
198
|
case import_isolate_protocol.MessageType.GET_TEST_COUNT:
|
|
200
199
|
await handleGetTestCount(message, connection, state);
|
|
201
200
|
break;
|
|
202
|
-
case import_isolate_protocol.MessageType.RUN_PLAYWRIGHT_TESTS:
|
|
203
|
-
await handleRunPlaywrightTests(message, connection, state);
|
|
204
|
-
break;
|
|
205
|
-
case import_isolate_protocol.MessageType.RESET_PLAYWRIGHT_TESTS:
|
|
206
|
-
await handleResetPlaywrightTests(message, connection, state);
|
|
207
|
-
break;
|
|
208
201
|
case import_isolate_protocol.MessageType.GET_COLLECTED_DATA:
|
|
209
202
|
await handleGetCollectedData(message, connection, state);
|
|
210
203
|
break;
|
|
@@ -235,34 +228,69 @@ async function handleMessage(message, connection, state) {
|
|
|
235
228
|
case import_isolate_protocol.MessageType.CALLBACK_STREAM_END:
|
|
236
229
|
handleCallbackStreamEnd(message, connection);
|
|
237
230
|
break;
|
|
231
|
+
case import_isolate_protocol.MessageType.CLIENT_EVENT:
|
|
232
|
+
handleClientEvent(message, connection, state);
|
|
233
|
+
break;
|
|
238
234
|
default:
|
|
239
235
|
sendError(connection.socket, message.requestId ?? 0, import_isolate_protocol.ErrorCode.UNKNOWN_MESSAGE_TYPE, `Unknown message type: ${message.type}`);
|
|
240
236
|
}
|
|
241
237
|
}
|
|
238
|
+
async function hardDeleteRuntime(instance, state) {
|
|
239
|
+
try {
|
|
240
|
+
await instance.runtime.dispose();
|
|
241
|
+
} finally {
|
|
242
|
+
state.isolates.delete(instance.isolateId);
|
|
243
|
+
if (instance.namespaceId != null) {
|
|
244
|
+
const indexed = state.namespacedRuntimes.get(instance.namespaceId);
|
|
245
|
+
if (indexed?.isolateId === instance.isolateId) {
|
|
246
|
+
state.namespacedRuntimes.delete(instance.namespaceId);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
instance.isDisposed = true;
|
|
250
|
+
instance.disposedAt = undefined;
|
|
251
|
+
instance.ownerConnection = null;
|
|
252
|
+
if (instance.callbackContext) {
|
|
253
|
+
instance.callbackContext.connection = null;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
242
257
|
function softDeleteRuntime(instance, state) {
|
|
243
258
|
instance.isDisposed = true;
|
|
244
259
|
instance.disposedAt = Date.now();
|
|
245
260
|
instance.ownerConnection = null;
|
|
261
|
+
if (instance.callbackContext) {
|
|
262
|
+
instance.callbackContext.connection = null;
|
|
263
|
+
}
|
|
246
264
|
instance.callbacks.clear();
|
|
247
265
|
instance.runtime.timers.clearAll();
|
|
248
266
|
instance.runtime.console.reset();
|
|
249
|
-
instance.pendingCallbacks.length = 0;
|
|
267
|
+
instance.runtime.pendingCallbacks.length = 0;
|
|
250
268
|
instance.returnedCallbacks?.clear();
|
|
251
269
|
instance.returnedPromises?.clear();
|
|
252
270
|
instance.returnedIterators?.clear();
|
|
271
|
+
instance.runtime.clearModuleCache();
|
|
253
272
|
}
|
|
254
273
|
function reuseNamespacedRuntime(instance, connection, message, state) {
|
|
255
274
|
instance.ownerConnection = connection.socket;
|
|
256
275
|
instance.isDisposed = false;
|
|
276
|
+
instance.isPoisoned = false;
|
|
257
277
|
instance.disposedAt = undefined;
|
|
258
278
|
instance.lastActivity = Date.now();
|
|
259
279
|
connection.isolates.add(instance.isolateId);
|
|
260
280
|
const callbacks = message.options.callbacks;
|
|
281
|
+
const testEnvOptions = message.options.testEnvironment != null && typeof message.options.testEnvironment === "object" ? message.options.testEnvironment : undefined;
|
|
261
282
|
if (instance.callbackContext) {
|
|
262
283
|
instance.callbackContext.connection = connection;
|
|
263
284
|
instance.callbackContext.consoleOnEntry = callbacks?.console?.onEntry?.callbackId;
|
|
264
285
|
instance.callbackContext.fetch = callbacks?.fetch?.callbackId;
|
|
265
286
|
instance.callbackContext.moduleLoader = callbacks?.moduleLoader?.callbackId;
|
|
287
|
+
instance.callbackContext.testEnvironmentOnEvent = testEnvOptions?.callbacks?.onEvent?.callbackId;
|
|
288
|
+
instance.callbackContext.playwright = {
|
|
289
|
+
handlerCallbackId: callbacks?.playwright?.handlerCallbackId,
|
|
290
|
+
onBrowserConsoleLogCallbackId: callbacks?.playwright?.onBrowserConsoleLogCallbackId,
|
|
291
|
+
onNetworkRequestCallbackId: callbacks?.playwright?.onNetworkRequestCallbackId,
|
|
292
|
+
onNetworkResponseCallbackId: callbacks?.playwright?.onNetworkResponseCallbackId
|
|
293
|
+
};
|
|
266
294
|
instance.callbackContext.fs = {
|
|
267
295
|
readFile: callbacks?.fs?.readFile?.callbackId,
|
|
268
296
|
writeFile: callbacks?.fs?.writeFile?.callbackId,
|
|
@@ -299,7 +327,6 @@ function reuseNamespacedRuntime(instance, connection, message, state) {
|
|
|
299
327
|
}
|
|
300
328
|
}
|
|
301
329
|
if (callbacks?.moduleLoader) {
|
|
302
|
-
instance.moduleLoaderCallbackId = callbacks.moduleLoader.callbackId;
|
|
303
330
|
instance.callbacks.set(callbacks.moduleLoader.callbackId, callbacks.moduleLoader);
|
|
304
331
|
}
|
|
305
332
|
if (callbacks?.custom) {
|
|
@@ -309,23 +336,46 @@ function reuseNamespacedRuntime(instance, connection, message, state) {
|
|
|
309
336
|
}
|
|
310
337
|
}
|
|
311
338
|
}
|
|
339
|
+
if (testEnvOptions?.callbacks?.onEvent) {
|
|
340
|
+
instance.callbacks.set(testEnvOptions.callbacks.onEvent.callbackId, {
|
|
341
|
+
...testEnvOptions.callbacks.onEvent,
|
|
342
|
+
name: "testEnvironment.onEvent"
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
if (callbacks?.playwright) {
|
|
346
|
+
instance.callbacks.set(callbacks.playwright.handlerCallbackId, {
|
|
347
|
+
callbackId: callbacks.playwright.handlerCallbackId,
|
|
348
|
+
name: "playwright.handler",
|
|
349
|
+
type: "async"
|
|
350
|
+
});
|
|
351
|
+
if (callbacks.playwright.onBrowserConsoleLogCallbackId !== undefined) {
|
|
352
|
+
instance.callbacks.set(callbacks.playwright.onBrowserConsoleLogCallbackId, {
|
|
353
|
+
callbackId: callbacks.playwright.onBrowserConsoleLogCallbackId,
|
|
354
|
+
name: "playwright.onBrowserConsoleLog",
|
|
355
|
+
type: "sync"
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
if (callbacks.playwright.onNetworkRequestCallbackId !== undefined) {
|
|
359
|
+
instance.callbacks.set(callbacks.playwright.onNetworkRequestCallbackId, {
|
|
360
|
+
callbackId: callbacks.playwright.onNetworkRequestCallbackId,
|
|
361
|
+
name: "playwright.onNetworkRequest",
|
|
362
|
+
type: "sync"
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
if (callbacks.playwright.onNetworkResponseCallbackId !== undefined) {
|
|
366
|
+
instance.callbacks.set(callbacks.playwright.onNetworkResponseCallbackId, {
|
|
367
|
+
callbackId: callbacks.playwright.onNetworkResponseCallbackId,
|
|
368
|
+
name: "playwright.onNetworkResponse",
|
|
369
|
+
type: "sync"
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
}
|
|
312
373
|
instance.returnedCallbacks = new Map;
|
|
313
374
|
instance.returnedPromises = new Map;
|
|
314
375
|
instance.returnedIterators = new Map;
|
|
315
376
|
instance.nextLocalCallbackId = 1e6;
|
|
316
|
-
if (callbacks?.custom) {
|
|
317
|
-
const newCallbackIdMap = {};
|
|
318
|
-
for (const [name, reg] of Object.entries(callbacks.custom)) {
|
|
319
|
-
if (reg) {
|
|
320
|
-
newCallbackIdMap[name] = reg.callbackId;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
try {
|
|
324
|
-
instance.runtime.context.global.setSync("__customFnCallbackIds", new import_isolated_vm.default.ExternalCopy(newCallbackIdMap).copyInto());
|
|
325
|
-
} catch {}
|
|
326
|
-
}
|
|
327
377
|
}
|
|
328
|
-
function evictOldestDisposedRuntime(state) {
|
|
378
|
+
async function evictOldestDisposedRuntime(state) {
|
|
329
379
|
let oldest = null;
|
|
330
380
|
let oldestTime = Infinity;
|
|
331
381
|
for (const [, instance] of state.isolates) {
|
|
@@ -338,21 +388,15 @@ function evictOldestDisposedRuntime(state) {
|
|
|
338
388
|
}
|
|
339
389
|
if (oldest) {
|
|
340
390
|
try {
|
|
341
|
-
|
|
342
|
-
oldest.playwrightHandle.dispose();
|
|
343
|
-
}
|
|
344
|
-
oldest.runtime.dispose();
|
|
391
|
+
await hardDeleteRuntime(oldest, state);
|
|
345
392
|
} catch {}
|
|
346
|
-
state.isolates.delete(oldest.isolateId);
|
|
347
|
-
if (oldest.namespaceId != null) {
|
|
348
|
-
state.namespacedRuntimes.delete(oldest.namespaceId);
|
|
349
|
-
}
|
|
350
393
|
return true;
|
|
351
394
|
}
|
|
352
395
|
return false;
|
|
353
396
|
}
|
|
354
397
|
async function handleCreateRuntime(message, connection, state) {
|
|
355
398
|
const namespaceId = message.options.namespaceId;
|
|
399
|
+
let namespaceCreationLocked = false;
|
|
356
400
|
if (namespaceId != null) {
|
|
357
401
|
const existing = state.namespacedRuntimes.get(namespaceId);
|
|
358
402
|
if (existing) {
|
|
@@ -374,26 +418,38 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
374
418
|
});
|
|
375
419
|
return;
|
|
376
420
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (!evictOldestDisposedRuntime(state)) {
|
|
380
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_MEMORY_LIMIT, `Maximum isolates (${state.options.maxIsolates}) reached`);
|
|
421
|
+
if (state.namespacedCreatesInFlight.has(namespaceId)) {
|
|
422
|
+
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, `Namespace "${namespaceId}" creation already in progress`);
|
|
381
423
|
return;
|
|
382
424
|
}
|
|
425
|
+
state.namespacedCreatesInFlight.add(namespaceId);
|
|
426
|
+
namespaceCreationLocked = true;
|
|
383
427
|
}
|
|
384
428
|
try {
|
|
429
|
+
if (state.isolates.size >= state.options.maxIsolates) {
|
|
430
|
+
if (!await evictOldestDisposedRuntime(state)) {
|
|
431
|
+
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_MEMORY_LIMIT, `Maximum isolates (${state.options.maxIsolates}) reached`);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
385
435
|
const isolateId = import_node_crypto.randomUUID();
|
|
386
436
|
const consoleCallbacks = message.options.callbacks?.console;
|
|
387
437
|
const fetchCallback = message.options.callbacks?.fetch;
|
|
388
438
|
const fsCallbacks = message.options.callbacks?.fs;
|
|
389
439
|
const moduleLoaderCallback = message.options.callbacks?.moduleLoader;
|
|
390
440
|
const customCallbacks = message.options.callbacks?.custom;
|
|
391
|
-
const pendingCallbacks = [];
|
|
392
441
|
const callbackContext = {
|
|
393
442
|
connection,
|
|
394
443
|
consoleOnEntry: consoleCallbacks?.onEntry?.callbackId,
|
|
395
444
|
fetch: fetchCallback?.callbackId,
|
|
396
445
|
moduleLoader: moduleLoaderCallback?.callbackId,
|
|
446
|
+
testEnvironmentOnEvent: message.options.testEnvironment != null && typeof message.options.testEnvironment === "object" ? message.options.testEnvironment.callbacks?.onEvent?.callbackId : undefined,
|
|
447
|
+
playwright: {
|
|
448
|
+
handlerCallbackId: message.options.callbacks?.playwright?.handlerCallbackId,
|
|
449
|
+
onBrowserConsoleLogCallbackId: message.options.callbacks?.playwright?.onBrowserConsoleLogCallbackId,
|
|
450
|
+
onNetworkRequestCallbackId: message.options.callbacks?.playwright?.onNetworkRequestCallbackId,
|
|
451
|
+
onNetworkResponseCallbackId: message.options.callbacks?.playwright?.onNetworkResponseCallbackId
|
|
452
|
+
},
|
|
397
453
|
fs: {
|
|
398
454
|
readFile: fsCallbacks?.readFile?.callbackId,
|
|
399
455
|
writeFile: fsCallbacks?.writeFile?.callbackId,
|
|
@@ -405,7 +461,247 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
405
461
|
},
|
|
406
462
|
custom: new Map(customCallbacks ? Object.entries(customCallbacks).map(([name, reg]) => [name, reg.callbackId]) : [])
|
|
407
463
|
};
|
|
408
|
-
const
|
|
464
|
+
const instance = {
|
|
465
|
+
isolateId,
|
|
466
|
+
runtime: null,
|
|
467
|
+
ownerConnection: connection.socket,
|
|
468
|
+
callbacks: new Map,
|
|
469
|
+
createdAt: Date.now(),
|
|
470
|
+
lastActivity: Date.now(),
|
|
471
|
+
returnedCallbacks: new Map,
|
|
472
|
+
returnedPromises: new Map,
|
|
473
|
+
returnedIterators: new Map,
|
|
474
|
+
nextLocalCallbackId: 1e6,
|
|
475
|
+
namespaceId,
|
|
476
|
+
isDisposed: false,
|
|
477
|
+
isPoisoned: false,
|
|
478
|
+
callbackContext
|
|
479
|
+
};
|
|
480
|
+
let bridgedCustomFunctions;
|
|
481
|
+
let customFnMarshalOptions;
|
|
482
|
+
if (customCallbacks) {
|
|
483
|
+
const createMarshalContext = () => ({
|
|
484
|
+
registerCallback: (fn) => {
|
|
485
|
+
const callbackId = instance.nextLocalCallbackId++;
|
|
486
|
+
instance.returnedCallbacks.set(callbackId, fn);
|
|
487
|
+
return callbackId;
|
|
488
|
+
},
|
|
489
|
+
registerPromise: (promise) => {
|
|
490
|
+
const promiseId = instance.nextLocalCallbackId++;
|
|
491
|
+
instance.returnedPromises.set(promiseId, promise);
|
|
492
|
+
return promiseId;
|
|
493
|
+
},
|
|
494
|
+
registerIterator: (iterator) => {
|
|
495
|
+
const iteratorId = instance.nextLocalCallbackId++;
|
|
496
|
+
instance.returnedIterators.set(iteratorId, iterator);
|
|
497
|
+
return iteratorId;
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
const addCallbackIdsToRefs = (value) => {
|
|
501
|
+
if (value === null || typeof value !== "object")
|
|
502
|
+
return value;
|
|
503
|
+
if (import_isolate_protocol.isPromiseRef(value)) {
|
|
504
|
+
if ("__resolveCallbackId" in value)
|
|
505
|
+
return value;
|
|
506
|
+
const resolveCallbackId = instance.nextLocalCallbackId++;
|
|
507
|
+
instance.returnedCallbacks.set(resolveCallbackId, async (promiseId) => {
|
|
508
|
+
const promise = instance.returnedPromises.get(promiseId);
|
|
509
|
+
if (!promise)
|
|
510
|
+
throw new Error(`Promise ${promiseId} not found`);
|
|
511
|
+
const result2 = await promise;
|
|
512
|
+
instance.returnedPromises.delete(promiseId);
|
|
513
|
+
const ctx = createMarshalContext();
|
|
514
|
+
const marshalled = await import_isolate_protocol.marshalValue(result2, ctx);
|
|
515
|
+
return addCallbackIdsToRefs(marshalled);
|
|
516
|
+
});
|
|
517
|
+
return { ...value, __resolveCallbackId: resolveCallbackId };
|
|
518
|
+
}
|
|
519
|
+
if (import_isolate_protocol.isAsyncIteratorRef(value)) {
|
|
520
|
+
if ("__nextCallbackId" in value)
|
|
521
|
+
return value;
|
|
522
|
+
const nextCallbackId = instance.nextLocalCallbackId++;
|
|
523
|
+
instance.returnedCallbacks.set(nextCallbackId, async (iteratorId) => {
|
|
524
|
+
const iterator = instance.returnedIterators.get(iteratorId);
|
|
525
|
+
if (!iterator)
|
|
526
|
+
throw new Error(`Iterator ${iteratorId} not found`);
|
|
527
|
+
const result2 = await iterator.next();
|
|
528
|
+
if (result2.done)
|
|
529
|
+
instance.returnedIterators.delete(iteratorId);
|
|
530
|
+
const ctx = createMarshalContext();
|
|
531
|
+
const marshalledValue = await import_isolate_protocol.marshalValue(result2.value, ctx);
|
|
532
|
+
return { done: result2.done, value: addCallbackIdsToRefs(marshalledValue) };
|
|
533
|
+
});
|
|
534
|
+
const returnCallbackId = instance.nextLocalCallbackId++;
|
|
535
|
+
instance.returnedCallbacks.set(returnCallbackId, async (iteratorId, returnValue) => {
|
|
536
|
+
const iterator = instance.returnedIterators.get(iteratorId);
|
|
537
|
+
instance.returnedIterators.delete(iteratorId);
|
|
538
|
+
if (!iterator || !iterator.return)
|
|
539
|
+
return { done: true, value: undefined };
|
|
540
|
+
const result2 = await iterator.return(returnValue);
|
|
541
|
+
const ctx = createMarshalContext();
|
|
542
|
+
const marshalledValue = await import_isolate_protocol.marshalValue(result2.value, ctx);
|
|
543
|
+
return { done: true, value: addCallbackIdsToRefs(marshalledValue) };
|
|
544
|
+
});
|
|
545
|
+
return { ...value, __nextCallbackId: nextCallbackId, __returnCallbackId: returnCallbackId };
|
|
546
|
+
}
|
|
547
|
+
if (Array.isArray(value))
|
|
548
|
+
return value.map((item) => addCallbackIdsToRefs(item));
|
|
549
|
+
const result = {};
|
|
550
|
+
for (const key of Object.keys(value)) {
|
|
551
|
+
result[key] = addCallbackIdsToRefs(value[key]);
|
|
552
|
+
}
|
|
553
|
+
return result;
|
|
554
|
+
};
|
|
555
|
+
const LOCAL_CALLBACK_THRESHOLD = 1e6;
|
|
556
|
+
const invokeCallback = async (callbackId, args) => {
|
|
557
|
+
if (callbackId >= LOCAL_CALLBACK_THRESHOLD) {
|
|
558
|
+
const callback = instance.returnedCallbacks.get(callbackId);
|
|
559
|
+
if (!callback) {
|
|
560
|
+
throw new Error(`Local callback ${callbackId} not found`);
|
|
561
|
+
}
|
|
562
|
+
return await callback(...args);
|
|
563
|
+
} else {
|
|
564
|
+
const conn = callbackContext.connection;
|
|
565
|
+
if (!conn) {
|
|
566
|
+
throw new Error(`No connection available for callback ${callbackId}`);
|
|
567
|
+
}
|
|
568
|
+
return invokeClientCallback(conn, callbackId, args);
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
customFnMarshalOptions = { createMarshalContext, addCallbackIdsToRefs, invokeCallback };
|
|
572
|
+
bridgedCustomFunctions = {};
|
|
573
|
+
for (const [name, registration] of Object.entries(customCallbacks)) {
|
|
574
|
+
if (name.includes(":"))
|
|
575
|
+
continue;
|
|
576
|
+
const callbackContext_ = callbackContext;
|
|
577
|
+
if (registration.type === "asyncIterator") {
|
|
578
|
+
bridgedCustomFunctions[name] = {
|
|
579
|
+
type: "asyncIterator",
|
|
580
|
+
fn: (...args) => {
|
|
581
|
+
const startCallbackId = callbackContext_.custom.get(`${name}:start`);
|
|
582
|
+
const nextCallbackId = callbackContext_.custom.get(`${name}:next`);
|
|
583
|
+
const returnCallbackId = callbackContext_.custom.get(`${name}:return`);
|
|
584
|
+
async function* bridgedIterator() {
|
|
585
|
+
const conn = callbackContext_.connection;
|
|
586
|
+
if (!conn || startCallbackId === undefined) {
|
|
587
|
+
throw new Error(`AsyncIterator callback '${name}' not available`);
|
|
588
|
+
}
|
|
589
|
+
const startResult = await invokeClientCallback(conn, startCallbackId, args);
|
|
590
|
+
const iteratorId = startResult.iteratorId;
|
|
591
|
+
try {
|
|
592
|
+
while (true) {
|
|
593
|
+
const nextConn = callbackContext_.connection;
|
|
594
|
+
if (!nextConn || nextCallbackId === undefined) {
|
|
595
|
+
throw new Error(`AsyncIterator callback '${name}' not available`);
|
|
596
|
+
}
|
|
597
|
+
const nextResult = await invokeClientCallback(nextConn, nextCallbackId, [iteratorId]);
|
|
598
|
+
if (nextResult.done)
|
|
599
|
+
return nextResult.value;
|
|
600
|
+
yield nextResult.value;
|
|
601
|
+
}
|
|
602
|
+
} finally {
|
|
603
|
+
const retConn = callbackContext_.connection;
|
|
604
|
+
if (retConn && returnCallbackId !== undefined) {
|
|
605
|
+
await invokeClientCallback(retConn, returnCallbackId, [iteratorId]).catch(() => {});
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return bridgedIterator();
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
} else {
|
|
613
|
+
bridgedCustomFunctions[name] = {
|
|
614
|
+
type: registration.type,
|
|
615
|
+
fn: async (...args) => {
|
|
616
|
+
const conn = callbackContext_.connection;
|
|
617
|
+
const cbId = callbackContext_.custom.get(name);
|
|
618
|
+
if (!conn || cbId === undefined) {
|
|
619
|
+
throw new Error(`Custom function callback '${name}' not available`);
|
|
620
|
+
}
|
|
621
|
+
return invokeClientCallback(conn, cbId, args);
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
let moduleLoader;
|
|
628
|
+
if (moduleLoaderCallback) {
|
|
629
|
+
moduleLoader = async (specifier, importer) => {
|
|
630
|
+
const conn = callbackContext.connection;
|
|
631
|
+
const cbId = callbackContext.moduleLoader;
|
|
632
|
+
if (!conn || cbId === undefined) {
|
|
633
|
+
throw new Error("Module loader callback not available");
|
|
634
|
+
}
|
|
635
|
+
return invokeClientCallback(conn, cbId, [specifier, importer]);
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
let testEnvironment;
|
|
639
|
+
if (message.options.testEnvironment) {
|
|
640
|
+
const testEnvOption = message.options.testEnvironment;
|
|
641
|
+
const testEnvOptions = typeof testEnvOption === "object" ? testEnvOption : undefined;
|
|
642
|
+
testEnvironment = {
|
|
643
|
+
onEvent: testEnvOptions?.callbacks?.onEvent ? (event) => {
|
|
644
|
+
const conn = callbackContext.connection;
|
|
645
|
+
const callbackId = callbackContext.testEnvironmentOnEvent;
|
|
646
|
+
if (!conn || callbackId === undefined) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
const promise = invokeClientCallback(conn, callbackId, [JSON.stringify(event)]).catch(() => {});
|
|
650
|
+
instance.runtime?.pendingCallbacks?.push(promise);
|
|
651
|
+
} : undefined,
|
|
652
|
+
testTimeout: testEnvOptions?.testTimeout
|
|
653
|
+
};
|
|
654
|
+
if (testEnvOptions?.callbacks?.onEvent) {
|
|
655
|
+
instance.callbacks.set(testEnvOptions.callbacks.onEvent.callbackId, {
|
|
656
|
+
...testEnvOptions.callbacks.onEvent,
|
|
657
|
+
name: "testEnvironment.onEvent"
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
let playwrightOptions;
|
|
662
|
+
const playwrightCallbacks = message.options.callbacks?.playwright;
|
|
663
|
+
if (playwrightCallbacks) {
|
|
664
|
+
playwrightOptions = {
|
|
665
|
+
handler: async (op) => {
|
|
666
|
+
const conn = callbackContext.connection;
|
|
667
|
+
const callbackId = callbackContext.playwright.handlerCallbackId;
|
|
668
|
+
if (!conn || callbackId === undefined) {
|
|
669
|
+
return {
|
|
670
|
+
ok: false,
|
|
671
|
+
error: {
|
|
672
|
+
name: "Error",
|
|
673
|
+
message: "Playwright handler callback not available"
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
try {
|
|
678
|
+
const resultJson = await invokeClientCallback(conn, callbackId, [JSON.stringify(op)]);
|
|
679
|
+
return JSON.parse(resultJson);
|
|
680
|
+
} catch (err) {
|
|
681
|
+
const error = err;
|
|
682
|
+
return { ok: false, error: { name: error.name, message: error.message } };
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
console: playwrightCallbacks.console,
|
|
686
|
+
onEvent: (event) => {
|
|
687
|
+
const conn = callbackContext.connection;
|
|
688
|
+
if (!conn) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
if (event.type === "browserConsoleLog" && callbackContext.playwright.onBrowserConsoleLogCallbackId !== undefined) {
|
|
692
|
+
const promise = invokeClientCallback(conn, callbackContext.playwright.onBrowserConsoleLogCallbackId, [{ level: event.level, stdout: event.stdout, timestamp: event.timestamp }]).catch(() => {});
|
|
693
|
+
instance.runtime?.pendingCallbacks?.push(promise);
|
|
694
|
+
} else if (event.type === "networkRequest" && callbackContext.playwright.onNetworkRequestCallbackId !== undefined) {
|
|
695
|
+
const promise = invokeClientCallback(conn, callbackContext.playwright.onNetworkRequestCallbackId, [event]).catch(() => {});
|
|
696
|
+
instance.runtime?.pendingCallbacks?.push(promise);
|
|
697
|
+
} else if (event.type === "networkResponse" && callbackContext.playwright.onNetworkResponseCallbackId !== undefined) {
|
|
698
|
+
const promise = invokeClientCallback(conn, callbackContext.playwright.onNetworkResponseCallbackId, [event]).catch(() => {});
|
|
699
|
+
instance.runtime?.pendingCallbacks?.push(promise);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
const runtime = await import_isolate_runtime.createRuntime({
|
|
409
705
|
memoryLimitMB: message.options.memoryLimitMB ?? state.options.defaultMemoryLimitMB,
|
|
410
706
|
cwd: message.options.cwd,
|
|
411
707
|
console: {
|
|
@@ -415,28 +711,31 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
415
711
|
if (!conn || callbackId === undefined)
|
|
416
712
|
return;
|
|
417
713
|
const promise = invokeClientCallback(conn, callbackId, [entry]).catch(() => {});
|
|
418
|
-
pendingCallbacks.push(promise);
|
|
714
|
+
runtime.pendingCallbacks.push(promise);
|
|
419
715
|
}
|
|
420
716
|
},
|
|
421
|
-
fetch: {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
throw new Error("Fetch callback not available");
|
|
427
|
-
}
|
|
428
|
-
const serialized = await serializeRequest(request);
|
|
429
|
-
const result = await invokeClientCallback(conn, callbackId, [serialized], 60000);
|
|
430
|
-
if (result && typeof result === "object" && result.__streamingResponse) {
|
|
431
|
-
const response = result.response;
|
|
432
|
-
response.__isCallbackStream = true;
|
|
433
|
-
return response;
|
|
434
|
-
}
|
|
435
|
-
return deserializeResponse(result);
|
|
717
|
+
fetch: async (url, init) => {
|
|
718
|
+
const conn = callbackContext.connection;
|
|
719
|
+
const callbackId = callbackContext.fetch;
|
|
720
|
+
if (!conn || callbackId === undefined) {
|
|
721
|
+
throw new Error("Fetch callback not available");
|
|
436
722
|
}
|
|
723
|
+
const serialized = {
|
|
724
|
+
url,
|
|
725
|
+
method: init.method,
|
|
726
|
+
headers: init.headers,
|
|
727
|
+
body: init.rawBody
|
|
728
|
+
};
|
|
729
|
+
const result = await invokeClientCallback(conn, callbackId, [serialized]);
|
|
730
|
+
if (result && typeof result === "object" && result.__streamingResponse) {
|
|
731
|
+
const response = result.response;
|
|
732
|
+
response.__isCallbackStream = true;
|
|
733
|
+
return response;
|
|
734
|
+
}
|
|
735
|
+
return import_isolate_protocol.deserializeResponse(result);
|
|
437
736
|
},
|
|
438
737
|
fs: {
|
|
439
|
-
getDirectory: async (
|
|
738
|
+
getDirectory: async (dirPath) => {
|
|
440
739
|
const conn = callbackContext.connection;
|
|
441
740
|
if (!conn) {
|
|
442
741
|
throw new Error("FS callbacks not available");
|
|
@@ -445,35 +744,17 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
445
744
|
connection: conn,
|
|
446
745
|
callbackContext,
|
|
447
746
|
invokeClientCallback,
|
|
448
|
-
basePath:
|
|
747
|
+
basePath: dirPath
|
|
449
748
|
});
|
|
450
749
|
}
|
|
451
|
-
}
|
|
750
|
+
},
|
|
751
|
+
moduleLoader,
|
|
752
|
+
customFunctions: bridgedCustomFunctions,
|
|
753
|
+
customFunctionsMarshalOptions: customFnMarshalOptions,
|
|
754
|
+
testEnvironment,
|
|
755
|
+
playwright: playwrightOptions
|
|
452
756
|
});
|
|
453
|
-
|
|
454
|
-
isolateId,
|
|
455
|
-
runtime,
|
|
456
|
-
ownerConnection: connection.socket,
|
|
457
|
-
callbacks: new Map,
|
|
458
|
-
createdAt: Date.now(),
|
|
459
|
-
lastActivity: Date.now(),
|
|
460
|
-
pendingCallbacks,
|
|
461
|
-
returnedCallbacks: new Map,
|
|
462
|
-
returnedPromises: new Map,
|
|
463
|
-
returnedIterators: new Map,
|
|
464
|
-
nextLocalCallbackId: 1e6,
|
|
465
|
-
namespaceId,
|
|
466
|
-
isDisposed: false,
|
|
467
|
-
callbackContext
|
|
468
|
-
};
|
|
469
|
-
if (moduleLoaderCallback) {
|
|
470
|
-
instance.moduleLoaderCallbackId = moduleLoaderCallback.callbackId;
|
|
471
|
-
instance.moduleCache = new Map;
|
|
472
|
-
instance.moduleToFilename = new Map;
|
|
473
|
-
}
|
|
474
|
-
if (customCallbacks) {
|
|
475
|
-
await setupCustomFunctions(runtime.context, customCallbacks, connection, instance);
|
|
476
|
-
}
|
|
757
|
+
instance.runtime = runtime;
|
|
477
758
|
if (consoleCallbacks?.onEntry) {
|
|
478
759
|
instance.callbacks.set(consoleCallbacks.onEntry.callbackId, {
|
|
479
760
|
...consoleCallbacks.onEntry,
|
|
@@ -500,52 +781,33 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
500
781
|
}
|
|
501
782
|
}
|
|
502
783
|
}
|
|
503
|
-
if (
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
onEvent: onEventCallback ? (event) => {
|
|
509
|
-
const promise = invokeClientCallback(connection, onEventCallback.callbackId, [JSON.stringify(event)]).catch(() => {});
|
|
510
|
-
pendingCallbacks.push(promise);
|
|
511
|
-
} : undefined,
|
|
512
|
-
testTimeout: testEnvOptions?.testTimeout
|
|
784
|
+
if (playwrightCallbacks) {
|
|
785
|
+
instance.callbacks.set(playwrightCallbacks.handlerCallbackId, {
|
|
786
|
+
callbackId: playwrightCallbacks.handlerCallbackId,
|
|
787
|
+
name: "playwright.handler",
|
|
788
|
+
type: "async"
|
|
513
789
|
});
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
790
|
+
if (playwrightCallbacks.onBrowserConsoleLogCallbackId !== undefined) {
|
|
791
|
+
instance.callbacks.set(playwrightCallbacks.onBrowserConsoleLogCallbackId, {
|
|
792
|
+
callbackId: playwrightCallbacks.onBrowserConsoleLogCallbackId,
|
|
793
|
+
name: "playwright.onBrowserConsoleLog",
|
|
794
|
+
type: "sync"
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
if (playwrightCallbacks.onNetworkRequestCallbackId !== undefined) {
|
|
798
|
+
instance.callbacks.set(playwrightCallbacks.onNetworkRequestCallbackId, {
|
|
799
|
+
callbackId: playwrightCallbacks.onNetworkRequestCallbackId,
|
|
800
|
+
name: "playwright.onNetworkRequest",
|
|
801
|
+
type: "sync"
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
if (playwrightCallbacks.onNetworkResponseCallbackId !== undefined) {
|
|
805
|
+
instance.callbacks.set(playwrightCallbacks.onNetworkResponseCallbackId, {
|
|
806
|
+
callbackId: playwrightCallbacks.onNetworkResponseCallbackId,
|
|
807
|
+
name: "playwright.onNetworkResponse",
|
|
808
|
+
type: "sync"
|
|
519
809
|
});
|
|
520
810
|
}
|
|
521
|
-
}
|
|
522
|
-
const playwrightCallbacks = message.options.callbacks?.playwright;
|
|
523
|
-
if (playwrightCallbacks) {
|
|
524
|
-
const handler = async (op) => {
|
|
525
|
-
try {
|
|
526
|
-
const resultJson = await invokeClientCallback(connection, playwrightCallbacks.handlerCallbackId, [JSON.stringify(op)]);
|
|
527
|
-
return JSON.parse(resultJson);
|
|
528
|
-
} catch (err) {
|
|
529
|
-
const error = err;
|
|
530
|
-
return { ok: false, error: { name: error.name, message: error.message } };
|
|
531
|
-
}
|
|
532
|
-
};
|
|
533
|
-
instance.playwrightHandle = await import_isolate_playwright.setupPlaywright(runtime.context, {
|
|
534
|
-
handler,
|
|
535
|
-
console: playwrightCallbacks.console,
|
|
536
|
-
onEvent: (event) => {
|
|
537
|
-
if (event.type === "browserConsoleLog" && playwrightCallbacks.onBrowserConsoleLogCallbackId) {
|
|
538
|
-
const promise = invokeClientCallback(connection, playwrightCallbacks.onBrowserConsoleLogCallbackId, [{ level: event.level, stdout: event.stdout, timestamp: event.timestamp }]).catch(() => {});
|
|
539
|
-
pendingCallbacks.push(promise);
|
|
540
|
-
} else if (event.type === "networkRequest" && playwrightCallbacks.onNetworkRequestCallbackId) {
|
|
541
|
-
const promise = invokeClientCallback(connection, playwrightCallbacks.onNetworkRequestCallbackId, [event]).catch(() => {});
|
|
542
|
-
pendingCallbacks.push(promise);
|
|
543
|
-
} else if (event.type === "networkResponse" && playwrightCallbacks.onNetworkResponseCallbackId) {
|
|
544
|
-
const promise = invokeClientCallback(connection, playwrightCallbacks.onNetworkResponseCallbackId, [event]).catch(() => {});
|
|
545
|
-
pendingCallbacks.push(promise);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
});
|
|
549
811
|
}
|
|
550
812
|
state.isolates.set(isolateId, instance);
|
|
551
813
|
connection.isolates.add(isolateId);
|
|
@@ -553,30 +815,99 @@ async function handleCreateRuntime(message, connection, state) {
|
|
|
553
815
|
if (namespaceId != null) {
|
|
554
816
|
state.namespacedRuntimes.set(namespaceId, instance);
|
|
555
817
|
}
|
|
556
|
-
|
|
818
|
+
runtime.fetch.onWebSocketCommand((cmd) => {
|
|
819
|
+
const targetConnection = callbackContext.connection;
|
|
820
|
+
if (!targetConnection) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
557
823
|
let data;
|
|
558
824
|
if (cmd.data instanceof ArrayBuffer) {
|
|
559
825
|
data = new Uint8Array(cmd.data);
|
|
560
826
|
} else {
|
|
561
827
|
data = cmd.data;
|
|
562
828
|
}
|
|
563
|
-
const
|
|
564
|
-
type:
|
|
829
|
+
const payload = {
|
|
830
|
+
type: cmd.type,
|
|
831
|
+
connectionId: cmd.connectionId,
|
|
832
|
+
data,
|
|
833
|
+
code: cmd.code,
|
|
834
|
+
reason: cmd.reason
|
|
835
|
+
};
|
|
836
|
+
sendMessage(targetConnection.socket, {
|
|
837
|
+
type: import_isolate_protocol.MessageType.ISOLATE_EVENT,
|
|
565
838
|
isolateId,
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
839
|
+
event: import_isolate_protocol.IsolateEvents.WS_COMMAND,
|
|
840
|
+
payload
|
|
841
|
+
});
|
|
842
|
+
});
|
|
843
|
+
runtime.fetch.onClientWebSocketCommand((cmd) => {
|
|
844
|
+
const targetConnection = callbackContext.connection;
|
|
845
|
+
if (!targetConnection) {
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
let data;
|
|
849
|
+
if (cmd.data instanceof ArrayBuffer) {
|
|
850
|
+
data = new Uint8Array(cmd.data);
|
|
851
|
+
} else {
|
|
852
|
+
data = cmd.data;
|
|
853
|
+
}
|
|
854
|
+
if (cmd.type === "connect") {
|
|
855
|
+
const payload = {
|
|
856
|
+
socketId: cmd.socketId,
|
|
857
|
+
url: cmd.url,
|
|
858
|
+
protocols: cmd.protocols
|
|
859
|
+
};
|
|
860
|
+
sendMessage(targetConnection.socket, {
|
|
861
|
+
type: import_isolate_protocol.MessageType.ISOLATE_EVENT,
|
|
862
|
+
isolateId,
|
|
863
|
+
event: import_isolate_protocol.IsolateEvents.WS_CLIENT_CONNECT,
|
|
864
|
+
payload
|
|
865
|
+
});
|
|
866
|
+
} else if (cmd.type === "send") {
|
|
867
|
+
const payload = {
|
|
868
|
+
socketId: cmd.socketId,
|
|
869
|
+
data
|
|
870
|
+
};
|
|
871
|
+
sendMessage(targetConnection.socket, {
|
|
872
|
+
type: import_isolate_protocol.MessageType.ISOLATE_EVENT,
|
|
873
|
+
isolateId,
|
|
874
|
+
event: import_isolate_protocol.IsolateEvents.WS_CLIENT_SEND,
|
|
875
|
+
payload
|
|
876
|
+
});
|
|
877
|
+
} else if (cmd.type === "close") {
|
|
878
|
+
const payload = {
|
|
879
|
+
socketId: cmd.socketId,
|
|
570
880
|
code: cmd.code,
|
|
571
881
|
reason: cmd.reason
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
|
|
882
|
+
};
|
|
883
|
+
sendMessage(targetConnection.socket, {
|
|
884
|
+
type: import_isolate_protocol.MessageType.ISOLATE_EVENT,
|
|
885
|
+
isolateId,
|
|
886
|
+
event: import_isolate_protocol.IsolateEvents.WS_CLIENT_CLOSE,
|
|
887
|
+
payload
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
runtime.fetch.onEvent((eventName, payload) => {
|
|
892
|
+
const targetConnection = callbackContext.connection;
|
|
893
|
+
if (!targetConnection) {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
sendMessage(targetConnection.socket, {
|
|
897
|
+
type: import_isolate_protocol.MessageType.ISOLATE_EVENT,
|
|
898
|
+
isolateId,
|
|
899
|
+
event: eventName,
|
|
900
|
+
payload
|
|
901
|
+
});
|
|
575
902
|
});
|
|
576
903
|
sendOk(connection.socket, message.requestId, { isolateId, reused: false });
|
|
577
904
|
} catch (err) {
|
|
578
905
|
const error = err;
|
|
579
906
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
907
|
+
} finally {
|
|
908
|
+
if (namespaceCreationLocked && namespaceId != null) {
|
|
909
|
+
state.namespacedCreatesInFlight.delete(namespaceId);
|
|
910
|
+
}
|
|
580
911
|
}
|
|
581
912
|
}
|
|
582
913
|
async function handleDisposeRuntime(message, connection, state) {
|
|
@@ -592,17 +923,20 @@ async function handleDisposeRuntime(message, connection, state) {
|
|
|
592
923
|
try {
|
|
593
924
|
connection.isolates.delete(message.isolateId);
|
|
594
925
|
if (instance.namespaceId != null) {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
instance
|
|
926
|
+
if (instance.isPoisoned) {
|
|
927
|
+
await hardDeleteRuntime(instance, state);
|
|
928
|
+
} else {
|
|
929
|
+
softDeleteRuntime(instance, state);
|
|
599
930
|
}
|
|
600
|
-
|
|
601
|
-
state
|
|
931
|
+
} else {
|
|
932
|
+
await hardDeleteRuntime(instance, state);
|
|
602
933
|
}
|
|
603
934
|
sendOk(connection.socket, message.requestId);
|
|
604
935
|
} catch (err) {
|
|
605
936
|
const error = err;
|
|
937
|
+
if (instance.namespaceId != null && isLinkerConflictError(error)) {
|
|
938
|
+
instance.isPoisoned = true;
|
|
939
|
+
}
|
|
606
940
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
607
941
|
}
|
|
608
942
|
}
|
|
@@ -614,47 +948,16 @@ async function handleEval(message, connection, state) {
|
|
|
614
948
|
}
|
|
615
949
|
instance.lastActivity = Date.now();
|
|
616
950
|
try {
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
if (transformed.sourceMap) {
|
|
620
|
-
if (!instance.sourceMaps) {
|
|
621
|
-
instance.sourceMaps = new Map;
|
|
622
|
-
}
|
|
623
|
-
instance.sourceMaps.set(filename, transformed.sourceMap);
|
|
624
|
-
}
|
|
625
|
-
const mod = await instance.runtime.isolate.compileModule(transformed.code, {
|
|
626
|
-
filename
|
|
951
|
+
await instance.runtime.eval(message.code, {
|
|
952
|
+
filename: message.filename
|
|
627
953
|
});
|
|
628
|
-
if (instance.moduleLoaderCallbackId) {
|
|
629
|
-
instance.moduleToFilename?.set(mod, filename);
|
|
630
|
-
const resolver = createModuleResolver(instance, connection);
|
|
631
|
-
await mod.instantiate(instance.runtime.context, resolver);
|
|
632
|
-
} else {
|
|
633
|
-
await mod.instantiate(instance.runtime.context, (specifier) => {
|
|
634
|
-
throw new Error(`No module loader registered. Cannot import: ${specifier}`);
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
await mod.evaluate();
|
|
638
|
-
const ns = mod.namespace;
|
|
639
|
-
const runRef = await ns.get("default", { reference: true });
|
|
640
|
-
try {
|
|
641
|
-
await runRef.apply(undefined, [], {
|
|
642
|
-
result: { promise: true },
|
|
643
|
-
...message.maxExecutionMs ? { timeout: message.maxExecutionMs } : {}
|
|
644
|
-
});
|
|
645
|
-
} finally {
|
|
646
|
-
runRef.release();
|
|
647
|
-
}
|
|
648
|
-
await Promise.all(instance.pendingCallbacks);
|
|
649
|
-
instance.pendingCallbacks.length = 0;
|
|
650
954
|
sendOk(connection.socket, message.requestId, { value: undefined });
|
|
651
955
|
} catch (err) {
|
|
652
956
|
const error = err;
|
|
653
|
-
if (
|
|
654
|
-
|
|
957
|
+
if (instance.namespaceId != null && isLinkerConflictError(error)) {
|
|
958
|
+
instance.isPoisoned = true;
|
|
655
959
|
}
|
|
656
|
-
|
|
657
|
-
sendError(connection.socket, message.requestId, isTimeoutError ? import_isolate_protocol.ErrorCode.ISOLATE_TIMEOUT : import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
960
|
+
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
658
961
|
}
|
|
659
962
|
}
|
|
660
963
|
async function handleDispatchRequest(message, connection, state) {
|
|
@@ -762,6 +1065,39 @@ async function handleWsClose(message, connection, state) {
|
|
|
762
1065
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
763
1066
|
}
|
|
764
1067
|
}
|
|
1068
|
+
function handleClientEvent(message, connection, state) {
|
|
1069
|
+
const instance = state.isolates.get(message.isolateId);
|
|
1070
|
+
if (!instance)
|
|
1071
|
+
return;
|
|
1072
|
+
instance.lastActivity = Date.now();
|
|
1073
|
+
switch (message.event) {
|
|
1074
|
+
case import_isolate_protocol.ClientEvents.WS_CLIENT_OPENED: {
|
|
1075
|
+
const payload = message.payload;
|
|
1076
|
+
instance.runtime.fetch.dispatchClientWebSocketOpen(payload.socketId, payload.protocol, payload.extensions);
|
|
1077
|
+
break;
|
|
1078
|
+
}
|
|
1079
|
+
case import_isolate_protocol.ClientEvents.WS_CLIENT_MESSAGE: {
|
|
1080
|
+
const payload = message.payload;
|
|
1081
|
+
const data = payload.data instanceof Uint8Array ? payload.data.buffer.slice(payload.data.byteOffset, payload.data.byteOffset + payload.data.byteLength) : payload.data;
|
|
1082
|
+
instance.runtime.fetch.dispatchClientWebSocketMessage(payload.socketId, data);
|
|
1083
|
+
break;
|
|
1084
|
+
}
|
|
1085
|
+
case import_isolate_protocol.ClientEvents.WS_CLIENT_CLOSED: {
|
|
1086
|
+
const payload = message.payload;
|
|
1087
|
+
instance.runtime.fetch.dispatchClientWebSocketClose(payload.socketId, payload.code, payload.reason, payload.wasClean);
|
|
1088
|
+
break;
|
|
1089
|
+
}
|
|
1090
|
+
case import_isolate_protocol.ClientEvents.WS_CLIENT_ERROR: {
|
|
1091
|
+
const payload = message.payload;
|
|
1092
|
+
instance.runtime.fetch.dispatchClientWebSocketError(payload.socketId);
|
|
1093
|
+
break;
|
|
1094
|
+
}
|
|
1095
|
+
default: {
|
|
1096
|
+
instance.runtime.fetch.dispatchEvent(message.event, message.payload);
|
|
1097
|
+
break;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
765
1101
|
async function handleFetchGetUpgradeRequest(message, connection, state) {
|
|
766
1102
|
const instance = state.isolates.get(message.isolateId);
|
|
767
1103
|
if (!instance) {
|
|
@@ -904,9 +1240,6 @@ function handleCallbackResponse(message, connection) {
|
|
|
904
1240
|
return;
|
|
905
1241
|
}
|
|
906
1242
|
connection.pendingCallbacks.delete(message.requestId);
|
|
907
|
-
if (pending.timeoutId) {
|
|
908
|
-
clearTimeout(pending.timeoutId);
|
|
909
|
-
}
|
|
910
1243
|
if (message.error) {
|
|
911
1244
|
const error = new Error(message.error.message);
|
|
912
1245
|
error.name = message.error.name;
|
|
@@ -918,17 +1251,12 @@ function handleCallbackResponse(message, connection) {
|
|
|
918
1251
|
pending.resolve(message.result);
|
|
919
1252
|
}
|
|
920
1253
|
}
|
|
921
|
-
async function invokeClientCallback(connection, callbackId, args
|
|
1254
|
+
async function invokeClientCallback(connection, callbackId, args) {
|
|
922
1255
|
const requestId = connection.nextCallbackId++;
|
|
923
1256
|
return new Promise((resolve, reject) => {
|
|
924
|
-
const timeoutId = setTimeout(() => {
|
|
925
|
-
connection.pendingCallbacks.delete(requestId);
|
|
926
|
-
reject(new Error("Callback timeout"));
|
|
927
|
-
}, timeout);
|
|
928
1257
|
const pending = {
|
|
929
1258
|
resolve,
|
|
930
|
-
reject
|
|
931
|
-
timeoutId
|
|
1259
|
+
reject
|
|
932
1260
|
};
|
|
933
1261
|
connection.pendingCallbacks.set(requestId, pending);
|
|
934
1262
|
const invoke = {
|
|
@@ -940,530 +1268,6 @@ async function invokeClientCallback(connection, callbackId, args, timeout = 1e4)
|
|
|
940
1268
|
sendMessage(connection.socket, invoke);
|
|
941
1269
|
});
|
|
942
1270
|
}
|
|
943
|
-
var ISOLATE_MARSHAL_CODE = `
|
|
944
|
-
(function() {
|
|
945
|
-
// Marshal a value (JavaScript → Ref)
|
|
946
|
-
function marshalForHost(value, depth = 0) {
|
|
947
|
-
if (depth > 100) throw new Error('Maximum marshalling depth exceeded');
|
|
948
|
-
|
|
949
|
-
if (value === null) return null;
|
|
950
|
-
if (value === undefined) return { __type: 'UndefinedRef' };
|
|
951
|
-
|
|
952
|
-
const type = typeof value;
|
|
953
|
-
if (type === 'string' || type === 'number' || type === 'boolean') return value;
|
|
954
|
-
if (type === 'bigint') return { __type: 'BigIntRef', value: value.toString() };
|
|
955
|
-
if (type === 'function') throw new Error('Cannot marshal functions from isolate');
|
|
956
|
-
if (type === 'symbol') throw new Error('Cannot marshal Symbol values');
|
|
957
|
-
|
|
958
|
-
if (type === 'object') {
|
|
959
|
-
if (value instanceof Date) {
|
|
960
|
-
return { __type: 'DateRef', timestamp: value.getTime() };
|
|
961
|
-
}
|
|
962
|
-
if (value instanceof RegExp) {
|
|
963
|
-
return { __type: 'RegExpRef', source: value.source, flags: value.flags };
|
|
964
|
-
}
|
|
965
|
-
if (value instanceof URL) {
|
|
966
|
-
return { __type: 'URLRef', href: value.href };
|
|
967
|
-
}
|
|
968
|
-
if (typeof Headers !== 'undefined' && value instanceof Headers) {
|
|
969
|
-
const pairs = [];
|
|
970
|
-
value.forEach((v, k) => pairs.push([k, v]));
|
|
971
|
-
return { __type: 'HeadersRef', pairs };
|
|
972
|
-
}
|
|
973
|
-
if (value instanceof Uint8Array) {
|
|
974
|
-
return { __type: 'Uint8ArrayRef', data: Array.from(value) };
|
|
975
|
-
}
|
|
976
|
-
if (value instanceof ArrayBuffer) {
|
|
977
|
-
return { __type: 'Uint8ArrayRef', data: Array.from(new Uint8Array(value)) };
|
|
978
|
-
}
|
|
979
|
-
if (typeof Request !== 'undefined' && value instanceof Request) {
|
|
980
|
-
throw new Error('Cannot marshal Request from isolate. Use fetch callback instead.');
|
|
981
|
-
}
|
|
982
|
-
if (typeof Response !== 'undefined' && value instanceof Response) {
|
|
983
|
-
throw new Error('Cannot marshal Response from isolate. Return plain objects instead.');
|
|
984
|
-
}
|
|
985
|
-
if (typeof File !== 'undefined' && value instanceof File) {
|
|
986
|
-
throw new Error('Cannot marshal File from isolate.');
|
|
987
|
-
}
|
|
988
|
-
if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
989
|
-
throw new Error('Cannot marshal Blob from isolate.');
|
|
990
|
-
}
|
|
991
|
-
if (typeof FormData !== 'undefined' && value instanceof FormData) {
|
|
992
|
-
throw new Error('Cannot marshal FormData from isolate.');
|
|
993
|
-
}
|
|
994
|
-
if (Array.isArray(value)) {
|
|
995
|
-
return value.map(v => marshalForHost(v, depth + 1));
|
|
996
|
-
}
|
|
997
|
-
// Plain object
|
|
998
|
-
const result = {};
|
|
999
|
-
for (const key of Object.keys(value)) {
|
|
1000
|
-
result[key] = marshalForHost(value[key], depth + 1);
|
|
1001
|
-
}
|
|
1002
|
-
return result;
|
|
1003
|
-
}
|
|
1004
|
-
return value;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
// Unmarshal a value (Ref → JavaScript)
|
|
1008
|
-
function unmarshalFromHost(value, depth = 0) {
|
|
1009
|
-
if (depth > 100) throw new Error('Maximum unmarshalling depth exceeded');
|
|
1010
|
-
|
|
1011
|
-
if (value === null) return null;
|
|
1012
|
-
if (typeof value !== 'object') return value;
|
|
1013
|
-
|
|
1014
|
-
if (value.__type) {
|
|
1015
|
-
switch (value.__type) {
|
|
1016
|
-
case 'UndefinedRef': return undefined;
|
|
1017
|
-
case 'DateRef': return new Date(value.timestamp);
|
|
1018
|
-
case 'RegExpRef': return new RegExp(value.source, value.flags);
|
|
1019
|
-
case 'BigIntRef': return BigInt(value.value);
|
|
1020
|
-
case 'URLRef': return new URL(value.href);
|
|
1021
|
-
case 'HeadersRef': return new Headers(value.pairs);
|
|
1022
|
-
case 'Uint8ArrayRef': return new Uint8Array(value.data);
|
|
1023
|
-
case 'RequestRef': {
|
|
1024
|
-
const init = {
|
|
1025
|
-
method: value.method,
|
|
1026
|
-
headers: value.headers,
|
|
1027
|
-
body: value.body ? new Uint8Array(value.body) : null,
|
|
1028
|
-
};
|
|
1029
|
-
if (value.mode) init.mode = value.mode;
|
|
1030
|
-
if (value.credentials) init.credentials = value.credentials;
|
|
1031
|
-
if (value.cache) init.cache = value.cache;
|
|
1032
|
-
if (value.redirect) init.redirect = value.redirect;
|
|
1033
|
-
if (value.referrer) init.referrer = value.referrer;
|
|
1034
|
-
if (value.referrerPolicy) init.referrerPolicy = value.referrerPolicy;
|
|
1035
|
-
if (value.integrity) init.integrity = value.integrity;
|
|
1036
|
-
return new Request(value.url, init);
|
|
1037
|
-
}
|
|
1038
|
-
case 'ResponseRef': {
|
|
1039
|
-
return new Response(value.body ? new Uint8Array(value.body) : null, {
|
|
1040
|
-
status: value.status,
|
|
1041
|
-
statusText: value.statusText,
|
|
1042
|
-
headers: value.headers,
|
|
1043
|
-
});
|
|
1044
|
-
}
|
|
1045
|
-
case 'FileRef': {
|
|
1046
|
-
if (!value.name) {
|
|
1047
|
-
return new Blob([new Uint8Array(value.data)], { type: value.type });
|
|
1048
|
-
}
|
|
1049
|
-
return new File([new Uint8Array(value.data)], value.name, {
|
|
1050
|
-
type: value.type,
|
|
1051
|
-
lastModified: value.lastModified,
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
|
-
case 'FormDataRef': {
|
|
1055
|
-
const fd = new FormData();
|
|
1056
|
-
for (const [key, entry] of value.entries) {
|
|
1057
|
-
if (typeof entry === 'string') {
|
|
1058
|
-
fd.append(key, entry);
|
|
1059
|
-
} else {
|
|
1060
|
-
const file = unmarshalFromHost(entry, depth + 1);
|
|
1061
|
-
fd.append(key, file);
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
return fd;
|
|
1065
|
-
}
|
|
1066
|
-
case 'CallbackRef': {
|
|
1067
|
-
// Create a proxy function that invokes the callback
|
|
1068
|
-
const callbackId = value.callbackId;
|
|
1069
|
-
return function(...args) {
|
|
1070
|
-
const argsJson = JSON.stringify(marshalForHost(args));
|
|
1071
|
-
const resultJson = __customFn_invoke.applySyncPromise(undefined, [callbackId, argsJson]);
|
|
1072
|
-
const result = JSON.parse(resultJson);
|
|
1073
|
-
if (result.ok) {
|
|
1074
|
-
return unmarshalFromHost(result.value);
|
|
1075
|
-
} else {
|
|
1076
|
-
const error = new Error(result.error.message);
|
|
1077
|
-
error.name = result.error.name;
|
|
1078
|
-
throw error;
|
|
1079
|
-
}
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
case 'PromiseRef': {
|
|
1083
|
-
// Create a proxy Promise that resolves via callback
|
|
1084
|
-
const promiseId = value.promiseId;
|
|
1085
|
-
return new Promise((resolve, reject) => {
|
|
1086
|
-
try {
|
|
1087
|
-
const argsJson = JSON.stringify([promiseId]);
|
|
1088
|
-
const resultJson = __customFn_invoke.applySyncPromise(undefined, [value.__resolveCallbackId, argsJson]);
|
|
1089
|
-
const result = JSON.parse(resultJson);
|
|
1090
|
-
if (result.ok) {
|
|
1091
|
-
resolve(unmarshalFromHost(result.value));
|
|
1092
|
-
} else {
|
|
1093
|
-
reject(new Error(result.error.message));
|
|
1094
|
-
}
|
|
1095
|
-
} catch (e) {
|
|
1096
|
-
reject(e);
|
|
1097
|
-
}
|
|
1098
|
-
});
|
|
1099
|
-
}
|
|
1100
|
-
case 'AsyncIteratorRef': {
|
|
1101
|
-
const iteratorId = value.iteratorId;
|
|
1102
|
-
const nextCallbackId = value.__nextCallbackId;
|
|
1103
|
-
const returnCallbackId = value.__returnCallbackId;
|
|
1104
|
-
return {
|
|
1105
|
-
[Symbol.asyncIterator]() { return this; },
|
|
1106
|
-
async next() {
|
|
1107
|
-
const argsJson = JSON.stringify([iteratorId]);
|
|
1108
|
-
const resultJson = __customFn_invoke.applySyncPromise(undefined, [nextCallbackId, argsJson]);
|
|
1109
|
-
const result = JSON.parse(resultJson);
|
|
1110
|
-
if (!result.ok) {
|
|
1111
|
-
const error = new Error(result.error.message);
|
|
1112
|
-
error.name = result.error.name;
|
|
1113
|
-
throw error;
|
|
1114
|
-
}
|
|
1115
|
-
return {
|
|
1116
|
-
done: result.value.done,
|
|
1117
|
-
value: unmarshalFromHost(result.value.value)
|
|
1118
|
-
};
|
|
1119
|
-
},
|
|
1120
|
-
async return(v) {
|
|
1121
|
-
const argsJson = JSON.stringify([iteratorId, marshalForHost(v)]);
|
|
1122
|
-
const resultJson = __customFn_invoke.applySyncPromise(undefined, [returnCallbackId, argsJson]);
|
|
1123
|
-
const result = JSON.parse(resultJson);
|
|
1124
|
-
return { done: true, value: result.ok ? unmarshalFromHost(result.value) : undefined };
|
|
1125
|
-
}
|
|
1126
|
-
};
|
|
1127
|
-
}
|
|
1128
|
-
default:
|
|
1129
|
-
// Unknown ref type, return as-is
|
|
1130
|
-
break;
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
if (Array.isArray(value)) {
|
|
1135
|
-
return value.map(v => unmarshalFromHost(v, depth + 1));
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
// Plain object - recursively unmarshal
|
|
1139
|
-
const result = {};
|
|
1140
|
-
for (const key of Object.keys(value)) {
|
|
1141
|
-
result[key] = unmarshalFromHost(value[key], depth + 1);
|
|
1142
|
-
}
|
|
1143
|
-
return result;
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
globalThis.__marshalForHost = marshalForHost;
|
|
1147
|
-
globalThis.__unmarshalFromHost = unmarshalFromHost;
|
|
1148
|
-
})();
|
|
1149
|
-
`;
|
|
1150
|
-
var LOCAL_CALLBACK_THRESHOLD = 1e6;
|
|
1151
|
-
function isPromiseRef(value) {
|
|
1152
|
-
return typeof value === "object" && value !== null && value.__type === "PromiseRef";
|
|
1153
|
-
}
|
|
1154
|
-
function isAsyncIteratorRef(value) {
|
|
1155
|
-
return typeof value === "object" && value !== null && value.__type === "AsyncIteratorRef";
|
|
1156
|
-
}
|
|
1157
|
-
function isLocalCallbackId(callbackId) {
|
|
1158
|
-
return callbackId >= LOCAL_CALLBACK_THRESHOLD;
|
|
1159
|
-
}
|
|
1160
|
-
async function setupCustomFunctions(context, customCallbacks, connection, instance) {
|
|
1161
|
-
const global = context.global;
|
|
1162
|
-
function createMarshalContext() {
|
|
1163
|
-
return {
|
|
1164
|
-
registerCallback: (fn) => {
|
|
1165
|
-
const callbackId = instance.nextLocalCallbackId++;
|
|
1166
|
-
instance.returnedCallbacks.set(callbackId, fn);
|
|
1167
|
-
return callbackId;
|
|
1168
|
-
},
|
|
1169
|
-
registerPromise: (promise) => {
|
|
1170
|
-
const promiseId = instance.nextLocalCallbackId++;
|
|
1171
|
-
instance.returnedPromises.set(promiseId, promise);
|
|
1172
|
-
return promiseId;
|
|
1173
|
-
},
|
|
1174
|
-
registerIterator: (iterator) => {
|
|
1175
|
-
const iteratorId = instance.nextLocalCallbackId++;
|
|
1176
|
-
instance.returnedIterators.set(iteratorId, iterator);
|
|
1177
|
-
return iteratorId;
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1180
|
-
}
|
|
1181
|
-
function addCallbackIdsToRefs(value) {
|
|
1182
|
-
if (value === null || typeof value !== "object") {
|
|
1183
|
-
return value;
|
|
1184
|
-
}
|
|
1185
|
-
if (isPromiseRef(value)) {
|
|
1186
|
-
if ("__resolveCallbackId" in value) {
|
|
1187
|
-
return value;
|
|
1188
|
-
}
|
|
1189
|
-
const resolveCallbackId = instance.nextLocalCallbackId++;
|
|
1190
|
-
instance.returnedCallbacks.set(resolveCallbackId, async (promiseId) => {
|
|
1191
|
-
const promise = instance.returnedPromises.get(promiseId);
|
|
1192
|
-
if (!promise) {
|
|
1193
|
-
throw new Error(`Promise ${promiseId} not found`);
|
|
1194
|
-
}
|
|
1195
|
-
const result2 = await promise;
|
|
1196
|
-
instance.returnedPromises.delete(promiseId);
|
|
1197
|
-
const ctx = createMarshalContext();
|
|
1198
|
-
const marshalled = await import_isolate_protocol.marshalValue(result2, ctx);
|
|
1199
|
-
return addCallbackIdsToRefs(marshalled);
|
|
1200
|
-
});
|
|
1201
|
-
return {
|
|
1202
|
-
...value,
|
|
1203
|
-
__resolveCallbackId: resolveCallbackId
|
|
1204
|
-
};
|
|
1205
|
-
}
|
|
1206
|
-
if (isAsyncIteratorRef(value)) {
|
|
1207
|
-
if ("__nextCallbackId" in value) {
|
|
1208
|
-
return value;
|
|
1209
|
-
}
|
|
1210
|
-
const nextCallbackId = instance.nextLocalCallbackId++;
|
|
1211
|
-
instance.returnedCallbacks.set(nextCallbackId, async (iteratorId) => {
|
|
1212
|
-
const iterator = instance.returnedIterators.get(iteratorId);
|
|
1213
|
-
if (!iterator) {
|
|
1214
|
-
throw new Error(`Iterator ${iteratorId} not found`);
|
|
1215
|
-
}
|
|
1216
|
-
const result2 = await iterator.next();
|
|
1217
|
-
if (result2.done) {
|
|
1218
|
-
instance.returnedIterators.delete(iteratorId);
|
|
1219
|
-
}
|
|
1220
|
-
const ctx = createMarshalContext();
|
|
1221
|
-
const marshalledValue = await import_isolate_protocol.marshalValue(result2.value, ctx);
|
|
1222
|
-
return {
|
|
1223
|
-
done: result2.done,
|
|
1224
|
-
value: addCallbackIdsToRefs(marshalledValue)
|
|
1225
|
-
};
|
|
1226
|
-
});
|
|
1227
|
-
const returnCallbackId = instance.nextLocalCallbackId++;
|
|
1228
|
-
instance.returnedCallbacks.set(returnCallbackId, async (iteratorId, returnValue) => {
|
|
1229
|
-
const iterator = instance.returnedIterators.get(iteratorId);
|
|
1230
|
-
instance.returnedIterators.delete(iteratorId);
|
|
1231
|
-
if (!iterator || !iterator.return) {
|
|
1232
|
-
return { done: true, value: undefined };
|
|
1233
|
-
}
|
|
1234
|
-
const result2 = await iterator.return(returnValue);
|
|
1235
|
-
const ctx = createMarshalContext();
|
|
1236
|
-
const marshalledValue = await import_isolate_protocol.marshalValue(result2.value, ctx);
|
|
1237
|
-
return {
|
|
1238
|
-
done: true,
|
|
1239
|
-
value: addCallbackIdsToRefs(marshalledValue)
|
|
1240
|
-
};
|
|
1241
|
-
});
|
|
1242
|
-
return {
|
|
1243
|
-
...value,
|
|
1244
|
-
__nextCallbackId: nextCallbackId,
|
|
1245
|
-
__returnCallbackId: returnCallbackId
|
|
1246
|
-
};
|
|
1247
|
-
}
|
|
1248
|
-
if (Array.isArray(value)) {
|
|
1249
|
-
return value.map((item) => addCallbackIdsToRefs(item));
|
|
1250
|
-
}
|
|
1251
|
-
const result = {};
|
|
1252
|
-
for (const key of Object.keys(value)) {
|
|
1253
|
-
result[key] = addCallbackIdsToRefs(value[key]);
|
|
1254
|
-
}
|
|
1255
|
-
return result;
|
|
1256
|
-
}
|
|
1257
|
-
const invokeCallbackRef = new import_isolated_vm.default.Reference(async (callbackId, argsJson) => {
|
|
1258
|
-
const marshalledArgs = JSON.parse(argsJson);
|
|
1259
|
-
const args = import_isolate_protocol.unmarshalValue(marshalledArgs);
|
|
1260
|
-
try {
|
|
1261
|
-
let result;
|
|
1262
|
-
if (isLocalCallbackId(callbackId)) {
|
|
1263
|
-
const callback = instance.returnedCallbacks.get(callbackId);
|
|
1264
|
-
if (!callback) {
|
|
1265
|
-
throw new Error(`Local callback ${callbackId} not found`);
|
|
1266
|
-
}
|
|
1267
|
-
result = await callback(...args);
|
|
1268
|
-
} else {
|
|
1269
|
-
const conn = instance.callbackContext?.connection || connection;
|
|
1270
|
-
result = await invokeClientCallback(conn, callbackId, args);
|
|
1271
|
-
}
|
|
1272
|
-
const ctx = createMarshalContext();
|
|
1273
|
-
const marshalledResult = await import_isolate_protocol.marshalValue({ ok: true, value: result }, ctx);
|
|
1274
|
-
const processedResult = addCallbackIdsToRefs(marshalledResult);
|
|
1275
|
-
return JSON.stringify(processedResult);
|
|
1276
|
-
} catch (error) {
|
|
1277
|
-
const err = error;
|
|
1278
|
-
return JSON.stringify({
|
|
1279
|
-
ok: false,
|
|
1280
|
-
error: { message: err.message, name: err.name }
|
|
1281
|
-
});
|
|
1282
|
-
}
|
|
1283
|
-
});
|
|
1284
|
-
global.setSync("__customFn_invoke", invokeCallbackRef);
|
|
1285
|
-
context.evalSync(ISOLATE_MARSHAL_CODE);
|
|
1286
|
-
const callbackIdMap = {};
|
|
1287
|
-
for (const [name, registration] of Object.entries(customCallbacks)) {
|
|
1288
|
-
callbackIdMap[name] = registration.callbackId;
|
|
1289
|
-
}
|
|
1290
|
-
global.setSync("__customFnCallbackIds", new import_isolated_vm.default.ExternalCopy(callbackIdMap).copyInto());
|
|
1291
|
-
for (const [name, registration] of Object.entries(customCallbacks)) {
|
|
1292
|
-
if (name.includes(":")) {
|
|
1293
|
-
continue;
|
|
1294
|
-
}
|
|
1295
|
-
if (registration.type === "sync") {
|
|
1296
|
-
context.evalSync(`
|
|
1297
|
-
globalThis.${name} = function(...args) {
|
|
1298
|
-
const callbackId = globalThis.__customFnCallbackIds["${name}"];
|
|
1299
|
-
const argsJson = JSON.stringify(__marshalForHost(args));
|
|
1300
|
-
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1301
|
-
undefined,
|
|
1302
|
-
[callbackId, argsJson]
|
|
1303
|
-
);
|
|
1304
|
-
const result = JSON.parse(resultJson);
|
|
1305
|
-
if (result.ok) {
|
|
1306
|
-
return __unmarshalFromHost(result.value);
|
|
1307
|
-
} else {
|
|
1308
|
-
const error = new Error(result.error.message);
|
|
1309
|
-
error.name = result.error.name;
|
|
1310
|
-
throw error;
|
|
1311
|
-
}
|
|
1312
|
-
};
|
|
1313
|
-
`);
|
|
1314
|
-
} else if (registration.type === "asyncIterator") {
|
|
1315
|
-
const startReg = customCallbacks[`${name}:start`];
|
|
1316
|
-
const nextReg = customCallbacks[`${name}:next`];
|
|
1317
|
-
const returnReg = customCallbacks[`${name}:return`];
|
|
1318
|
-
const throwReg = customCallbacks[`${name}:throw`];
|
|
1319
|
-
if (!startReg || !nextReg || !returnReg || !throwReg) {
|
|
1320
|
-
throw new Error(`Missing companion callbacks for asyncIterator function "${name}"`);
|
|
1321
|
-
}
|
|
1322
|
-
context.evalSync(`
|
|
1323
|
-
globalThis.${name} = function(...args) {
|
|
1324
|
-
// Start the iterator and get the iteratorId
|
|
1325
|
-
const startCallbackId = globalThis.__customFnCallbackIds["${name}:start"];
|
|
1326
|
-
const argsJson = JSON.stringify(__marshalForHost(args));
|
|
1327
|
-
const startResultJson = __customFn_invoke.applySyncPromise(
|
|
1328
|
-
undefined,
|
|
1329
|
-
[startCallbackId, argsJson]
|
|
1330
|
-
);
|
|
1331
|
-
const startResult = JSON.parse(startResultJson);
|
|
1332
|
-
if (!startResult.ok) {
|
|
1333
|
-
const error = new Error(startResult.error.message);
|
|
1334
|
-
error.name = startResult.error.name;
|
|
1335
|
-
throw error;
|
|
1336
|
-
}
|
|
1337
|
-
const iteratorId = __unmarshalFromHost(startResult.value).iteratorId;
|
|
1338
|
-
|
|
1339
|
-
return {
|
|
1340
|
-
[Symbol.asyncIterator]() { return this; },
|
|
1341
|
-
async next() {
|
|
1342
|
-
const nextCallbackId = globalThis.__customFnCallbackIds["${name}:next"];
|
|
1343
|
-
const argsJson = JSON.stringify(__marshalForHost([iteratorId]));
|
|
1344
|
-
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1345
|
-
undefined,
|
|
1346
|
-
[nextCallbackId, argsJson]
|
|
1347
|
-
);
|
|
1348
|
-
const result = JSON.parse(resultJson);
|
|
1349
|
-
if (!result.ok) {
|
|
1350
|
-
const error = new Error(result.error.message);
|
|
1351
|
-
error.name = result.error.name;
|
|
1352
|
-
throw error;
|
|
1353
|
-
}
|
|
1354
|
-
const val = __unmarshalFromHost(result.value);
|
|
1355
|
-
return { done: val.done, value: val.value };
|
|
1356
|
-
},
|
|
1357
|
-
async return(v) {
|
|
1358
|
-
const returnCallbackId = globalThis.__customFnCallbackIds["${name}:return"];
|
|
1359
|
-
const argsJson = JSON.stringify(__marshalForHost([iteratorId, v]));
|
|
1360
|
-
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1361
|
-
undefined,
|
|
1362
|
-
[returnCallbackId, argsJson]
|
|
1363
|
-
);
|
|
1364
|
-
const result = JSON.parse(resultJson);
|
|
1365
|
-
return { done: true, value: result.ok ? __unmarshalFromHost(result.value) : undefined };
|
|
1366
|
-
},
|
|
1367
|
-
async throw(e) {
|
|
1368
|
-
const throwCallbackId = globalThis.__customFnCallbackIds["${name}:throw"];
|
|
1369
|
-
const argsJson = JSON.stringify(__marshalForHost([iteratorId, { message: e?.message, name: e?.name }]));
|
|
1370
|
-
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1371
|
-
undefined,
|
|
1372
|
-
[throwCallbackId, argsJson]
|
|
1373
|
-
);
|
|
1374
|
-
const result = JSON.parse(resultJson);
|
|
1375
|
-
if (!result.ok) {
|
|
1376
|
-
const error = new Error(result.error.message);
|
|
1377
|
-
error.name = result.error.name;
|
|
1378
|
-
throw error;
|
|
1379
|
-
}
|
|
1380
|
-
const val = __unmarshalFromHost(result.value);
|
|
1381
|
-
return { done: val.done, value: val.value };
|
|
1382
|
-
}
|
|
1383
|
-
};
|
|
1384
|
-
};
|
|
1385
|
-
`);
|
|
1386
|
-
} else if (registration.type === "async") {
|
|
1387
|
-
context.evalSync(`
|
|
1388
|
-
globalThis.${name} = async function(...args) {
|
|
1389
|
-
const callbackId = globalThis.__customFnCallbackIds["${name}"];
|
|
1390
|
-
const argsJson = JSON.stringify(__marshalForHost(args));
|
|
1391
|
-
const resultJson = __customFn_invoke.applySyncPromise(
|
|
1392
|
-
undefined,
|
|
1393
|
-
[callbackId, argsJson]
|
|
1394
|
-
);
|
|
1395
|
-
const result = JSON.parse(resultJson);
|
|
1396
|
-
if (result.ok) {
|
|
1397
|
-
return __unmarshalFromHost(result.value);
|
|
1398
|
-
} else {
|
|
1399
|
-
const error = new Error(result.error.message);
|
|
1400
|
-
error.name = result.error.name;
|
|
1401
|
-
throw error;
|
|
1402
|
-
}
|
|
1403
|
-
};
|
|
1404
|
-
`);
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
function createModuleResolver(instance, connection) {
|
|
1409
|
-
return async (specifier, referrer) => {
|
|
1410
|
-
const cached = instance.moduleCache?.get(specifier);
|
|
1411
|
-
if (cached)
|
|
1412
|
-
return cached;
|
|
1413
|
-
if (!instance.moduleLoaderCallbackId) {
|
|
1414
|
-
throw new Error(`Module not found: ${specifier}`);
|
|
1415
|
-
}
|
|
1416
|
-
const importerPath = instance.moduleToFilename?.get(referrer) ?? "<unknown>";
|
|
1417
|
-
const importerResolveDir = import_node_path.default.posix.dirname(importerPath);
|
|
1418
|
-
const result = await invokeClientCallback(connection, instance.moduleLoaderCallbackId, [specifier, { path: importerPath, resolveDir: importerResolveDir }]);
|
|
1419
|
-
const { code, resolveDir } = result;
|
|
1420
|
-
const hash = import_isolate_transform.contentHash(code);
|
|
1421
|
-
const cacheKey = `${specifier}:${hash}`;
|
|
1422
|
-
const hashCached = instance.moduleCache?.get(cacheKey);
|
|
1423
|
-
if (hashCached)
|
|
1424
|
-
return hashCached;
|
|
1425
|
-
const transformed = await import_isolate_transform.transformModuleCode(code, specifier);
|
|
1426
|
-
if (transformed.sourceMap) {
|
|
1427
|
-
if (!instance.sourceMaps) {
|
|
1428
|
-
instance.sourceMaps = new Map;
|
|
1429
|
-
}
|
|
1430
|
-
instance.sourceMaps.set(specifier, transformed.sourceMap);
|
|
1431
|
-
}
|
|
1432
|
-
const mod = await instance.runtime.isolate.compileModule(transformed.code, {
|
|
1433
|
-
filename: specifier
|
|
1434
|
-
});
|
|
1435
|
-
const resolvedPath = import_node_path.default.posix.join(resolveDir, import_node_path.default.posix.basename(specifier));
|
|
1436
|
-
instance.moduleToFilename?.set(mod, resolvedPath);
|
|
1437
|
-
const resolver = createModuleResolver(instance, connection);
|
|
1438
|
-
await mod.instantiate(instance.runtime.context, resolver);
|
|
1439
|
-
instance.moduleCache?.set(specifier, mod);
|
|
1440
|
-
instance.moduleCache?.set(cacheKey, mod);
|
|
1441
|
-
return mod;
|
|
1442
|
-
};
|
|
1443
|
-
}
|
|
1444
|
-
async function serializeRequest(request) {
|
|
1445
|
-
const headers = [];
|
|
1446
|
-
request.headers.forEach((value, key) => {
|
|
1447
|
-
headers.push([key, value]);
|
|
1448
|
-
});
|
|
1449
|
-
let body = null;
|
|
1450
|
-
if (request.body) {
|
|
1451
|
-
body = new Uint8Array(await request.arrayBuffer());
|
|
1452
|
-
}
|
|
1453
|
-
return {
|
|
1454
|
-
method: request.method,
|
|
1455
|
-
url: request.url,
|
|
1456
|
-
headers,
|
|
1457
|
-
body
|
|
1458
|
-
};
|
|
1459
|
-
}
|
|
1460
|
-
function deserializeResponse(data) {
|
|
1461
|
-
return new Response(data.body, {
|
|
1462
|
-
status: data.status,
|
|
1463
|
-
statusText: data.statusText,
|
|
1464
|
-
headers: data.headers
|
|
1465
|
-
});
|
|
1466
|
-
}
|
|
1467
1271
|
function handleStreamPush(message, connection) {
|
|
1468
1272
|
const receiver = connection.streamReceivers.get(message.streamId);
|
|
1469
1273
|
if (!receiver) {
|
|
@@ -1591,9 +1395,6 @@ function handleCallbackStreamStart(message, connection) {
|
|
|
1591
1395
|
const pending = connection.pendingCallbacks.get(message.requestId);
|
|
1592
1396
|
if (pending) {
|
|
1593
1397
|
connection.pendingCallbacks.delete(message.requestId);
|
|
1594
|
-
if (pending.timeoutId) {
|
|
1595
|
-
clearTimeout(pending.timeoutId);
|
|
1596
|
-
}
|
|
1597
1398
|
const response = new Response(readableStream, {
|
|
1598
1399
|
status: message.metadata.status,
|
|
1599
1400
|
statusText: message.metadata.statusText,
|
|
@@ -1723,28 +1524,11 @@ async function handleRunTests(message, connection, state) {
|
|
|
1723
1524
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
|
|
1724
1525
|
return;
|
|
1725
1526
|
}
|
|
1726
|
-
if (!instance.testEnvironmentEnabled) {
|
|
1727
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
1728
|
-
return;
|
|
1729
|
-
}
|
|
1730
1527
|
instance.lastActivity = Date.now();
|
|
1731
1528
|
try {
|
|
1732
1529
|
const timeout = message.timeout ?? 30000;
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
timeoutId = setTimeout(() => reject(new Error("Test timeout")), timeout);
|
|
1736
|
-
});
|
|
1737
|
-
try {
|
|
1738
|
-
const results = await Promise.race([
|
|
1739
|
-
import_isolate_test_environment.runTests(instance.runtime.context),
|
|
1740
|
-
timeoutPromise
|
|
1741
|
-
]);
|
|
1742
|
-
sendOk(connection.socket, message.requestId, results);
|
|
1743
|
-
} finally {
|
|
1744
|
-
if (timeoutId) {
|
|
1745
|
-
clearTimeout(timeoutId);
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1530
|
+
const results = await instance.runtime.testEnvironment.runTests(timeout);
|
|
1531
|
+
sendOk(connection.socket, message.requestId, results);
|
|
1748
1532
|
} catch (err) {
|
|
1749
1533
|
const error = err;
|
|
1750
1534
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
@@ -1756,13 +1540,9 @@ async function handleResetTestEnv(message, connection, state) {
|
|
|
1756
1540
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
|
|
1757
1541
|
return;
|
|
1758
1542
|
}
|
|
1759
|
-
if (!instance.testEnvironmentEnabled) {
|
|
1760
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
1761
|
-
return;
|
|
1762
|
-
}
|
|
1763
1543
|
instance.lastActivity = Date.now();
|
|
1764
1544
|
try {
|
|
1765
|
-
|
|
1545
|
+
instance.runtime.testEnvironment.reset();
|
|
1766
1546
|
sendOk(connection.socket, message.requestId);
|
|
1767
1547
|
} catch (err) {
|
|
1768
1548
|
const error = err;
|
|
@@ -1775,13 +1555,9 @@ async function handleHasTests(message, connection, state) {
|
|
|
1775
1555
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
|
|
1776
1556
|
return;
|
|
1777
1557
|
}
|
|
1778
|
-
if (!instance.testEnvironmentEnabled) {
|
|
1779
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
1780
|
-
return;
|
|
1781
|
-
}
|
|
1782
1558
|
instance.lastActivity = Date.now();
|
|
1783
1559
|
try {
|
|
1784
|
-
const result =
|
|
1560
|
+
const result = instance.runtime.testEnvironment.hasTests();
|
|
1785
1561
|
sendOk(connection.socket, message.requestId, result);
|
|
1786
1562
|
} catch (err) {
|
|
1787
1563
|
const error = err;
|
|
@@ -1794,42 +1570,24 @@ async function handleGetTestCount(message, connection, state) {
|
|
|
1794
1570
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
|
|
1795
1571
|
return;
|
|
1796
1572
|
}
|
|
1797
|
-
if (!instance.testEnvironmentEnabled) {
|
|
1798
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
1799
|
-
return;
|
|
1800
|
-
}
|
|
1801
1573
|
instance.lastActivity = Date.now();
|
|
1802
1574
|
try {
|
|
1803
|
-
const result =
|
|
1575
|
+
const result = instance.runtime.testEnvironment.getTestCount();
|
|
1804
1576
|
sendOk(connection.socket, message.requestId, result);
|
|
1805
1577
|
} catch (err) {
|
|
1806
1578
|
const error = err;
|
|
1807
1579
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
|
|
1808
1580
|
}
|
|
1809
1581
|
}
|
|
1810
|
-
async function handleRunPlaywrightTests(message, connection, _state) {
|
|
1811
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "playwright.runTests() has been removed. Use testEnvironment.runTests() instead.");
|
|
1812
|
-
}
|
|
1813
|
-
async function handleResetPlaywrightTests(message, connection, _state) {
|
|
1814
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "playwright.reset() has been removed. Use testEnvironment.reset() instead.");
|
|
1815
|
-
}
|
|
1816
1582
|
async function handleGetCollectedData(message, connection, state) {
|
|
1817
1583
|
const instance = state.isolates.get(message.isolateId);
|
|
1818
1584
|
if (!instance) {
|
|
1819
1585
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
|
|
1820
1586
|
return;
|
|
1821
1587
|
}
|
|
1822
|
-
if (!instance.playwrightHandle) {
|
|
1823
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "Playwright not configured. Provide playwright.page in createRuntime options.");
|
|
1824
|
-
return;
|
|
1825
|
-
}
|
|
1826
1588
|
instance.lastActivity = Date.now();
|
|
1827
1589
|
try {
|
|
1828
|
-
const data =
|
|
1829
|
-
browserConsoleLogs: instance.playwrightHandle.getBrowserConsoleLogs(),
|
|
1830
|
-
networkRequests: instance.playwrightHandle.getNetworkRequests(),
|
|
1831
|
-
networkResponses: instance.playwrightHandle.getNetworkResponses()
|
|
1832
|
-
};
|
|
1590
|
+
const data = instance.runtime.playwright.getCollectedData();
|
|
1833
1591
|
sendOk(connection.socket, message.requestId, data);
|
|
1834
1592
|
} catch (err) {
|
|
1835
1593
|
const error = err;
|
|
@@ -1842,13 +1600,9 @@ async function handleClearCollectedData(message, connection, state) {
|
|
|
1842
1600
|
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
|
|
1843
1601
|
return;
|
|
1844
1602
|
}
|
|
1845
|
-
if (!instance.playwrightHandle) {
|
|
1846
|
-
sendError(connection.socket, message.requestId, import_isolate_protocol.ErrorCode.SCRIPT_ERROR, "Playwright not configured. Provide playwright.page in createRuntime options.");
|
|
1847
|
-
return;
|
|
1848
|
-
}
|
|
1849
1603
|
instance.lastActivity = Date.now();
|
|
1850
1604
|
try {
|
|
1851
|
-
instance.
|
|
1605
|
+
instance.runtime.playwright.clearCollectedData();
|
|
1852
1606
|
sendOk(connection.socket, message.requestId);
|
|
1853
1607
|
} catch (err) {
|
|
1854
1608
|
const error = err;
|
|
@@ -1856,4 +1610,4 @@ async function handleClearCollectedData(message, connection, state) {
|
|
|
1856
1610
|
}
|
|
1857
1611
|
}
|
|
1858
1612
|
|
|
1859
|
-
//# debugId=
|
|
1613
|
+
//# debugId=20B12DB74E4F312D64756E2164756E21
|