@ricsam/isolate-runtime 0.1.14 → 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 +88 -24
- package/dist/cjs/index.cjs +308 -38
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/index.mjs +314 -24
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/index.d.ts +41 -5
- package/package.json +1 -1
- package/dist/cjs/internal.cjs +0 -95
- package/dist/cjs/internal.cjs.map +0 -10
- package/dist/mjs/internal.mjs +0 -52
- package/dist/mjs/internal.mjs.map +0 -10
- package/dist/types/internal.d.ts +0 -39
package/dist/mjs/index.mjs
CHANGED
|
@@ -23,7 +23,9 @@ import {
|
|
|
23
23
|
hasTests as hasTestsInContext,
|
|
24
24
|
getTestCount as getTestCountInContext
|
|
25
25
|
} from "@ricsam/isolate-test-environment";
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
setupPlaywright
|
|
28
|
+
} from "@ricsam/isolate-playwright";
|
|
27
29
|
import {
|
|
28
30
|
marshalValue,
|
|
29
31
|
unmarshalValue
|
|
@@ -47,10 +49,10 @@ import {
|
|
|
47
49
|
} from "@ricsam/isolate-test-environment";
|
|
48
50
|
import {
|
|
49
51
|
setupPlaywright as setupPlaywright2,
|
|
50
|
-
createPlaywrightHandler
|
|
52
|
+
createPlaywrightHandler,
|
|
53
|
+
defaultPlaywrightHandler,
|
|
54
|
+
getDefaultPlaywrightHandlerMetadata
|
|
51
55
|
} from "@ricsam/isolate-playwright";
|
|
52
|
-
|
|
53
|
-
export * from "./internal.mjs";
|
|
54
56
|
var iteratorSessions = new Map;
|
|
55
57
|
var nextIteratorId = 1;
|
|
56
58
|
var ISOLATE_MARSHAL_CODE = `
|
|
@@ -176,6 +178,68 @@ var ISOLATE_MARSHAL_CODE = `
|
|
|
176
178
|
}
|
|
177
179
|
return fd;
|
|
178
180
|
}
|
|
181
|
+
case 'CallbackRef': {
|
|
182
|
+
// Create a proxy function that invokes the callback
|
|
183
|
+
const callbackId = value.callbackId;
|
|
184
|
+
return function(...args) {
|
|
185
|
+
const argsJson = JSON.stringify(marshalForHost(args));
|
|
186
|
+
const resultJson = __customFn_invoke.applySyncPromise(undefined, [callbackId, argsJson]);
|
|
187
|
+
const result = JSON.parse(resultJson);
|
|
188
|
+
if (result.ok) {
|
|
189
|
+
return unmarshalFromHost(result.value);
|
|
190
|
+
} else {
|
|
191
|
+
const error = new Error(result.error.message);
|
|
192
|
+
error.name = result.error.name;
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
case 'PromiseRef': {
|
|
198
|
+
// Create a proxy Promise that resolves via callback
|
|
199
|
+
const promiseId = value.promiseId;
|
|
200
|
+
return new Promise((resolve, reject) => {
|
|
201
|
+
try {
|
|
202
|
+
const argsJson = JSON.stringify([promiseId]);
|
|
203
|
+
const resultJson = __customFn_invoke.applySyncPromise(undefined, [value.__resolveCallbackId, argsJson]);
|
|
204
|
+
const result = JSON.parse(resultJson);
|
|
205
|
+
if (result.ok) {
|
|
206
|
+
resolve(unmarshalFromHost(result.value));
|
|
207
|
+
} else {
|
|
208
|
+
reject(new Error(result.error.message));
|
|
209
|
+
}
|
|
210
|
+
} catch (e) {
|
|
211
|
+
reject(e);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
case 'AsyncIteratorRef': {
|
|
216
|
+
const iteratorId = value.iteratorId;
|
|
217
|
+
const nextCallbackId = value.__nextCallbackId;
|
|
218
|
+
const returnCallbackId = value.__returnCallbackId;
|
|
219
|
+
return {
|
|
220
|
+
[Symbol.asyncIterator]() { return this; },
|
|
221
|
+
async next() {
|
|
222
|
+
const argsJson = JSON.stringify([iteratorId]);
|
|
223
|
+
const resultJson = __customFn_invoke.applySyncPromise(undefined, [nextCallbackId, argsJson]);
|
|
224
|
+
const result = JSON.parse(resultJson);
|
|
225
|
+
if (!result.ok) {
|
|
226
|
+
const error = new Error(result.error.message);
|
|
227
|
+
error.name = result.error.name;
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
done: result.value.done,
|
|
232
|
+
value: unmarshalFromHost(result.value.value)
|
|
233
|
+
};
|
|
234
|
+
},
|
|
235
|
+
async return(v) {
|
|
236
|
+
const argsJson = JSON.stringify([iteratorId, marshalForHost(v)]);
|
|
237
|
+
const resultJson = __customFn_invoke.applySyncPromise(undefined, [returnCallbackId, argsJson]);
|
|
238
|
+
const result = JSON.parse(resultJson);
|
|
239
|
+
return { done: true, value: result.ok ? unmarshalFromHost(result.value) : undefined };
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
179
243
|
default:
|
|
180
244
|
// Unknown ref type, return as-is
|
|
181
245
|
break;
|
|
@@ -199,9 +263,27 @@ var ISOLATE_MARSHAL_CODE = `
|
|
|
199
263
|
globalThis.__unmarshalFromHost = unmarshalFromHost;
|
|
200
264
|
})();
|
|
201
265
|
`;
|
|
202
|
-
async function setupCustomFunctions(context, customFunctions) {
|
|
266
|
+
async function setupCustomFunctions(context, customFunctions, marshalOptions) {
|
|
203
267
|
const global = context.global;
|
|
204
|
-
const invokeCallbackRef = new ivm.Reference(async (
|
|
268
|
+
const invokeCallbackRef = new ivm.Reference(async (nameOrId, argsJson) => {
|
|
269
|
+
if (typeof nameOrId === "number" && marshalOptions) {
|
|
270
|
+
const rawArgs2 = JSON.parse(argsJson);
|
|
271
|
+
const args2 = unmarshalValue(rawArgs2);
|
|
272
|
+
try {
|
|
273
|
+
const result = await marshalOptions.invokeCallback(nameOrId, args2);
|
|
274
|
+
const ctx = marshalOptions.createMarshalContext();
|
|
275
|
+
const marshalledResult = await marshalValue(result, ctx);
|
|
276
|
+
const processedResult = marshalOptions.addCallbackIdsToRefs(marshalledResult);
|
|
277
|
+
return JSON.stringify({ ok: true, value: processedResult });
|
|
278
|
+
} catch (error) {
|
|
279
|
+
const err = error;
|
|
280
|
+
return JSON.stringify({
|
|
281
|
+
ok: false,
|
|
282
|
+
error: { message: err.message, name: err.name }
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const name = String(nameOrId);
|
|
205
287
|
const def = customFunctions[name];
|
|
206
288
|
if (!def) {
|
|
207
289
|
return JSON.stringify({
|
|
@@ -215,7 +297,13 @@ async function setupCustomFunctions(context, customFunctions) {
|
|
|
215
297
|
const rawArgs = JSON.parse(argsJson);
|
|
216
298
|
const args = unmarshalValue(rawArgs);
|
|
217
299
|
try {
|
|
218
|
-
const result =
|
|
300
|
+
const result = await def.fn(...args);
|
|
301
|
+
if (marshalOptions) {
|
|
302
|
+
const ctx = marshalOptions.createMarshalContext();
|
|
303
|
+
const marshalledResult2 = await marshalValue(result, ctx);
|
|
304
|
+
const processedResult = marshalOptions.addCallbackIdsToRefs(marshalledResult2);
|
|
305
|
+
return JSON.stringify({ ok: true, value: processedResult });
|
|
306
|
+
}
|
|
219
307
|
const marshalledResult = await marshalValue(result);
|
|
220
308
|
return JSON.stringify({ ok: true, value: marshalledResult });
|
|
221
309
|
} catch (error) {
|
|
@@ -271,7 +359,14 @@ async function setupCustomFunctions(context, customFunctions) {
|
|
|
271
359
|
if (result.done) {
|
|
272
360
|
iteratorSessions.delete(iteratorId);
|
|
273
361
|
}
|
|
274
|
-
|
|
362
|
+
let marshalledValue;
|
|
363
|
+
if (marshalOptions) {
|
|
364
|
+
const ctx = marshalOptions.createMarshalContext();
|
|
365
|
+
marshalledValue = await marshalValue(result.value, ctx);
|
|
366
|
+
marshalledValue = marshalOptions.addCallbackIdsToRefs(marshalledValue);
|
|
367
|
+
} else {
|
|
368
|
+
marshalledValue = await marshalValue(result.value);
|
|
369
|
+
}
|
|
275
370
|
return JSON.stringify({
|
|
276
371
|
ok: true,
|
|
277
372
|
done: result.done,
|
|
@@ -297,7 +392,14 @@ async function setupCustomFunctions(context, customFunctions) {
|
|
|
297
392
|
const value = unmarshalValue(rawValue);
|
|
298
393
|
const result = await session.iterator.return?.(value);
|
|
299
394
|
iteratorSessions.delete(iteratorId);
|
|
300
|
-
|
|
395
|
+
let marshalledValue;
|
|
396
|
+
if (marshalOptions) {
|
|
397
|
+
const ctx = marshalOptions.createMarshalContext();
|
|
398
|
+
marshalledValue = await marshalValue(result?.value, ctx);
|
|
399
|
+
marshalledValue = marshalOptions.addCallbackIdsToRefs(marshalledValue);
|
|
400
|
+
} else {
|
|
401
|
+
marshalledValue = await marshalValue(result?.value);
|
|
402
|
+
}
|
|
301
403
|
return JSON.stringify({ ok: true, done: true, value: marshalledValue });
|
|
302
404
|
} catch (error) {
|
|
303
405
|
const err = error;
|
|
@@ -327,7 +429,14 @@ async function setupCustomFunctions(context, customFunctions) {
|
|
|
327
429
|
});
|
|
328
430
|
const result = await session.iterator.throw?.(error);
|
|
329
431
|
iteratorSessions.delete(iteratorId);
|
|
330
|
-
|
|
432
|
+
let marshalledValue;
|
|
433
|
+
if (marshalOptions) {
|
|
434
|
+
const ctx = marshalOptions.createMarshalContext();
|
|
435
|
+
marshalledValue = await marshalValue(result?.value, ctx);
|
|
436
|
+
marshalledValue = marshalOptions.addCallbackIdsToRefs(marshalledValue);
|
|
437
|
+
} else {
|
|
438
|
+
marshalledValue = await marshalValue(result?.value);
|
|
439
|
+
}
|
|
331
440
|
return JSON.stringify({
|
|
332
441
|
ok: true,
|
|
333
442
|
done: result?.done ?? true,
|
|
@@ -418,8 +527,114 @@ async function setupCustomFunctions(context, customFunctions) {
|
|
|
418
527
|
}
|
|
419
528
|
return invokeCallbackRef;
|
|
420
529
|
}
|
|
530
|
+
function createLocalCustomFunctionsMarshalOptions() {
|
|
531
|
+
const returnedCallbacks = new Map;
|
|
532
|
+
const returnedPromises = new Map;
|
|
533
|
+
const returnedIterators = new Map;
|
|
534
|
+
let nextLocalCallbackId = 1e6;
|
|
535
|
+
const createMarshalContext = () => ({
|
|
536
|
+
registerCallback: (fn) => {
|
|
537
|
+
const callbackId = nextLocalCallbackId++;
|
|
538
|
+
returnedCallbacks.set(callbackId, fn);
|
|
539
|
+
return callbackId;
|
|
540
|
+
},
|
|
541
|
+
registerPromise: (promise) => {
|
|
542
|
+
const promiseId = nextLocalCallbackId++;
|
|
543
|
+
returnedPromises.set(promiseId, promise);
|
|
544
|
+
return promiseId;
|
|
545
|
+
},
|
|
546
|
+
registerIterator: (iterator) => {
|
|
547
|
+
const iteratorId = nextLocalCallbackId++;
|
|
548
|
+
returnedIterators.set(iteratorId, iterator);
|
|
549
|
+
return iteratorId;
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
const isPromiseRef = (value) => typeof value === "object" && value !== null && value.__type === "PromiseRef";
|
|
553
|
+
const isAsyncIteratorRef = (value) => typeof value === "object" && value !== null && value.__type === "AsyncIteratorRef";
|
|
554
|
+
const addCallbackIdsToRefs = (value) => {
|
|
555
|
+
if (value === null || typeof value !== "object")
|
|
556
|
+
return value;
|
|
557
|
+
if (isPromiseRef(value)) {
|
|
558
|
+
if ("__resolveCallbackId" in value)
|
|
559
|
+
return value;
|
|
560
|
+
const resolveCallbackId = nextLocalCallbackId++;
|
|
561
|
+
returnedCallbacks.set(resolveCallbackId, async (promiseId) => {
|
|
562
|
+
const promise = returnedPromises.get(promiseId);
|
|
563
|
+
if (!promise) {
|
|
564
|
+
throw new Error(`Promise ${promiseId} not found`);
|
|
565
|
+
}
|
|
566
|
+
const result2 = await promise;
|
|
567
|
+
returnedPromises.delete(promiseId);
|
|
568
|
+
const ctx = createMarshalContext();
|
|
569
|
+
const marshalled = await marshalValue(result2, ctx);
|
|
570
|
+
return addCallbackIdsToRefs(marshalled);
|
|
571
|
+
});
|
|
572
|
+
return { ...value, __resolveCallbackId: resolveCallbackId };
|
|
573
|
+
}
|
|
574
|
+
if (isAsyncIteratorRef(value)) {
|
|
575
|
+
if ("__nextCallbackId" in value)
|
|
576
|
+
return value;
|
|
577
|
+
const nextCallbackId = nextLocalCallbackId++;
|
|
578
|
+
returnedCallbacks.set(nextCallbackId, async (iteratorId) => {
|
|
579
|
+
const iterator = returnedIterators.get(iteratorId);
|
|
580
|
+
if (!iterator) {
|
|
581
|
+
throw new Error(`Iterator ${iteratorId} not found`);
|
|
582
|
+
}
|
|
583
|
+
const result2 = await iterator.next();
|
|
584
|
+
if (result2.done) {
|
|
585
|
+
returnedIterators.delete(iteratorId);
|
|
586
|
+
}
|
|
587
|
+
const ctx = createMarshalContext();
|
|
588
|
+
const marshalledValue = await marshalValue(result2.value, ctx);
|
|
589
|
+
return {
|
|
590
|
+
done: result2.done,
|
|
591
|
+
value: addCallbackIdsToRefs(marshalledValue)
|
|
592
|
+
};
|
|
593
|
+
});
|
|
594
|
+
const returnCallbackId = nextLocalCallbackId++;
|
|
595
|
+
returnedCallbacks.set(returnCallbackId, async (iteratorId, returnValue) => {
|
|
596
|
+
const iterator = returnedIterators.get(iteratorId);
|
|
597
|
+
returnedIterators.delete(iteratorId);
|
|
598
|
+
if (!iterator || !iterator.return) {
|
|
599
|
+
return { done: true, value: undefined };
|
|
600
|
+
}
|
|
601
|
+
const result2 = await iterator.return(returnValue);
|
|
602
|
+
const ctx = createMarshalContext();
|
|
603
|
+
const marshalledValue = await marshalValue(result2.value, ctx);
|
|
604
|
+
return {
|
|
605
|
+
done: true,
|
|
606
|
+
value: addCallbackIdsToRefs(marshalledValue)
|
|
607
|
+
};
|
|
608
|
+
});
|
|
609
|
+
return {
|
|
610
|
+
...value,
|
|
611
|
+
__nextCallbackId: nextCallbackId,
|
|
612
|
+
__returnCallbackId: returnCallbackId
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
if (Array.isArray(value)) {
|
|
616
|
+
return value.map((item) => addCallbackIdsToRefs(item));
|
|
617
|
+
}
|
|
618
|
+
const result = {};
|
|
619
|
+
for (const key of Object.keys(value)) {
|
|
620
|
+
result[key] = addCallbackIdsToRefs(value[key]);
|
|
621
|
+
}
|
|
622
|
+
return result;
|
|
623
|
+
};
|
|
624
|
+
const invokeCallback = async (callbackId, args) => {
|
|
625
|
+
const callback = returnedCallbacks.get(callbackId);
|
|
626
|
+
if (!callback) {
|
|
627
|
+
throw new Error(`Local callback ${callbackId} not found`);
|
|
628
|
+
}
|
|
629
|
+
return await callback(...args);
|
|
630
|
+
};
|
|
631
|
+
return { createMarshalContext, addCallbackIdsToRefs, invokeCallback };
|
|
632
|
+
}
|
|
421
633
|
function createModuleResolver(state) {
|
|
422
634
|
return async (specifier, referrer) => {
|
|
635
|
+
const staticCached = state.staticModuleCache.get(specifier);
|
|
636
|
+
if (staticCached)
|
|
637
|
+
return staticCached;
|
|
423
638
|
const cached = state.moduleCache.get(specifier);
|
|
424
639
|
if (cached)
|
|
425
640
|
return cached;
|
|
@@ -428,16 +643,21 @@ function createModuleResolver(state) {
|
|
|
428
643
|
}
|
|
429
644
|
const importerPath = state.moduleToFilename.get(referrer) ?? "<unknown>";
|
|
430
645
|
const importerResolveDir = path.posix.dirname(importerPath);
|
|
431
|
-
const
|
|
646
|
+
const result = await state.moduleLoader(specifier, {
|
|
432
647
|
path: importerPath,
|
|
433
648
|
resolveDir: importerResolveDir
|
|
434
649
|
});
|
|
650
|
+
const { code, resolveDir } = result;
|
|
435
651
|
const hash = contentHash(code);
|
|
436
652
|
const cacheKey = `${specifier}:${hash}`;
|
|
437
653
|
const hashCached = state.moduleCache.get(cacheKey);
|
|
438
654
|
if (hashCached)
|
|
439
655
|
return hashCached;
|
|
440
|
-
|
|
656
|
+
let transformed = state.transformCache.get(hash);
|
|
657
|
+
if (!transformed) {
|
|
658
|
+
transformed = await transformModuleCode(code, specifier);
|
|
659
|
+
state.transformCache.set(hash, transformed);
|
|
660
|
+
}
|
|
441
661
|
if (transformed.sourceMap) {
|
|
442
662
|
state.sourceMaps.set(specifier, transformed.sourceMap);
|
|
443
663
|
}
|
|
@@ -446,8 +666,12 @@ function createModuleResolver(state) {
|
|
|
446
666
|
});
|
|
447
667
|
const resolvedPath = path.posix.join(resolveDir, path.posix.basename(specifier));
|
|
448
668
|
state.moduleToFilename.set(mod, resolvedPath);
|
|
449
|
-
|
|
450
|
-
|
|
669
|
+
if (result.static) {
|
|
670
|
+
state.staticModuleCache.set(specifier, mod);
|
|
671
|
+
} else {
|
|
672
|
+
state.moduleCache.set(specifier, mod);
|
|
673
|
+
state.moduleCache.set(cacheKey, mod);
|
|
674
|
+
}
|
|
451
675
|
const resolver = createModuleResolver(state);
|
|
452
676
|
await mod.instantiate(state.context, resolver);
|
|
453
677
|
return mod;
|
|
@@ -458,8 +682,8 @@ function convertFetchCallback(callback) {
|
|
|
458
682
|
return {};
|
|
459
683
|
}
|
|
460
684
|
return {
|
|
461
|
-
onFetch: async (
|
|
462
|
-
return Promise.resolve(callback(
|
|
685
|
+
onFetch: async (url, init) => {
|
|
686
|
+
return Promise.resolve(callback(url, init));
|
|
463
687
|
}
|
|
464
688
|
};
|
|
465
689
|
}
|
|
@@ -475,8 +699,11 @@ async function createRuntime(options) {
|
|
|
475
699
|
context,
|
|
476
700
|
handles: {},
|
|
477
701
|
moduleCache: new Map,
|
|
702
|
+
staticModuleCache: new Map,
|
|
703
|
+
transformCache: new Map,
|
|
478
704
|
moduleToFilename: new Map,
|
|
479
705
|
sourceMaps: new Map,
|
|
706
|
+
pendingCallbacks: [],
|
|
480
707
|
moduleLoader: opts.moduleLoader,
|
|
481
708
|
customFunctions: opts.customFunctions
|
|
482
709
|
};
|
|
@@ -491,13 +718,17 @@ async function createRuntime(options) {
|
|
|
491
718
|
state.handles.fs = await setupFs(context, opts.fs);
|
|
492
719
|
}
|
|
493
720
|
if (opts.customFunctions) {
|
|
494
|
-
|
|
721
|
+
const customMarshalOptions = opts.customFunctionsMarshalOptions ?? createLocalCustomFunctionsMarshalOptions();
|
|
722
|
+
state.customFnInvokeRef = await setupCustomFunctions(context, opts.customFunctions, customMarshalOptions);
|
|
495
723
|
}
|
|
496
724
|
if (opts.testEnvironment) {
|
|
497
725
|
const testEnvOptions = typeof opts.testEnvironment === "object" ? opts.testEnvironment : undefined;
|
|
498
726
|
state.handles.testEnvironment = await setupTestEnvironment(context, testEnvOptions);
|
|
499
727
|
}
|
|
500
728
|
if (opts.playwright) {
|
|
729
|
+
if (!opts.playwright.handler) {
|
|
730
|
+
throw new Error("Playwright configured without handler. Provide playwright.handler in createRuntime options.");
|
|
731
|
+
}
|
|
501
732
|
let eventCallback = opts.playwright.onEvent;
|
|
502
733
|
if (opts.playwright.console && opts.console?.onEntry) {
|
|
503
734
|
const originalCallback = eventCallback;
|
|
@@ -516,12 +747,13 @@ async function createRuntime(options) {
|
|
|
516
747
|
}
|
|
517
748
|
};
|
|
518
749
|
}
|
|
519
|
-
|
|
520
|
-
|
|
750
|
+
const playwrightSetupOptions = {
|
|
751
|
+
handler: opts.playwright.handler,
|
|
521
752
|
timeout: opts.playwright.timeout,
|
|
522
753
|
console: opts.playwright.console && !opts.console?.onEntry,
|
|
523
754
|
onEvent: eventCallback
|
|
524
|
-
}
|
|
755
|
+
};
|
|
756
|
+
state.handles.playwright = await setupPlaywright(context, playwrightSetupOptions);
|
|
525
757
|
}
|
|
526
758
|
const fetchHandle = {
|
|
527
759
|
async dispatchRequest(request, options2) {
|
|
@@ -577,6 +809,36 @@ async function createRuntime(options) {
|
|
|
577
809
|
throw new Error("Fetch handle not available");
|
|
578
810
|
}
|
|
579
811
|
return state.handles.fetch.hasActiveConnections();
|
|
812
|
+
},
|
|
813
|
+
dispatchClientWebSocketOpen(socketId, protocol, extensions) {
|
|
814
|
+
if (!state.handles.fetch) {
|
|
815
|
+
throw new Error("Fetch handle not available");
|
|
816
|
+
}
|
|
817
|
+
state.handles.fetch.dispatchClientWebSocketOpen(socketId, protocol, extensions);
|
|
818
|
+
},
|
|
819
|
+
dispatchClientWebSocketMessage(socketId, data) {
|
|
820
|
+
if (!state.handles.fetch) {
|
|
821
|
+
throw new Error("Fetch handle not available");
|
|
822
|
+
}
|
|
823
|
+
state.handles.fetch.dispatchClientWebSocketMessage(socketId, data);
|
|
824
|
+
},
|
|
825
|
+
dispatchClientWebSocketClose(socketId, code, reason, wasClean) {
|
|
826
|
+
if (!state.handles.fetch) {
|
|
827
|
+
throw new Error("Fetch handle not available");
|
|
828
|
+
}
|
|
829
|
+
state.handles.fetch.dispatchClientWebSocketClose(socketId, code, reason, wasClean);
|
|
830
|
+
},
|
|
831
|
+
dispatchClientWebSocketError(socketId) {
|
|
832
|
+
if (!state.handles.fetch) {
|
|
833
|
+
throw new Error("Fetch handle not available");
|
|
834
|
+
}
|
|
835
|
+
state.handles.fetch.dispatchClientWebSocketError(socketId);
|
|
836
|
+
},
|
|
837
|
+
onClientWebSocketCommand(callback) {
|
|
838
|
+
if (!state.handles.fetch) {
|
|
839
|
+
throw new Error("Fetch handle not available");
|
|
840
|
+
}
|
|
841
|
+
return state.handles.fetch.onClientWebSocketCommand(callback);
|
|
580
842
|
}
|
|
581
843
|
};
|
|
582
844
|
const timersHandle = {
|
|
@@ -599,11 +861,27 @@ async function createRuntime(options) {
|
|
|
599
861
|
}
|
|
600
862
|
};
|
|
601
863
|
const testEnvironmentHandle = {
|
|
602
|
-
async runTests(
|
|
864
|
+
async runTests(timeout) {
|
|
603
865
|
if (!state.handles.testEnvironment) {
|
|
604
866
|
throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
605
867
|
}
|
|
606
|
-
|
|
868
|
+
if (timeout === undefined) {
|
|
869
|
+
return runTestsInContext(state.context);
|
|
870
|
+
}
|
|
871
|
+
let timeoutId;
|
|
872
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
873
|
+
timeoutId = setTimeout(() => reject(new Error("Test timeout")), timeout);
|
|
874
|
+
});
|
|
875
|
+
try {
|
|
876
|
+
return await Promise.race([
|
|
877
|
+
runTestsInContext(state.context),
|
|
878
|
+
timeoutPromise
|
|
879
|
+
]);
|
|
880
|
+
} finally {
|
|
881
|
+
if (timeoutId) {
|
|
882
|
+
clearTimeout(timeoutId);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
607
885
|
},
|
|
608
886
|
hasTests() {
|
|
609
887
|
if (!state.handles.testEnvironment) {
|
|
@@ -624,7 +902,7 @@ async function createRuntime(options) {
|
|
|
624
902
|
const playwrightHandle = {
|
|
625
903
|
getCollectedData() {
|
|
626
904
|
if (!state.handles.playwright) {
|
|
627
|
-
throw new Error("Playwright not configured. Provide playwright.
|
|
905
|
+
throw new Error("Playwright not configured. Provide playwright.handler in createRuntime options.");
|
|
628
906
|
}
|
|
629
907
|
return {
|
|
630
908
|
browserConsoleLogs: state.handles.playwright.getBrowserConsoleLogs(),
|
|
@@ -638,6 +916,7 @@ async function createRuntime(options) {
|
|
|
638
916
|
};
|
|
639
917
|
return {
|
|
640
918
|
id,
|
|
919
|
+
pendingCallbacks: state.pendingCallbacks,
|
|
641
920
|
fetch: fetchHandle,
|
|
642
921
|
timers: timersHandle,
|
|
643
922
|
console: consoleHandle,
|
|
@@ -668,6 +947,10 @@ async function createRuntime(options) {
|
|
|
668
947
|
} finally {
|
|
669
948
|
runRef.release();
|
|
670
949
|
}
|
|
950
|
+
if (state.pendingCallbacks.length > 0) {
|
|
951
|
+
await Promise.all(state.pendingCallbacks);
|
|
952
|
+
state.pendingCallbacks.length = 0;
|
|
953
|
+
}
|
|
671
954
|
} catch (err) {
|
|
672
955
|
const error = err;
|
|
673
956
|
if (error.stack && state.sourceMaps.size > 0) {
|
|
@@ -676,6 +959,11 @@ async function createRuntime(options) {
|
|
|
676
959
|
throw error;
|
|
677
960
|
}
|
|
678
961
|
},
|
|
962
|
+
clearModuleCache() {
|
|
963
|
+
state.moduleCache.clear();
|
|
964
|
+
state.moduleToFilename.clear();
|
|
965
|
+
state.sourceMaps.clear();
|
|
966
|
+
},
|
|
679
967
|
async dispose() {
|
|
680
968
|
if (state.customFnInvokeRef) {
|
|
681
969
|
state.customFnInvokeRef.release();
|
|
@@ -712,9 +1000,11 @@ export {
|
|
|
712
1000
|
normalizeEntryFilename2 as normalizeEntryFilename,
|
|
713
1001
|
hasTests,
|
|
714
1002
|
getTestCount,
|
|
1003
|
+
getDefaultPlaywrightHandlerMetadata,
|
|
1004
|
+
defaultPlaywrightHandler,
|
|
715
1005
|
createRuntime,
|
|
716
1006
|
createPlaywrightHandler,
|
|
717
1007
|
createNodeFileSystemHandler
|
|
718
1008
|
};
|
|
719
1009
|
|
|
720
|
-
//# debugId=
|
|
1010
|
+
//# debugId=D363252DB857D59164756E2164756E21
|