@ricsam/isolate-runtime 0.1.4 → 0.1.7

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.
@@ -0,0 +1,97 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __toESM = (mod, isNodeMode, target) => {
9
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
10
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
+ for (let key of __getOwnPropNames(mod))
12
+ if (!__hasOwnProp.call(to, key))
13
+ __defProp(to, key, {
14
+ get: () => mod[key],
15
+ enumerable: true
16
+ });
17
+ return to;
18
+ };
19
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
20
+ var __toCommonJS = (from) => {
21
+ var entry = __moduleCache.get(from), desc;
22
+ if (entry)
23
+ return entry;
24
+ entry = __defProp({}, "__esModule", { value: true });
25
+ if (from && typeof from === "object" || typeof from === "function")
26
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
27
+ get: () => from[key],
28
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
29
+ }));
30
+ __moduleCache.set(from, entry);
31
+ return entry;
32
+ };
33
+ var __export = (target, all) => {
34
+ for (var name in all)
35
+ __defProp(target, name, {
36
+ get: all[name],
37
+ enumerable: true,
38
+ configurable: true,
39
+ set: (newValue) => all[name] = () => newValue
40
+ });
41
+ };
42
+
43
+ // packages/runtime/src/internal.ts
44
+ var exports_internal = {};
45
+ __export(exports_internal, {
46
+ createInternalRuntime: () => createInternalRuntime
47
+ });
48
+ module.exports = __toCommonJS(exports_internal);
49
+ var import_isolated_vm = __toESM(require("isolated-vm"));
50
+ var import_isolate_core = require("@ricsam/isolate-core");
51
+ var import_isolate_console = require("@ricsam/isolate-console");
52
+ var import_isolate_encoding = require("@ricsam/isolate-encoding");
53
+ var import_isolate_timers = require("@ricsam/isolate-timers");
54
+ var import_isolate_path = require("@ricsam/isolate-path");
55
+ var import_isolate_crypto = require("@ricsam/isolate-crypto");
56
+ var import_isolate_fetch = require("@ricsam/isolate-fetch");
57
+ var import_isolate_fs = require("@ricsam/isolate-fs");
58
+ async function createInternalRuntime(options) {
59
+ const opts = options ?? {};
60
+ const isolate = new import_isolated_vm.default.Isolate({
61
+ memoryLimit: opts.memoryLimitMB
62
+ });
63
+ const context = await isolate.createContext();
64
+ const handles = {};
65
+ handles.core = await import_isolate_core.setupCore(context);
66
+ handles.console = await import_isolate_console.setupConsole(context, opts.console);
67
+ handles.encoding = await import_isolate_encoding.setupEncoding(context);
68
+ handles.timers = await import_isolate_timers.setupTimers(context);
69
+ handles.path = await import_isolate_path.setupPath(context, { cwd: opts.cwd });
70
+ handles.crypto = await import_isolate_crypto.setupCrypto(context);
71
+ handles.fetch = await import_isolate_fetch.setupFetch(context, opts.fetch);
72
+ if (opts.fs) {
73
+ handles.fs = await import_isolate_fs.setupFs(context, opts.fs);
74
+ }
75
+ return {
76
+ isolate,
77
+ context,
78
+ fetch: handles.fetch,
79
+ timers: handles.timers,
80
+ console: handles.console,
81
+ dispose() {
82
+ handles.fs?.dispose();
83
+ handles.fetch?.dispose();
84
+ handles.crypto?.dispose();
85
+ handles.path?.dispose();
86
+ handles.timers?.dispose();
87
+ handles.encoding?.dispose();
88
+ handles.console?.dispose();
89
+ handles.core?.dispose();
90
+ context.release();
91
+ isolate.dispose();
92
+ }
93
+ };
94
+ }
95
+ })
96
+
97
+ //# debugId=D12930C28AC6F96064756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/internal.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Internal APIs for @ricsam/isolate-runtime\n *\n * These are not part of the public API and may change without notice.\n * Only used by @ricsam/isolate-daemon internally.\n */\n\nimport ivm from \"isolated-vm\";\nimport { setupCore } from \"@ricsam/isolate-core\";\nimport { setupConsole } from \"@ricsam/isolate-console\";\nimport { setupEncoding } from \"@ricsam/isolate-encoding\";\nimport { setupTimers } from \"@ricsam/isolate-timers\";\nimport { setupPath } from \"@ricsam/isolate-path\";\nimport { setupCrypto } from \"@ricsam/isolate-crypto\";\nimport { setupFetch } from \"@ricsam/isolate-fetch\";\nimport { setupFs } from \"@ricsam/isolate-fs\";\n\nimport type { ConsoleOptions, ConsoleHandle } from \"@ricsam/isolate-console\";\nimport type { FetchOptions, FetchHandle } from \"@ricsam/isolate-fetch\";\nimport type { FsOptions, FsHandle } from \"@ricsam/isolate-fs\";\nimport type { CoreHandle } from \"@ricsam/isolate-core\";\nimport type { EncodingHandle } from \"@ricsam/isolate-encoding\";\nimport type { TimersHandle } from \"@ricsam/isolate-timers\";\nimport type { PathHandle } from \"@ricsam/isolate-path\";\nimport type { CryptoHandle } from \"@ricsam/isolate-crypto\";\n\n/**\n * @internal Options for creating a legacy runtime.\n */\nexport interface InternalRuntimeOptions {\n memoryLimitMB?: number;\n console?: ConsoleOptions;\n fetch?: FetchOptions;\n fs?: FsOptions;\n /** Current working directory for path.resolve(). Defaults to \"/\" */\n cwd?: string;\n}\n\n/**\n * @internal Runtime handle with direct isolate/context access.\n * Used by isolate-daemon for low-level operations.\n */\nexport interface InternalRuntimeHandle {\n readonly isolate: ivm.Isolate;\n readonly context: ivm.Context;\n readonly fetch: FetchHandle;\n readonly timers: TimersHandle;\n readonly console: ConsoleHandle;\n dispose(): void;\n}\n\n/**\n * @internal Create a runtime with direct access to isolate and context.\n * This is for internal use by @ricsam/isolate-daemon only.\n */\nexport async function createInternalRuntime(\n options?: InternalRuntimeOptions\n): Promise<InternalRuntimeHandle> {\n const opts = options ?? {};\n\n const isolate = new ivm.Isolate({\n memoryLimit: opts.memoryLimitMB,\n });\n\n const context = await isolate.createContext();\n\n // Setup all APIs\n const handles: {\n core?: CoreHandle;\n console?: ConsoleHandle;\n encoding?: EncodingHandle;\n timers?: TimersHandle;\n path?: PathHandle;\n crypto?: CryptoHandle;\n fetch?: FetchHandle;\n fs?: FsHandle;\n } = {};\n\n handles.core = await setupCore(context);\n handles.console = await setupConsole(context, opts.console);\n handles.encoding = await setupEncoding(context);\n handles.timers = await setupTimers(context);\n handles.path = await setupPath(context, { cwd: opts.cwd });\n handles.crypto = await setupCrypto(context);\n handles.fetch = await setupFetch(context, opts.fetch);\n\n if (opts.fs) {\n handles.fs = await setupFs(context, opts.fs);\n }\n\n return {\n isolate,\n context,\n fetch: handles.fetch,\n timers: handles.timers!,\n console: handles.console!,\n dispose() {\n handles.fs?.dispose();\n handles.fetch?.dispose();\n handles.crypto?.dispose();\n handles.path?.dispose();\n handles.timers?.dispose();\n handles.encoding?.dispose();\n handles.console?.dispose();\n handles.core?.dispose();\n context.release();\n isolate.dispose();\n },\n };\n}\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOgB,IAAhB;AAC0B,IAA1B;AAC6B,IAA7B;AAC8B,IAA9B;AAC4B,IAA5B;AAC0B,IAA1B;AAC4B,IAA5B;AAC2B,IAA3B;AACwB,IAAxB;AAwCA,eAAsB,qBAAqB,CACzC,SACgC;AAAA,EAChC,MAAM,OAAO,WAAW,CAAC;AAAA,EAEzB,MAAM,UAAU,IAAI,2BAAI,QAAQ;AAAA,IAC9B,aAAa,KAAK;AAAA,EACpB,CAAC;AAAA,EAED,MAAM,UAAU,MAAM,QAAQ,cAAc;AAAA,EAG5C,MAAM,UASF,CAAC;AAAA,EAEL,QAAQ,OAAO,MAAM,8BAAU,OAAO;AAAA,EACtC,QAAQ,UAAU,MAAM,oCAAa,SAAS,KAAK,OAAO;AAAA,EAC1D,QAAQ,WAAW,MAAM,sCAAc,OAAO;AAAA,EAC9C,QAAQ,SAAS,MAAM,kCAAY,OAAO;AAAA,EAC1C,QAAQ,OAAO,MAAM,8BAAU,SAAS,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,EACzD,QAAQ,SAAS,MAAM,kCAAY,OAAO;AAAA,EAC1C,QAAQ,QAAQ,MAAM,gCAAW,SAAS,KAAK,KAAK;AAAA,EAEpD,IAAI,KAAK,IAAI;AAAA,IACX,QAAQ,KAAK,MAAM,0BAAQ,SAAS,KAAK,EAAE;AAAA,EAC7C;AAAA,EAEA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,IAChB,SAAS,QAAQ;AAAA,IACjB,OAAO,GAAG;AAAA,MACR,QAAQ,IAAI,QAAQ;AAAA,MACpB,QAAQ,OAAO,QAAQ;AAAA,MACvB,QAAQ,QAAQ,QAAQ;AAAA,MACxB,QAAQ,MAAM,QAAQ;AAAA,MACtB,QAAQ,QAAQ,QAAQ;AAAA,MACxB,QAAQ,UAAU,QAAQ;AAAA,MAC1B,QAAQ,SAAS,QAAQ;AAAA,MACzB,QAAQ,MAAM,QAAQ;AAAA,MACtB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA;AAAA,EAEpB;AAAA;",
8
+ "debugId": "D12930C28AC6F96064756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/isolate-runtime",
3
- "version": "0.1.4",
3
+ "version": "0.1.7",
4
4
  "type": "commonjs"
5
5
  }
@@ -9,54 +9,454 @@ import { setupPath } from "@ricsam/isolate-path";
9
9
  import { setupCrypto } from "@ricsam/isolate-crypto";
10
10
  import { setupFetch } from "@ricsam/isolate-fetch";
11
11
  import { setupFs } from "@ricsam/isolate-fs";
12
+ import {
13
+ setupTestEnvironment,
14
+ runTests as runTestsInContext,
15
+ hasTests as hasTestsInContext,
16
+ getTestCount as getTestCountInContext
17
+ } from "@ricsam/isolate-test-environment";
18
+ import { setupPlaywright } from "@ricsam/isolate-playwright";
12
19
  import { setupCore as setupCore2 } from "@ricsam/isolate-core";
13
- import { setupConsole as setupConsole2 } from "@ricsam/isolate-console";
20
+ import { setupConsole as setupConsole2, simpleConsoleHandler } from "@ricsam/isolate-console";
14
21
  import { setupCrypto as setupCrypto2 } from "@ricsam/isolate-crypto";
15
22
  import { setupEncoding as setupEncoding2 } from "@ricsam/isolate-encoding";
16
23
  import { setupFetch as setupFetch2 } from "@ricsam/isolate-fetch";
17
24
  import { setupFs as setupFs2, createNodeFileSystemHandler } from "@ricsam/isolate-fs";
18
25
  import { setupPath as setupPath2 } from "@ricsam/isolate-path";
19
26
  import { setupTimers as setupTimers2 } from "@ricsam/isolate-timers";
27
+ import { setupTestEnvironment as setupTestEnvironment2, runTests, hasTests, getTestCount } from "@ricsam/isolate-test-environment";
28
+ import { setupPlaywright as setupPlaywright2, createPlaywrightHandler } from "@ricsam/isolate-playwright";
29
+
30
+ export * from "./internal.mjs";
31
+ var iteratorSessions = new Map;
32
+ var nextIteratorId = 1;
33
+ async function setupCustomFunctions(context, customFunctions) {
34
+ const global = context.global;
35
+ const invokeCallbackRef = new ivm.Reference(async (name, argsJson) => {
36
+ const def = customFunctions[name];
37
+ if (!def) {
38
+ return JSON.stringify({
39
+ ok: false,
40
+ error: { message: `Custom function '${name}' not found`, name: "Error" }
41
+ });
42
+ }
43
+ const args = JSON.parse(argsJson);
44
+ try {
45
+ const result = def.type === "async" ? await def.fn(...args) : def.fn(...args);
46
+ return JSON.stringify({ ok: true, value: result });
47
+ } catch (error) {
48
+ const err = error;
49
+ return JSON.stringify({
50
+ ok: false,
51
+ error: { message: err.message, name: err.name }
52
+ });
53
+ }
54
+ });
55
+ global.setSync("__customFn_invoke", invokeCallbackRef);
56
+ const iterStartRef = new ivm.Reference(async (name, argsJson) => {
57
+ const def = customFunctions[name];
58
+ if (!def || def.type !== "asyncIterator") {
59
+ return JSON.stringify({
60
+ ok: false,
61
+ error: { message: `Async iterator function '${name}' not found`, name: "Error" }
62
+ });
63
+ }
64
+ try {
65
+ const args = JSON.parse(argsJson);
66
+ const fn = def.fn;
67
+ const iterator = fn(...args);
68
+ const iteratorId = nextIteratorId++;
69
+ iteratorSessions.set(iteratorId, { iterator });
70
+ return JSON.stringify({ ok: true, iteratorId });
71
+ } catch (error) {
72
+ const err = error;
73
+ return JSON.stringify({
74
+ ok: false,
75
+ error: { message: err.message, name: err.name }
76
+ });
77
+ }
78
+ });
79
+ global.setSync("__iter_start", iterStartRef);
80
+ const iterNextRef = new ivm.Reference(async (iteratorId) => {
81
+ const session = iteratorSessions.get(iteratorId);
82
+ if (!session) {
83
+ return JSON.stringify({
84
+ ok: false,
85
+ error: { message: `Iterator session ${iteratorId} not found`, name: "Error" }
86
+ });
87
+ }
88
+ try {
89
+ const result = await session.iterator.next();
90
+ if (result.done) {
91
+ iteratorSessions.delete(iteratorId);
92
+ }
93
+ return JSON.stringify({ ok: true, done: result.done, value: result.value });
94
+ } catch (error) {
95
+ const err = error;
96
+ iteratorSessions.delete(iteratorId);
97
+ return JSON.stringify({
98
+ ok: false,
99
+ error: { message: err.message, name: err.name }
100
+ });
101
+ }
102
+ });
103
+ global.setSync("__iter_next", iterNextRef);
104
+ const iterReturnRef = new ivm.Reference(async (iteratorId, valueJson) => {
105
+ const session = iteratorSessions.get(iteratorId);
106
+ if (!session) {
107
+ return JSON.stringify({ ok: true, done: true, value: undefined });
108
+ }
109
+ try {
110
+ const value = valueJson ? JSON.parse(valueJson) : undefined;
111
+ const result = await session.iterator.return?.(value);
112
+ iteratorSessions.delete(iteratorId);
113
+ return JSON.stringify({ ok: true, done: true, value: result?.value });
114
+ } catch (error) {
115
+ const err = error;
116
+ iteratorSessions.delete(iteratorId);
117
+ return JSON.stringify({
118
+ ok: false,
119
+ error: { message: err.message, name: err.name }
120
+ });
121
+ }
122
+ });
123
+ global.setSync("__iter_return", iterReturnRef);
124
+ const iterThrowRef = new ivm.Reference(async (iteratorId, errorJson) => {
125
+ const session = iteratorSessions.get(iteratorId);
126
+ if (!session) {
127
+ return JSON.stringify({
128
+ ok: false,
129
+ error: { message: `Iterator session ${iteratorId} not found`, name: "Error" }
130
+ });
131
+ }
132
+ try {
133
+ const errorData = JSON.parse(errorJson);
134
+ const error = Object.assign(new Error(errorData.message), { name: errorData.name });
135
+ const result = await session.iterator.throw?.(error);
136
+ iteratorSessions.delete(iteratorId);
137
+ return JSON.stringify({ ok: true, done: result?.done ?? true, value: result?.value });
138
+ } catch (error) {
139
+ const err = error;
140
+ iteratorSessions.delete(iteratorId);
141
+ return JSON.stringify({
142
+ ok: false,
143
+ error: { message: err.message, name: err.name }
144
+ });
145
+ }
146
+ });
147
+ global.setSync("__iter_throw", iterThrowRef);
148
+ for (const name of Object.keys(customFunctions)) {
149
+ const def = customFunctions[name];
150
+ if (def.type === "async") {
151
+ context.evalSync(`
152
+ globalThis.${name} = async function(...args) {
153
+ const resultJson = __customFn_invoke.applySyncPromise(
154
+ undefined,
155
+ ["${name}", JSON.stringify(args)]
156
+ );
157
+ const result = JSON.parse(resultJson);
158
+ if (result.ok) {
159
+ return result.value;
160
+ } else {
161
+ const error = new Error(result.error.message);
162
+ error.name = result.error.name;
163
+ throw error;
164
+ }
165
+ };
166
+ `);
167
+ } else if (def.type === "sync") {
168
+ context.evalSync(`
169
+ globalThis.${name} = function(...args) {
170
+ const resultJson = __customFn_invoke.applySyncPromise(
171
+ undefined,
172
+ ["${name}", JSON.stringify(args)]
173
+ );
174
+ const result = JSON.parse(resultJson);
175
+ if (result.ok) {
176
+ return result.value;
177
+ } else {
178
+ const error = new Error(result.error.message);
179
+ error.name = result.error.name;
180
+ throw error;
181
+ }
182
+ };
183
+ `);
184
+ } else if (def.type === "asyncIterator") {
185
+ context.evalSync(`
186
+ globalThis.${name} = function(...args) {
187
+ const startResult = JSON.parse(__iter_start.applySyncPromise(undefined, ["${name}", JSON.stringify(args)]));
188
+ if (!startResult.ok) {
189
+ throw Object.assign(new Error(startResult.error.message), { name: startResult.error.name });
190
+ }
191
+ const iteratorId = startResult.iteratorId;
192
+ return {
193
+ [Symbol.asyncIterator]() { return this; },
194
+ async next() {
195
+ const result = JSON.parse(__iter_next.applySyncPromise(undefined, [iteratorId]));
196
+ if (!result.ok) {
197
+ throw Object.assign(new Error(result.error.message), { name: result.error.name });
198
+ }
199
+ return { done: result.done, value: result.value };
200
+ },
201
+ async return(v) {
202
+ const result = JSON.parse(__iter_return.applySyncPromise(undefined, [iteratorId, JSON.stringify(v)]));
203
+ return { done: true, value: result.value };
204
+ },
205
+ async throw(e) {
206
+ const result = JSON.parse(__iter_throw.applySyncPromise(undefined, [iteratorId, JSON.stringify({ message: e.message, name: e.name })]));
207
+ if (!result.ok) {
208
+ throw Object.assign(new Error(result.error.message), { name: result.error.name });
209
+ }
210
+ return { done: result.done, value: result.value };
211
+ }
212
+ };
213
+ };
214
+ `);
215
+ }
216
+ }
217
+ return invokeCallbackRef;
218
+ }
219
+ function createModuleResolver(state) {
220
+ return async (specifier, _referrer) => {
221
+ const cached = state.moduleCache.get(specifier);
222
+ if (cached)
223
+ return cached;
224
+ if (!state.moduleLoader) {
225
+ throw new Error(`No module loader registered. Cannot import: ${specifier}`);
226
+ }
227
+ const code = await state.moduleLoader(specifier);
228
+ const mod = await state.isolate.compileModule(code, {
229
+ filename: specifier
230
+ });
231
+ state.moduleCache.set(specifier, mod);
232
+ const resolver = createModuleResolver(state);
233
+ await mod.instantiate(state.context, resolver);
234
+ return mod;
235
+ };
236
+ }
237
+ function convertFetchCallback(callback) {
238
+ if (!callback) {
239
+ return {};
240
+ }
241
+ return {
242
+ onFetch: async (request) => {
243
+ return Promise.resolve(callback(request));
244
+ }
245
+ };
246
+ }
20
247
  async function createRuntime(options) {
21
248
  const opts = options ?? {};
249
+ const id = crypto.randomUUID();
22
250
  const isolate = new ivm.Isolate({
23
- memoryLimit: opts.memoryLimit
251
+ memoryLimit: opts.memoryLimitMB
24
252
  });
25
253
  const context = await isolate.createContext();
26
- const handles = {};
27
- handles.core = await setupCore(context);
28
- handles.console = await setupConsole(context, opts.console);
29
- handles.encoding = await setupEncoding(context);
30
- handles.timers = await setupTimers(context);
31
- handles.path = await setupPath(context);
32
- handles.crypto = await setupCrypto(context);
33
- handles.fetch = await setupFetch(context, opts.fetch);
254
+ const state = {
255
+ isolate,
256
+ context,
257
+ handles: {},
258
+ moduleCache: new Map,
259
+ moduleLoader: opts.moduleLoader,
260
+ customFunctions: opts.customFunctions
261
+ };
262
+ state.handles.core = await setupCore(context);
263
+ state.handles.console = await setupConsole(context, opts.console);
264
+ state.handles.encoding = await setupEncoding(context);
265
+ state.handles.timers = await setupTimers(context);
266
+ state.handles.path = await setupPath(context, { cwd: opts.cwd });
267
+ state.handles.crypto = await setupCrypto(context);
268
+ state.handles.fetch = await setupFetch(context, convertFetchCallback(opts.fetch));
34
269
  if (opts.fs) {
35
- handles.fs = await setupFs(context, opts.fs);
270
+ state.handles.fs = await setupFs(context, opts.fs);
271
+ }
272
+ if (opts.customFunctions) {
273
+ state.customFnInvokeRef = await setupCustomFunctions(context, opts.customFunctions);
36
274
  }
275
+ if (opts.testEnvironment) {
276
+ const testEnvOptions = typeof opts.testEnvironment === "object" ? opts.testEnvironment : undefined;
277
+ state.handles.testEnvironment = await setupTestEnvironment(context, testEnvOptions);
278
+ }
279
+ if (opts.playwright) {
280
+ let eventCallback = opts.playwright.onEvent;
281
+ if (opts.playwright.console && opts.console?.onEntry) {
282
+ const originalCallback = eventCallback;
283
+ const consoleHandler = opts.console.onEntry;
284
+ eventCallback = (event) => {
285
+ if (originalCallback) {
286
+ originalCallback(event);
287
+ }
288
+ if (event.type === "browserConsoleLog") {
289
+ consoleHandler({
290
+ type: "browserOutput",
291
+ level: event.level,
292
+ args: event.args,
293
+ timestamp: event.timestamp
294
+ });
295
+ }
296
+ };
297
+ }
298
+ state.handles.playwright = await setupPlaywright(context, {
299
+ page: opts.playwright.page,
300
+ timeout: opts.playwright.timeout,
301
+ baseUrl: opts.playwright.baseUrl,
302
+ console: opts.playwright.console && !opts.console?.onEntry,
303
+ onEvent: eventCallback
304
+ });
305
+ }
306
+ const fetchHandle = {
307
+ async dispatchRequest(request, options2) {
308
+ if (!state.handles.fetch) {
309
+ throw new Error("Fetch handle not available");
310
+ }
311
+ return state.handles.fetch.dispatchRequest(request, options2);
312
+ },
313
+ getUpgradeRequest() {
314
+ if (!state.handles.fetch) {
315
+ throw new Error("Fetch handle not available");
316
+ }
317
+ return state.handles.fetch.getUpgradeRequest();
318
+ },
319
+ dispatchWebSocketOpen(connectionId) {
320
+ if (!state.handles.fetch) {
321
+ throw new Error("Fetch handle not available");
322
+ }
323
+ state.handles.fetch.dispatchWebSocketOpen(connectionId);
324
+ },
325
+ dispatchWebSocketMessage(connectionId, message) {
326
+ if (!state.handles.fetch) {
327
+ throw new Error("Fetch handle not available");
328
+ }
329
+ state.handles.fetch.dispatchWebSocketMessage(connectionId, message);
330
+ },
331
+ dispatchWebSocketClose(connectionId, code, reason) {
332
+ if (!state.handles.fetch) {
333
+ throw new Error("Fetch handle not available");
334
+ }
335
+ state.handles.fetch.dispatchWebSocketClose(connectionId, code, reason);
336
+ },
337
+ dispatchWebSocketError(connectionId, error) {
338
+ if (!state.handles.fetch) {
339
+ throw new Error("Fetch handle not available");
340
+ }
341
+ state.handles.fetch.dispatchWebSocketError(connectionId, error);
342
+ },
343
+ onWebSocketCommand(callback) {
344
+ if (!state.handles.fetch) {
345
+ throw new Error("Fetch handle not available");
346
+ }
347
+ return state.handles.fetch.onWebSocketCommand(callback);
348
+ },
349
+ hasServeHandler() {
350
+ if (!state.handles.fetch) {
351
+ throw new Error("Fetch handle not available");
352
+ }
353
+ return state.handles.fetch.hasServeHandler();
354
+ },
355
+ hasActiveConnections() {
356
+ if (!state.handles.fetch) {
357
+ throw new Error("Fetch handle not available");
358
+ }
359
+ return state.handles.fetch.hasActiveConnections();
360
+ }
361
+ };
362
+ const timersHandle = {
363
+ clearAll() {
364
+ state.handles.timers?.clearAll();
365
+ }
366
+ };
367
+ const consoleHandle = {
368
+ reset() {
369
+ state.handles.console?.reset();
370
+ },
371
+ getTimers() {
372
+ return state.handles.console?.getTimers() ?? new Map;
373
+ },
374
+ getCounters() {
375
+ return state.handles.console?.getCounters() ?? new Map;
376
+ },
377
+ getGroupDepth() {
378
+ return state.handles.console?.getGroupDepth() ?? 0;
379
+ }
380
+ };
381
+ const testEnvironmentHandle = {
382
+ async runTests(_timeout) {
383
+ if (!state.handles.testEnvironment) {
384
+ throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
385
+ }
386
+ return runTestsInContext(state.context);
387
+ },
388
+ hasTests() {
389
+ if (!state.handles.testEnvironment) {
390
+ throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
391
+ }
392
+ return hasTestsInContext(state.context);
393
+ },
394
+ getTestCount() {
395
+ if (!state.handles.testEnvironment) {
396
+ throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
397
+ }
398
+ return getTestCountInContext(state.context);
399
+ },
400
+ reset() {
401
+ state.handles.testEnvironment?.dispose();
402
+ }
403
+ };
404
+ const playwrightHandle = {
405
+ getCollectedData() {
406
+ if (!state.handles.playwright) {
407
+ throw new Error("Playwright not configured. Provide playwright.page in createRuntime options.");
408
+ }
409
+ return {
410
+ browserConsoleLogs: state.handles.playwright.getBrowserConsoleLogs(),
411
+ networkRequests: state.handles.playwright.getNetworkRequests(),
412
+ networkResponses: state.handles.playwright.getNetworkResponses()
413
+ };
414
+ },
415
+ clearCollectedData() {
416
+ state.handles.playwright?.clearCollected();
417
+ }
418
+ };
37
419
  return {
38
- isolate,
39
- context,
40
- fetch: handles.fetch,
41
- async tick(ms) {
42
- await handles.timers.tick(ms);
43
- },
44
- dispose() {
45
- handles.fs?.dispose();
46
- handles.fetch?.dispose();
47
- handles.crypto?.dispose();
48
- handles.path?.dispose();
49
- handles.timers?.dispose();
50
- handles.encoding?.dispose();
51
- handles.console?.dispose();
52
- handles.core?.dispose();
53
- context.release();
54
- isolate.dispose();
420
+ id,
421
+ fetch: fetchHandle,
422
+ timers: timersHandle,
423
+ console: consoleHandle,
424
+ testEnvironment: testEnvironmentHandle,
425
+ playwright: playwrightHandle,
426
+ async eval(code, filenameOrOptions) {
427
+ const options2 = typeof filenameOrOptions === "string" ? { filename: filenameOrOptions } : filenameOrOptions;
428
+ const mod = await state.isolate.compileModule(code, {
429
+ filename: options2?.filename ?? "<eval>"
430
+ });
431
+ const resolver = createModuleResolver(state);
432
+ await mod.instantiate(state.context, resolver);
433
+ await mod.evaluate(options2?.maxExecutionMs ? { timeout: options2.maxExecutionMs } : undefined);
434
+ },
435
+ async dispose() {
436
+ if (state.customFnInvokeRef) {
437
+ state.customFnInvokeRef.release();
438
+ }
439
+ state.handles.playwright?.dispose();
440
+ state.handles.testEnvironment?.dispose();
441
+ state.handles.fs?.dispose();
442
+ state.handles.fetch?.dispose();
443
+ state.handles.crypto?.dispose();
444
+ state.handles.path?.dispose();
445
+ state.handles.timers?.dispose();
446
+ state.handles.encoding?.dispose();
447
+ state.handles.console?.dispose();
448
+ state.handles.core?.dispose();
449
+ state.moduleCache.clear();
450
+ state.context.release();
451
+ state.isolate.dispose();
55
452
  }
56
453
  };
57
454
  }
58
455
  export {
456
+ simpleConsoleHandler,
59
457
  setupTimers2 as setupTimers,
458
+ setupTestEnvironment2 as setupTestEnvironment,
459
+ setupPlaywright2 as setupPlaywright,
60
460
  setupPath2 as setupPath,
61
461
  setupFs2 as setupFs,
62
462
  setupFetch2 as setupFetch,
@@ -64,8 +464,12 @@ export {
64
464
  setupCrypto2 as setupCrypto,
65
465
  setupCore2 as setupCore,
66
466
  setupConsole2 as setupConsole,
467
+ runTests,
468
+ hasTests,
469
+ getTestCount,
67
470
  createRuntime,
471
+ createPlaywrightHandler,
68
472
  createNodeFileSystemHandler
69
473
  };
70
474
 
71
- //# debugId=FDBFD94222E0044364756E2164756E21
475
+ //# debugId=727908D2ABC724D264756E2164756E21