@ricsam/isolate 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.md +257 -18
  2. package/dist/cjs/bridge/diagnostics.cjs +37 -2
  3. package/dist/cjs/bridge/diagnostics.cjs.map +3 -3
  4. package/dist/cjs/bridge/runtime-bindings.cjs +230 -51
  5. package/dist/cjs/bridge/runtime-bindings.cjs.map +3 -3
  6. package/dist/cjs/bridge/sandbox-isolate.cjs +464 -0
  7. package/dist/cjs/bridge/sandbox-isolate.cjs.map +10 -0
  8. package/dist/cjs/host/create-isolate-host.cjs +130 -25
  9. package/dist/cjs/host/create-isolate-host.cjs.map +3 -3
  10. package/dist/cjs/host/nested-host-controller.cjs +369 -0
  11. package/dist/cjs/host/nested-host-controller.cjs.map +10 -0
  12. package/dist/cjs/index.cjs.map +1 -1
  13. package/dist/cjs/internal/browser-source.cjs +102 -0
  14. package/dist/cjs/internal/browser-source.cjs.map +10 -0
  15. package/dist/cjs/internal/client/connection.cjs +163 -172
  16. package/dist/cjs/internal/client/connection.cjs.map +3 -3
  17. package/dist/cjs/internal/daemon/callback-fs-handler.cjs +3 -3
  18. package/dist/cjs/internal/daemon/callback-fs-handler.cjs.map +3 -3
  19. package/dist/cjs/internal/daemon/connection.cjs +156 -13
  20. package/dist/cjs/internal/daemon/connection.cjs.map +3 -3
  21. package/dist/cjs/internal/playwright/client.cjs +4 -2
  22. package/dist/cjs/internal/playwright/client.cjs.map +3 -3
  23. package/dist/cjs/internal/playwright/handler.cjs +298 -25
  24. package/dist/cjs/internal/playwright/handler.cjs.map +3 -3
  25. package/dist/cjs/internal/playwright/index.cjs +54 -8
  26. package/dist/cjs/internal/playwright/index.cjs.map +3 -3
  27. package/dist/cjs/internal/playwright/types.cjs +3 -1
  28. package/dist/cjs/internal/playwright/types.cjs.map +3 -3
  29. package/dist/cjs/internal/protocol/codec.cjs +16 -5
  30. package/dist/cjs/internal/protocol/codec.cjs.map +3 -3
  31. package/dist/cjs/internal/protocol/marshalValue.cjs +37 -6
  32. package/dist/cjs/internal/protocol/marshalValue.cjs.map +3 -3
  33. package/dist/cjs/internal/protocol/types.cjs +2 -1
  34. package/dist/cjs/internal/protocol/types.cjs.map +3 -3
  35. package/dist/cjs/internal/runtime/index.cjs +377 -22
  36. package/dist/cjs/internal/runtime/index.cjs.map +3 -3
  37. package/dist/cjs/internal/typecheck/index.cjs +2 -1
  38. package/dist/cjs/internal/typecheck/index.cjs.map +3 -3
  39. package/dist/cjs/internal/typecheck/isolate-types.cjs +218 -13
  40. package/dist/cjs/internal/typecheck/isolate-types.cjs.map +3 -3
  41. package/dist/cjs/internal/typecheck/typecheck.cjs +2 -3
  42. package/dist/cjs/internal/typecheck/typecheck.cjs.map +3 -3
  43. package/dist/cjs/package.json +1 -1
  44. package/dist/cjs/playwright.cjs +76 -0
  45. package/dist/cjs/playwright.cjs.map +10 -0
  46. package/dist/cjs/runtime/namespaced-runtime.cjs +181 -0
  47. package/dist/cjs/runtime/namespaced-runtime.cjs.map +10 -0
  48. package/dist/cjs/runtime/script-runtime.cjs +14 -12
  49. package/dist/cjs/runtime/script-runtime.cjs.map +3 -3
  50. package/dist/cjs/runtime/test-runtime.cjs +113 -0
  51. package/dist/cjs/runtime/test-runtime.cjs.map +10 -0
  52. package/dist/cjs/server/app-server.cjs +16 -9
  53. package/dist/cjs/server/app-server.cjs.map +3 -3
  54. package/dist/cjs/typecheck/index.cjs +2 -1
  55. package/dist/cjs/typecheck/index.cjs.map +3 -3
  56. package/dist/mjs/bridge/diagnostics.mjs +37 -2
  57. package/dist/mjs/bridge/diagnostics.mjs.map +3 -3
  58. package/dist/mjs/bridge/runtime-bindings.mjs +233 -51
  59. package/dist/mjs/bridge/runtime-bindings.mjs.map +3 -3
  60. package/dist/mjs/bridge/sandbox-isolate.mjs +424 -0
  61. package/dist/mjs/bridge/sandbox-isolate.mjs.map +10 -0
  62. package/dist/mjs/host/create-isolate-host.mjs +132 -25
  63. package/dist/mjs/host/create-isolate-host.mjs.map +3 -3
  64. package/dist/mjs/host/nested-host-controller.mjs +333 -0
  65. package/dist/mjs/host/nested-host-controller.mjs.map +10 -0
  66. package/dist/mjs/index.mjs.map +1 -1
  67. package/dist/mjs/internal/browser-source.mjs +62 -0
  68. package/dist/mjs/internal/browser-source.mjs.map +10 -0
  69. package/dist/mjs/internal/client/connection.mjs +165 -173
  70. package/dist/mjs/internal/client/connection.mjs.map +3 -3
  71. package/dist/mjs/internal/daemon/callback-fs-handler.mjs +3 -3
  72. package/dist/mjs/internal/daemon/callback-fs-handler.mjs.map +3 -3
  73. package/dist/mjs/internal/daemon/connection.mjs +156 -13
  74. package/dist/mjs/internal/daemon/connection.mjs.map +3 -3
  75. package/dist/mjs/internal/playwright/client.mjs +7 -3
  76. package/dist/mjs/internal/playwright/client.mjs.map +3 -3
  77. package/dist/mjs/internal/playwright/handler.mjs +300 -26
  78. package/dist/mjs/internal/playwright/handler.mjs.map +3 -3
  79. package/dist/mjs/internal/playwright/index.mjs +59 -9
  80. package/dist/mjs/internal/playwright/index.mjs.map +3 -3
  81. package/dist/mjs/internal/playwright/types.mjs +3 -1
  82. package/dist/mjs/internal/playwright/types.mjs.map +3 -3
  83. package/dist/mjs/internal/protocol/codec.mjs +16 -5
  84. package/dist/mjs/internal/protocol/codec.mjs.map +3 -3
  85. package/dist/mjs/internal/protocol/marshalValue.mjs +38 -6
  86. package/dist/mjs/internal/protocol/marshalValue.mjs.map +3 -3
  87. package/dist/mjs/internal/protocol/types.mjs +2 -1
  88. package/dist/mjs/internal/protocol/types.mjs.map +3 -3
  89. package/dist/mjs/internal/runtime/index.mjs +377 -22
  90. package/dist/mjs/internal/runtime/index.mjs.map +3 -3
  91. package/dist/mjs/internal/typecheck/index.mjs +3 -1
  92. package/dist/mjs/internal/typecheck/index.mjs.map +3 -3
  93. package/dist/mjs/internal/typecheck/isolate-types.mjs +218 -13
  94. package/dist/mjs/internal/typecheck/isolate-types.mjs.map +3 -3
  95. package/dist/mjs/internal/typecheck/typecheck.mjs +2 -3
  96. package/dist/mjs/internal/typecheck/typecheck.mjs.map +3 -3
  97. package/dist/mjs/package.json +1 -1
  98. package/dist/mjs/playwright.mjs +47 -0
  99. package/dist/mjs/playwright.mjs.map +10 -0
  100. package/dist/mjs/runtime/namespaced-runtime.mjs +143 -0
  101. package/dist/mjs/runtime/namespaced-runtime.mjs.map +10 -0
  102. package/dist/mjs/runtime/script-runtime.mjs +16 -12
  103. package/dist/mjs/runtime/script-runtime.mjs.map +3 -3
  104. package/dist/mjs/runtime/test-runtime.mjs +78 -0
  105. package/dist/mjs/runtime/test-runtime.mjs.map +10 -0
  106. package/dist/mjs/server/app-server.mjs +23 -11
  107. package/dist/mjs/server/app-server.mjs.map +3 -3
  108. package/dist/mjs/typecheck/index.mjs +2 -1
  109. package/dist/mjs/typecheck/index.mjs.map +3 -3
  110. package/dist/types/bridge/diagnostics.d.ts +6 -1
  111. package/dist/types/bridge/runtime-bindings.d.ts +5 -1
  112. package/dist/types/bridge/sandbox-isolate.d.ts +21 -0
  113. package/dist/types/host/nested-host-controller.d.ts +15 -0
  114. package/dist/types/index.d.ts +1 -1
  115. package/dist/types/internal/browser-source.d.ts +10 -0
  116. package/dist/types/internal/client/types.d.ts +9 -0
  117. package/dist/types/internal/daemon/types.d.ts +0 -2
  118. package/dist/types/internal/playwright/client.d.ts +2 -2
  119. package/dist/types/internal/playwright/handler.d.ts +27 -4
  120. package/dist/types/internal/playwright/index.d.ts +2 -2
  121. package/dist/types/internal/playwright/types.d.ts +33 -1
  122. package/dist/types/internal/protocol/codec.d.ts +12 -2
  123. package/dist/types/internal/protocol/marshalValue.d.ts +3 -2
  124. package/dist/types/internal/protocol/types.d.ts +33 -2
  125. package/dist/types/internal/runtime/index.d.ts +5 -0
  126. package/dist/types/internal/typecheck/index.d.ts +1 -1
  127. package/dist/types/internal/typecheck/isolate-types.d.ts +6 -4
  128. package/dist/types/internal/typecheck/typecheck.d.ts +1 -1
  129. package/dist/types/playwright.d.ts +26 -0
  130. package/dist/types/runtime/namespaced-runtime.d.ts +11 -0
  131. package/dist/types/runtime/script-runtime.d.ts +2 -1
  132. package/dist/types/runtime/test-runtime.d.ts +4 -0
  133. package/dist/types/server/app-server.d.ts +2 -1
  134. package/dist/types/types.d.ts +75 -33
  135. package/package.json +8 -3
  136. package/dist/cjs/browser/browser-runtime.cjs +0 -157
  137. package/dist/cjs/browser/browser-runtime.cjs.map +0 -10
  138. package/dist/mjs/browser/browser-runtime.mjs +0 -93
  139. package/dist/mjs/browser/browser-runtime.mjs.map +0 -10
  140. package/dist/types/browser/browser-runtime.d.ts +0 -3
@@ -174,6 +174,29 @@ var ISOLATE_MARSHAL_CODE = `
174
174
  );
175
175
  let __customFn_nextCallbackId = 1;
176
176
  const __customFn_callbacks = new Map();
177
+ let __customFn_nextAsyncRefId = 1;
178
+ const __customFn_promises = new Map();
179
+ const __customFn_iterators = new Map();
180
+
181
+ function __customFn_attachAsyncIterator(resultPromise, label) {
182
+ resultPromise[Symbol.asyncIterator] = async function* () {
183
+ const iterable = await resultPromise;
184
+ if (iterable && typeof iterable[Symbol.asyncIterator] === 'function') {
185
+ yield* iterable;
186
+ return;
187
+ }
188
+ if (iterable && typeof iterable[Symbol.iterator] === 'function') {
189
+ yield* iterable;
190
+ return;
191
+ }
192
+ throw new TypeError(label + '(...) is not async iterable');
193
+ };
194
+ return resultPromise;
195
+ }
196
+
197
+ async function __customFn_waitForTurn() {
198
+ await new Promise((resolve) => setTimeout(resolve, 0));
199
+ }
177
200
 
178
201
  function __customFn_registerCallback(callback) {
179
202
  const callbackId = __customFn_nextCallbackId++;
@@ -192,7 +215,15 @@ var ISOLATE_MARSHAL_CODE = `
192
215
  if (type === 'string' || type === 'number' || type === 'boolean') return value;
193
216
  if (type === 'bigint') return { __type: 'BigIntRef', value: value.toString() };
194
217
  if (type === 'function') {
195
- return { __type: 'CallbackRef', callbackId: __customFn_registerCallback(value) };
218
+ return {
219
+ __type: 'CallbackRef',
220
+ callbackId: __customFn_registerCallback(value),
221
+ callbackKind:
222
+ value.__isolateCallbackKind === 'asyncGenerator' ||
223
+ (value.constructor && value.constructor.name === 'AsyncGeneratorFunction')
224
+ ? 'asyncGenerator'
225
+ : undefined,
226
+ };
196
227
  }
197
228
  if (type === 'symbol') throw new Error('Cannot marshal Symbol values');
198
229
 
@@ -206,6 +237,9 @@ var ISOLATE_MARSHAL_CODE = `
206
237
  if (value instanceof URL) {
207
238
  return { __type: 'URLRef', href: value.href };
208
239
  }
240
+ if (typeof AbortSignal !== 'undefined' && value instanceof AbortSignal) {
241
+ return { __type: 'AbortSignalRef', aborted: value.aborted };
242
+ }
209
243
  if (typeof Headers !== 'undefined' && value instanceof Headers) {
210
244
  const pairs = [];
211
245
  value.forEach((v, k) => pairs.push([k, v]));
@@ -245,6 +279,192 @@ var ISOLATE_MARSHAL_CODE = `
245
279
  return value;
246
280
  }
247
281
 
282
+ async function marshalForHostAsync(value, depth = 0) {
283
+ if (depth > 100) throw new Error('Maximum marshalling depth exceeded');
284
+
285
+ if (value === null || value === undefined) {
286
+ return marshalForHost(value, depth);
287
+ }
288
+
289
+ const type = typeof value;
290
+ if (
291
+ type === 'string' ||
292
+ type === 'number' ||
293
+ type === 'boolean' ||
294
+ type === 'bigint' ||
295
+ type === 'function'
296
+ ) {
297
+ return marshalForHost(value, depth);
298
+ }
299
+ if (type === 'symbol') {
300
+ throw new Error('Cannot marshal Symbol values');
301
+ }
302
+
303
+ if (value && typeof value.then === 'function') {
304
+ return await marshalForHostAsync(await value, depth);
305
+ }
306
+
307
+ if (value && typeof value[Symbol.asyncIterator] === 'function') {
308
+ const iteratorId = __customFn_nextAsyncRefId++;
309
+ const iterator = value[Symbol.asyncIterator]();
310
+ __customFn_iterators.set(iteratorId, iterator);
311
+
312
+ const nextCallbackId = __customFn_registerCallback(async (id) => {
313
+ const target = __customFn_iterators.get(id);
314
+ if (!target) {
315
+ throw new Error('Iterator ' + id + ' not found');
316
+ }
317
+ const result = await target.next();
318
+ if (result.done) {
319
+ __customFn_iterators.delete(id);
320
+ }
321
+ return {
322
+ done: result.done,
323
+ value: await marshalForHostAsync(result.value, depth + 1),
324
+ };
325
+ });
326
+
327
+ const returnCallbackId = __customFn_registerCallback(async (id, returnValue) => {
328
+ const target = __customFn_iterators.get(id);
329
+ __customFn_iterators.delete(id);
330
+ if (!target || typeof target.return !== 'function') {
331
+ return {
332
+ done: true,
333
+ value: marshalForHost(undefined, depth + 1),
334
+ };
335
+ }
336
+ const result = await target.return(returnValue);
337
+ return {
338
+ done: result.done ?? true,
339
+ value: await marshalForHostAsync(result.value, depth + 1),
340
+ };
341
+ });
342
+
343
+ const throwCallbackId = __customFn_registerCallback(async (id, errorValue) => {
344
+ const target = __customFn_iterators.get(id);
345
+ if (!target) {
346
+ throw new Error('Iterator ' + id + ' not found');
347
+ }
348
+ if (typeof target.throw !== 'function') {
349
+ throw Object.assign(
350
+ new Error(errorValue?.message ?? 'Iterator does not support throw()'),
351
+ { name: errorValue?.name ?? 'Error', stack: errorValue?.stack }
352
+ );
353
+ }
354
+
355
+ try {
356
+ const thrown = Object.assign(
357
+ new Error(errorValue?.message ?? 'Iterator throw()'),
358
+ { name: errorValue?.name ?? 'Error', stack: errorValue?.stack }
359
+ );
360
+ const result = await target.throw(thrown);
361
+ if (result.done) {
362
+ __customFn_iterators.delete(id);
363
+ }
364
+ return {
365
+ done: result.done,
366
+ value: await marshalForHostAsync(result.value, depth + 1),
367
+ };
368
+ } catch (error) {
369
+ __customFn_iterators.delete(id);
370
+ throw error;
371
+ }
372
+ });
373
+
374
+ return {
375
+ __type: 'AsyncIteratorRef',
376
+ iteratorId,
377
+ __nextCallbackId: nextCallbackId,
378
+ __returnCallbackId: returnCallbackId,
379
+ __throwCallbackId: throwCallbackId,
380
+ };
381
+ }
382
+
383
+ if (value instanceof Date || value instanceof RegExp || value instanceof URL) {
384
+ return marshalForHost(value, depth);
385
+ }
386
+ if (typeof AbortSignal !== 'undefined' && value instanceof AbortSignal) {
387
+ return marshalForHost(value, depth);
388
+ }
389
+ if (typeof Headers !== 'undefined' && value instanceof Headers) {
390
+ return marshalForHost(value, depth);
391
+ }
392
+ if (value instanceof Uint8Array || value instanceof ArrayBuffer) {
393
+ return marshalForHost(value, depth);
394
+ }
395
+ if (typeof Request !== 'undefined' && value instanceof Request) {
396
+ const headers = [];
397
+ value.headers.forEach((headerValue, key) => headers.push([key, headerValue]));
398
+ const body = value.body
399
+ ? Array.from(new Uint8Array(await value.clone().arrayBuffer()))
400
+ : null;
401
+ return {
402
+ __type: 'RequestRef',
403
+ url: value.url,
404
+ method: value.method,
405
+ headers,
406
+ body,
407
+ mode: value.mode,
408
+ credentials: value.credentials,
409
+ cache: value.cache,
410
+ redirect: value.redirect,
411
+ referrer: value.referrer,
412
+ referrerPolicy: value.referrerPolicy,
413
+ integrity: value.integrity,
414
+ };
415
+ }
416
+ if (typeof Response !== 'undefined' && value instanceof Response) {
417
+ const headers = [];
418
+ value.headers.forEach((headerValue, key) => headers.push([key, headerValue]));
419
+ const body = value.body
420
+ ? Array.from(new Uint8Array(await value.clone().arrayBuffer()))
421
+ : null;
422
+ return {
423
+ __type: 'ResponseRef',
424
+ status: value.status,
425
+ statusText: value.statusText,
426
+ headers,
427
+ body,
428
+ };
429
+ }
430
+ if (typeof File !== 'undefined' && value instanceof File) {
431
+ return {
432
+ __type: 'FileRef',
433
+ name: value.name,
434
+ type: value.type,
435
+ lastModified: value.lastModified,
436
+ data: Array.from(new Uint8Array(await value.arrayBuffer())),
437
+ };
438
+ }
439
+ if (typeof Blob !== 'undefined' && value instanceof Blob) {
440
+ return {
441
+ __type: 'FileRef',
442
+ type: value.type,
443
+ data: Array.from(new Uint8Array(await value.arrayBuffer())),
444
+ };
445
+ }
446
+ if (typeof FormData !== 'undefined' && value instanceof FormData) {
447
+ const entries = [];
448
+ for (const [key, entry] of value.entries()) {
449
+ if (typeof entry === 'string') {
450
+ entries.push([key, entry]);
451
+ } else {
452
+ entries.push([key, await marshalForHostAsync(entry, depth + 1)]);
453
+ }
454
+ }
455
+ return { __type: 'FormDataRef', entries };
456
+ }
457
+ if (Array.isArray(value)) {
458
+ return await Promise.all(value.map((item) => marshalForHostAsync(item, depth + 1)));
459
+ }
460
+
461
+ const result = {};
462
+ for (const key of Object.keys(value)) {
463
+ result[key] = await marshalForHostAsync(value[key], depth + 1);
464
+ }
465
+ return result;
466
+ }
467
+
248
468
  async function invokeLocalCallback(callbackId, argsJson) {
249
469
  const callback = __customFn_callbacks.get(callbackId);
250
470
  if (!callback) {
@@ -260,8 +480,8 @@ var ISOLATE_MARSHAL_CODE = `
260
480
  try {
261
481
  const rawArgs = JSON.parse(argsJson);
262
482
  const args = unmarshalFromHost(rawArgs);
263
- const result = await callback(...args);
264
- return JSON.stringify({ ok: true, value: marshalForHost(result) });
483
+ const result = callback(...args);
484
+ return JSON.stringify({ ok: true, value: await marshalForHostAsync(result) });
265
485
  } catch (error) {
266
486
  const err = error instanceof Error ? error : new Error(String(error));
267
487
  return JSON.stringify({
@@ -288,6 +508,12 @@ var ISOLATE_MARSHAL_CODE = `
288
508
  case 'RegExpRef': return new RegExp(value.source, value.flags);
289
509
  case 'BigIntRef': return BigInt(value.value);
290
510
  case 'URLRef': return new URL(value.href);
511
+ case 'AbortSignalRef': {
512
+ if (value.aborted) {
513
+ return AbortSignal.abort();
514
+ }
515
+ return new AbortController().signal;
516
+ }
291
517
  case 'HeadersRef': return new Headers(value.pairs);
292
518
  case 'Uint8ArrayRef': return new Uint8Array(value.data);
293
519
  case 'RequestRef': {
@@ -391,6 +617,7 @@ var ISOLATE_MARSHAL_CODE = `
391
617
  error.name = result.error.name;
392
618
  throw error;
393
619
  }
620
+ await __customFn_waitForTurn();
394
621
  return {
395
622
  done: result.value.done,
396
623
  value: unmarshalFromHost(result.value.value)
@@ -409,6 +636,7 @@ var ISOLATE_MARSHAL_CODE = `
409
636
  error.name = result.error.name;
410
637
  throw error;
411
638
  }
639
+ await __customFn_waitForTurn();
412
640
  return {
413
641
  done: result.value.done ?? true,
414
642
  value: unmarshalFromHost(result.value.value ?? result.value),
@@ -433,6 +661,7 @@ var ISOLATE_MARSHAL_CODE = `
433
661
  error.name = result.error.name;
434
662
  throw error;
435
663
  }
664
+ await __customFn_waitForTurn();
436
665
  return {
437
666
  done: result.value.done,
438
667
  value: unmarshalFromHost(result.value.value),
@@ -462,6 +691,8 @@ var ISOLATE_MARSHAL_CODE = `
462
691
  globalThis.__marshalForHost = marshalForHost;
463
692
  globalThis.__unmarshalFromHost = unmarshalFromHost;
464
693
  globalThis.__customFn_invokeLocalCallback = invokeLocalCallback;
694
+ globalThis.__customFn_attachAsyncIterator = __customFn_attachAsyncIterator;
695
+ globalThis.__customFn_waitForTurn = __customFn_waitForTurn;
465
696
  })();
466
697
  `;
467
698
  async function setupCustomFunctions(context, customFunctions, marshalOptions) {
@@ -519,6 +750,23 @@ async function setupCustomFunctions(context, customFunctions, marshalOptions) {
519
750
  global.setSync("__customFn_invoke", invokeCallbackRef);
520
751
  context.evalSync(ISOLATE_MARSHAL_CODE);
521
752
  const invokeIsolateCallbackRef = context.global.getSync("__customFn_invokeLocalCallback", { reference: true });
753
+ const normalizeIsolateCallbackResult = async (value) => {
754
+ if (typeof Response !== "undefined" && value instanceof Response) {
755
+ const headers = [];
756
+ value.headers.forEach((headerValue, key) => {
757
+ headers.push([key, headerValue]);
758
+ });
759
+ const body = value.body ? Array.from(new Uint8Array(await value.clone().arrayBuffer())) : null;
760
+ return {
761
+ __type: "ResponseRef",
762
+ status: value.status,
763
+ statusText: value.statusText,
764
+ headers,
765
+ body
766
+ };
767
+ }
768
+ return value;
769
+ };
522
770
  isolateUnmarshalContext.getCallback = (callbackId) => {
523
771
  return async (...args) => {
524
772
  let marshalledArgs;
@@ -532,31 +780,110 @@ async function setupCustomFunctions(context, customFunctions, marshalOptions) {
532
780
  const resultJson = await invokeIsolateCallbackRef.apply(undefined, [callbackId, JSON.stringify(marshalledArgs)], { result: { promise: true, copy: true } });
533
781
  const result = JSON.parse(resultJson);
534
782
  if (result.ok) {
535
- return unmarshalValue(result.value, isolateUnmarshalContext);
783
+ const unmarshalled = unmarshalValue(result.value, isolateUnmarshalContext);
784
+ return await normalizeIsolateCallbackResult(unmarshalled);
536
785
  }
537
786
  const error = new Error(result.error?.message ?? `Callback ${callbackId} failed`);
538
787
  error.name = result.error?.name ?? "Error";
539
788
  throw error;
540
789
  };
541
790
  };
791
+ isolateUnmarshalContext.createPromiseProxy = (promiseId, ref) => {
792
+ const resolveCallbackId = ref?.__resolveCallbackId;
793
+ if (typeof resolveCallbackId !== "number") {
794
+ throw new Error(`Promise ${promiseId} is missing a resolve callback`);
795
+ }
796
+ return (async () => {
797
+ const resultJson = await invokeIsolateCallbackRef.apply(undefined, [resolveCallbackId, JSON.stringify([promiseId])], { result: { promise: true, copy: true } });
798
+ const result = JSON.parse(resultJson);
799
+ if (result.ok) {
800
+ return unmarshalValue(result.value, isolateUnmarshalContext);
801
+ }
802
+ const error = new Error(result.error?.message ?? `Promise ${promiseId} failed`);
803
+ error.name = result.error?.name ?? "Error";
804
+ throw error;
805
+ })();
806
+ };
807
+ isolateUnmarshalContext.createIteratorProxy = (iteratorId, ref) => {
808
+ const nextCallbackId = ref?.__nextCallbackId;
809
+ const returnCallbackId = ref?.__returnCallbackId;
810
+ const throwCallbackId = ref?.__throwCallbackId;
811
+ if (typeof nextCallbackId !== "number") {
812
+ throw new Error(`Iterator ${iteratorId} is missing a next callback`);
813
+ }
814
+ const invokeIteratorCallback = async (callbackId, args, label) => {
815
+ const resultJson = await invokeIsolateCallbackRef.apply(undefined, [callbackId, JSON.stringify(args)], { result: { promise: true, copy: true } });
816
+ const result = JSON.parse(resultJson);
817
+ if (result.ok) {
818
+ return result.value;
819
+ }
820
+ const error = new Error(result.error?.message ?? `${label} failed for iterator ${iteratorId}`);
821
+ error.name = result.error?.name ?? "Error";
822
+ throw error;
823
+ };
824
+ return {
825
+ [Symbol.asyncIterator]() {
826
+ return this;
827
+ },
828
+ async next() {
829
+ const result = await invokeIteratorCallback(nextCallbackId, [iteratorId], "Iterator next()");
830
+ return {
831
+ done: Boolean(result.done),
832
+ value: unmarshalValue(result.value, isolateUnmarshalContext)
833
+ };
834
+ },
835
+ async return(value) {
836
+ if (typeof returnCallbackId !== "number") {
837
+ return { done: true, value };
838
+ }
839
+ const result = await invokeIteratorCallback(returnCallbackId, [iteratorId, value], "Iterator return()");
840
+ return {
841
+ done: result.done ?? true,
842
+ value: unmarshalValue(result.value, isolateUnmarshalContext)
843
+ };
844
+ },
845
+ async throw(errorValue) {
846
+ if (typeof throwCallbackId !== "number") {
847
+ throw errorValue;
848
+ }
849
+ const serializedError = errorValue && typeof errorValue === "object" ? {
850
+ message: errorValue.message,
851
+ name: errorValue.name,
852
+ stack: errorValue.stack
853
+ } : {
854
+ message: String(errorValue ?? "Iterator throw()"),
855
+ name: "Error"
856
+ };
857
+ const result = await invokeIteratorCallback(throwCallbackId, [iteratorId, serializedError], "Iterator throw()");
858
+ return {
859
+ done: Boolean(result.done),
860
+ value: unmarshalValue(result.value, isolateUnmarshalContext)
861
+ };
862
+ }
863
+ };
864
+ };
542
865
  for (const name of Object.keys(customFunctions)) {
543
866
  const def = customFunctions[name];
544
867
  if (def.type === "async") {
545
868
  context.evalSync(`
546
- globalThis.${name} = async function(...args) {
547
- const marshalledArgs = __marshalForHost(args);
548
- const resultJson = await __customFn_invoke.apply(
549
- undefined,
550
- ["${name}", JSON.stringify(marshalledArgs)],
551
- { result: { promise: true, copy: true } }
552
- );
553
- const result = JSON.parse(resultJson);
554
- if (result.ok) {
555
- return __unmarshalFromHost(result.value);
556
- }
557
- const error = new Error(result.error.message);
558
- error.name = result.error.name;
559
- throw error;
869
+ globalThis.${name} = function(...args) {
870
+ const resultPromise = (async () => {
871
+ const marshalledArgs = __marshalForHost(args);
872
+ const resultJson = await __customFn_invoke.apply(
873
+ undefined,
874
+ ["${name}", JSON.stringify(marshalledArgs)],
875
+ { result: { promise: true, copy: true } }
876
+ );
877
+ const result = JSON.parse(resultJson);
878
+ if (result.ok) {
879
+ await __customFn_waitForTurn();
880
+ return __unmarshalFromHost(result.value);
881
+ }
882
+ const error = new Error(result.error.message);
883
+ error.name = result.error.name;
884
+ throw error;
885
+ })();
886
+ return __customFn_attachAsyncIterator(resultPromise, "${name}");
560
887
  };
561
888
  `);
562
889
  } else if (def.type === "sync") {
@@ -595,18 +922,38 @@ async function setupCustomFunctions(context, customFunctions, marshalOptions) {
595
922
  name: result.error.name,
596
923
  });
597
924
  })();
925
+ let iteratorRef;
926
+ const getIterator = async () => {
927
+ if (!iteratorRef) {
928
+ let iterator = await iteratorPromise;
929
+ for (let depth = 0; depth < 4; depth += 1) {
930
+ if (iterator && typeof iterator.next === 'function') {
931
+ break;
932
+ }
933
+ if (!iterator || typeof iterator[Symbol.asyncIterator] !== 'function') {
934
+ break;
935
+ }
936
+ iterator = iterator[Symbol.asyncIterator]();
937
+ }
938
+ iteratorRef = iterator;
939
+ }
940
+ return iteratorRef;
941
+ };
598
942
  return {
599
943
  [Symbol.asyncIterator]() { return this; },
600
944
  async next() {
601
- const iterator = await iteratorPromise;
945
+ const iterator = await getIterator();
946
+ if (!iterator || typeof iterator.next !== 'function') {
947
+ throw new TypeError('Custom async iterator resolved to a non-iterator');
948
+ }
602
949
  return iterator.next();
603
950
  },
604
951
  async return(v) {
605
- const iterator = await iteratorPromise;
952
+ const iterator = await getIterator();
606
953
  return iterator.return ? iterator.return(v) : { done: true, value: v };
607
954
  },
608
955
  async throw(e) {
609
- const iterator = await iteratorPromise;
956
+ const iterator = await getIterator();
610
957
  if (!iterator.throw) {
611
958
  throw e;
612
959
  }
@@ -932,6 +1279,7 @@ async function createRuntime(options) {
932
1279
  }
933
1280
  const playwrightSetupOptions = {
934
1281
  handler: opts.playwright.handler,
1282
+ hasDefaultPage: opts.playwright.hasDefaultPage,
935
1283
  timeout: opts.playwright.timeout,
936
1284
  console: opts.playwright.console && !opts.console?.onEntry,
937
1285
  onEvent: eventCallback
@@ -1123,6 +1471,13 @@ async function createRuntime(options) {
1123
1471
  requestFailures: state.handles.playwright.getRequestFailures()
1124
1472
  };
1125
1473
  },
1474
+ getTrackedResources() {
1475
+ ensureRuntimeUsable();
1476
+ if (!state.handles.playwright) {
1477
+ throw new Error("Playwright not configured. Provide playwright.handler in createRuntime options.");
1478
+ }
1479
+ return state.handles.playwright.getTrackedResources();
1480
+ },
1126
1481
  clearCollectedData() {
1127
1482
  ensureRuntimeUsable();
1128
1483
  state.handles.playwright?.clearCollected();
@@ -1267,4 +1622,4 @@ export {
1267
1622
  createNodeFileSystemHandler
1268
1623
  };
1269
1624
 
1270
- //# debugId=46DA9086D0B9D52764756E2164756E21
1625
+ //# debugId=FBA344872E70838164756E2164756E21