@ricsam/isolate-client 0.1.0 → 0.1.4
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 +313 -39
- package/dist/cjs/connection.cjs +744 -104
- package/dist/cjs/connection.cjs.map +3 -3
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/connection.mjs +749 -105
- package/dist/mjs/connection.mjs.map +3 -3
- package/dist/mjs/index.mjs.map +1 -1
- package/dist/mjs/package.json +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/types.d.ts +207 -82
- package/package.json +10 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/connection.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Connection handling for the isolate client.\n */\n\nimport { connect as netConnect, type Socket } from \"node:net\";\nimport {\n createFrameParser,\n buildFrame,\n MessageType,\n type Message,\n type ResponseOk,\n type ResponseError,\n type CreateRuntimeRequest,\n type DisposeRuntimeRequest,\n type EvalRequest,\n type DispatchRequestRequest,\n type TickRequest,\n type CallbackInvoke,\n type CallbackResponseMsg,\n type CallbackRegistration,\n type RuntimeCallbackRegistrations,\n type CreateRuntimeResult,\n type SerializedResponse,\n type SetupTestEnvRequest,\n type RunTestsRequest,\n type RunTestsResult,\n type SetupPlaywrightRequest,\n type RunPlaywrightTestsRequest,\n type ResetPlaywrightTestsRequest,\n type GetCollectedDataRequest,\n type PlaywrightTestResult,\n type CollectedData,\n type PlaywrightEvent,\n} from \"@ricsam/isolate-protocol\";\nimport type {\n ConnectOptions,\n DaemonConnection,\n RuntimeOptions,\n RemoteRuntime,\n DispatchOptions,\n ConsoleCallbacks,\n FetchCallback,\n FileSystemCallbacks,\n PlaywrightSetupOptions,\n PlaywrightEventHandler,\n} from \"./types.mjs\";\n\nconst DEFAULT_TIMEOUT = 30000;\n\ninterface PendingRequest {\n resolve: (data: unknown) => void;\n reject: (error: Error) => void;\n timeoutId?: ReturnType<typeof setTimeout>;\n}\n\ninterface ConnectionState {\n socket: Socket;\n pendingRequests: Map<number, PendingRequest>;\n callbacks: Map<number, (...args: unknown[]) => unknown>;\n nextRequestId: number;\n nextCallbackId: number;\n connected: boolean;\n /** Playwright event handlers per isolate */\n playwrightEventHandlers: Map<string, PlaywrightEventHandler>;\n}\n\n/**\n * Connect to the isolate daemon.\n */\nexport async function connect(options: ConnectOptions = {}): Promise<DaemonConnection> {\n const socket = await createSocket(options);\n\n const state: ConnectionState = {\n socket,\n pendingRequests: new Map(),\n callbacks: new Map(),\n nextRequestId: 1,\n nextCallbackId: 1,\n connected: true,\n playwrightEventHandlers: new Map(),\n };\n\n const parser = createFrameParser();\n\n socket.on(\"data\", (data) => {\n try {\n for (const frame of parser.feed(new Uint8Array(data))) {\n handleMessage(frame.message, state);\n }\n } catch (err) {\n console.error(\"Error parsing frame:\", err);\n }\n });\n\n socket.on(\"close\", () => {\n state.connected = false;\n // Reject all pending requests\n for (const [, pending] of state.pendingRequests) {\n pending.reject(new Error(\"Connection closed\"));\n }\n state.pendingRequests.clear();\n });\n\n socket.on(\"error\", (err) => {\n console.error(\"Socket error:\", err);\n });\n\n return {\n createRuntime: (runtimeOptions) =>\n createRuntime(state, runtimeOptions),\n close: async () => {\n state.connected = false;\n socket.destroy();\n },\n isConnected: () => state.connected,\n };\n}\n\n/**\n * Create a socket connection.\n */\nfunction createSocket(options: ConnectOptions): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const timeout = options.timeout ?? DEFAULT_TIMEOUT;\n\n let socket: Socket;\n\n const onError = (err: Error) => {\n reject(err);\n };\n\n const onConnect = () => {\n socket.removeListener(\"error\", onError);\n resolve(socket);\n };\n\n if (options.socket) {\n socket = netConnect(options.socket, onConnect);\n } else {\n socket = netConnect(\n options.port ?? 47891,\n options.host ?? \"127.0.0.1\",\n onConnect\n );\n }\n\n socket.on(\"error\", onError);\n\n // Connection timeout\n const timeoutId = setTimeout(() => {\n socket.destroy();\n reject(new Error(\"Connection timeout\"));\n }, timeout);\n\n socket.once(\"connect\", () => {\n clearTimeout(timeoutId);\n });\n });\n}\n\n/**\n * Handle an incoming message from the daemon.\n */\nfunction handleMessage(message: Message, state: ConnectionState): void {\n switch (message.type) {\n case MessageType.RESPONSE_OK: {\n const response = message as ResponseOk;\n const pending = state.pendingRequests.get(response.requestId);\n if (pending) {\n state.pendingRequests.delete(response.requestId);\n if (pending.timeoutId) clearTimeout(pending.timeoutId);\n pending.resolve(response.data);\n }\n break;\n }\n\n case MessageType.RESPONSE_ERROR: {\n const response = message as ResponseError;\n const pending = state.pendingRequests.get(response.requestId);\n if (pending) {\n state.pendingRequests.delete(response.requestId);\n if (pending.timeoutId) clearTimeout(pending.timeoutId);\n const error = new Error(response.message);\n if (response.details) {\n error.name = response.details.name;\n if (response.details.stack) {\n error.stack = response.details.stack;\n }\n }\n pending.reject(error);\n }\n break;\n }\n\n case MessageType.CALLBACK_INVOKE: {\n const invoke = message as CallbackInvoke;\n handleCallbackInvoke(invoke, state);\n break;\n }\n\n case MessageType.PONG:\n // Heartbeat response, ignore\n break;\n\n case MessageType.PLAYWRIGHT_EVENT: {\n const event = message as PlaywrightEvent;\n const handler = state.playwrightEventHandlers.get(event.isolateId);\n if (handler) {\n switch (event.eventType) {\n case \"consoleLog\":\n handler.onConsoleLog?.(event.payload as { level: string; args: unknown[] });\n break;\n case \"networkRequest\":\n handler.onNetworkRequest?.(event.payload as { url: string; method: string; headers: Record<string, string>; timestamp: number });\n break;\n case \"networkResponse\":\n handler.onNetworkResponse?.(event.payload as { url: string; status: number; headers: Record<string, string>; timestamp: number });\n break;\n }\n }\n break;\n }\n\n default:\n console.warn(`Unexpected message type: ${message.type}`);\n }\n}\n\n/**\n * Handle a callback invocation from the daemon.\n */\nasync function handleCallbackInvoke(\n invoke: CallbackInvoke,\n state: ConnectionState\n): Promise<void> {\n const callback = state.callbacks.get(invoke.callbackId);\n\n const response: CallbackResponseMsg = {\n type: MessageType.CALLBACK_RESPONSE,\n requestId: invoke.requestId,\n };\n\n if (!callback) {\n response.error = {\n name: \"Error\",\n message: `Unknown callback: ${invoke.callbackId}`,\n };\n } else {\n try {\n const result = await callback(...invoke.args);\n response.result = result;\n } catch (err) {\n const error = err as Error;\n response.error = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n }\n }\n\n sendMessage(state.socket, response);\n}\n\n/**\n * Send a message to the daemon.\n */\nfunction sendMessage(socket: Socket, message: Message): void {\n const frame = buildFrame(message);\n socket.write(frame);\n}\n\n/**\n * Send a request and wait for response.\n */\nfunction sendRequest<T>(\n state: ConnectionState,\n message: Message,\n timeout = DEFAULT_TIMEOUT\n): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!state.connected) {\n reject(new Error(\"Not connected\"));\n return;\n }\n\n const requestId = (message as { requestId: number }).requestId;\n\n const timeoutId = setTimeout(() => {\n state.pendingRequests.delete(requestId);\n reject(new Error(\"Request timeout\"));\n }, timeout);\n\n state.pendingRequests.set(requestId, {\n resolve: resolve as (data: unknown) => void,\n reject,\n timeoutId,\n });\n\n sendMessage(state.socket, message);\n });\n}\n\n/**\n * Create a runtime in the daemon.\n */\nasync function createRuntime(\n state: ConnectionState,\n options: RuntimeOptions = {}\n): Promise<RemoteRuntime> {\n // Register callbacks\n const callbacks: RuntimeCallbackRegistrations = {};\n\n if (options.console) {\n callbacks.console = registerConsoleCallbacks(state, options.console);\n }\n\n if (options.fetch) {\n callbacks.fetch = registerFetchCallback(state, options.fetch);\n }\n\n if (options.fs) {\n callbacks.fs = registerFsCallbacks(state, options.fs);\n }\n\n const requestId = state.nextRequestId++;\n const request: CreateRuntimeRequest = {\n type: MessageType.CREATE_RUNTIME,\n requestId,\n options: {\n memoryLimit: options.memoryLimit,\n callbacks,\n },\n };\n\n const result = await sendRequest<CreateRuntimeResult>(state, request);\n const isolateId = result.isolateId;\n\n return {\n isolateId,\n\n eval: async (code: string, filename?: string) => {\n const reqId = state.nextRequestId++;\n const req: EvalRequest = {\n type: MessageType.EVAL,\n requestId: reqId,\n isolateId,\n code,\n filename,\n };\n const res = await sendRequest<{ value: unknown }>(state, req);\n return res.value;\n },\n\n dispatchRequest: async (\n request: Request,\n dispatchOptions?: DispatchOptions\n ) => {\n const reqId = state.nextRequestId++;\n const serialized = await serializeRequest(request);\n const req: DispatchRequestRequest = {\n type: MessageType.DISPATCH_REQUEST,\n requestId: reqId,\n isolateId,\n request: serialized,\n options: dispatchOptions,\n };\n const res = await sendRequest<{ response: SerializedResponse }>(\n state,\n req,\n dispatchOptions?.timeout ?? DEFAULT_TIMEOUT\n );\n return deserializeResponse(res.response);\n },\n\n tick: async (ms?: number) => {\n const reqId = state.nextRequestId++;\n const req: TickRequest = {\n type: MessageType.TICK,\n requestId: reqId,\n isolateId,\n ms,\n };\n await sendRequest(state, req);\n },\n\n setupTestEnvironment: async () => {\n const reqId = state.nextRequestId++;\n const req: SetupTestEnvRequest = {\n type: MessageType.SETUP_TEST_ENV,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n\n runTests: async (timeout?: number) => {\n const reqId = state.nextRequestId++;\n const req: RunTestsRequest = {\n type: MessageType.RUN_TESTS,\n requestId: reqId,\n isolateId,\n timeout,\n };\n return sendRequest<RunTestsResult>(state, req, timeout ?? DEFAULT_TIMEOUT);\n },\n\n setupPlaywright: async (playwrightOptions?: PlaywrightSetupOptions) => {\n const reqId = state.nextRequestId++;\n const req: SetupPlaywrightRequest = {\n type: MessageType.SETUP_PLAYWRIGHT,\n requestId: reqId,\n isolateId,\n options: {\n browserType: playwrightOptions?.browserType,\n headless: playwrightOptions?.headless,\n baseURL: playwrightOptions?.baseURL,\n },\n };\n\n // Register event handlers if provided\n if (playwrightOptions?.onConsoleLog || playwrightOptions?.onNetworkRequest || playwrightOptions?.onNetworkResponse) {\n state.playwrightEventHandlers.set(isolateId, {\n onConsoleLog: playwrightOptions.onConsoleLog,\n onNetworkRequest: playwrightOptions.onNetworkRequest,\n onNetworkResponse: playwrightOptions.onNetworkResponse,\n });\n }\n\n await sendRequest(state, req);\n },\n\n runPlaywrightTests: async (timeout?: number) => {\n const reqId = state.nextRequestId++;\n const req: RunPlaywrightTestsRequest = {\n type: MessageType.RUN_PLAYWRIGHT_TESTS,\n requestId: reqId,\n isolateId,\n timeout,\n };\n return sendRequest<PlaywrightTestResult>(state, req, timeout ?? DEFAULT_TIMEOUT);\n },\n\n resetPlaywrightTests: async () => {\n const reqId = state.nextRequestId++;\n const req: ResetPlaywrightTestsRequest = {\n type: MessageType.RESET_PLAYWRIGHT_TESTS,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n\n getCollectedData: async () => {\n const reqId = state.nextRequestId++;\n const req: GetCollectedDataRequest = {\n type: MessageType.GET_COLLECTED_DATA,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<CollectedData>(state, req);\n },\n\n dispose: async () => {\n // Clean up event handlers\n state.playwrightEventHandlers.delete(isolateId);\n\n const reqId = state.nextRequestId++;\n const req: DisposeRuntimeRequest = {\n type: MessageType.DISPOSE_RUNTIME,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n };\n}\n\n/**\n * Register console callbacks.\n */\nfunction registerConsoleCallbacks(\n state: ConnectionState,\n callbacks: ConsoleCallbacks\n): Record<string, CallbackRegistration> {\n const registrations: Record<string, CallbackRegistration> = {};\n\n const register = (name: string, fn: (...args: unknown[]) => void) => {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, (_level: unknown, ...args: unknown[]) => {\n fn(...args);\n });\n registrations[name] = { callbackId, name, async: false };\n };\n\n if (callbacks.log) register(\"log\", callbacks.log);\n if (callbacks.warn) register(\"warn\", callbacks.warn);\n if (callbacks.error) register(\"error\", callbacks.error);\n if (callbacks.info) register(\"info\", callbacks.info);\n if (callbacks.debug) register(\"debug\", callbacks.debug);\n if (callbacks.dir) register(\"dir\", callbacks.dir);\n\n return registrations;\n}\n\n/**\n * Register fetch callback.\n */\nfunction registerFetchCallback(\n state: ConnectionState,\n callback: FetchCallback\n): CallbackRegistration {\n const callbackId = state.nextCallbackId++;\n\n state.callbacks.set(callbackId, async (serialized: unknown) => {\n const request = deserializeRequest(serialized as SerializedRequestData);\n const response = await callback(request);\n return serializeResponse(response);\n });\n\n return { callbackId, name: \"fetch\", async: true };\n}\n\n/**\n * Register file system callbacks.\n */\nfunction registerFsCallbacks(\n state: ConnectionState,\n callbacks: FileSystemCallbacks\n): Record<string, CallbackRegistration> {\n const registrations: Record<string, CallbackRegistration> = {};\n\n // readFile: (path: string) => Promise<ArrayBuffer>\n if (callbacks.readFile) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n const result = await callbacks.readFile!(path as string);\n // Convert ArrayBuffer to Uint8Array for serialization\n return new Uint8Array(result);\n });\n registrations.readFile = { callbackId, name: \"readFile\", async: true };\n }\n\n // writeFile: (path: string, data: ArrayBuffer) => Promise<void>\n if (callbacks.writeFile) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown, data: unknown) => {\n // Convert Uint8Array or array back to ArrayBuffer\n let buffer: ArrayBuffer;\n if (data instanceof Uint8Array) {\n buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n } else if (Array.isArray(data)) {\n buffer = new Uint8Array(data as number[]).buffer;\n } else if (data instanceof ArrayBuffer) {\n buffer = data;\n } else {\n buffer = new ArrayBuffer(0);\n }\n await callbacks.writeFile!(path as string, buffer);\n });\n registrations.writeFile = { callbackId, name: \"writeFile\", async: true };\n }\n\n // unlink: (path: string) => Promise<void>\n if (callbacks.unlink) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n await callbacks.unlink!(path as string);\n });\n registrations.unlink = { callbackId, name: \"unlink\", async: true };\n }\n\n // readdir: (path: string) => Promise<string[]>\n if (callbacks.readdir) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n return callbacks.readdir!(path as string);\n });\n registrations.readdir = { callbackId, name: \"readdir\", async: true };\n }\n\n // mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>\n if (callbacks.mkdir) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown, options: unknown) => {\n await callbacks.mkdir!(path as string, options as { recursive?: boolean });\n });\n registrations.mkdir = { callbackId, name: \"mkdir\", async: true };\n }\n\n // rmdir: (path: string) => Promise<void>\n if (callbacks.rmdir) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n await callbacks.rmdir!(path as string);\n });\n registrations.rmdir = { callbackId, name: \"rmdir\", async: true };\n }\n\n // stat: (path: string) => Promise<{ isFile: boolean; isDirectory: boolean; size: number }>\n if (callbacks.stat) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n return callbacks.stat!(path as string);\n });\n registrations.stat = { callbackId, name: \"stat\", async: true };\n }\n\n // rename: (from: string, to: string) => Promise<void>\n if (callbacks.rename) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (from: unknown, to: unknown) => {\n await callbacks.rename!(from as string, to as string);\n });\n registrations.rename = { callbackId, name: \"rename\", async: true };\n }\n\n return registrations;\n}\n\n// ============================================================================\n// Request/Response Serialization\n// ============================================================================\n\ninterface SerializedRequestData {\n method: string;\n url: string;\n headers: [string, string][];\n body: Uint8Array | null;\n}\n\ninterface SerializedResponseData {\n status: number;\n statusText: string;\n headers: [string, string][];\n body: Uint8Array | null;\n}\n\nasync function serializeRequest(request: Request): Promise<SerializedRequestData> {\n const headers: [string, string][] = [];\n request.headers.forEach((value, key) => {\n headers.push([key, value]);\n });\n\n let body: Uint8Array | null = null;\n if (request.body) {\n body = new Uint8Array(await request.arrayBuffer());\n }\n\n return {\n method: request.method,\n url: request.url,\n headers,\n body,\n };\n}\n\nasync function serializeResponse(response: Response): Promise<SerializedResponseData> {\n const headers: [string, string][] = [];\n response.headers.forEach((value, key) => {\n headers.push([key, value]);\n });\n\n let body: Uint8Array | null = null;\n if (response.body) {\n body = new Uint8Array(await response.arrayBuffer());\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers,\n body,\n };\n}\n\nfunction deserializeRequest(data: SerializedRequestData): Request {\n return new Request(data.url, {\n method: data.method,\n headers: data.headers,\n body: data.body as unknown as BodyInit | null | undefined,\n });\n}\n\nfunction deserializeResponse(data: SerializedResponse): Response {\n return new Response(data.body as unknown as BodyInit | null, {\n status: data.status,\n statusText: data.statusText,\n headers: data.headers,\n });\n}\n"
|
|
5
|
+
"/**\n * Connection handling for the isolate client.\n */\n\nimport { connect as netConnect, type Socket } from \"node:net\";\nimport {\n createFrameParser,\n buildFrame,\n MessageType,\n STREAM_THRESHOLD,\n STREAM_CHUNK_SIZE,\n STREAM_DEFAULT_CREDIT,\n type Message,\n type ResponseOk,\n type ResponseError,\n type CreateRuntimeRequest,\n type DisposeRuntimeRequest,\n type EvalRequest,\n type DispatchRequestRequest,\n type CallbackInvoke,\n type CallbackResponseMsg,\n type CallbackRegistration,\n type RuntimeCallbackRegistrations,\n type CreateRuntimeResult,\n type SerializedResponse,\n type RunTestsRequest,\n type RunTestsResult,\n type HasTestsRequest,\n type GetTestCountRequest,\n type TestEnvironmentCallbackRegistrations,\n type TestEnvironmentOptionsProtocol,\n type TestEventMessage,\n type GetCollectedDataRequest,\n type CollectedData,\n type ResetTestEnvRequest,\n type ClearCollectedDataRequest,\n type PlaywrightOperation,\n type PlaywrightResult,\n type WsOpenRequest,\n type WsMessageRequest,\n type WsCloseRequest,\n type FetchGetUpgradeRequestRequest,\n type FetchHasServeHandlerRequest,\n type FetchHasActiveConnectionsRequest,\n type FetchWsErrorRequest,\n type TimersClearAllRequest,\n type ConsoleResetRequest,\n type ConsoleGetTimersRequest,\n type ConsoleGetCountersRequest,\n type ConsoleGetGroupDepthRequest,\n type WsCommandMessage,\n type ResponseStreamStart,\n type ResponseStreamChunk,\n type ResponseStreamEnd,\n type StreamPush,\n type StreamPull,\n type StreamClose,\n type StreamError,\n marshalValue,\n type MarshalContext,\n} from \"@ricsam/isolate-protocol\";\nimport { createPlaywrightHandler, type PlaywrightCallback } from \"@ricsam/isolate-playwright\";\nimport type {\n ConnectOptions,\n DaemonConnection,\n RuntimeOptions,\n RemoteRuntime,\n RemoteFetchHandle,\n RemoteTimersHandle,\n RemoteConsoleHandle,\n RemoteTestEnvironmentHandle,\n RemotePlaywrightHandle,\n DispatchOptions,\n ConsoleCallbacks,\n FetchCallback,\n FileSystemCallbacks,\n ModuleLoaderCallback,\n CustomFunctions,\n EvalOptions,\n UpgradeRequest,\n WebSocketCommand,\n TestEnvironmentOptions,\n} from \"./types.mjs\";\n\nconst DEFAULT_TIMEOUT = 30000;\n\n// Track WebSocket command callbacks per isolate for handling WS_COMMAND messages\nconst isolateWsCallbacks = new Map<string, Set<(cmd: WebSocketCommand) => void>>();\n\ninterface PendingRequest {\n resolve: (data: unknown) => void;\n reject: (error: Error) => void;\n timeoutId?: ReturnType<typeof setTimeout>;\n}\n\n/** Stream receiver for collecting streamed response chunks */\ninterface StreamResponseReceiver {\n streamId: number;\n requestId: number;\n metadata?: {\n status?: number;\n statusText?: string;\n headers?: [string, string][];\n };\n chunks: Uint8Array[];\n totalBytes: number;\n}\n\n/** Stream session for tracking upload streams (client sending to daemon) */\ninterface StreamUploadSession {\n streamId: number;\n requestId: number;\n state: \"active\" | \"closing\" | \"closed\";\n bytesTransferred: number;\n credit: number;\n creditResolver?: () => void;\n}\n\ninterface ConnectionState {\n socket: Socket;\n pendingRequests: Map<number, PendingRequest>;\n callbacks: Map<number, (...args: unknown[]) => unknown>;\n nextRequestId: number;\n nextCallbackId: number;\n nextStreamId: number;\n connected: boolean;\n /** Track streaming responses being received */\n streamResponses: Map<number, StreamResponseReceiver>;\n /** Track upload streams (for request body streaming) */\n uploadStreams: Map<number, StreamUploadSession>;\n}\n\n/**\n * Connect to the isolate daemon.\n */\nexport async function connect(options: ConnectOptions = {}): Promise<DaemonConnection> {\n const socket = await createSocket(options);\n\n const state: ConnectionState = {\n socket,\n pendingRequests: new Map(),\n callbacks: new Map(),\n nextRequestId: 1,\n nextCallbackId: 1,\n nextStreamId: 1,\n connected: true,\n streamResponses: new Map(),\n uploadStreams: new Map(),\n };\n\n const parser = createFrameParser();\n\n socket.on(\"data\", (data) => {\n try {\n for (const frame of parser.feed(new Uint8Array(data))) {\n handleMessage(frame.message, state);\n }\n } catch (err) {\n console.error(\"Error parsing frame:\", err);\n }\n });\n\n socket.on(\"close\", () => {\n state.connected = false;\n // Reject all pending requests\n for (const [, pending] of state.pendingRequests) {\n pending.reject(new Error(\"Connection closed\"));\n }\n state.pendingRequests.clear();\n });\n\n socket.on(\"error\", (err) => {\n console.error(\"Socket error:\", err);\n });\n\n return {\n createRuntime: (runtimeOptions) =>\n createRuntime(state, runtimeOptions),\n close: async () => {\n state.connected = false;\n socket.destroy();\n },\n isConnected: () => state.connected,\n };\n}\n\n/**\n * Create a socket connection.\n */\nfunction createSocket(options: ConnectOptions): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const timeout = options.timeout ?? DEFAULT_TIMEOUT;\n\n let socket: Socket;\n\n const onError = (err: Error) => {\n reject(err);\n };\n\n const onConnect = () => {\n socket.removeListener(\"error\", onError);\n resolve(socket);\n };\n\n if (options.socket) {\n socket = netConnect(options.socket, onConnect);\n } else {\n socket = netConnect(\n options.port ?? 47891,\n options.host ?? \"127.0.0.1\",\n onConnect\n );\n }\n\n socket.on(\"error\", onError);\n\n // Connection timeout\n const timeoutId = setTimeout(() => {\n socket.destroy();\n reject(new Error(\"Connection timeout\"));\n }, timeout);\n\n socket.once(\"connect\", () => {\n clearTimeout(timeoutId);\n });\n });\n}\n\n/**\n * Handle an incoming message from the daemon.\n */\nfunction handleMessage(message: Message, state: ConnectionState): void {\n switch (message.type) {\n case MessageType.RESPONSE_OK: {\n const response = message as ResponseOk;\n const pending = state.pendingRequests.get(response.requestId);\n if (pending) {\n state.pendingRequests.delete(response.requestId);\n if (pending.timeoutId) clearTimeout(pending.timeoutId);\n pending.resolve(response.data);\n }\n break;\n }\n\n case MessageType.RESPONSE_ERROR: {\n const response = message as ResponseError;\n const pending = state.pendingRequests.get(response.requestId);\n if (pending) {\n state.pendingRequests.delete(response.requestId);\n if (pending.timeoutId) clearTimeout(pending.timeoutId);\n const error = new Error(response.message);\n if (response.details) {\n error.name = response.details.name;\n if (response.details.stack) {\n error.stack = response.details.stack;\n }\n }\n pending.reject(error);\n }\n break;\n }\n\n case MessageType.CALLBACK_INVOKE: {\n const invoke = message as CallbackInvoke;\n handleCallbackInvoke(invoke, state);\n break;\n }\n\n case MessageType.PONG:\n // Heartbeat response, ignore\n break;\n\n case MessageType.WS_COMMAND: {\n const msg = message as WsCommandMessage;\n const callbacks = isolateWsCallbacks.get(msg.isolateId);\n if (callbacks) {\n // Convert Uint8Array to ArrayBuffer if needed\n let data: string | ArrayBuffer | undefined;\n if (msg.command.data instanceof Uint8Array) {\n data = msg.command.data.buffer.slice(\n msg.command.data.byteOffset,\n msg.command.data.byteOffset + msg.command.data.byteLength\n ) as ArrayBuffer;\n } else {\n data = msg.command.data;\n }\n const cmd: WebSocketCommand = {\n type: msg.command.type,\n connectionId: msg.command.connectionId,\n data,\n code: msg.command.code,\n reason: msg.command.reason,\n };\n for (const cb of callbacks) {\n cb(cmd);\n }\n }\n break;\n }\n\n // Streaming response messages\n case MessageType.RESPONSE_STREAM_START: {\n const msg = message as ResponseStreamStart;\n // Create a receiver to collect chunks\n const receiver: StreamResponseReceiver = {\n streamId: msg.streamId,\n requestId: msg.requestId,\n metadata: msg.metadata,\n chunks: [],\n totalBytes: 0,\n };\n state.streamResponses.set(msg.streamId, receiver);\n // Send initial credit to allow daemon to start sending\n sendMessage(state.socket, {\n type: MessageType.STREAM_PULL,\n streamId: msg.streamId,\n maxBytes: STREAM_DEFAULT_CREDIT,\n } as StreamPull);\n break;\n }\n\n case MessageType.RESPONSE_STREAM_CHUNK: {\n const msg = message as ResponseStreamChunk;\n const receiver = state.streamResponses.get(msg.streamId);\n if (receiver) {\n receiver.chunks.push(msg.chunk);\n receiver.totalBytes += msg.chunk.length;\n // Send more credit\n sendMessage(state.socket, {\n type: MessageType.STREAM_PULL,\n streamId: msg.streamId,\n maxBytes: STREAM_DEFAULT_CREDIT,\n } as StreamPull);\n }\n break;\n }\n\n case MessageType.RESPONSE_STREAM_END: {\n const msg = message as ResponseStreamEnd;\n const receiver = state.streamResponses.get(msg.streamId);\n if (receiver) {\n // Concatenate all chunks\n const body = concatUint8Arrays(receiver.chunks);\n // Resolve pending request with the streamed response\n const pending = state.pendingRequests.get(receiver.requestId);\n if (pending) {\n state.pendingRequests.delete(receiver.requestId);\n if (pending.timeoutId) clearTimeout(pending.timeoutId);\n pending.resolve({\n response: {\n status: receiver.metadata?.status ?? 200,\n statusText: receiver.metadata?.statusText ?? \"OK\",\n headers: receiver.metadata?.headers ?? [],\n body,\n },\n });\n }\n state.streamResponses.delete(msg.streamId);\n }\n break;\n }\n\n case MessageType.STREAM_PULL: {\n const msg = message as StreamPull;\n const session = state.uploadStreams.get(msg.streamId);\n if (session) {\n session.credit += msg.maxBytes;\n // Wake up waiting sender if there's a credit resolver\n if (session.creditResolver) {\n session.creditResolver();\n session.creditResolver = undefined;\n }\n }\n break;\n }\n\n case MessageType.STREAM_ERROR: {\n const msg = message as StreamError;\n // Handle error for upload streams\n const uploadSession = state.uploadStreams.get(msg.streamId);\n if (uploadSession) {\n uploadSession.state = \"closed\";\n state.uploadStreams.delete(msg.streamId);\n }\n // Handle error for response streams\n const receiver = state.streamResponses.get(msg.streamId);\n if (receiver) {\n const pending = state.pendingRequests.get(receiver.requestId);\n if (pending) {\n state.pendingRequests.delete(receiver.requestId);\n if (pending.timeoutId) clearTimeout(pending.timeoutId);\n pending.reject(new Error(msg.error));\n }\n state.streamResponses.delete(msg.streamId);\n }\n break;\n }\n\n default:\n console.warn(`Unexpected message type: ${message.type}`);\n }\n}\n\n/**\n * Helper to concatenate Uint8Arrays.\n */\nfunction concatUint8Arrays(arrays: Uint8Array[]): Uint8Array {\n const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\n/**\n * Handle a callback invocation from the daemon.\n */\nasync function handleCallbackInvoke(\n invoke: CallbackInvoke,\n state: ConnectionState\n): Promise<void> {\n const callback = state.callbacks.get(invoke.callbackId);\n\n const response: CallbackResponseMsg = {\n type: MessageType.CALLBACK_RESPONSE,\n requestId: invoke.requestId,\n };\n\n if (!callback) {\n response.error = {\n name: \"Error\",\n message: `Unknown callback: ${invoke.callbackId}`,\n };\n } else {\n try {\n const result = await callback(...invoke.args);\n response.result = result;\n } catch (err) {\n const error = err as Error;\n response.error = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n }\n }\n\n sendMessage(state.socket, response);\n}\n\n/**\n * Send a message to the daemon.\n */\nfunction sendMessage(socket: Socket, message: Message): void {\n const frame = buildFrame(message);\n socket.write(frame);\n}\n\n/**\n * Send a request and wait for response.\n */\nfunction sendRequest<T>(\n state: ConnectionState,\n message: Message,\n timeout = DEFAULT_TIMEOUT\n): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!state.connected) {\n reject(new Error(\"Not connected\"));\n return;\n }\n\n const requestId = (message as { requestId: number }).requestId;\n\n const timeoutId = setTimeout(() => {\n state.pendingRequests.delete(requestId);\n reject(new Error(\"Request timeout\"));\n }, timeout);\n\n state.pendingRequests.set(requestId, {\n resolve: resolve as (data: unknown) => void,\n reject,\n timeoutId,\n });\n\n sendMessage(state.socket, message);\n });\n}\n\n/**\n * Create a runtime in the daemon.\n */\nasync function createRuntime(\n state: ConnectionState,\n options: RuntimeOptions = {}\n): Promise<RemoteRuntime> {\n // Register callbacks\n const callbacks: RuntimeCallbackRegistrations = {};\n\n if (options.console) {\n callbacks.console = registerConsoleCallbacks(state, options.console);\n }\n\n if (options.fetch) {\n callbacks.fetch = registerFetchCallback(state, options.fetch);\n }\n\n if (options.fs) {\n callbacks.fs = registerFsCallbacks(state, options.fs);\n }\n\n if (options.moduleLoader) {\n callbacks.moduleLoader = registerModuleLoaderCallback(\n state,\n options.moduleLoader\n );\n }\n\n if (options.customFunctions) {\n callbacks.custom = registerCustomFunctions(state, options.customFunctions);\n }\n\n // Playwright callback registration - client owns the browser\n let playwrightHandler: PlaywrightCallback | undefined;\n if (options.playwright) {\n playwrightHandler = createPlaywrightHandler(options.playwright.page, {\n timeout: options.playwright.timeout,\n baseUrl: options.playwright.baseUrl,\n });\n\n const handlerCallbackId = state.nextCallbackId++;\n state.callbacks.set(handlerCallbackId, async (opJson: unknown) => {\n const op = JSON.parse(opJson as string) as PlaywrightOperation;\n const result = await playwrightHandler!(op);\n return JSON.stringify(result);\n });\n\n // Determine if we need event callbacks\n const hasOnEvent = !!options.playwright.onEvent;\n const hasConsoleHandler = options.playwright.console && options.console?.onEntry;\n\n // Browser console log callback\n let browserConsoleLogCallbackId: number | undefined;\n if (hasOnEvent || hasConsoleHandler) {\n browserConsoleLogCallbackId = registerEventCallback(state, (entry: unknown) => {\n const browserEntry = entry as { level: string; args: unknown[]; timestamp: number };\n\n if (options.playwright!.onEvent) {\n options.playwright!.onEvent({\n type: \"browserConsoleLog\",\n level: browserEntry.level,\n args: browserEntry.args,\n timestamp: browserEntry.timestamp,\n });\n }\n\n // Route through console handler as browserOutput entry if console: true\n if (options.playwright!.console && options.console?.onEntry) {\n options.console.onEntry({\n type: \"browserOutput\",\n level: browserEntry.level,\n args: browserEntry.args,\n timestamp: browserEntry.timestamp,\n });\n }\n });\n }\n\n // Network request callback\n let networkRequestCallbackId: number | undefined;\n if (hasOnEvent) {\n networkRequestCallbackId = registerEventCallback(state, (info: unknown) => {\n const reqInfo = info as { url: string; method: string; headers: Record<string, string>; postData?: string; resourceType?: string; timestamp: number };\n\n options.playwright!.onEvent!({\n type: \"networkRequest\",\n url: reqInfo.url,\n method: reqInfo.method,\n headers: reqInfo.headers,\n postData: reqInfo.postData,\n resourceType: reqInfo.resourceType,\n timestamp: reqInfo.timestamp,\n });\n });\n }\n\n // Network response callback\n let networkResponseCallbackId: number | undefined;\n if (hasOnEvent) {\n networkResponseCallbackId = registerEventCallback(state, (info: unknown) => {\n const resInfo = info as { url: string; status: number; statusText?: string; headers: Record<string, string>; timestamp: number };\n\n options.playwright!.onEvent!({\n type: \"networkResponse\",\n url: resInfo.url,\n status: resInfo.status,\n statusText: resInfo.statusText,\n headers: resInfo.headers,\n timestamp: resInfo.timestamp,\n });\n });\n }\n\n callbacks.playwright = {\n handlerCallbackId,\n // Don't let daemon print directly if we're routing through console handler\n console: options.playwright.console && !options.console?.onEntry,\n onBrowserConsoleLogCallbackId: browserConsoleLogCallbackId,\n onNetworkRequestCallbackId: networkRequestCallbackId,\n onNetworkResponseCallbackId: networkResponseCallbackId,\n };\n }\n\n // Test environment callback registration\n let testEnvironmentOption: boolean | TestEnvironmentOptionsProtocol | undefined;\n if (options.testEnvironment) {\n if (typeof options.testEnvironment === \"object\") {\n const testEnvOptions = options.testEnvironment;\n const testEnvCallbacks: TestEnvironmentCallbackRegistrations = {};\n\n if (testEnvOptions.onEvent) {\n const userOnEvent = testEnvOptions.onEvent;\n const onEventCallbackId = registerEventCallback(state, (eventJson: unknown) => {\n const event = JSON.parse(eventJson as string);\n userOnEvent(event);\n });\n testEnvCallbacks.onEvent = {\n callbackId: onEventCallbackId,\n name: \"testEnvironment.onEvent\",\n type: 'sync',\n };\n }\n\n testEnvironmentOption = {\n callbacks: testEnvCallbacks,\n testTimeout: testEnvOptions.testTimeout,\n };\n } else {\n testEnvironmentOption = true;\n }\n }\n\n const requestId = state.nextRequestId++;\n const request: CreateRuntimeRequest = {\n type: MessageType.CREATE_RUNTIME,\n requestId,\n options: {\n memoryLimitMB: options.memoryLimitMB,\n cwd: options.cwd,\n callbacks,\n testEnvironment: testEnvironmentOption,\n },\n };\n\n const result = await sendRequest<CreateRuntimeResult>(state, request);\n const isolateId = result.isolateId;\n\n // WebSocket command callbacks - store in module-level Map for WS_COMMAND message handling\n const wsCommandCallbacks: Set<(cmd: WebSocketCommand) => void> = new Set();\n isolateWsCallbacks.set(isolateId, wsCommandCallbacks);\n\n // Create fetch handle\n const fetchHandle: RemoteFetchHandle = {\n async dispatchRequest(req: Request, opts?: DispatchOptions) {\n const reqId = state.nextRequestId++;\n const serialized = await serializeRequestWithStreaming(state, req);\n\n // Extract bodyStream before creating the protocol message (can't be serialized)\n const { bodyStream, ...serializableRequest } = serialized;\n\n const request: DispatchRequestRequest = {\n type: MessageType.DISPATCH_REQUEST,\n requestId: reqId,\n isolateId,\n request: serializableRequest,\n options: opts,\n };\n\n // If streaming body, start sending chunks after request is sent\n if (serialized.bodyStreamId !== undefined && bodyStream) {\n const streamId = serialized.bodyStreamId;\n\n // Send the request first\n const responsePromise = sendRequest<{ response: SerializedResponse }>(\n state,\n request,\n opts?.timeout ?? DEFAULT_TIMEOUT\n );\n\n // Then stream the body\n await sendBodyStream(state, streamId, bodyStream);\n\n // Wait for response\n const res = await responsePromise;\n return deserializeResponse(res.response);\n } else {\n const res = await sendRequest<{ response: SerializedResponse }>(\n state,\n request,\n opts?.timeout ?? DEFAULT_TIMEOUT\n );\n return deserializeResponse(res.response);\n }\n },\n\n async getUpgradeRequest(): Promise<UpgradeRequest | null> {\n const reqId = state.nextRequestId++;\n const req: FetchGetUpgradeRequestRequest = {\n type: MessageType.FETCH_GET_UPGRADE_REQUEST,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<UpgradeRequest | null>(state, req);\n },\n\n async dispatchWebSocketOpen(connectionId: string): Promise<void> {\n const reqId = state.nextRequestId++;\n const req: WsOpenRequest = {\n type: MessageType.WS_OPEN,\n requestId: reqId,\n isolateId,\n connectionId,\n };\n await sendRequest(state, req);\n },\n\n async dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): Promise<void> {\n const reqId = state.nextRequestId++;\n const data = message instanceof ArrayBuffer ? new Uint8Array(message) : message;\n const req: WsMessageRequest = {\n type: MessageType.WS_MESSAGE,\n requestId: reqId,\n isolateId,\n connectionId,\n data,\n };\n await sendRequest(state, req);\n },\n\n async dispatchWebSocketClose(connectionId: string, code: number, reason: string): Promise<void> {\n const reqId = state.nextRequestId++;\n const req: WsCloseRequest = {\n type: MessageType.WS_CLOSE,\n requestId: reqId,\n isolateId,\n connectionId,\n code,\n reason,\n };\n await sendRequest(state, req);\n },\n\n async dispatchWebSocketError(connectionId: string, error: Error): Promise<void> {\n const reqId = state.nextRequestId++;\n const req: FetchWsErrorRequest = {\n type: MessageType.FETCH_WS_ERROR,\n requestId: reqId,\n isolateId,\n connectionId,\n error: error.message,\n };\n await sendRequest(state, req);\n },\n\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void {\n wsCommandCallbacks.add(callback);\n return () => {\n wsCommandCallbacks.delete(callback);\n };\n },\n\n async hasServeHandler(): Promise<boolean> {\n const reqId = state.nextRequestId++;\n const req: FetchHasServeHandlerRequest = {\n type: MessageType.FETCH_HAS_SERVE_HANDLER,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<boolean>(state, req);\n },\n\n async hasActiveConnections(): Promise<boolean> {\n const reqId = state.nextRequestId++;\n const req: FetchHasActiveConnectionsRequest = {\n type: MessageType.FETCH_HAS_ACTIVE_CONNECTIONS,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<boolean>(state, req);\n },\n };\n\n // Create timers handle\n const timersHandle: RemoteTimersHandle = {\n async clearAll(): Promise<void> {\n const reqId = state.nextRequestId++;\n const req: TimersClearAllRequest = {\n type: MessageType.TIMERS_CLEAR_ALL,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n };\n\n // Create console handle\n const consoleHandle: RemoteConsoleHandle = {\n async reset(): Promise<void> {\n const reqId = state.nextRequestId++;\n const req: ConsoleResetRequest = {\n type: MessageType.CONSOLE_RESET,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n\n async getTimers(): Promise<Map<string, number>> {\n const reqId = state.nextRequestId++;\n const req: ConsoleGetTimersRequest = {\n type: MessageType.CONSOLE_GET_TIMERS,\n requestId: reqId,\n isolateId,\n };\n const result = await sendRequest<Record<string, number>>(state, req);\n return new Map(Object.entries(result));\n },\n\n async getCounters(): Promise<Map<string, number>> {\n const reqId = state.nextRequestId++;\n const req: ConsoleGetCountersRequest = {\n type: MessageType.CONSOLE_GET_COUNTERS,\n requestId: reqId,\n isolateId,\n };\n const result = await sendRequest<Record<string, number>>(state, req);\n return new Map(Object.entries(result));\n },\n\n async getGroupDepth(): Promise<number> {\n const reqId = state.nextRequestId++;\n const req: ConsoleGetGroupDepthRequest = {\n type: MessageType.CONSOLE_GET_GROUP_DEPTH,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<number>(state, req);\n },\n };\n\n // Track whether testEnvironment and playwright were enabled\n const testEnvironmentEnabled = !!options.testEnvironment;\n const playwrightEnabled = !!options.playwright;\n\n // Create test environment handle\n const testEnvironmentHandle: RemoteTestEnvironmentHandle = {\n async runTests(timeout?: number): Promise<RunTestsResult> {\n if (!testEnvironmentEnabled) {\n throw new Error(\"Test environment not enabled. Set testEnvironment: true in createRuntime options.\");\n }\n const reqId = state.nextRequestId++;\n const req: RunTestsRequest = {\n type: MessageType.RUN_TESTS,\n requestId: reqId,\n isolateId,\n timeout,\n };\n return sendRequest<RunTestsResult>(state, req, timeout ?? DEFAULT_TIMEOUT);\n },\n\n async hasTests(): Promise<boolean> {\n if (!testEnvironmentEnabled) {\n throw new Error(\"Test environment not enabled. Set testEnvironment: true in createRuntime options.\");\n }\n const reqId = state.nextRequestId++;\n const req: HasTestsRequest = {\n type: MessageType.HAS_TESTS,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<boolean>(state, req);\n },\n\n async getTestCount(): Promise<number> {\n if (!testEnvironmentEnabled) {\n throw new Error(\"Test environment not enabled. Set testEnvironment: true in createRuntime options.\");\n }\n const reqId = state.nextRequestId++;\n const req: GetTestCountRequest = {\n type: MessageType.GET_TEST_COUNT,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<number>(state, req);\n },\n\n async reset(): Promise<void> {\n if (!testEnvironmentEnabled) {\n throw new Error(\"Test environment not enabled. Set testEnvironment: true in createRuntime options.\");\n }\n const reqId = state.nextRequestId++;\n const req: ResetTestEnvRequest = {\n type: MessageType.RESET_TEST_ENV,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n };\n\n // Create playwright handle\n const playwrightHandle: RemotePlaywrightHandle = {\n async getCollectedData(): Promise<CollectedData> {\n if (!playwrightEnabled) {\n throw new Error(\"Playwright not configured. Provide playwright.page in createRuntime options.\");\n }\n const reqId = state.nextRequestId++;\n const req: GetCollectedDataRequest = {\n type: MessageType.GET_COLLECTED_DATA,\n requestId: reqId,\n isolateId,\n };\n return sendRequest<CollectedData>(state, req);\n },\n\n async clearCollectedData(): Promise<void> {\n if (!playwrightEnabled) {\n throw new Error(\"Playwright not configured. Provide playwright.page in createRuntime options.\");\n }\n const reqId = state.nextRequestId++;\n const req: ClearCollectedDataRequest = {\n type: MessageType.CLEAR_COLLECTED_DATA,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n };\n\n return {\n id: isolateId,\n isolateId,\n\n // Module handles\n fetch: fetchHandle,\n timers: timersHandle,\n console: consoleHandle,\n testEnvironment: testEnvironmentHandle,\n playwright: playwrightHandle,\n\n eval: async (\n code: string,\n filenameOrOptions?: string | EvalOptions\n ): Promise<void> => {\n const reqId = state.nextRequestId++;\n // Support both new signature (filename string) and old signature (EvalOptions)\n const options =\n typeof filenameOrOptions === \"string\"\n ? { filename: filenameOrOptions }\n : filenameOrOptions;\n const req: EvalRequest = {\n type: MessageType.EVAL,\n requestId: reqId,\n isolateId,\n code,\n filename: options?.filename,\n maxExecutionMs: options?.maxExecutionMs,\n module: true, // Always use module mode\n };\n await sendRequest<{ value: unknown }>(state, req);\n // Module evaluation returns void - don't return the value\n },\n\n dispose: async () => {\n // Clean up WebSocket callbacks\n isolateWsCallbacks.delete(isolateId);\n\n const reqId = state.nextRequestId++;\n const req: DisposeRuntimeRequest = {\n type: MessageType.DISPOSE_RUNTIME,\n requestId: reqId,\n isolateId,\n };\n await sendRequest(state, req);\n },\n };\n}\n\n/**\n * Register a simple event callback (fire-and-forget).\n */\nfunction registerEventCallback(\n state: ConnectionState,\n handler: (data: unknown) => void\n): number {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, (data: unknown) => {\n handler(data);\n return undefined;\n });\n return callbackId;\n}\n\n/**\n * Register console callbacks.\n */\nfunction registerConsoleCallbacks(\n state: ConnectionState,\n callbacks: ConsoleCallbacks\n): Record<string, CallbackRegistration> {\n const registrations: Record<string, CallbackRegistration> = {};\n\n if (callbacks.onEntry) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, (entry: unknown) => {\n callbacks.onEntry!(entry as Parameters<typeof callbacks.onEntry>[0]);\n });\n registrations.onEntry = { callbackId, name: \"onEntry\", type: 'sync' };\n }\n\n return registrations;\n}\n\n/**\n * Register fetch callback.\n */\nfunction registerFetchCallback(\n state: ConnectionState,\n callback: FetchCallback\n): CallbackRegistration {\n const callbackId = state.nextCallbackId++;\n\n state.callbacks.set(callbackId, async (serialized: unknown) => {\n const request = deserializeRequest(serialized as SerializedRequestData);\n const response = await callback(request);\n return serializeResponse(response);\n });\n\n return { callbackId, name: \"fetch\", type: 'async' };\n}\n\n/**\n * Register file system callbacks.\n */\nfunction registerFsCallbacks(\n state: ConnectionState,\n callbacks: FileSystemCallbacks\n): Record<string, CallbackRegistration> {\n const registrations: Record<string, CallbackRegistration> = {};\n\n // readFile: (path: string) => Promise<ArrayBuffer>\n if (callbacks.readFile) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n const result = await callbacks.readFile!(path as string);\n // Convert ArrayBuffer to Uint8Array for serialization\n return new Uint8Array(result);\n });\n registrations.readFile = { callbackId, name: \"readFile\", type: 'async' };\n }\n\n // writeFile: (path: string, data: ArrayBuffer) => Promise<void>\n if (callbacks.writeFile) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown, data: unknown) => {\n // Convert Uint8Array or array back to ArrayBuffer\n let buffer: ArrayBuffer;\n if (data instanceof Uint8Array) {\n buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n } else if (Array.isArray(data)) {\n buffer = new Uint8Array(data as number[]).buffer;\n } else if (data instanceof ArrayBuffer) {\n buffer = data;\n } else {\n buffer = new ArrayBuffer(0);\n }\n await callbacks.writeFile!(path as string, buffer);\n });\n registrations.writeFile = { callbackId, name: \"writeFile\", type: 'async' };\n }\n\n // unlink: (path: string) => Promise<void>\n if (callbacks.unlink) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n await callbacks.unlink!(path as string);\n });\n registrations.unlink = { callbackId, name: \"unlink\", type: 'async' };\n }\n\n // readdir: (path: string) => Promise<string[]>\n if (callbacks.readdir) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n return callbacks.readdir!(path as string);\n });\n registrations.readdir = { callbackId, name: \"readdir\", type: 'async' };\n }\n\n // mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>\n if (callbacks.mkdir) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown, options: unknown) => {\n await callbacks.mkdir!(path as string, options as { recursive?: boolean });\n });\n registrations.mkdir = { callbackId, name: \"mkdir\", type: 'async' };\n }\n\n // rmdir: (path: string) => Promise<void>\n if (callbacks.rmdir) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n await callbacks.rmdir!(path as string);\n });\n registrations.rmdir = { callbackId, name: \"rmdir\", type: 'async' };\n }\n\n // stat: (path: string) => Promise<{ isFile: boolean; isDirectory: boolean; size: number }>\n if (callbacks.stat) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (path: unknown) => {\n return callbacks.stat!(path as string);\n });\n registrations.stat = { callbackId, name: \"stat\", type: 'async' };\n }\n\n // rename: (from: string, to: string) => Promise<void>\n if (callbacks.rename) {\n const callbackId = state.nextCallbackId++;\n state.callbacks.set(callbackId, async (from: unknown, to: unknown) => {\n await callbacks.rename!(from as string, to as string);\n });\n registrations.rename = { callbackId, name: \"rename\", type: 'async' };\n }\n\n return registrations;\n}\n\n/**\n * Register module loader callback.\n */\nfunction registerModuleLoaderCallback(\n state: ConnectionState,\n callback: ModuleLoaderCallback\n): CallbackRegistration {\n const callbackId = state.nextCallbackId++;\n\n state.callbacks.set(callbackId, async (moduleName: unknown) => {\n return callback(moduleName as string);\n });\n\n return { callbackId, name: \"moduleLoader\", type: 'async' };\n}\n\n// Iterator session tracking for async iterator custom functions on the client side\ninterface ClientIteratorSession {\n iterator: AsyncGenerator<unknown, unknown, unknown>;\n}\n\nconst clientIteratorSessions = new Map<number, ClientIteratorSession>();\nlet nextClientIteratorId = 1;\n\n// Registries for returned promises/iterators from custom function callbacks\n// These are populated when a custom function returns a Promise or AsyncIterator\nconst returnedPromiseRegistry = new Map<number, Promise<unknown>>();\nconst returnedIteratorRegistry = new Map<number, AsyncIterator<unknown>>();\n\n/**\n * Type guard for PromiseRef\n */\nfunction isPromiseRef(value: unknown): value is { __type: \"PromiseRef\"; promiseId: number } {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __type?: string }).__type === 'PromiseRef'\n );\n}\n\n/**\n * Type guard for AsyncIteratorRef\n */\nfunction isAsyncIteratorRef(value: unknown): value is { __type: \"AsyncIteratorRef\"; iteratorId: number } {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __type?: string }).__type === 'AsyncIteratorRef'\n );\n}\n\n/**\n * Register custom function callbacks.\n */\nfunction registerCustomFunctions(\n state: ConnectionState,\n customFunctions: CustomFunctions\n): Record<string, CallbackRegistration> {\n const registrations: Record<string, CallbackRegistration> = {};\n\n for (const [name, def] of Object.entries(customFunctions)) {\n if (def.type === 'asyncIterator') {\n // For async iterators, we need to register 4 callbacks:\n // start, next, return, throw\n\n // Start callback: creates iterator, returns iteratorId\n const startCallbackId = state.nextCallbackId++;\n state.callbacks.set(startCallbackId, async (...args: unknown[]) => {\n try {\n const fn = def.fn as (...args: unknown[]) => AsyncGenerator<unknown, unknown, unknown>;\n const iterator = fn(...args);\n const iteratorId = nextClientIteratorId++;\n clientIteratorSessions.set(iteratorId, { iterator });\n return { iteratorId };\n } catch (error: unknown) {\n throw error;\n }\n });\n\n // Next callback: calls iterator.next() - marshal the value for type fidelity\n const nextCallbackId = state.nextCallbackId++;\n state.callbacks.set(nextCallbackId, async (iteratorId: unknown) => {\n const session = clientIteratorSessions.get(iteratorId as number);\n if (!session) {\n throw new Error(`Iterator session ${iteratorId} not found`);\n }\n try {\n const result = await session.iterator.next();\n if (result.done) {\n clientIteratorSessions.delete(iteratorId as number);\n }\n return { done: result.done, value: await marshalValue(result.value) };\n } catch (error: unknown) {\n clientIteratorSessions.delete(iteratorId as number);\n throw error;\n }\n });\n\n // Return callback: calls iterator.return() - marshal the value for type fidelity\n const returnCallbackId = state.nextCallbackId++;\n state.callbacks.set(returnCallbackId, async (iteratorId: unknown, value: unknown) => {\n const session = clientIteratorSessions.get(iteratorId as number);\n if (!session) {\n return { done: true, value: await marshalValue(undefined) };\n }\n try {\n const result = await session.iterator.return?.(value);\n clientIteratorSessions.delete(iteratorId as number);\n return { done: true, value: await marshalValue(result?.value) };\n } catch (error: unknown) {\n clientIteratorSessions.delete(iteratorId as number);\n throw error;\n }\n });\n\n // Throw callback: calls iterator.throw() - marshal the value for type fidelity\n const throwCallbackId = state.nextCallbackId++;\n state.callbacks.set(throwCallbackId, async (iteratorId: unknown, errorData: unknown) => {\n const session = clientIteratorSessions.get(iteratorId as number);\n if (!session) {\n throw new Error(`Iterator session ${iteratorId} not found`);\n }\n try {\n const errInfo = errorData as { message: string; name: string };\n const error = Object.assign(new Error(errInfo.message), { name: errInfo.name });\n const result = await session.iterator.throw?.(error);\n clientIteratorSessions.delete(iteratorId as number);\n return { done: result?.done ?? true, value: await marshalValue(result?.value) };\n } catch (error: unknown) {\n clientIteratorSessions.delete(iteratorId as number);\n throw error;\n }\n });\n\n // Register with special naming convention for iterator callbacks\n registrations[`${name}:start`] = { callbackId: startCallbackId, name: `${name}:start`, type: 'async' };\n registrations[`${name}:next`] = { callbackId: nextCallbackId, name: `${name}:next`, type: 'async' };\n registrations[`${name}:return`] = { callbackId: returnCallbackId, name: `${name}:return`, type: 'async' };\n registrations[`${name}:throw`] = { callbackId: throwCallbackId, name: `${name}:throw`, type: 'async' };\n\n // Also register the main entry with asyncIterator type so daemon knows this is an iterator\n registrations[name] = {\n callbackId: startCallbackId,\n name,\n type: 'asyncIterator',\n };\n } else {\n const callbackId = state.nextCallbackId++;\n\n // Register the callback - marshal the result to preserve type fidelity\n // (Request, Response, File, undefined, etc. → Refs)\n // Also register returned functions/promises/iterators so they can be called back\n state.callbacks.set(callbackId, async (...args: unknown[]) => {\n const result = await def.fn(...args);\n\n // Helper to add callback IDs to PromiseRef and AsyncIteratorRef\n const addCallbackIdsToRefs = (value: unknown): unknown => {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Check for PromiseRef\n if (isPromiseRef(value)) {\n // Create a resolve callback\n const resolveCallbackId = state.nextCallbackId++;\n state.callbacks.set(resolveCallbackId, async (...args: unknown[]) => {\n const promiseId = args[0] as number;\n const promise = returnedPromiseRegistry.get(promiseId);\n if (!promise) {\n throw new Error(`Promise ${promiseId} not found`);\n }\n const promiseResult = await promise;\n // Clean up\n returnedPromiseRegistry.delete(promiseId);\n // Marshal and process the result recursively\n const marshalledResult = await marshalValue(promiseResult, marshalCtx);\n return addCallbackIdsToRefs(marshalledResult);\n });\n return {\n ...value,\n __resolveCallbackId: resolveCallbackId,\n };\n }\n\n // Check for AsyncIteratorRef\n if (isAsyncIteratorRef(value)) {\n // Create next callback\n const nextCallbackId = state.nextCallbackId++;\n state.callbacks.set(nextCallbackId, async (...args: unknown[]) => {\n const iteratorId = args[0] as number;\n const iterator = returnedIteratorRegistry.get(iteratorId);\n if (!iterator) {\n throw new Error(`Iterator ${iteratorId} not found`);\n }\n const iterResult = await iterator.next();\n if (iterResult.done) {\n returnedIteratorRegistry.delete(iteratorId);\n }\n // Marshal and process the value recursively\n const marshalledValue = await marshalValue(iterResult.value, marshalCtx);\n return {\n done: iterResult.done,\n value: addCallbackIdsToRefs(marshalledValue),\n };\n });\n\n // Create return callback\n const returnCallbackId = state.nextCallbackId++;\n state.callbacks.set(returnCallbackId, async (...args: unknown[]) => {\n const iteratorId = args[0] as number;\n const returnValue = args[1];\n const iterator = returnedIteratorRegistry.get(iteratorId);\n returnedIteratorRegistry.delete(iteratorId);\n if (!iterator || !iterator.return) {\n return { done: true, value: undefined };\n }\n const iterResult = await iterator.return(returnValue);\n const marshalledValue = await marshalValue(iterResult.value, marshalCtx);\n return {\n done: true,\n value: addCallbackIdsToRefs(marshalledValue),\n };\n });\n\n return {\n ...value,\n __nextCallbackId: nextCallbackId,\n __returnCallbackId: returnCallbackId,\n };\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n return value.map(item => addCallbackIdsToRefs(item));\n }\n\n // Handle plain objects (recursively process values)\n const objResult: Record<string, unknown> = {};\n for (const key of Object.keys(value)) {\n objResult[key] = addCallbackIdsToRefs((value as Record<string, unknown>)[key]);\n }\n return objResult;\n };\n\n // Create context for registering returned callbacks/promises/iterators\n // These will be registered in state.callbacks so the daemon can call them back\n const marshalCtx: MarshalContext = {\n registerCallback: (fn: Function): number => {\n const returnedCallbackId = state.nextCallbackId++;\n // Register a callback that marshals its result recursively\n state.callbacks.set(returnedCallbackId, async (...args: unknown[]) => {\n const fnResult = await fn(...args);\n const marshalledResult = await marshalValue(fnResult, marshalCtx);\n return addCallbackIdsToRefs(marshalledResult);\n });\n return returnedCallbackId;\n },\n registerPromise: (promise: Promise<unknown>): number => {\n const promiseId = state.nextCallbackId++;\n // Store the promise - callback to resolve it will be created in addCallbackIdsToRefs\n returnedPromiseRegistry.set(promiseId, promise);\n return promiseId;\n },\n registerIterator: (iterator: AsyncIterator<unknown>): number => {\n const iteratorId = state.nextCallbackId++;\n // Store the iterator - callbacks for next/return will be created in addCallbackIdsToRefs\n returnedIteratorRegistry.set(iteratorId, iterator);\n return iteratorId;\n },\n };\n\n const marshalled = await marshalValue(result, marshalCtx);\n const withCallbackIds = addCallbackIdsToRefs(marshalled);\n return withCallbackIds;\n });\n\n registrations[name] = {\n callbackId,\n name,\n type: def.type,\n };\n }\n }\n\n return registrations;\n}\n\n// ============================================================================\n// Request/Response Serialization\n// ============================================================================\n\ninterface SerializedRequestData {\n method: string;\n url: string;\n headers: [string, string][];\n body: Uint8Array | null;\n}\n\ninterface SerializedResponseData {\n status: number;\n statusText: string;\n headers: [string, string][];\n body: Uint8Array | null;\n}\n\nasync function serializeRequest(request: Request): Promise<SerializedRequestData> {\n const headers: [string, string][] = [];\n request.headers.forEach((value, key) => {\n headers.push([key, value]);\n });\n\n let body: Uint8Array | null = null;\n if (request.body) {\n body = new Uint8Array(await request.arrayBuffer());\n }\n\n return {\n method: request.method,\n url: request.url,\n headers,\n body,\n };\n}\n\nasync function serializeResponse(response: Response): Promise<SerializedResponseData> {\n const headers: [string, string][] = [];\n response.headers.forEach((value, key) => {\n headers.push([key, value]);\n });\n\n let body: Uint8Array | null = null;\n if (response.body) {\n body = new Uint8Array(await response.arrayBuffer());\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers,\n body,\n };\n}\n\nfunction deserializeRequest(data: SerializedRequestData): Request {\n return new Request(data.url, {\n method: data.method,\n headers: data.headers,\n body: data.body as unknown as BodyInit | null | undefined,\n });\n}\n\nfunction deserializeResponse(data: SerializedResponse): Response {\n return new Response(data.body as unknown as BodyInit | null, {\n status: data.status,\n statusText: data.statusText,\n headers: data.headers,\n });\n}\n\n// ============================================================================\n// Streaming Request Serialization\n// ============================================================================\n\ninterface SerializedRequestWithStream extends SerializedRequestData {\n bodyStreamId?: number;\n bodyStream?: ReadableStream<Uint8Array>;\n}\n\n/**\n * Serialize a request, using streaming for large bodies.\n */\nasync function serializeRequestWithStreaming(\n state: ConnectionState,\n request: Request\n): Promise<SerializedRequestWithStream> {\n const headers: [string, string][] = [];\n request.headers.forEach((value, key) => {\n headers.push([key, value]);\n });\n\n let body: Uint8Array | null = null;\n let bodyStreamId: number | undefined;\n let bodyStream: ReadableStream<Uint8Array> | undefined;\n\n if (request.body) {\n // Check Content-Length header first\n const contentLength = request.headers.get(\"content-length\");\n const knownSize = contentLength ? parseInt(contentLength, 10) : null;\n\n if (knownSize !== null && knownSize > STREAM_THRESHOLD) {\n // Large body with known size - use streaming\n bodyStreamId = state.nextStreamId++;\n bodyStream = request.body;\n } else {\n // Small or unknown size - read into memory\n const clonedRequest = request.clone();\n try {\n body = new Uint8Array(await request.arrayBuffer());\n\n // Check if it ended up being large\n if (body.length > STREAM_THRESHOLD) {\n // Use the cloned request's body for streaming\n bodyStreamId = state.nextStreamId++;\n bodyStream = clonedRequest.body!;\n body = null;\n }\n } catch {\n // Failed to read body, try streaming\n bodyStreamId = state.nextStreamId++;\n bodyStream = clonedRequest.body!;\n }\n }\n }\n\n const result: SerializedRequestWithStream = {\n method: request.method,\n url: request.url,\n headers,\n body,\n };\n\n // Only include streaming fields if actually streaming\n if (bodyStreamId !== undefined) {\n result.bodyStreamId = bodyStreamId;\n result.bodyStream = bodyStream;\n }\n\n return result;\n}\n\n/**\n * Wait for credit to become available on an upload stream session.\n */\nfunction waitForUploadCredit(session: StreamUploadSession): Promise<void> {\n return new Promise((resolve) => {\n session.creditResolver = resolve;\n });\n}\n\n/**\n * Send a request body as a stream.\n */\nasync function sendBodyStream(\n state: ConnectionState,\n streamId: number,\n body: ReadableStream<Uint8Array>\n): Promise<void> {\n // Create upload session for tracking\n const session: StreamUploadSession = {\n streamId,\n requestId: 0,\n state: \"active\",\n bytesTransferred: 0,\n credit: 0, // Wait for initial credit from daemon\n };\n state.uploadStreams.set(streamId, session);\n\n const reader = body.getReader();\n\n try {\n while (true) {\n if (session.state !== \"active\") {\n throw new Error(\"Stream cancelled\");\n }\n\n // Wait for credit if needed\n while (session.credit < STREAM_CHUNK_SIZE && session.state === \"active\") {\n await waitForUploadCredit(session);\n }\n\n if (session.state !== \"active\") {\n throw new Error(\"Stream cancelled\");\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Send stream close\n sendMessage(state.socket, {\n type: MessageType.STREAM_CLOSE,\n streamId,\n } as StreamClose);\n break;\n }\n\n // Send chunk(s)\n for (let offset = 0; offset < value.length; offset += STREAM_CHUNK_SIZE) {\n const chunk = value.slice(offset, offset + STREAM_CHUNK_SIZE);\n\n sendMessage(state.socket, {\n type: MessageType.STREAM_PUSH,\n streamId,\n chunk,\n } as StreamPush);\n\n session.credit -= chunk.length;\n session.bytesTransferred += chunk.length;\n }\n }\n } catch (err) {\n sendMessage(state.socket, {\n type: MessageType.STREAM_ERROR,\n streamId,\n error: (err as Error).message,\n } as StreamError);\n throw err;\n } finally {\n reader.releaseLock();\n state.uploadStreams.delete(streamId);\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;AAIA,oBAAS;AACT;AAAA;AAAA;AAAA;AAAA;AA0CA,IAAM,kBAAkB;AAsBxB,eAAsB,OAAO,CAAC,UAA0B,CAAC,GAA8B;AAAA,EACrF,MAAM,SAAS,MAAM,aAAa,OAAO;AAAA,EAEzC,MAAM,QAAyB;AAAA,IAC7B;AAAA,IACA,iBAAiB,IAAI;AAAA,IACrB,WAAW,IAAI;AAAA,IACf,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,WAAW;AAAA,IACX,yBAAyB,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,SAAS,kBAAkB;AAAA,EAEjC,OAAO,GAAG,QAAQ,CAAC,SAAS;AAAA,IAC1B,IAAI;AAAA,MACF,WAAW,SAAS,OAAO,KAAK,IAAI,WAAW,IAAI,CAAC,GAAG;AAAA,QACrD,cAAc,MAAM,SAAS,KAAK;AAAA,MACpC;AAAA,MACA,OAAO,KAAK;AAAA,MACZ,QAAQ,MAAM,wBAAwB,GAAG;AAAA;AAAA,GAE5C;AAAA,EAED,OAAO,GAAG,SAAS,MAAM;AAAA,IACvB,MAAM,YAAY;AAAA,IAElB,cAAc,YAAY,MAAM,iBAAiB;AAAA,MAC/C,QAAQ,OAAO,IAAI,MAAM,mBAAmB,CAAC;AAAA,IAC/C;AAAA,IACA,MAAM,gBAAgB,MAAM;AAAA,GAC7B;AAAA,EAED,OAAO,GAAG,SAAS,CAAC,QAAQ;AAAA,IAC1B,QAAQ,MAAM,iBAAiB,GAAG;AAAA,GACnC;AAAA,EAED,OAAO;AAAA,IACL,eAAe,CAAC,mBACd,cAAc,OAAO,cAAc;AAAA,IACrC,OAAO,YAAY;AAAA,MACjB,MAAM,YAAY;AAAA,MAClB,OAAO,QAAQ;AAAA;AAAA,IAEjB,aAAa,MAAM,MAAM;AAAA,EAC3B;AAAA;AAMF,SAAS,YAAY,CAAC,SAA0C;AAAA,EAC9D,OAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,IACtC,MAAM,UAAU,QAAQ,WAAW;AAAA,IAEnC,IAAI;AAAA,IAEJ,MAAM,UAAU,CAAC,QAAe;AAAA,MAC9B,OAAO,GAAG;AAAA;AAAA,IAGZ,MAAM,YAAY,MAAM;AAAA,MACtB,OAAO,eAAe,SAAS,OAAO;AAAA,MACtC,QAAQ,MAAM;AAAA;AAAA,IAGhB,IAAI,QAAQ,QAAQ;AAAA,MAClB,SAAS,WAAW,QAAQ,QAAQ,SAAS;AAAA,IAC/C,EAAO;AAAA,MACL,SAAS,WACP,QAAQ,QAAQ,OAChB,QAAQ,QAAQ,aAChB,SACF;AAAA;AAAA,IAGF,OAAO,GAAG,SAAS,OAAO;AAAA,IAG1B,MAAM,YAAY,WAAW,MAAM;AAAA,MACjC,OAAO,QAAQ;AAAA,MACf,OAAO,IAAI,MAAM,oBAAoB,CAAC;AAAA,OACrC,OAAO;AAAA,IAEV,OAAO,KAAK,WAAW,MAAM;AAAA,MAC3B,aAAa,SAAS;AAAA,KACvB;AAAA,GACF;AAAA;AAMH,SAAS,aAAa,CAAC,SAAkB,OAA8B;AAAA,EACrE,QAAQ,QAAQ;AAAA,SACT,YAAY,aAAa;AAAA,MAC5B,MAAM,WAAW;AAAA,MACjB,MAAM,UAAU,MAAM,gBAAgB,IAAI,SAAS,SAAS;AAAA,MAC5D,IAAI,SAAS;AAAA,QACX,MAAM,gBAAgB,OAAO,SAAS,SAAS;AAAA,QAC/C,IAAI,QAAQ;AAAA,UAAW,aAAa,QAAQ,SAAS;AAAA,QACrD,QAAQ,QAAQ,SAAS,IAAI;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,SAEK,YAAY,gBAAgB;AAAA,MAC/B,MAAM,WAAW;AAAA,MACjB,MAAM,UAAU,MAAM,gBAAgB,IAAI,SAAS,SAAS;AAAA,MAC5D,IAAI,SAAS;AAAA,QACX,MAAM,gBAAgB,OAAO,SAAS,SAAS;AAAA,QAC/C,IAAI,QAAQ;AAAA,UAAW,aAAa,QAAQ,SAAS;AAAA,QACrD,MAAM,QAAQ,IAAI,MAAM,SAAS,OAAO;AAAA,QACxC,IAAI,SAAS,SAAS;AAAA,UACpB,MAAM,OAAO,SAAS,QAAQ;AAAA,UAC9B,IAAI,SAAS,QAAQ,OAAO;AAAA,YAC1B,MAAM,QAAQ,SAAS,QAAQ;AAAA,UACjC;AAAA,QACF;AAAA,QACA,QAAQ,OAAO,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAAA,SAEK,YAAY,iBAAiB;AAAA,MAChC,MAAM,SAAS;AAAA,MACf,qBAAqB,QAAQ,KAAK;AAAA,MAClC;AAAA,IACF;AAAA,SAEK,YAAY;AAAA,MAEf;AAAA,SAEG,YAAY,kBAAkB;AAAA,MACjC,MAAM,QAAQ;AAAA,MACd,MAAM,UAAU,MAAM,wBAAwB,IAAI,MAAM,SAAS;AAAA,MACjE,IAAI,SAAS;AAAA,QACX,QAAQ,MAAM;AAAA,eACP;AAAA,YACH,QAAQ,eAAe,MAAM,OAA6C;AAAA,YAC1E;AAAA,eACG;AAAA,YACH,QAAQ,mBAAmB,MAAM,OAA8F;AAAA,YAC/H;AAAA,eACG;AAAA,YACH,QAAQ,oBAAoB,MAAM,OAA8F;AAAA,YAChI;AAAA;AAAA,MAEN;AAAA,MACA;AAAA,IACF;AAAA;AAAA,MAGE,QAAQ,KAAK,4BAA4B,QAAQ,MAAM;AAAA;AAAA;AAO7D,eAAe,oBAAoB,CACjC,QACA,OACe;AAAA,EACf,MAAM,WAAW,MAAM,UAAU,IAAI,OAAO,UAAU;AAAA,EAEtD,MAAM,WAAgC;AAAA,IACpC,MAAM,YAAY;AAAA,IAClB,WAAW,OAAO;AAAA,EACpB;AAAA,EAEA,IAAI,CAAC,UAAU;AAAA,IACb,SAAS,QAAQ;AAAA,MACf,MAAM;AAAA,MACN,SAAS,qBAAqB,OAAO;AAAA,IACvC;AAAA,EACF,EAAO;AAAA,IACL,IAAI;AAAA,MACF,MAAM,SAAS,MAAM,SAAS,GAAG,OAAO,IAAI;AAAA,MAC5C,SAAS,SAAS;AAAA,MAClB,OAAO,KAAK;AAAA,MACZ,MAAM,QAAQ;AAAA,MACd,SAAS,QAAQ;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,MACf;AAAA;AAAA;AAAA,EAIJ,YAAY,MAAM,QAAQ,QAAQ;AAAA;AAMpC,SAAS,WAAW,CAAC,QAAgB,SAAwB;AAAA,EAC3D,MAAM,QAAQ,WAAW,OAAO;AAAA,EAChC,OAAO,MAAM,KAAK;AAAA;AAMpB,SAAS,WAAc,CACrB,OACA,SACA,UAAU,iBACE;AAAA,EACZ,OAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,IACtC,IAAI,CAAC,MAAM,WAAW;AAAA,MACpB,OAAO,IAAI,MAAM,eAAe,CAAC;AAAA,MACjC;AAAA,IACF;AAAA,IAEA,MAAM,YAAa,QAAkC;AAAA,IAErD,MAAM,YAAY,WAAW,MAAM;AAAA,MACjC,MAAM,gBAAgB,OAAO,SAAS;AAAA,MACtC,OAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,OAClC,OAAO;AAAA,IAEV,MAAM,gBAAgB,IAAI,WAAW;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IAED,YAAY,MAAM,QAAQ,OAAO;AAAA,GAClC;AAAA;AAMH,eAAe,aAAa,CAC1B,OACA,UAA0B,CAAC,GACH;AAAA,EAExB,MAAM,YAA0C,CAAC;AAAA,EAEjD,IAAI,QAAQ,SAAS;AAAA,IACnB,UAAU,UAAU,yBAAyB,OAAO,QAAQ,OAAO;AAAA,EACrE;AAAA,EAEA,IAAI,QAAQ,OAAO;AAAA,IACjB,UAAU,QAAQ,sBAAsB,OAAO,QAAQ,KAAK;AAAA,EAC9D;AAAA,EAEA,IAAI,QAAQ,IAAI;AAAA,IACd,UAAU,KAAK,oBAAoB,OAAO,QAAQ,EAAE;AAAA,EACtD;AAAA,EAEA,MAAM,YAAY,MAAM;AAAA,EACxB,MAAM,UAAgC;AAAA,IACpC,MAAM,YAAY;AAAA,IAClB;AAAA,IACA,SAAS;AAAA,MACP,aAAa,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,MAAM,YAAiC,OAAO,OAAO;AAAA,EACpE,MAAM,YAAY,OAAO;AAAA,EAEzB,OAAO;AAAA,IACL;AAAA,IAEA,MAAM,OAAO,MAAc,aAAsB;AAAA,MAC/C,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAAmB;AAAA,QACvB,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAM,MAAM,MAAM,YAAgC,OAAO,GAAG;AAAA,MAC5D,OAAO,IAAI;AAAA;AAAA,IAGb,iBAAiB,OACf,UACA,oBACG;AAAA,MACH,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,aAAa,MAAM,iBAAiB,QAAO;AAAA,MACjD,MAAM,MAA8B;AAAA,QAClC,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,QACA,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,MACA,MAAM,MAAM,MAAM,YAChB,OACA,KACA,iBAAiB,WAAW,eAC9B;AAAA,MACA,OAAO,oBAAoB,IAAI,QAAQ;AAAA;AAAA,IAGzC,MAAM,OAAO,OAAgB;AAAA,MAC3B,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAAmB;AAAA,QACvB,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAM,YAAY,OAAO,GAAG;AAAA;AAAA,IAG9B,sBAAsB,YAAY;AAAA,MAChC,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAA2B;AAAA,QAC/B,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,YAAY,OAAO,GAAG;AAAA;AAAA,IAG9B,UAAU,OAAO,YAAqB;AAAA,MACpC,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAAuB;AAAA,QAC3B,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,YAA4B,OAAO,KAAK,WAAW,eAAe;AAAA;AAAA,IAG3E,iBAAiB,OAAO,sBAA+C;AAAA,MACrE,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAA8B;AAAA,QAClC,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,QACA,SAAS;AAAA,UACP,aAAa,mBAAmB;AAAA,UAChC,UAAU,mBAAmB;AAAA,UAC7B,SAAS,mBAAmB;AAAA,QAC9B;AAAA,MACF;AAAA,MAGA,IAAI,mBAAmB,gBAAgB,mBAAmB,oBAAoB,mBAAmB,mBAAmB;AAAA,QAClH,MAAM,wBAAwB,IAAI,WAAW;AAAA,UAC3C,cAAc,kBAAkB;AAAA,UAChC,kBAAkB,kBAAkB;AAAA,UACpC,mBAAmB,kBAAkB;AAAA,QACvC,CAAC;AAAA,MACH;AAAA,MAEA,MAAM,YAAY,OAAO,GAAG;AAAA;AAAA,IAG9B,oBAAoB,OAAO,YAAqB;AAAA,MAC9C,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAAiC;AAAA,QACrC,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,YAAkC,OAAO,KAAK,WAAW,eAAe;AAAA;AAAA,IAGjF,sBAAsB,YAAY;AAAA,MAChC,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAAmC;AAAA,QACvC,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,YAAY,OAAO,GAAG;AAAA;AAAA,IAG9B,kBAAkB,YAAY;AAAA,MAC5B,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAA+B;AAAA,QACnC,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,OAAO,YAA2B,OAAO,GAAG;AAAA;AAAA,IAG9C,SAAS,YAAY;AAAA,MAEnB,MAAM,wBAAwB,OAAO,SAAS;AAAA,MAE9C,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,MAA6B;AAAA,QACjC,MAAM,YAAY;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,YAAY,OAAO,GAAG;AAAA;AAAA,EAEhC;AAAA;AAMF,SAAS,wBAAwB,CAC/B,OACA,WACsC;AAAA,EACtC,MAAM,gBAAsD,CAAC;AAAA,EAE7D,MAAM,WAAW,CAAC,MAAc,OAAqC;AAAA,IACnE,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,CAAC,WAAoB,SAAoB;AAAA,MACvE,GAAG,GAAG,IAAI;AAAA,KACX;AAAA,IACD,cAAc,QAAQ,EAAE,YAAY,MAAM,OAAO,MAAM;AAAA;AAAA,EAGzD,IAAI,UAAU;AAAA,IAAK,SAAS,OAAO,UAAU,GAAG;AAAA,EAChD,IAAI,UAAU;AAAA,IAAM,SAAS,QAAQ,UAAU,IAAI;AAAA,EACnD,IAAI,UAAU;AAAA,IAAO,SAAS,SAAS,UAAU,KAAK;AAAA,EACtD,IAAI,UAAU;AAAA,IAAM,SAAS,QAAQ,UAAU,IAAI;AAAA,EACnD,IAAI,UAAU;AAAA,IAAO,SAAS,SAAS,UAAU,KAAK;AAAA,EACtD,IAAI,UAAU;AAAA,IAAK,SAAS,OAAO,UAAU,GAAG;AAAA,EAEhD,OAAO;AAAA;AAMT,SAAS,qBAAqB,CAC5B,OACA,UACsB;AAAA,EACtB,MAAM,aAAa,MAAM;AAAA,EAEzB,MAAM,UAAU,IAAI,YAAY,OAAO,eAAwB;AAAA,IAC7D,MAAM,UAAU,mBAAmB,UAAmC;AAAA,IACtE,MAAM,WAAW,MAAM,SAAS,OAAO;AAAA,IACvC,OAAO,kBAAkB,QAAQ;AAAA,GAClC;AAAA,EAED,OAAO,EAAE,YAAY,MAAM,SAAS,OAAO,KAAK;AAAA;AAMlD,SAAS,mBAAmB,CAC1B,OACA,WACsC;AAAA,EACtC,MAAM,gBAAsD,CAAC;AAAA,EAG7D,IAAI,UAAU,UAAU;AAAA,IACtB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,SAAkB;AAAA,MACvD,MAAM,SAAS,MAAM,UAAU,SAAU,IAAc;AAAA,MAEvD,OAAO,IAAI,WAAW,MAAM;AAAA,KAC7B;AAAA,IACD,cAAc,WAAW,EAAE,YAAY,MAAM,YAAY,OAAO,KAAK;AAAA,EACvE;AAAA,EAGA,IAAI,UAAU,WAAW;AAAA,IACvB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,MAAe,SAAkB;AAAA,MAEtE,IAAI;AAAA,MACJ,IAAI,gBAAgB,YAAY;AAAA,QAC9B,SAAS,KAAK,OAAO,MAAM,KAAK,YAAY,KAAK,aAAa,KAAK,UAAU;AAAA,MAC/E,EAAO,SAAI,MAAM,QAAQ,IAAI,GAAG;AAAA,QAC9B,SAAS,IAAI,WAAW,IAAgB,EAAE;AAAA,MAC5C,EAAO,SAAI,gBAAgB,aAAa;AAAA,QACtC,SAAS;AAAA,MACX,EAAO;AAAA,QACL,SAAS,IAAI,YAAY,CAAC;AAAA;AAAA,MAE5B,MAAM,UAAU,UAAW,MAAgB,MAAM;AAAA,KAClD;AAAA,IACD,cAAc,YAAY,EAAE,YAAY,MAAM,aAAa,OAAO,KAAK;AAAA,EACzE;AAAA,EAGA,IAAI,UAAU,QAAQ;AAAA,IACpB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,SAAkB;AAAA,MACvD,MAAM,UAAU,OAAQ,IAAc;AAAA,KACvC;AAAA,IACD,cAAc,SAAS,EAAE,YAAY,MAAM,UAAU,OAAO,KAAK;AAAA,EACnE;AAAA,EAGA,IAAI,UAAU,SAAS;AAAA,IACrB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,SAAkB;AAAA,MACvD,OAAO,UAAU,QAAS,IAAc;AAAA,KACzC;AAAA,IACD,cAAc,UAAU,EAAE,YAAY,MAAM,WAAW,OAAO,KAAK;AAAA,EACrE;AAAA,EAGA,IAAI,UAAU,OAAO;AAAA,IACnB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,MAAe,YAAqB;AAAA,MACzE,MAAM,UAAU,MAAO,MAAgB,OAAkC;AAAA,KAC1E;AAAA,IACD,cAAc,QAAQ,EAAE,YAAY,MAAM,SAAS,OAAO,KAAK;AAAA,EACjE;AAAA,EAGA,IAAI,UAAU,OAAO;AAAA,IACnB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,SAAkB;AAAA,MACvD,MAAM,UAAU,MAAO,IAAc;AAAA,KACtC;AAAA,IACD,cAAc,QAAQ,EAAE,YAAY,MAAM,SAAS,OAAO,KAAK;AAAA,EACjE;AAAA,EAGA,IAAI,UAAU,MAAM;AAAA,IAClB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,SAAkB;AAAA,MACvD,OAAO,UAAU,KAAM,IAAc;AAAA,KACtC;AAAA,IACD,cAAc,OAAO,EAAE,YAAY,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC/D;AAAA,EAGA,IAAI,UAAU,QAAQ;AAAA,IACpB,MAAM,aAAa,MAAM;AAAA,IACzB,MAAM,UAAU,IAAI,YAAY,OAAO,MAAe,OAAgB;AAAA,MACpE,MAAM,UAAU,OAAQ,MAAgB,EAAY;AAAA,KACrD;AAAA,IACD,cAAc,SAAS,EAAE,YAAY,MAAM,UAAU,OAAO,KAAK;AAAA,EACnE;AAAA,EAEA,OAAO;AAAA;AAqBT,eAAe,gBAAgB,CAAC,SAAkD;AAAA,EAChF,MAAM,UAA8B,CAAC;AAAA,EACrC,QAAQ,QAAQ,QAAQ,CAAC,OAAO,QAAQ;AAAA,IACtC,QAAQ,KAAK,CAAC,KAAK,KAAK,CAAC;AAAA,GAC1B;AAAA,EAED,IAAI,OAA0B;AAAA,EAC9B,IAAI,QAAQ,MAAM;AAAA,IAChB,OAAO,IAAI,WAAW,MAAM,QAAQ,YAAY,CAAC;AAAA,EACnD;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ,QAAQ;AAAA,IAChB,KAAK,QAAQ;AAAA,IACb;AAAA,IACA;AAAA,EACF;AAAA;AAGF,eAAe,iBAAiB,CAAC,UAAqD;AAAA,EACpF,MAAM,UAA8B,CAAC;AAAA,EACrC,SAAS,QAAQ,QAAQ,CAAC,OAAO,QAAQ;AAAA,IACvC,QAAQ,KAAK,CAAC,KAAK,KAAK,CAAC;AAAA,GAC1B;AAAA,EAED,IAAI,OAA0B;AAAA,EAC9B,IAAI,SAAS,MAAM;AAAA,IACjB,OAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AAAA,EACpD;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AAAA;AAGF,SAAS,kBAAkB,CAAC,MAAsC;AAAA,EAChE,OAAO,IAAI,QAAQ,KAAK,KAAK;AAAA,IAC3B,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd,MAAM,KAAK;AAAA,EACb,CAAC;AAAA;AAGH,SAAS,mBAAmB,CAAC,MAAoC;AAAA,EAC/D,OAAO,IAAI,SAAS,KAAK,MAAoC;AAAA,IAC3D,QAAQ,KAAK;AAAA,IACb,YAAY,KAAK;AAAA,IACjB,SAAS,KAAK;AAAA,EAChB,CAAC;AAAA;",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "8168995DA414336764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/mjs/index.mjs.map
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * @ricsam/isolate-client\n *\n * Client library for connecting to the isolate daemon.\n * Works with Bun, Node.js, and other JavaScript runtimes.\n */\n\nexport { connect } from \"./connection.mjs\";\nexport type {\n ConnectOptions,\n DaemonConnection,\n RuntimeOptions,\n RemoteRuntime,\n DispatchOptions,\n ConsoleCallbacks,\n FetchCallback,\n FileSystemCallbacks,\n
|
|
5
|
+
"/**\n * @ricsam/isolate-client\n *\n * Client library for connecting to the isolate daemon.\n * Works with Bun, Node.js, and other JavaScript runtimes.\n */\n\nexport { connect } from \"./connection.mjs\";\nexport type {\n ConnectOptions,\n DaemonConnection,\n RuntimeOptions,\n RemoteRuntime,\n RemoteFetchHandle,\n RemoteTimersHandle,\n RemoteConsoleHandle,\n RemoteTestEnvironmentHandle,\n RemotePlaywrightHandle,\n DispatchOptions,\n ConsoleCallbacks,\n FetchCallback,\n FileSystemCallbacks,\n PlaywrightOptions,\n PlaywrightEvent,\n TestEnvironmentOptions,\n RunResults,\n TestResult,\n TestInfo,\n TestError,\n TestEvent,\n SuiteInfo,\n SuiteResult,\n CollectedData,\n ConsoleEntry,\n} from \"./types.mjs\";\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;AAOA;",
|
|
8
8
|
"debugId": "330C2EADEC2FFB8D64756E2164756E21",
|
package/dist/mjs/package.json
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* Works with Bun, Node.js, and other JavaScript runtimes.
|
|
6
6
|
*/
|
|
7
7
|
export { connect } from "./connection.ts";
|
|
8
|
-
export type { ConnectOptions, DaemonConnection, RuntimeOptions, RemoteRuntime, DispatchOptions, ConsoleCallbacks, FetchCallback, FileSystemCallbacks,
|
|
8
|
+
export type { ConnectOptions, DaemonConnection, RuntimeOptions, RemoteRuntime, RemoteFetchHandle, RemoteTimersHandle, RemoteConsoleHandle, RemoteTestEnvironmentHandle, RemotePlaywrightHandle, DispatchOptions, ConsoleCallbacks, FetchCallback, FileSystemCallbacks, PlaywrightOptions, PlaywrightEvent, TestEnvironmentOptions, RunResults, TestResult, TestInfo, TestError, TestEvent, SuiteInfo, SuiteResult, CollectedData, ConsoleEntry, } from "./types.ts";
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Types for the isolate client.
|
|
3
3
|
*/
|
|
4
|
-
import type { RunTestsResult, TestResult as ProtocolTestResult,
|
|
5
|
-
export type
|
|
4
|
+
import type { RunTestsResult, TestResult as ProtocolTestResult, TestInfo as ProtocolTestInfo, TestError as ProtocolTestError, TestEvent as ProtocolTestEvent, SuiteInfo as ProtocolSuiteInfo, SuiteResult as ProtocolSuiteResult, CollectedData as ProtocolCollectedData, ConsoleEntry as ProtocolConsoleEntry, PlaywrightEvent as ProtocolPlaywrightEvent, CustomFunctionType } from "@ricsam/isolate-protocol";
|
|
5
|
+
export type RunResults = RunTestsResult;
|
|
6
6
|
export type TestResult = ProtocolTestResult;
|
|
7
|
-
export type
|
|
7
|
+
export type TestInfo = ProtocolTestInfo;
|
|
8
|
+
export type TestError = ProtocolTestError;
|
|
9
|
+
export type TestEvent = ProtocolTestEvent;
|
|
10
|
+
export type SuiteInfo = ProtocolSuiteInfo;
|
|
11
|
+
export type SuiteResult = ProtocolSuiteResult;
|
|
8
12
|
export type CollectedData = ProtocolCollectedData;
|
|
13
|
+
export type ConsoleEntry = ProtocolConsoleEntry;
|
|
14
|
+
export type PlaywrightEvent = ProtocolPlaywrightEvent;
|
|
9
15
|
/**
|
|
10
16
|
* Options for connecting to the daemon.
|
|
11
17
|
*/
|
|
@@ -30,29 +36,63 @@ export interface DaemonConnection {
|
|
|
30
36
|
/** Check if connected */
|
|
31
37
|
isConnected(): boolean;
|
|
32
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Test environment options for createRuntime.
|
|
41
|
+
*/
|
|
42
|
+
export interface TestEnvironmentOptions {
|
|
43
|
+
/** Receive test lifecycle events */
|
|
44
|
+
onEvent?: (event: TestEvent) => void;
|
|
45
|
+
/** Timeout for individual tests (ms) */
|
|
46
|
+
testTimeout?: number;
|
|
47
|
+
}
|
|
33
48
|
/**
|
|
34
49
|
* Options for creating a runtime.
|
|
35
50
|
*/
|
|
36
51
|
export interface RuntimeOptions {
|
|
37
|
-
/** Memory limit in
|
|
38
|
-
|
|
52
|
+
/** Memory limit in megabytes (optional) */
|
|
53
|
+
memoryLimitMB?: number;
|
|
39
54
|
/** Console callback handlers */
|
|
40
55
|
console?: ConsoleCallbacks;
|
|
41
56
|
/** Fetch callback handler */
|
|
42
57
|
fetch?: FetchCallback;
|
|
43
58
|
/** File system callback handlers */
|
|
44
59
|
fs?: FileSystemCallbacks;
|
|
60
|
+
/** Module loader callback for resolving dynamic imports */
|
|
61
|
+
moduleLoader?: ModuleLoaderCallback;
|
|
62
|
+
/** Custom functions callable from within the isolate */
|
|
63
|
+
customFunctions?: CustomFunctions;
|
|
64
|
+
/** Current working directory for path.resolve(). Defaults to "/" */
|
|
65
|
+
cwd?: string;
|
|
66
|
+
/** Enable test environment (describe, it, expect, etc.) */
|
|
67
|
+
testEnvironment?: boolean | TestEnvironmentOptions;
|
|
68
|
+
/** Playwright options - user provides page */
|
|
69
|
+
playwright?: PlaywrightOptions;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Options for Playwright integration.
|
|
73
|
+
* User provides the page object - client owns the browser.
|
|
74
|
+
*/
|
|
75
|
+
export interface PlaywrightOptions {
|
|
76
|
+
/** Playwright page object */
|
|
77
|
+
page: import("playwright").Page;
|
|
78
|
+
/** Default timeout for operations in ms */
|
|
79
|
+
timeout?: number;
|
|
80
|
+
/** Base URL for navigation */
|
|
81
|
+
baseUrl?: string;
|
|
82
|
+
/** If true, browser console logs are routed through console handler (or printed to stdout if no handler) */
|
|
83
|
+
console?: boolean;
|
|
84
|
+
/** Unified event callback for all playwright events */
|
|
85
|
+
onEvent?: (event: PlaywrightEvent) => void;
|
|
45
86
|
}
|
|
46
87
|
/**
|
|
47
|
-
* Console callback handlers.
|
|
88
|
+
* Console callback handlers with single structured callback.
|
|
48
89
|
*/
|
|
49
90
|
export interface ConsoleCallbacks {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
dir?: (...args: unknown[]) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Callback invoked for each console operation.
|
|
93
|
+
* Receives a structured entry with all data needed to render the output.
|
|
94
|
+
*/
|
|
95
|
+
onEntry?: (entry: ConsoleEntry) => void;
|
|
56
96
|
}
|
|
57
97
|
/**
|
|
58
98
|
* Fetch callback type.
|
|
@@ -77,33 +117,169 @@ export interface FileSystemCallbacks {
|
|
|
77
117
|
}>;
|
|
78
118
|
rename?: (from: string, to: string) => Promise<void>;
|
|
79
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Module loader callback type.
|
|
122
|
+
* Called when the isolate imports a module dynamically.
|
|
123
|
+
* Returns the JavaScript source code for the module.
|
|
124
|
+
*/
|
|
125
|
+
export type ModuleLoaderCallback = (moduleName: string) => string | Promise<string>;
|
|
126
|
+
export type { CustomFunctionType };
|
|
127
|
+
/**
|
|
128
|
+
* A custom function that can be called from within the isolate.
|
|
129
|
+
*/
|
|
130
|
+
export type CustomFunction = (...args: unknown[]) => unknown | Promise<unknown>;
|
|
131
|
+
/**
|
|
132
|
+
* An async generator function that can be consumed in the isolate via for await...of.
|
|
133
|
+
*/
|
|
134
|
+
export type CustomAsyncGeneratorFunction = (...args: unknown[]) => AsyncGenerator<unknown, unknown, unknown>;
|
|
135
|
+
/**
|
|
136
|
+
* Custom function definition with metadata.
|
|
137
|
+
*/
|
|
138
|
+
export interface CustomFunctionDefinition {
|
|
139
|
+
/** The function implementation */
|
|
140
|
+
fn: CustomFunction | CustomAsyncGeneratorFunction;
|
|
141
|
+
/** Function type: 'sync', 'async', or 'asyncIterator' */
|
|
142
|
+
type: CustomFunctionType;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Custom functions to register in the runtime.
|
|
146
|
+
*/
|
|
147
|
+
export type CustomFunctions = Record<string, CustomFunctionDefinition>;
|
|
148
|
+
/**
|
|
149
|
+
* Options for eval() method.
|
|
150
|
+
*/
|
|
151
|
+
export interface EvalOptions {
|
|
152
|
+
/** Filename for stack traces */
|
|
153
|
+
filename?: string;
|
|
154
|
+
/** Maximum execution time in milliseconds. If exceeded, throws a timeout error. */
|
|
155
|
+
maxExecutionMs?: number;
|
|
156
|
+
/**
|
|
157
|
+
* @deprecated Always uses module mode now. This option is ignored.
|
|
158
|
+
*/
|
|
159
|
+
module?: boolean;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* WebSocket upgrade request info.
|
|
163
|
+
*/
|
|
164
|
+
export interface UpgradeRequest {
|
|
165
|
+
requested: true;
|
|
166
|
+
connectionId: string;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* WebSocket command from isolate.
|
|
170
|
+
*/
|
|
171
|
+
export interface WebSocketCommand {
|
|
172
|
+
type: "message" | "close";
|
|
173
|
+
connectionId: string;
|
|
174
|
+
data?: string | ArrayBuffer;
|
|
175
|
+
code?: number;
|
|
176
|
+
reason?: string;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Remote fetch handle - provides access to fetch/serve operations.
|
|
180
|
+
* All methods are async since they communicate over IPC.
|
|
181
|
+
*/
|
|
182
|
+
export interface RemoteFetchHandle {
|
|
183
|
+
/** Dispatch HTTP request to serve() handler */
|
|
184
|
+
dispatchRequest(request: Request, options?: DispatchOptions): Promise<Response>;
|
|
185
|
+
/** Check if isolate requested WebSocket upgrade */
|
|
186
|
+
getUpgradeRequest(): Promise<UpgradeRequest | null>;
|
|
187
|
+
/** Dispatch WebSocket open event to isolate */
|
|
188
|
+
dispatchWebSocketOpen(connectionId: string): Promise<void>;
|
|
189
|
+
/** Dispatch WebSocket message event to isolate */
|
|
190
|
+
dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): Promise<void>;
|
|
191
|
+
/** Dispatch WebSocket close event to isolate */
|
|
192
|
+
dispatchWebSocketClose(connectionId: string, code: number, reason: string): Promise<void>;
|
|
193
|
+
/** Dispatch WebSocket error event to isolate */
|
|
194
|
+
dispatchWebSocketError(connectionId: string, error: Error): Promise<void>;
|
|
195
|
+
/** Register callback for WebSocket commands from isolate */
|
|
196
|
+
onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void;
|
|
197
|
+
/** Check if serve() has been called */
|
|
198
|
+
hasServeHandler(): Promise<boolean>;
|
|
199
|
+
/** Check if there are active WebSocket connections */
|
|
200
|
+
hasActiveConnections(): Promise<boolean>;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Remote timers handle - provides access to timer operations.
|
|
204
|
+
* Timers fire automatically based on real time.
|
|
205
|
+
* All methods are async since they communicate over IPC.
|
|
206
|
+
*/
|
|
207
|
+
export interface RemoteTimersHandle {
|
|
208
|
+
/** Clear all pending timers */
|
|
209
|
+
clearAll(): Promise<void>;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Remote console handle - provides access to console state.
|
|
213
|
+
* All methods are async since they communicate over IPC.
|
|
214
|
+
*/
|
|
215
|
+
export interface RemoteConsoleHandle {
|
|
216
|
+
/** Reset all console state (timers, counters, group depth) */
|
|
217
|
+
reset(): Promise<void>;
|
|
218
|
+
/** Get console.time() timers */
|
|
219
|
+
getTimers(): Promise<Map<string, number>>;
|
|
220
|
+
/** Get console.count() counters */
|
|
221
|
+
getCounters(): Promise<Map<string, number>>;
|
|
222
|
+
/** Get current console.group() nesting depth */
|
|
223
|
+
getGroupDepth(): Promise<number>;
|
|
224
|
+
}
|
|
80
225
|
/**
|
|
81
226
|
* Remote runtime handle.
|
|
82
227
|
*/
|
|
83
228
|
export interface RemoteRuntime {
|
|
84
|
-
/**
|
|
229
|
+
/** Unique runtime identifier */
|
|
230
|
+
readonly id: string;
|
|
231
|
+
/**
|
|
232
|
+
* @deprecated Use id instead
|
|
233
|
+
*/
|
|
85
234
|
readonly isolateId: string;
|
|
86
|
-
/**
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
235
|
+
/** Fetch handle - access to fetch/serve operations */
|
|
236
|
+
readonly fetch: RemoteFetchHandle;
|
|
237
|
+
/** Timers handle - access to timer operations */
|
|
238
|
+
readonly timers: RemoteTimersHandle;
|
|
239
|
+
/** Console handle - access to console state */
|
|
240
|
+
readonly console: RemoteConsoleHandle;
|
|
241
|
+
/** Test environment handle (methods throw if not enabled) */
|
|
242
|
+
readonly testEnvironment: RemoteTestEnvironmentHandle;
|
|
243
|
+
/** Playwright handle (methods throw if not configured) */
|
|
244
|
+
readonly playwright: RemotePlaywrightHandle;
|
|
245
|
+
/**
|
|
246
|
+
* Execute code as ES module in the isolate.
|
|
247
|
+
* Supports top-level await.
|
|
248
|
+
* @param code - The code to execute
|
|
249
|
+
* @param filename - Optional filename for stack traces
|
|
250
|
+
*/
|
|
251
|
+
eval(code: string, filename?: string): Promise<void>;
|
|
252
|
+
/**
|
|
253
|
+
* @deprecated Use the new signature: eval(code: string, filename?: string)
|
|
254
|
+
*/
|
|
255
|
+
eval(code: string, options?: EvalOptions): Promise<void>;
|
|
104
256
|
/** Dispose the runtime */
|
|
105
257
|
dispose(): Promise<void>;
|
|
106
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Remote test environment handle.
|
|
261
|
+
* All methods are async since they communicate over IPC.
|
|
262
|
+
*/
|
|
263
|
+
export interface RemoteTestEnvironmentHandle {
|
|
264
|
+
/** Run all registered tests and return results */
|
|
265
|
+
runTests(timeout?: number): Promise<RunResults>;
|
|
266
|
+
/** Check if any tests are registered */
|
|
267
|
+
hasTests(): Promise<boolean>;
|
|
268
|
+
/** Get count of registered tests */
|
|
269
|
+
getTestCount(): Promise<number>;
|
|
270
|
+
/** Reset test environment state */
|
|
271
|
+
reset(): Promise<void>;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Remote playwright handle - provides access to browser data collection.
|
|
275
|
+
* All methods are async since they communicate over IPC.
|
|
276
|
+
*/
|
|
277
|
+
export interface RemotePlaywrightHandle {
|
|
278
|
+
/** Get collected browser console logs and network data */
|
|
279
|
+
getCollectedData(): Promise<CollectedData>;
|
|
280
|
+
/** Clear collected data */
|
|
281
|
+
clearCollectedData(): Promise<void>;
|
|
282
|
+
}
|
|
107
283
|
/**
|
|
108
284
|
* Options for dispatching a request.
|
|
109
285
|
*/
|
|
@@ -111,54 +287,3 @@ export interface DispatchOptions {
|
|
|
111
287
|
/** Request timeout in ms */
|
|
112
288
|
timeout?: number;
|
|
113
289
|
}
|
|
114
|
-
/**
|
|
115
|
-
* Options for setting up Playwright.
|
|
116
|
-
*/
|
|
117
|
-
export interface PlaywrightSetupOptions {
|
|
118
|
-
/** Browser type to use */
|
|
119
|
-
browserType?: "chromium" | "firefox" | "webkit";
|
|
120
|
-
/** Run browser in headless mode */
|
|
121
|
-
headless?: boolean;
|
|
122
|
-
/** Base URL for navigation */
|
|
123
|
-
baseURL?: string;
|
|
124
|
-
/** Console log event handler */
|
|
125
|
-
onConsoleLog?: (log: {
|
|
126
|
-
level: string;
|
|
127
|
-
args: unknown[];
|
|
128
|
-
}) => void;
|
|
129
|
-
/** Network request event handler */
|
|
130
|
-
onNetworkRequest?: (request: {
|
|
131
|
-
url: string;
|
|
132
|
-
method: string;
|
|
133
|
-
headers: Record<string, string>;
|
|
134
|
-
timestamp: number;
|
|
135
|
-
}) => void;
|
|
136
|
-
/** Network response event handler */
|
|
137
|
-
onNetworkResponse?: (response: {
|
|
138
|
-
url: string;
|
|
139
|
-
status: number;
|
|
140
|
-
headers: Record<string, string>;
|
|
141
|
-
timestamp: number;
|
|
142
|
-
}) => void;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Handler for Playwright events streamed from daemon.
|
|
146
|
-
*/
|
|
147
|
-
export interface PlaywrightEventHandler {
|
|
148
|
-
onConsoleLog?: (log: {
|
|
149
|
-
level: string;
|
|
150
|
-
args: unknown[];
|
|
151
|
-
}) => void;
|
|
152
|
-
onNetworkRequest?: (request: {
|
|
153
|
-
url: string;
|
|
154
|
-
method: string;
|
|
155
|
-
headers: Record<string, string>;
|
|
156
|
-
timestamp: number;
|
|
157
|
-
}) => void;
|
|
158
|
-
onNetworkResponse?: (response: {
|
|
159
|
-
url: string;
|
|
160
|
-
status: number;
|
|
161
|
-
headers: Record<string, string>;
|
|
162
|
-
timestamp: number;
|
|
163
|
-
}) => void;
|
|
164
|
-
}
|