@execbox/quickjs 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +38 -38
  2. package/dist/index.cjs +23 -309
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +6 -6
  5. package/dist/index.d.cts.map +1 -1
  6. package/dist/index.d.ts +6 -6
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +18 -304
  9. package/dist/index.js.map +1 -1
  10. package/dist/{protocolEndpoint-DGOUVf6J.cjs → protocolEndpoint-BGyrwlr_.cjs} +5 -40
  11. package/dist/protocolEndpoint-BGyrwlr_.cjs.map +1 -0
  12. package/dist/{protocolEndpoint-T_JEz8YY.js → protocolEndpoint-Ceadcq_L.js} +4 -39
  13. package/dist/protocolEndpoint-Ceadcq_L.js.map +1 -0
  14. package/dist/remoteEndpoint.cjs +45 -0
  15. package/dist/remoteEndpoint.cjs.map +1 -0
  16. package/dist/remoteEndpoint.d.cts +29 -0
  17. package/dist/remoteEndpoint.d.cts.map +1 -0
  18. package/dist/remoteEndpoint.d.ts +29 -0
  19. package/dist/remoteEndpoint.d.ts.map +1 -0
  20. package/dist/remoteEndpoint.js +45 -0
  21. package/dist/remoteEndpoint.js.map +1 -0
  22. package/dist/runner/index.cjs +1 -1
  23. package/dist/runner/index.d.cts +2 -2
  24. package/dist/runner/index.d.cts.map +1 -1
  25. package/dist/runner/index.d.ts +2 -2
  26. package/dist/runner/index.d.ts.map +1 -1
  27. package/dist/runner/index.js +1 -1
  28. package/dist/runner/protocolEndpoint.cjs +2 -2
  29. package/dist/runner/protocolEndpoint.d.cts +2 -2
  30. package/dist/runner/protocolEndpoint.d.cts.map +1 -1
  31. package/dist/runner/protocolEndpoint.d.ts +2 -2
  32. package/dist/runner/protocolEndpoint.d.ts.map +1 -1
  33. package/dist/runner/protocolEndpoint.js +2 -2
  34. package/dist/runner-DRLfwiqY.cjs +348 -0
  35. package/dist/runner-DRLfwiqY.cjs.map +1 -0
  36. package/dist/runner-oZXbguX3.js +343 -0
  37. package/dist/runner-oZXbguX3.js.map +1 -0
  38. package/dist/{types-BeVqrcj8.d.ts → types-C-XfFJ7u.d.cts} +8 -21
  39. package/dist/types-C-XfFJ7u.d.cts.map +1 -0
  40. package/dist/{types-CnNmLawC.d.cts → types-CE7SvejR.d.ts} +8 -21
  41. package/dist/types-CE7SvejR.d.ts.map +1 -0
  42. package/dist/workerEntry.cjs +2 -2
  43. package/dist/workerEntry.js +2 -2
  44. package/package.json +12 -3
  45. package/dist/processEntry.cjs +0 -17
  46. package/dist/processEntry.cjs.map +0 -1
  47. package/dist/processEntry.d.cts +0 -5
  48. package/dist/processEntry.d.ts +0 -5
  49. package/dist/processEntry.js +0 -18
  50. package/dist/processEntry.js.map +0 -1
  51. package/dist/protocolEndpoint-DGOUVf6J.cjs.map +0 -1
  52. package/dist/protocolEndpoint-T_JEz8YY.js.map +0 -1
  53. package/dist/runner-CteKTaPD.js +0 -5654
  54. package/dist/runner-CteKTaPD.js.map +0 -1
  55. package/dist/runner-DRt0kpEk.cjs +0 -5707
  56. package/dist/runner-DRt0kpEk.cjs.map +0 -1
  57. package/dist/types-BeVqrcj8.d.ts.map +0 -1
  58. package/dist/types-CnNmLawC.d.cts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["isExecuteFailure","normalizeThrownMessage","getExecutionTimeoutMessage","createExecutionContext","isJsonSerializable","ExecuteFailure","DEFAULT_POOL_OPTIONS: Required<ExecutorPoolOptions>","resolveExecutorRuntimeOptions","closeReason: TransportCloseReason | undefined","resolvePoolOptions","leases: Array<{\n release: (reusable: boolean) => Promise<void>;\n value: ProcessShell;\n }>","createTimeoutExecuteResult","child: ChildProcess","closeReason: TransportCloseReason | undefined","Worker","leases: Array<{\n release: (reusable: boolean) => Promise<void>;\n value: WorkerShell;\n }>","createTimeoutExecuteResult","createTimeoutExecuteResult","runQuickJsSession"],"sources":["../../core/src/runner.ts","../src/hosted/shared.ts","../src/hosted/processHostedExecutor.ts","../src/hosted/workerHostedExecutor.ts","../src/quickjsExecutor.ts"],"sourcesContent":["import {\n createExecutionContext,\n getExecutionTimeoutMessage,\n normalizeThrownMessage,\n} from \"./executor/shared.ts\";\nimport {\n ExecuteFailure,\n isExecuteFailure,\n isJsonSerializable,\n} from \"./errors.ts\";\nimport type { ExecuteError, ResolvedToolProvider } from \"./types.ts\";\n\n/**\n * Transport-safe metadata for one exposed tool.\n */\nexport interface ProviderToolManifest {\n description?: string;\n originalName: string;\n safeName: string;\n}\n\n/**\n * Namespace manifest shared with runner implementations.\n */\nexport interface ProviderManifest {\n name: string;\n tools: Record<string, ProviderToolManifest>;\n types: string;\n}\n\n/**\n * Execution limits forwarded to runner implementations.\n */\nexport interface ExecutorRuntimeOptions {\n maxLogChars?: number;\n maxLogLines?: number;\n memoryLimitBytes?: number;\n timeoutMs?: number;\n}\n\n/**\n * Public execution options accepted by executors per call.\n */\nexport interface ExecutionOptions extends ExecutorRuntimeOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Tool invocation request emitted from a runner.\n */\nexport interface ToolCall {\n input: unknown;\n providerName: string;\n safeToolName: string;\n}\n\n/**\n * Trusted host response to a tool invocation request.\n */\nexport type ToolCallResult =\n | {\n ok: true;\n result: unknown;\n }\n | {\n error: ExecuteError;\n ok: false;\n };\n\nfunction toTrustedExecuteError(error: unknown): ExecuteError {\n if (isExecuteFailure(error)) {\n return {\n code: error.code,\n message: error.message,\n };\n }\n\n return {\n code: \"tool_error\",\n message: normalizeThrownMessage(error),\n };\n}\n\n/**\n * Converts resolved providers into manifest metadata that reveals only namespace details.\n */\nexport function extractProviderManifests(\n providers: ResolvedToolProvider[],\n): ProviderManifest[] {\n return providers.map((provider) => ({\n name: provider.name,\n tools: Object.fromEntries(\n Object.entries(provider.tools).map(([safeToolName, descriptor]) => [\n safeToolName,\n {\n description: descriptor.description,\n originalName: descriptor.originalName,\n safeName: descriptor.safeName,\n },\n ]),\n ),\n types: provider.types,\n }));\n}\n\n/**\n * Creates a host-side dispatcher for runner-emitted tool calls.\n */\nexport function createToolCallDispatcher(\n providers: ResolvedToolProvider[],\n signal: AbortSignal,\n): (call: ToolCall) => Promise<ToolCallResult> {\n const providerMap = new Map(\n providers.map((provider) => [provider.name, provider] as const),\n );\n\n return async (call) => {\n const provider = providerMap.get(call.providerName);\n const descriptor = provider?.tools[call.safeToolName];\n\n if (!provider || !descriptor) {\n return {\n error: {\n code: \"internal_error\",\n message: `Unknown tool ${call.providerName}.${call.safeToolName}`,\n },\n ok: false,\n };\n }\n\n try {\n if (signal.aborted) {\n return {\n error: {\n code: \"timeout\",\n message: getExecutionTimeoutMessage(),\n },\n ok: false,\n };\n }\n\n const result = await descriptor.execute(\n call.input,\n createExecutionContext(\n signal,\n provider.name,\n descriptor.safeName,\n descriptor.originalName,\n ),\n );\n\n if (result !== undefined && !isJsonSerializable(result)) {\n throw new ExecuteFailure(\n \"serialization_error\",\n \"Host value is not JSON-serializable\",\n );\n }\n\n return {\n ok: true,\n result,\n };\n } catch (error) {\n return {\n error: toTrustedExecuteError(error),\n ok: false,\n };\n }\n };\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport {\n runHostTransportSession,\n type HostTransport,\n} from \"@execbox/core/protocol\";\nimport type { ExecutorPoolOptions } from \"@execbox/core\";\nimport {\n resolveExecutorRuntimeOptions,\n type ExecutionOptions,\n type ExecuteResult,\n type ExecutorRuntimeOptions,\n type ResolvedToolProvider,\n} from \"../../../core/src/runtime.ts\";\n\n/**\n * Default grace period before a hosted shell is forcefully terminated.\n */\nconst DEFAULT_CANCEL_GRACE_MS = 25;\n\n/**\n * Default pooling limits shared by the hosted QuickJS executors.\n */\nconst DEFAULT_POOL_OPTIONS: Required<ExecutorPoolOptions> = {\n idleTimeoutMs: 30_000,\n maxSize: 1,\n minSize: 0,\n prewarm: false,\n};\n\n/**\n * Minimal code used to warm a hosted shell without touching user providers.\n */\nconst DEFAULT_PREWARM_CODE = \"undefined\";\n\nexport { DEFAULT_CANCEL_GRACE_MS, DEFAULT_POOL_OPTIONS, DEFAULT_PREWARM_CODE };\n\n/**\n * Wraps a transport so warmup and pooled execution can borrow it without\n * taking ownership of its lifecycle.\n */\nexport function createBorrowedTransport(\n transport: HostTransport,\n): HostTransport {\n return {\n dispose() {},\n onClose: transport.onClose,\n onError: transport.onError,\n onMessage: transport.onMessage,\n send: transport.send,\n terminate: transport.terminate,\n };\n}\n\n/**\n * Resolves how many pooled shells should be prewarmed from the pool settings.\n */\nexport function getPrewarmCount(pool: ExecutorPoolOptions | undefined): number {\n if (!pool?.prewarm) {\n return 0;\n }\n\n if (typeof pool.prewarm === \"number\") {\n return Math.max(0, Math.min(pool.prewarm, pool.maxSize));\n }\n\n return Math.max(1, Math.min(pool.minSize ?? 1, pool.maxSize));\n}\n\n/**\n * Caps an explicit warmup request to the configured pool boundaries.\n */\nexport function getWarmupTarget(\n count: number | undefined,\n poolOptions: ExecutorPoolOptions,\n): number {\n return Math.max(\n 0,\n Math.min(count ?? poolOptions.minSize ?? 0, poolOptions.maxSize),\n );\n}\n\n/**\n * Returns whether a hosted execution result is safe to return to a pool.\n */\nexport function isReusableResult(result: ExecuteResult): boolean {\n return (\n result.ok || ![\"internal_error\", \"timeout\"].includes(result.error.code)\n );\n}\n\n/**\n * Normalizes a failed warmup result into an actionable host-side error.\n */\nexport function toWarmupError(label: string, result: ExecuteResult): Error {\n if (result.ok) {\n return new Error(`Failed to prewarm pooled ${label}`);\n }\n\n return new Error(\n `Failed to prewarm pooled ${label}: ${result.error.message}`,\n );\n}\n\n/**\n * Runs one transport-backed execution session with resolved runtime limits and\n * a fresh execution identifier.\n */\nexport async function runHostedTransportSession(options: {\n cancelGraceMs: number;\n code: string;\n executorOptions: ExecutorRuntimeOptions;\n onSettled?: (result: ExecuteResult) => Promise<void> | void;\n providers: ResolvedToolProvider[];\n requestOptions?: ExecutionOptions;\n transport: HostTransport;\n}): Promise<ExecuteResult> {\n return await runHostTransportSession({\n cancelGraceMs: options.cancelGraceMs,\n code: options.code,\n executionId: randomUUID(),\n onSettled: options.onSettled,\n providers: options.providers,\n runtimeOptions: resolveExecutorRuntimeOptions(\n options.executorOptions,\n options.requestOptions,\n ),\n signal: options.requestOptions?.signal,\n transport: options.transport,\n });\n}\n\n/**\n * Exercises a set of leased shells with a warmup run and releases each lease\n * according to the warmup result.\n */\nexport async function warmHostedPool<Shell>(options: {\n count: number;\n getTransport: (shell: Shell) => HostTransport;\n label: string;\n onRelease: (shell: Shell, reusable: boolean) => Promise<void>;\n runSession: (\n transport: HostTransport,\n code: string,\n providers: ResolvedToolProvider[],\n ) => Promise<ExecuteResult>;\n shells: Shell[];\n}): Promise<void> {\n const results = await Promise.allSettled(\n options.shells.map(async (shell) => {\n let reusable = false;\n\n try {\n const result = await options.runSession(\n createBorrowedTransport(options.getTransport(shell)),\n DEFAULT_PREWARM_CODE,\n [],\n );\n reusable = result.ok;\n if (!result.ok) {\n throw toWarmupError(options.label, result);\n }\n } finally {\n await options.onRelease(shell, reusable);\n }\n }),\n );\n\n const rejected = results.find((result) => result.status === \"rejected\");\n if (rejected?.status === \"rejected\") {\n throw rejected.reason;\n }\n}\n","import { fork, type ChildProcess } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\n\nimport {\n createResourcePool,\n getNodeTransportExecArgv,\n type HostTransport,\n type ResourcePool,\n type RunnerMessage,\n type TransportCloseReason,\n} from \"@execbox/core/protocol\";\nimport {\n createTimeoutExecuteResult,\n type ExecutionOptions,\n type Executor,\n type ExecuteResult,\n type ResolvedToolProvider,\n} from \"../../../core/src/runtime.ts\";\nimport type { ExecutorPoolOptions } from \"@execbox/core\";\n\nimport type { QuickJsProcessExecutorOptions } from \"../types.ts\";\nimport {\n DEFAULT_CANCEL_GRACE_MS,\n DEFAULT_POOL_OPTIONS,\n createBorrowedTransport,\n getPrewarmCount,\n getWarmupTarget,\n isReusableResult,\n runHostedTransportSession,\n warmHostedPool,\n} from \"./shared.ts\";\n\ninterface ProcessShell {\n child: ChildProcess;\n transport: HostTransport;\n}\n\nfunction resolveProcessEntryPath(): string {\n const extension = import.meta.url.endsWith(\".ts\") ? \".ts\" : \".js\";\n return fileURLToPath(new URL(`../processEntry${extension}`, import.meta.url));\n}\n\nfunction createUnexpectedExitMessage(\n code: number | null,\n signal: NodeJS.Signals | null,\n): string {\n if (code !== null) {\n return `Child process exited unexpectedly with code ${code}`;\n }\n\n if (signal) {\n return `Child process exited unexpectedly with signal ${signal}`;\n }\n\n return \"Child process exited unexpectedly\";\n}\n\nfunction createChildProcess(): ChildProcess {\n return fork(resolveProcessEntryPath(), [], {\n execArgv: getNodeTransportExecArgv(import.meta.url),\n stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"],\n });\n}\n\nfunction createProcessTransport(child: ChildProcess): HostTransport {\n let terminated = false;\n let closeReason: TransportCloseReason | undefined;\n const closeHandlers = new Set<(reason?: TransportCloseReason) => void>();\n const errorHandlers = new Set<(error: Error) => void>();\n const messageHandlers = new Set<(message: RunnerMessage) => void>();\n\n const terminateChild = () => {\n if (terminated) {\n return;\n }\n\n terminated = true;\n child.kill(\"SIGKILL\");\n };\n\n const notifyClose = (reason: TransportCloseReason) => {\n if (closeReason) {\n return;\n }\n\n closeReason = reason;\n for (const handler of closeHandlers) {\n handler(reason);\n }\n };\n\n const onDisconnect = () => {\n notifyClose({\n message: \"Child process disconnected unexpectedly\",\n });\n };\n const onExit = (code: number | null, signal: NodeJS.Signals | null) => {\n notifyClose({\n code,\n message: createUnexpectedExitMessage(code, signal),\n signal,\n });\n };\n const onError = (error: Error) => {\n for (const handler of errorHandlers) {\n handler(error);\n }\n };\n const onMessage = (message: unknown) => {\n for (const handler of messageHandlers) {\n handler(message as RunnerMessage);\n }\n };\n\n child.on(\"disconnect\", onDisconnect);\n child.on(\"exit\", onExit);\n child.on(\"error\", onError);\n child.on(\"message\", onMessage);\n\n return {\n dispose: () => {\n child.off(\"disconnect\", onDisconnect);\n child.off(\"exit\", onExit);\n child.off(\"error\", onError);\n child.off(\"message\", onMessage);\n terminateChild();\n },\n onClose: (handler) => {\n closeHandlers.add(handler);\n if (closeReason) {\n queueMicrotask(() => {\n if (closeHandlers.has(handler)) {\n handler(closeReason);\n }\n });\n }\n return () => {\n closeHandlers.delete(handler);\n };\n },\n onError: (handler) => {\n errorHandlers.add(handler);\n return () => errorHandlers.delete(handler);\n },\n onMessage: (handler) => {\n messageHandlers.add(handler);\n return () => messageHandlers.delete(handler);\n },\n send: (message) =>\n new Promise<void>((resolve, reject) => {\n if (!child.connected || typeof child.send !== \"function\") {\n reject(new Error(\"Child process disconnected unexpectedly\"));\n return;\n }\n\n child.send(message, (error) => {\n if (error) {\n reject(error);\n return;\n }\n\n resolve();\n });\n }),\n terminate: () => {\n terminateChild();\n },\n };\n}\n\nfunction createProcessShell(): ProcessShell {\n const child = createChildProcess();\n return {\n child,\n transport: createProcessTransport(child),\n };\n}\n\nfunction resolvePoolOptions(\n options: QuickJsProcessExecutorOptions,\n): ExecutorPoolOptions | undefined {\n if (options.mode === \"ephemeral\") {\n return undefined;\n }\n\n return {\n ...DEFAULT_POOL_OPTIONS,\n ...options.pool,\n };\n}\n\n/**\n * Child-process executor that runs guest code inside a dedicated QuickJS runtime per call.\n */\nexport class ProcessHostedQuickJsExecutor implements Executor {\n private readonly cancelGraceMs: number;\n private readonly options: QuickJsProcessExecutorOptions;\n private readonly pool: ResourcePool<ProcessShell> | undefined;\n private readonly poolOptions: ExecutorPoolOptions | undefined;\n private readonly warmup: Promise<void> | undefined;\n\n /**\n * Creates a hosted QuickJS executor that launches child-process shells on demand.\n */\n constructor(options: QuickJsProcessExecutorOptions) {\n this.cancelGraceMs = options.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;\n this.options = options;\n const poolOptions = resolvePoolOptions(options);\n this.poolOptions = poolOptions;\n\n if (poolOptions) {\n this.pool = createResourcePool({\n create: async () => createProcessShell(),\n destroy: async (shell) => {\n await shell.transport.dispose();\n },\n idleTimeoutMs: poolOptions.idleTimeoutMs,\n maxSize: poolOptions.maxSize,\n minSize: poolOptions.minSize,\n });\n const prewarmCount = getPrewarmCount(poolOptions);\n if (prewarmCount > 0) {\n this.warmup = this.warmPool(prewarmCount);\n }\n }\n }\n\n /**\n * Disposes any pooled child-process shells owned by this executor.\n */\n async dispose(): Promise<void> {\n await this.pool?.dispose();\n }\n\n /**\n * Prewarms pooled child-process shells up to the requested count.\n */\n async prewarm(count?: number): Promise<void> {\n if (!this.pool || !this.poolOptions) {\n return;\n }\n\n const target = getWarmupTarget(count, this.poolOptions);\n if (target <= 0) {\n return;\n }\n\n await this.warmPool(target);\n }\n\n private async runTransportSession(\n transport: HostTransport,\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n onSettled?: (result: ExecuteResult) => Promise<void> | void,\n ): Promise<ExecuteResult> {\n return await runHostedTransportSession({\n cancelGraceMs: this.cancelGraceMs,\n code,\n executorOptions: this.options,\n onSettled,\n providers,\n requestOptions: options,\n transport,\n });\n }\n\n private async warmPool(count: number): Promise<void> {\n if (!this.pool) {\n return;\n }\n\n await this.pool.prewarm(count);\n\n const leases: Array<{\n release: (reusable: boolean) => Promise<void>;\n value: ProcessShell;\n }> = [];\n try {\n for (let index = 0; index < count; index += 1) {\n leases.push(await this.pool.acquire());\n }\n } catch (error) {\n await Promise.allSettled(\n leases.map(async (lease) => await lease.release(false)),\n );\n throw error;\n }\n\n await warmHostedPool({\n count,\n getTransport: (lease) => lease.value.transport,\n label: \"child process\",\n onRelease: async (lease, reusable) => await lease.release(reusable),\n runSession: async (transport, code, providers) =>\n await this.runTransportSession(transport, code, providers),\n shells: leases,\n });\n }\n\n /**\n * Executes guest code in a child-process-hosted QuickJS shell.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n ): Promise<ExecuteResult> {\n if (options.signal?.aborted) {\n return createTimeoutExecuteResult();\n }\n\n await this.warmup;\n if (this.pool) {\n const lease = await this.pool.acquire();\n\n return await this.runTransportSession(\n createBorrowedTransport(lease.value.transport),\n code,\n providers,\n options,\n async (result) => {\n await lease.release(isReusableResult(result));\n },\n );\n }\n\n let child: ChildProcess;\n\n try {\n child = createChildProcess();\n } catch (error) {\n return {\n durationMs: 0,\n error: {\n code: \"internal_error\",\n message: error instanceof Error ? error.message : String(error),\n },\n logs: [],\n ok: false,\n };\n }\n\n return await this.runTransportSession(\n createProcessTransport(child),\n code,\n providers,\n options,\n );\n }\n}\n","import { availableParallelism } from \"node:os\";\nimport { Worker } from \"node:worker_threads\";\n\nimport {\n createResourcePool,\n getNodeTransportExecArgv,\n type HostTransport,\n type ResourcePool,\n type RunnerMessage,\n type TransportCloseReason,\n} from \"@execbox/core/protocol\";\nimport {\n createTimeoutExecuteResult,\n type ExecutionOptions,\n type Executor,\n type ExecuteResult,\n type ResolvedToolProvider,\n} from \"../../../core/src/runtime.ts\";\nimport type { ExecutorPoolOptions } from \"@execbox/core\";\n\nimport type { QuickJsWorkerExecutorOptions } from \"../types.ts\";\nimport {\n DEFAULT_CANCEL_GRACE_MS,\n DEFAULT_POOL_OPTIONS,\n createBorrowedTransport,\n getPrewarmCount,\n getWarmupTarget,\n isReusableResult,\n runHostedTransportSession,\n warmHostedPool,\n} from \"./shared.ts\";\n\nconst DEFAULT_POOLED_WORKER_MAX_SIZE = 4;\n\ninterface WorkerShell {\n transport: HostTransport;\n worker: Worker;\n}\n\nfunction resolveWorkerEntryUrl(): URL {\n const extension = import.meta.url.endsWith(\".ts\") ? \".ts\" : \".js\";\n return new URL(`../workerEntry${extension}`, import.meta.url);\n}\n\nfunction createWorkerTransport(worker: Worker): HostTransport {\n let terminated = false;\n let closeReason: TransportCloseReason | undefined;\n const closeHandlers = new Set<(reason?: TransportCloseReason) => void>();\n const errorHandlers = new Set<(error: Error) => void>();\n const messageHandlers = new Set<(message: RunnerMessage) => void>();\n\n const terminateWorker = async () => {\n if (terminated) {\n return;\n }\n\n terminated = true;\n await worker.terminate().catch(() => {});\n };\n\n const notifyClose = (reason: TransportCloseReason) => {\n if (closeReason) {\n return;\n }\n\n closeReason = reason;\n for (const handler of closeHandlers) {\n handler(reason);\n }\n };\n\n const onExit = (code: number) => {\n notifyClose({\n code,\n message: `Worker exited unexpectedly with code ${code}`,\n });\n };\n const onError = (error: Error) => {\n for (const handler of errorHandlers) {\n handler(error);\n }\n };\n const onMessage = (message: unknown) => {\n for (const handler of messageHandlers) {\n handler(message as RunnerMessage);\n }\n };\n\n worker.on(\"exit\", onExit);\n worker.on(\"error\", onError);\n worker.on(\"message\", onMessage);\n\n return {\n dispose: async () => {\n worker.off(\"exit\", onExit);\n worker.off(\"error\", onError);\n worker.off(\"message\", onMessage);\n await terminateWorker();\n },\n onClose: (handler) => {\n closeHandlers.add(handler);\n if (closeReason) {\n queueMicrotask(() => {\n if (closeHandlers.has(handler)) {\n handler(closeReason);\n }\n });\n }\n return () => closeHandlers.delete(handler);\n },\n onError: (handler) => {\n errorHandlers.add(handler);\n return () => errorHandlers.delete(handler);\n },\n onMessage: (handler) => {\n messageHandlers.add(handler);\n return () => messageHandlers.delete(handler);\n },\n send: (message) => {\n worker.postMessage(message);\n },\n terminate: async () => {\n await terminateWorker();\n },\n };\n}\n\nfunction createWorkerShell(options: QuickJsWorkerExecutorOptions): WorkerShell {\n const worker = new Worker(resolveWorkerEntryUrl(), {\n execArgv: getNodeTransportExecArgv(import.meta.url),\n resourceLimits: options.workerResourceLimits,\n });\n\n return {\n transport: createWorkerTransport(worker),\n worker,\n };\n}\n\nfunction getDefaultPoolMaxSize(): number {\n try {\n return Math.max(\n 1,\n Math.min(availableParallelism(), DEFAULT_POOLED_WORKER_MAX_SIZE),\n );\n } catch {\n return 1;\n }\n}\n\nfunction resolvePoolOptions(\n options: QuickJsWorkerExecutorOptions,\n): ExecutorPoolOptions | undefined {\n if (options.mode === \"ephemeral\") {\n return undefined;\n }\n\n return {\n ...DEFAULT_POOL_OPTIONS,\n maxSize: getDefaultPoolMaxSize(),\n ...options.pool,\n };\n}\n\n/**\n * Worker-thread executor that runs guest code inside a dedicated QuickJS runtime per call.\n */\nexport class WorkerHostedQuickJsExecutor implements Executor {\n private readonly cancelGraceMs: number;\n private readonly options: QuickJsWorkerExecutorOptions;\n private readonly pool: ResourcePool<WorkerShell> | undefined;\n private readonly poolOptions: ExecutorPoolOptions | undefined;\n private readonly warmup: Promise<void> | undefined;\n\n /**\n * Creates a hosted QuickJS executor that launches worker-thread shells on demand.\n */\n constructor(options: QuickJsWorkerExecutorOptions) {\n this.cancelGraceMs = options.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;\n this.options = options;\n const poolOptions = resolvePoolOptions(options);\n this.poolOptions = poolOptions;\n\n if (poolOptions) {\n this.pool = createResourcePool({\n create: async () => createWorkerShell(options),\n destroy: async (shell) => {\n await shell.transport.dispose();\n },\n idleTimeoutMs: poolOptions.idleTimeoutMs,\n maxSize: poolOptions.maxSize,\n minSize: poolOptions.minSize,\n });\n const prewarmCount = getPrewarmCount(poolOptions);\n if (prewarmCount > 0) {\n this.warmup = this.warmPool(prewarmCount);\n }\n }\n }\n\n /**\n * Disposes any pooled worker-thread shells owned by this executor.\n */\n async dispose(): Promise<void> {\n await this.pool?.dispose();\n }\n\n /**\n * Prewarms pooled worker-thread shells up to the requested count.\n */\n async prewarm(count?: number): Promise<void> {\n if (!this.pool || !this.poolOptions) {\n return;\n }\n\n const target = getWarmupTarget(count, this.poolOptions);\n if (target <= 0) {\n return;\n }\n\n await this.warmPool(target);\n }\n\n private async runTransportSession(\n transport: HostTransport,\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n onSettled?: (result: ExecuteResult) => Promise<void> | void,\n ): Promise<ExecuteResult> {\n return await runHostedTransportSession({\n cancelGraceMs: this.cancelGraceMs,\n code,\n executorOptions: this.options,\n onSettled,\n providers,\n requestOptions: options,\n transport,\n });\n }\n\n private async warmPool(count: number): Promise<void> {\n if (!this.pool) {\n return;\n }\n\n await this.pool.prewarm(count);\n\n const leases: Array<{\n release: (reusable: boolean) => Promise<void>;\n value: WorkerShell;\n }> = [];\n try {\n for (let index = 0; index < count; index += 1) {\n leases.push(await this.pool.acquire());\n }\n } catch (error) {\n await Promise.allSettled(\n leases.map(async (lease) => await lease.release(false)),\n );\n throw error;\n }\n\n await warmHostedPool({\n count,\n getTransport: (lease) => lease.value.transport,\n label: \"worker shell\",\n onRelease: async (lease, reusable) => await lease.release(reusable),\n runSession: async (transport, code, providers) =>\n await this.runTransportSession(transport, code, providers),\n shells: leases,\n });\n }\n\n /**\n * Executes guest code in a worker-thread-hosted QuickJS shell.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n ): Promise<ExecuteResult> {\n if (options.signal?.aborted) {\n return createTimeoutExecuteResult();\n }\n\n await this.warmup;\n if (this.pool) {\n const lease = await this.pool.acquire();\n\n return await this.runTransportSession(\n createBorrowedTransport(lease.value.transport),\n code,\n providers,\n options,\n async (result) => {\n await lease.release(isReusableResult(result));\n },\n );\n }\n\n const worker = new Worker(resolveWorkerEntryUrl(), {\n execArgv: getNodeTransportExecArgv(import.meta.url),\n resourceLimits: this.options.workerResourceLimits,\n });\n\n return await this.runTransportSession(\n createWorkerTransport(worker),\n code,\n providers,\n options,\n );\n }\n}\n","import {\n createTimeoutExecuteResult,\n createToolCallDispatcher,\n extractProviderManifests,\n} from \"../../core/src/runtime.ts\";\nimport type {\n ExecutionOptions,\n ExecuteResult,\n Executor,\n ResolvedToolProvider,\n} from \"@execbox/core\";\n\nimport { ProcessHostedQuickJsExecutor } from \"./hosted/processHostedExecutor.ts\";\nimport { WorkerHostedQuickJsExecutor } from \"./hosted/workerHostedExecutor.ts\";\nimport { runQuickJsSession } from \"./runner/index.ts\";\nimport type {\n QuickJsExecutorOptions,\n QuickJsInlineExecutorOptions,\n QuickJsProcessExecutorOptions,\n QuickJsWorkerExecutorOptions,\n} from \"./types\";\n\nfunction isWorkerOptions(\n options: QuickJsExecutorOptions,\n): options is QuickJsWorkerExecutorOptions {\n return options.host === \"worker\";\n}\n\nfunction isProcessOptions(\n options: QuickJsExecutorOptions,\n): options is QuickJsProcessExecutorOptions {\n return options.host === \"process\";\n}\n\n/**\n * QuickJS-backed executor for inline, worker-backed, or process-backed JavaScript runs.\n */\nexport class QuickJsExecutor implements Executor {\n private readonly hostedExecutor: Executor | undefined;\n private readonly options: QuickJsInlineExecutorOptions | undefined;\n\n /**\n * Creates a QuickJS executor with inline QuickJS by default, or a hosted\n * worker/process shell when `host` is explicitly set.\n */\n constructor(options: QuickJsExecutorOptions = {}) {\n if (isWorkerOptions(options)) {\n this.hostedExecutor = new WorkerHostedQuickJsExecutor(options);\n return;\n }\n\n if (isProcessOptions(options)) {\n this.hostedExecutor = new ProcessHostedQuickJsExecutor(options);\n return;\n }\n\n this.options = options;\n }\n\n /**\n * Disposes any pooled hosted shells owned by this executor.\n */\n async dispose(): Promise<void> {\n await this.hostedExecutor?.dispose?.();\n }\n\n /**\n * Prewarms pooled hosted shells when the executor is running in worker or\n * process mode. Inline mode treats this as a no-op.\n */\n async prewarm(count?: number): Promise<void> {\n await this.hostedExecutor?.prewarm?.(count);\n }\n\n /**\n * Executes JavaScript against the provided tool namespaces in a fresh QuickJS runtime.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n ): Promise<ExecuteResult> {\n if (this.hostedExecutor) {\n return await this.hostedExecutor.execute(code, providers, options);\n }\n\n if (options.signal?.aborted) {\n return createTimeoutExecuteResult();\n }\n\n const abortController = new AbortController();\n const onToolCall = createToolCallDispatcher(\n providers,\n abortController.signal,\n );\n const onAbort = () => {\n abortController.abort();\n };\n\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n try {\n return await runQuickJsSession(\n {\n abortController,\n code,\n onToolCall,\n providers: extractProviderManifests(providers),\n },\n {\n ...this.options,\n ...options,\n },\n );\n } finally {\n options.signal?.removeEventListener(\"abort\", onAbort);\n abortController.abort();\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["DEFAULT_POOL_OPTIONS: Required<ExecutorPoolOptions>","closeReason: TransportCloseReason | undefined","Worker","leases: Array<{\n release: (reusable: boolean) => Promise<void>;\n value: WorkerShell;\n }>","runQuickJsSession"],"sources":["../src/hosted/shared.ts","../src/hosted/workerHostedExecutor.ts","../src/quickjsExecutor.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\n\nimport {\n runHostTransportSession,\n type HostTransport,\n} from \"@execbox/core/protocol\";\nimport type { ExecutorPoolOptions } from \"@execbox/core\";\nimport { resolveExecutorRuntimeOptions } from \"@execbox/core/runtime\";\nimport type {\n ExecutionOptions,\n ExecuteResult,\n ExecutorRuntimeOptions,\n ResolvedToolProvider,\n} from \"@execbox/core\";\n\n/**\n * Default grace period before a worker-hosted shell is forcefully terminated.\n */\nconst DEFAULT_CANCEL_GRACE_MS = 25;\n\n/**\n * Default pooling limits shared by worker-hosted QuickJS executors.\n */\nconst DEFAULT_POOL_OPTIONS: Required<ExecutorPoolOptions> = {\n idleTimeoutMs: 30_000,\n maxSize: 1,\n minSize: 0,\n prewarm: false,\n};\n\n/**\n * Minimal code used to warm a worker shell without touching user providers.\n */\nconst DEFAULT_PREWARM_CODE = \"undefined\";\n\nexport { DEFAULT_CANCEL_GRACE_MS, DEFAULT_POOL_OPTIONS, DEFAULT_PREWARM_CODE };\n\n/**\n * Wraps a transport so warmup and pooled execution can borrow it without\n * taking ownership of its lifecycle.\n */\nexport function createBorrowedTransport(\n transport: HostTransport,\n): HostTransport {\n return {\n dispose() {},\n onClose: transport.onClose,\n onError: transport.onError,\n onMessage: transport.onMessage,\n send: transport.send,\n terminate: transport.terminate,\n };\n}\n\n/**\n * Resolves how many pooled shells should be prewarmed from the pool settings.\n */\nexport function getPrewarmCount(pool: ExecutorPoolOptions | undefined): number {\n if (!pool?.prewarm) {\n return 0;\n }\n\n if (typeof pool.prewarm === \"number\") {\n return Math.max(0, Math.min(pool.prewarm, pool.maxSize));\n }\n\n return Math.max(1, Math.min(pool.minSize ?? 1, pool.maxSize));\n}\n\n/**\n * Caps an explicit warmup request to the configured pool boundaries.\n */\nexport function getWarmupTarget(\n count: number | undefined,\n poolOptions: ExecutorPoolOptions,\n): number {\n return Math.max(\n 0,\n Math.min(count ?? poolOptions.minSize ?? 0, poolOptions.maxSize),\n );\n}\n\n/**\n * Returns whether a hosted execution result is safe to return to a pool.\n */\nexport function isReusableResult(result: ExecuteResult): boolean {\n return (\n result.ok || ![\"internal_error\", \"timeout\"].includes(result.error.code)\n );\n}\n\n/**\n * Normalizes a failed warmup result into an actionable host-side error.\n */\nexport function toWarmupError(label: string, result: ExecuteResult): Error {\n if (result.ok) {\n return new Error(`Failed to prewarm pooled ${label}`);\n }\n\n return new Error(\n `Failed to prewarm pooled ${label}: ${result.error.message}`,\n );\n}\n\n/**\n * Runs one transport-backed execution session with resolved runtime limits and\n * a fresh execution identifier.\n */\nexport async function runHostedTransportSession(options: {\n cancelGraceMs: number;\n code: string;\n executorOptions: ExecutorRuntimeOptions;\n onSettled?: (result: ExecuteResult) => Promise<void> | void;\n providers: ResolvedToolProvider[];\n requestOptions?: ExecutionOptions;\n transport: HostTransport;\n}): Promise<ExecuteResult> {\n return await runHostTransportSession({\n cancelGraceMs: options.cancelGraceMs,\n code: options.code,\n executionId: randomUUID(),\n onSettled: options.onSettled,\n providers: options.providers,\n runtimeOptions: resolveExecutorRuntimeOptions(\n options.executorOptions,\n options.requestOptions,\n ),\n signal: options.requestOptions?.signal,\n transport: options.transport,\n });\n}\n\n/**\n * Exercises a set of leased shells with a warmup run and releases each lease\n * according to the warmup result.\n */\nexport async function warmHostedPool<Shell>(options: {\n count: number;\n getTransport: (shell: Shell) => HostTransport;\n label: string;\n onRelease: (shell: Shell, reusable: boolean) => Promise<void>;\n runSession: (\n transport: HostTransport,\n code: string,\n providers: ResolvedToolProvider[],\n ) => Promise<ExecuteResult>;\n shells: Shell[];\n}): Promise<void> {\n const results = await Promise.allSettled(\n options.shells.map(async (shell) => {\n let reusable = false;\n\n try {\n const result = await options.runSession(\n createBorrowedTransport(options.getTransport(shell)),\n DEFAULT_PREWARM_CODE,\n [],\n );\n reusable = result.ok;\n if (!result.ok) {\n throw toWarmupError(options.label, result);\n }\n } finally {\n await options.onRelease(shell, reusable);\n }\n }),\n );\n\n const rejected = results.find((result) => result.status === \"rejected\");\n if (rejected?.status === \"rejected\") {\n throw rejected.reason;\n }\n}\n","import { availableParallelism } from \"node:os\";\nimport { Worker } from \"node:worker_threads\";\n\nimport {\n createResourcePool,\n getNodeTransportExecArgv,\n type HostTransport,\n type ResourcePool,\n type RunnerMessage,\n type TransportCloseReason,\n} from \"@execbox/core/protocol\";\nimport { createTimeoutExecuteResult } from \"@execbox/core/runtime\";\nimport type {\n ExecutionOptions,\n Executor,\n ExecutorPoolOptions,\n ExecuteResult,\n ResolvedToolProvider,\n} from \"@execbox/core\";\n\nimport type { QuickJsWorkerExecutorOptions } from \"../types.ts\";\nimport {\n DEFAULT_CANCEL_GRACE_MS,\n DEFAULT_POOL_OPTIONS,\n createBorrowedTransport,\n getPrewarmCount,\n getWarmupTarget,\n isReusableResult,\n runHostedTransportSession,\n warmHostedPool,\n} from \"./shared.ts\";\n\nconst DEFAULT_POOLED_WORKER_MAX_SIZE = 4;\n\ninterface WorkerShell {\n transport: HostTransport;\n worker: Worker;\n}\n\nfunction resolveWorkerEntryUrl(): URL {\n const extension = import.meta.url.endsWith(\".ts\") ? \".ts\" : \".js\";\n return new URL(`../workerEntry${extension}`, import.meta.url);\n}\n\nfunction createWorkerTransport(worker: Worker): HostTransport {\n let terminated = false;\n let closeReason: TransportCloseReason | undefined;\n const closeHandlers = new Set<(reason?: TransportCloseReason) => void>();\n const errorHandlers = new Set<(error: Error) => void>();\n const messageHandlers = new Set<(message: RunnerMessage) => void>();\n\n const terminateWorker = async () => {\n if (terminated) {\n return;\n }\n\n terminated = true;\n await worker.terminate().catch(() => {});\n };\n\n const notifyClose = (reason: TransportCloseReason) => {\n if (closeReason) {\n return;\n }\n\n closeReason = reason;\n for (const handler of closeHandlers) {\n handler(reason);\n }\n };\n\n const onExit = (code: number) => {\n notifyClose({\n code,\n message: `Worker exited unexpectedly with code ${code}`,\n });\n };\n const onError = (error: Error) => {\n for (const handler of errorHandlers) {\n handler(error);\n }\n };\n const onMessage = (message: unknown) => {\n for (const handler of messageHandlers) {\n handler(message as RunnerMessage);\n }\n };\n\n worker.on(\"exit\", onExit);\n worker.on(\"error\", onError);\n worker.on(\"message\", onMessage);\n\n return {\n dispose: async () => {\n worker.off(\"exit\", onExit);\n worker.off(\"error\", onError);\n worker.off(\"message\", onMessage);\n await terminateWorker();\n },\n onClose: (handler) => {\n closeHandlers.add(handler);\n if (closeReason) {\n queueMicrotask(() => {\n if (closeHandlers.has(handler)) {\n handler(closeReason);\n }\n });\n }\n return () => closeHandlers.delete(handler);\n },\n onError: (handler) => {\n errorHandlers.add(handler);\n return () => errorHandlers.delete(handler);\n },\n onMessage: (handler) => {\n messageHandlers.add(handler);\n return () => messageHandlers.delete(handler);\n },\n send: (message) => {\n worker.postMessage(message);\n },\n terminate: async () => {\n await terminateWorker();\n },\n };\n}\n\nfunction createWorkerShell(options: QuickJsWorkerExecutorOptions): WorkerShell {\n const worker = new Worker(resolveWorkerEntryUrl(), {\n execArgv: getNodeTransportExecArgv(import.meta.url),\n resourceLimits: options.workerResourceLimits,\n });\n\n return {\n transport: createWorkerTransport(worker),\n worker,\n };\n}\n\nfunction getDefaultPoolMaxSize(): number {\n try {\n return Math.max(\n 1,\n Math.min(availableParallelism(), DEFAULT_POOLED_WORKER_MAX_SIZE),\n );\n } catch {\n return 1;\n }\n}\n\nfunction resolvePoolOptions(\n options: QuickJsWorkerExecutorOptions,\n): ExecutorPoolOptions | undefined {\n if (options.mode === \"ephemeral\") {\n return undefined;\n }\n\n return {\n ...DEFAULT_POOL_OPTIONS,\n maxSize: getDefaultPoolMaxSize(),\n ...options.pool,\n };\n}\n\n/**\n * Worker-thread executor that runs guest code inside a dedicated QuickJS runtime per call.\n */\nexport class WorkerHostedQuickJsExecutor implements Executor {\n private readonly cancelGraceMs: number;\n private readonly options: QuickJsWorkerExecutorOptions;\n private readonly pool: ResourcePool<WorkerShell> | undefined;\n private readonly poolOptions: ExecutorPoolOptions | undefined;\n private readonly warmup: Promise<void> | undefined;\n\n /**\n * Creates a QuickJS executor that launches worker-thread shells on demand.\n */\n constructor(options: QuickJsWorkerExecutorOptions) {\n this.cancelGraceMs = options.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;\n this.options = options;\n const poolOptions = resolvePoolOptions(options);\n this.poolOptions = poolOptions;\n\n if (poolOptions) {\n this.pool = createResourcePool({\n create: async () => createWorkerShell(options),\n destroy: async (shell) => {\n await shell.transport.dispose();\n },\n idleTimeoutMs: poolOptions.idleTimeoutMs,\n maxSize: poolOptions.maxSize,\n minSize: poolOptions.minSize,\n });\n const prewarmCount = getPrewarmCount(poolOptions);\n if (prewarmCount > 0) {\n this.warmup = this.warmPool(prewarmCount);\n }\n }\n }\n\n /**\n * Disposes any pooled worker-thread shells owned by this executor.\n */\n async dispose(): Promise<void> {\n await this.pool?.dispose();\n }\n\n /**\n * Prewarms pooled worker-thread shells up to the requested count.\n */\n async prewarm(count?: number): Promise<void> {\n if (!this.pool || !this.poolOptions) {\n return;\n }\n\n const target = getWarmupTarget(count, this.poolOptions);\n if (target <= 0) {\n return;\n }\n\n await this.warmPool(target);\n }\n\n private async runTransportSession(\n transport: HostTransport,\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n onSettled?: (result: ExecuteResult) => Promise<void> | void,\n ): Promise<ExecuteResult> {\n return await runHostedTransportSession({\n cancelGraceMs: this.cancelGraceMs,\n code,\n executorOptions: this.options,\n onSettled,\n providers,\n requestOptions: options,\n transport,\n });\n }\n\n private async warmPool(count: number): Promise<void> {\n if (!this.pool) {\n return;\n }\n\n await this.pool.prewarm(count);\n\n const leases: Array<{\n release: (reusable: boolean) => Promise<void>;\n value: WorkerShell;\n }> = [];\n try {\n for (let index = 0; index < count; index += 1) {\n leases.push(await this.pool.acquire());\n }\n } catch (error) {\n await Promise.allSettled(\n leases.map(async (lease) => await lease.release(false)),\n );\n throw error;\n }\n\n await warmHostedPool({\n count,\n getTransport: (lease) => lease.value.transport,\n label: \"worker shell\",\n onRelease: async (lease, reusable) => await lease.release(reusable),\n runSession: async (transport, code, providers) =>\n await this.runTransportSession(transport, code, providers),\n shells: leases,\n });\n }\n\n /**\n * Executes guest code in a worker-thread-hosted QuickJS shell.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n ): Promise<ExecuteResult> {\n if (options.signal?.aborted) {\n return createTimeoutExecuteResult();\n }\n\n await this.warmup;\n if (this.pool) {\n const lease = await this.pool.acquire();\n\n return await this.runTransportSession(\n createBorrowedTransport(lease.value.transport),\n code,\n providers,\n options,\n async (result) => {\n await lease.release(isReusableResult(result));\n },\n );\n }\n\n const worker = new Worker(resolveWorkerEntryUrl(), {\n execArgv: getNodeTransportExecArgv(import.meta.url),\n resourceLimits: this.options.workerResourceLimits,\n });\n\n return await this.runTransportSession(\n createWorkerTransport(worker),\n code,\n providers,\n options,\n );\n }\n}\n","import {\n createTimeoutExecuteResult,\n createToolCallDispatcher,\n extractProviderManifests,\n} from \"@execbox/core/runtime\";\nimport type {\n ExecutionOptions,\n ExecuteResult,\n Executor,\n ResolvedToolProvider,\n} from \"@execbox/core\";\n\nimport { WorkerHostedQuickJsExecutor } from \"./hosted/workerHostedExecutor.ts\";\nimport { runQuickJsSession } from \"./runner/index.ts\";\nimport type {\n QuickJsExecutorOptions,\n QuickJsInlineExecutorOptions,\n QuickJsWorkerExecutorOptions,\n} from \"./types\";\n\nfunction isWorkerOptions(\n options: QuickJsExecutorOptions,\n): options is QuickJsWorkerExecutorOptions {\n return options.host === \"worker\";\n}\n\nfunction getUnsupportedHost(\n options: QuickJsExecutorOptions,\n): string | undefined {\n const host = (options as { host?: unknown }).host;\n if (host === undefined || host === \"inline\" || host === \"worker\") {\n return undefined;\n }\n\n return String(host);\n}\n\n/**\n * QuickJS-backed executor for inline or worker-backed JavaScript runs.\n */\nexport class QuickJsExecutor implements Executor {\n private readonly hostedExecutor: Executor | undefined;\n private readonly options: QuickJsInlineExecutorOptions | undefined;\n\n /**\n * Creates a QuickJS executor with inline QuickJS by default, or a hosted\n * worker shell when `host` is explicitly set.\n */\n constructor(options: QuickJsExecutorOptions = {}) {\n const unsupportedHost = getUnsupportedHost(options);\n if (unsupportedHost !== undefined) {\n throw new Error(\n `QuickJsExecutor host \"${unsupportedHost}\" is no longer supported. ` +\n 'Use host \"worker\" for local hosted execution, or @execbox/remote ' +\n \"for process, container, or VM boundaries.\",\n );\n }\n\n if (isWorkerOptions(options)) {\n this.hostedExecutor = new WorkerHostedQuickJsExecutor(options);\n return;\n }\n\n this.options = options;\n }\n\n /**\n * Disposes any pooled hosted shells owned by this executor.\n */\n async dispose(): Promise<void> {\n await this.hostedExecutor?.dispose?.();\n }\n\n /**\n * Prewarms pooled hosted shells when the executor is running in worker mode.\n * Inline mode treats this as a no-op.\n */\n async prewarm(count?: number): Promise<void> {\n await this.hostedExecutor?.prewarm?.(count);\n }\n\n /**\n * Executes JavaScript against the provided tool namespaces in a fresh QuickJS runtime.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n options: ExecutionOptions = {},\n ): Promise<ExecuteResult> {\n if (this.hostedExecutor) {\n return await this.hostedExecutor.execute(code, providers, options);\n }\n\n if (options.signal?.aborted) {\n return createTimeoutExecuteResult();\n }\n\n const abortController = new AbortController();\n const onToolCall = createToolCallDispatcher(\n providers,\n abortController.signal,\n );\n const onAbort = () => {\n abortController.abort();\n };\n\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n try {\n return await runQuickJsSession(\n {\n abortController,\n code,\n onToolCall,\n providers: extractProviderManifests(providers),\n },\n {\n ...this.options,\n ...options,\n },\n );\n } finally {\n options.signal?.removeEventListener(\"abort\", onAbort);\n abortController.abort();\n }\n }\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -2,20 +2,20 @@
2
2
  * @packageDocumentation
3
3
  * Public TypeScript declarations for this package entrypoint.
4
4
  */
5
- import { a as QuickJsProcessExecutorOptions, i as QuickJsInlineExecutorOptions, n as QuickJsExecutorOptions, o as QuickJsWorkerExecutorOptions, r as QuickJsHostedMode, s as WorkerResourceLimits, t as QuickJsExecutorHost } from "./types-CnNmLawC.cjs";
5
+ import { a as QuickJsWorkerExecutorOptions, i as QuickJsInlineExecutorOptions, n as QuickJsExecutorOptions, o as WorkerResourceLimits, r as QuickJsHostedMode, t as QuickJsExecutorHost } from "./types-C-XfFJ7u.cjs";
6
6
  import { ExecuteResult, ExecutionOptions, Executor, ResolvedToolProvider } from "@execbox/core";
7
7
 
8
8
  //#region src/quickjsExecutor.d.ts
9
9
 
10
10
  /**
11
- * QuickJS-backed executor for inline, worker-backed, or process-backed JavaScript runs.
11
+ * QuickJS-backed executor for inline or worker-backed JavaScript runs.
12
12
  */
13
13
  declare class QuickJsExecutor implements Executor {
14
14
  private readonly hostedExecutor;
15
15
  private readonly options;
16
16
  /**
17
17
  * Creates a QuickJS executor with inline QuickJS by default, or a hosted
18
- * worker/process shell when `host` is explicitly set.
18
+ * worker shell when `host` is explicitly set.
19
19
  */
20
20
  constructor(options?: QuickJsExecutorOptions);
21
21
  /**
@@ -23,8 +23,8 @@ declare class QuickJsExecutor implements Executor {
23
23
  */
24
24
  dispose(): Promise<void>;
25
25
  /**
26
- * Prewarms pooled hosted shells when the executor is running in worker or
27
- * process mode. Inline mode treats this as a no-op.
26
+ * Prewarms pooled hosted shells when the executor is running in worker mode.
27
+ * Inline mode treats this as a no-op.
28
28
  */
29
29
  prewarm(count?: number): Promise<void>;
30
30
  /**
@@ -33,5 +33,5 @@ declare class QuickJsExecutor implements Executor {
33
33
  execute(code: string, providers: ResolvedToolProvider[], options?: ExecutionOptions): Promise<ExecuteResult>;
34
34
  }
35
35
  //#endregion
36
- export { QuickJsExecutor, type QuickJsExecutorHost, type QuickJsExecutorOptions, type QuickJsHostedMode, type QuickJsInlineExecutorOptions, type QuickJsProcessExecutorOptions, type QuickJsWorkerExecutorOptions, type WorkerResourceLimits };
36
+ export { QuickJsExecutor, type QuickJsExecutorHost, type QuickJsExecutorOptions, type QuickJsHostedMode, type QuickJsInlineExecutorOptions, type QuickJsWorkerExecutorOptions, type WorkerResourceLimits };
37
37
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/quickjsExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAqCA,CAAA,CAAA;AAQuB,OAAA,CAAA,KAAA,CARV,eAAA,CAAA,UAAA,CAA2B,QAQjB,CAAA;EAiBJ,OAAA,CAAA,QAAA,CAAA,cAAA;EAQc,OAAA,CAAA,QAAA,CAAA,OAAA;EASlB,CAAA,CAAA;;;;EA1CyB,WAAA,CAAA,OAAA,CAAA,CAAA,CAQjB,sBARiB,CAAA;EAAQ,CAAA,CAAA;;;aAyB7B;;;;;2BAQc;;;;mCASlB,kCACF,mBACR,QAAQ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/quickjsExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAwCA,CAAA,CAAA;AAQuB,OAAA,CAAA,KAAA,CARV,eAAA,CAAA,UAAA,CAA2B,QAQjB,CAAA;EAqBJ,OAAA,CAAA,QAAA,CAAA,cAAA;EAQc,OAAA,CAAA,QAAA,CAAA,OAAA;EASlB,CAAA,CAAA;;;;EA9CyB,WAAA,CAAA,OAAA,CAAA,CAAA,CAQjB,sBARiB,CAAA;EAAQ,CAAA,CAAA;;;aA6B7B;;;;;2BAQc;;;;mCASlB,kCACF,mBACR,QAAQ"}
package/dist/index.d.ts CHANGED
@@ -2,20 +2,20 @@
2
2
  * @packageDocumentation
3
3
  * Public TypeScript declarations for this package entrypoint.
4
4
  */
5
- import { a as QuickJsProcessExecutorOptions, i as QuickJsInlineExecutorOptions, n as QuickJsExecutorOptions, o as QuickJsWorkerExecutorOptions, r as QuickJsHostedMode, s as WorkerResourceLimits, t as QuickJsExecutorHost } from "./types-BeVqrcj8.js";
5
+ import { a as QuickJsWorkerExecutorOptions, i as QuickJsInlineExecutorOptions, n as QuickJsExecutorOptions, o as WorkerResourceLimits, r as QuickJsHostedMode, t as QuickJsExecutorHost } from "./types-CE7SvejR.js";
6
6
  import { ExecuteResult, ExecutionOptions, Executor, ResolvedToolProvider } from "@execbox/core";
7
7
 
8
8
  //#region src/quickjsExecutor.d.ts
9
9
 
10
10
  /**
11
- * QuickJS-backed executor for inline, worker-backed, or process-backed JavaScript runs.
11
+ * QuickJS-backed executor for inline or worker-backed JavaScript runs.
12
12
  */
13
13
  declare class QuickJsExecutor implements Executor {
14
14
  private readonly hostedExecutor;
15
15
  private readonly options;
16
16
  /**
17
17
  * Creates a QuickJS executor with inline QuickJS by default, or a hosted
18
- * worker/process shell when `host` is explicitly set.
18
+ * worker shell when `host` is explicitly set.
19
19
  */
20
20
  constructor(options?: QuickJsExecutorOptions);
21
21
  /**
@@ -23,8 +23,8 @@ declare class QuickJsExecutor implements Executor {
23
23
  */
24
24
  dispose(): Promise<void>;
25
25
  /**
26
- * Prewarms pooled hosted shells when the executor is running in worker or
27
- * process mode. Inline mode treats this as a no-op.
26
+ * Prewarms pooled hosted shells when the executor is running in worker mode.
27
+ * Inline mode treats this as a no-op.
28
28
  */
29
29
  prewarm(count?: number): Promise<void>;
30
30
  /**
@@ -33,5 +33,5 @@ declare class QuickJsExecutor implements Executor {
33
33
  execute(code: string, providers: ResolvedToolProvider[], options?: ExecutionOptions): Promise<ExecuteResult>;
34
34
  }
35
35
  //#endregion
36
- export { QuickJsExecutor, type QuickJsExecutorHost, type QuickJsExecutorOptions, type QuickJsHostedMode, type QuickJsInlineExecutorOptions, type QuickJsProcessExecutorOptions, type QuickJsWorkerExecutorOptions, type WorkerResourceLimits };
36
+ export { QuickJsExecutor, type QuickJsExecutorHost, type QuickJsExecutorOptions, type QuickJsHostedMode, type QuickJsInlineExecutorOptions, type QuickJsWorkerExecutorOptions, type WorkerResourceLimits };
37
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/quickjsExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAqCA,CAAA,CAAA;AAQuB,OAAA,CAAA,KAAA,CARV,eAAA,CAAA,UAAA,CAA2B,QAQjB,CAAA;EAiBJ,OAAA,CAAA,QAAA,CAAA,cAAA;EAQc,OAAA,CAAA,QAAA,CAAA,OAAA;EASlB,CAAA,CAAA;;;;EA1CyB,WAAA,CAAA,OAAA,CAAA,CAAA,CAQjB,sBARiB,CAAA;EAAQ,CAAA,CAAA;;;aAyB7B;;;;;2BAQc;;;;mCASlB,kCACF,mBACR,QAAQ"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/quickjsExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAwCA,CAAA,CAAA;AAQuB,OAAA,CAAA,KAAA,CARV,eAAA,CAAA,UAAA,CAA2B,QAQjB,CAAA;EAqBJ,OAAA,CAAA,QAAA,CAAA,cAAA;EAQc,OAAA,CAAA,QAAA,CAAA,OAAA;EASlB,CAAA,CAAA;;;;EA9CyB,WAAA,CAAA,OAAA,CAAA,CAAA,CAQjB,sBARiB,CAAA;EAAQ,CAAA,CAAA;;;aA6B7B;;;;;2BAQc;;;;mCASlB,kCACF,mBACR,QAAQ"}
package/dist/index.js CHANGED
@@ -1,82 +1,17 @@
1
- import { a as isJsonSerializable, c as getExecutionTimeoutMessage, i as isExecuteFailure, l as normalizeThrownMessage, n as resolveExecutorRuntimeOptions, o as createExecutionContext, r as ExecuteFailure, s as createTimeoutExecuteResult, t as runQuickJsSession } from "./runner-CteKTaPD.js";
2
- import { fork } from "node:child_process";
3
- import { fileURLToPath } from "node:url";
4
- import { createResourcePool, getNodeTransportExecArgv, runHostTransportSession } from "@execbox/core/protocol";
5
- import { randomUUID } from "node:crypto";
1
+ import { t as runQuickJsSession } from "./runner-oZXbguX3.js";
2
+ import { createTimeoutExecuteResult, createToolCallDispatcher, extractProviderManifests, resolveExecutorRuntimeOptions } from "@execbox/core/runtime";
6
3
  import { availableParallelism } from "node:os";
7
4
  import { Worker } from "node:worker_threads";
5
+ import { createResourcePool, getNodeTransportExecArgv, runHostTransportSession } from "@execbox/core/protocol";
6
+ import { randomUUID } from "node:crypto";
8
7
 
9
- //#region ../core/src/runner.ts
10
- function toTrustedExecuteError(error) {
11
- if (isExecuteFailure(error)) return {
12
- code: error.code,
13
- message: error.message
14
- };
15
- return {
16
- code: "tool_error",
17
- message: normalizeThrownMessage(error)
18
- };
19
- }
20
- /**
21
- * Converts resolved providers into manifest metadata that reveals only namespace details.
22
- */
23
- function extractProviderManifests(providers) {
24
- return providers.map((provider) => ({
25
- name: provider.name,
26
- tools: Object.fromEntries(Object.entries(provider.tools).map(([safeToolName, descriptor]) => [safeToolName, {
27
- description: descriptor.description,
28
- originalName: descriptor.originalName,
29
- safeName: descriptor.safeName
30
- }])),
31
- types: provider.types
32
- }));
33
- }
34
- /**
35
- * Creates a host-side dispatcher for runner-emitted tool calls.
36
- */
37
- function createToolCallDispatcher(providers, signal) {
38
- const providerMap = new Map(providers.map((provider) => [provider.name, provider]));
39
- return async (call) => {
40
- const provider = providerMap.get(call.providerName);
41
- const descriptor = provider?.tools[call.safeToolName];
42
- if (!provider || !descriptor) return {
43
- error: {
44
- code: "internal_error",
45
- message: `Unknown tool ${call.providerName}.${call.safeToolName}`
46
- },
47
- ok: false
48
- };
49
- try {
50
- if (signal.aborted) return {
51
- error: {
52
- code: "timeout",
53
- message: getExecutionTimeoutMessage()
54
- },
55
- ok: false
56
- };
57
- const result = await descriptor.execute(call.input, createExecutionContext(signal, provider.name, descriptor.safeName, descriptor.originalName));
58
- if (result !== void 0 && !isJsonSerializable(result)) throw new ExecuteFailure("serialization_error", "Host value is not JSON-serializable");
59
- return {
60
- ok: true,
61
- result
62
- };
63
- } catch (error) {
64
- return {
65
- error: toTrustedExecuteError(error),
66
- ok: false
67
- };
68
- }
69
- };
70
- }
71
-
72
- //#endregion
73
8
  //#region src/hosted/shared.ts
74
9
  /**
75
- * Default grace period before a hosted shell is forcefully terminated.
10
+ * Default grace period before a worker-hosted shell is forcefully terminated.
76
11
  */
77
12
  const DEFAULT_CANCEL_GRACE_MS = 25;
78
13
  /**
79
- * Default pooling limits shared by the hosted QuickJS executors.
14
+ * Default pooling limits shared by worker-hosted QuickJS executors.
80
15
  */
81
16
  const DEFAULT_POOL_OPTIONS = {
82
17
  idleTimeoutMs: 3e4,
@@ -85,7 +20,7 @@ const DEFAULT_POOL_OPTIONS = {
85
20
  prewarm: false
86
21
  };
87
22
  /**
88
- * Minimal code used to warm a hosted shell without touching user providers.
23
+ * Minimal code used to warm a worker shell without touching user providers.
89
24
  */
90
25
  const DEFAULT_PREWARM_CODE = "undefined";
91
26
  /**
@@ -163,227 +98,6 @@ async function warmHostedPool(options) {
163
98
  if (rejected?.status === "rejected") throw rejected.reason;
164
99
  }
165
100
 
166
- //#endregion
167
- //#region src/hosted/processHostedExecutor.ts
168
- function resolveProcessEntryPath() {
169
- const extension = import.meta.url.endsWith(".ts") ? ".ts" : ".js";
170
- return fileURLToPath(new URL(`../processEntry${extension}`, import.meta.url));
171
- }
172
- function createUnexpectedExitMessage(code, signal) {
173
- if (code !== null) return `Child process exited unexpectedly with code ${code}`;
174
- if (signal) return `Child process exited unexpectedly with signal ${signal}`;
175
- return "Child process exited unexpectedly";
176
- }
177
- function createChildProcess() {
178
- return fork(resolveProcessEntryPath(), [], {
179
- execArgv: getNodeTransportExecArgv(import.meta.url),
180
- stdio: [
181
- "ignore",
182
- "ignore",
183
- "ignore",
184
- "ipc"
185
- ]
186
- });
187
- }
188
- function createProcessTransport(child) {
189
- let terminated = false;
190
- let closeReason;
191
- const closeHandlers = /* @__PURE__ */ new Set();
192
- const errorHandlers = /* @__PURE__ */ new Set();
193
- const messageHandlers = /* @__PURE__ */ new Set();
194
- const terminateChild = () => {
195
- if (terminated) return;
196
- terminated = true;
197
- child.kill("SIGKILL");
198
- };
199
- const notifyClose = (reason) => {
200
- if (closeReason) return;
201
- closeReason = reason;
202
- for (const handler of closeHandlers) handler(reason);
203
- };
204
- const onDisconnect = () => {
205
- notifyClose({ message: "Child process disconnected unexpectedly" });
206
- };
207
- const onExit = (code, signal) => {
208
- notifyClose({
209
- code,
210
- message: createUnexpectedExitMessage(code, signal),
211
- signal
212
- });
213
- };
214
- const onError = (error) => {
215
- for (const handler of errorHandlers) handler(error);
216
- };
217
- const onMessage = (message) => {
218
- for (const handler of messageHandlers) handler(message);
219
- };
220
- child.on("disconnect", onDisconnect);
221
- child.on("exit", onExit);
222
- child.on("error", onError);
223
- child.on("message", onMessage);
224
- return {
225
- dispose: () => {
226
- child.off("disconnect", onDisconnect);
227
- child.off("exit", onExit);
228
- child.off("error", onError);
229
- child.off("message", onMessage);
230
- terminateChild();
231
- },
232
- onClose: (handler) => {
233
- closeHandlers.add(handler);
234
- if (closeReason) queueMicrotask(() => {
235
- if (closeHandlers.has(handler)) handler(closeReason);
236
- });
237
- return () => {
238
- closeHandlers.delete(handler);
239
- };
240
- },
241
- onError: (handler) => {
242
- errorHandlers.add(handler);
243
- return () => errorHandlers.delete(handler);
244
- },
245
- onMessage: (handler) => {
246
- messageHandlers.add(handler);
247
- return () => messageHandlers.delete(handler);
248
- },
249
- send: (message) => new Promise((resolve, reject) => {
250
- if (!child.connected || typeof child.send !== "function") {
251
- reject(/* @__PURE__ */ new Error("Child process disconnected unexpectedly"));
252
- return;
253
- }
254
- child.send(message, (error) => {
255
- if (error) {
256
- reject(error);
257
- return;
258
- }
259
- resolve();
260
- });
261
- }),
262
- terminate: () => {
263
- terminateChild();
264
- }
265
- };
266
- }
267
- function createProcessShell() {
268
- const child = createChildProcess();
269
- return {
270
- child,
271
- transport: createProcessTransport(child)
272
- };
273
- }
274
- function resolvePoolOptions$1(options) {
275
- if (options.mode === "ephemeral") return;
276
- return {
277
- ...DEFAULT_POOL_OPTIONS,
278
- ...options.pool
279
- };
280
- }
281
- /**
282
- * Child-process executor that runs guest code inside a dedicated QuickJS runtime per call.
283
- */
284
- var ProcessHostedQuickJsExecutor = class {
285
- cancelGraceMs;
286
- options;
287
- pool;
288
- poolOptions;
289
- warmup;
290
- /**
291
- * Creates a hosted QuickJS executor that launches child-process shells on demand.
292
- */
293
- constructor(options) {
294
- this.cancelGraceMs = options.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;
295
- this.options = options;
296
- const poolOptions = resolvePoolOptions$1(options);
297
- this.poolOptions = poolOptions;
298
- if (poolOptions) {
299
- this.pool = createResourcePool({
300
- create: async () => createProcessShell(),
301
- destroy: async (shell) => {
302
- await shell.transport.dispose();
303
- },
304
- idleTimeoutMs: poolOptions.idleTimeoutMs,
305
- maxSize: poolOptions.maxSize,
306
- minSize: poolOptions.minSize
307
- });
308
- const prewarmCount = getPrewarmCount(poolOptions);
309
- if (prewarmCount > 0) this.warmup = this.warmPool(prewarmCount);
310
- }
311
- }
312
- /**
313
- * Disposes any pooled child-process shells owned by this executor.
314
- */
315
- async dispose() {
316
- await this.pool?.dispose();
317
- }
318
- /**
319
- * Prewarms pooled child-process shells up to the requested count.
320
- */
321
- async prewarm(count) {
322
- if (!this.pool || !this.poolOptions) return;
323
- const target = getWarmupTarget(count, this.poolOptions);
324
- if (target <= 0) return;
325
- await this.warmPool(target);
326
- }
327
- async runTransportSession(transport, code, providers, options = {}, onSettled) {
328
- return await runHostedTransportSession({
329
- cancelGraceMs: this.cancelGraceMs,
330
- code,
331
- executorOptions: this.options,
332
- onSettled,
333
- providers,
334
- requestOptions: options,
335
- transport
336
- });
337
- }
338
- async warmPool(count) {
339
- if (!this.pool) return;
340
- await this.pool.prewarm(count);
341
- const leases = [];
342
- try {
343
- for (let index = 0; index < count; index += 1) leases.push(await this.pool.acquire());
344
- } catch (error) {
345
- await Promise.allSettled(leases.map(async (lease) => await lease.release(false)));
346
- throw error;
347
- }
348
- await warmHostedPool({
349
- count,
350
- getTransport: (lease) => lease.value.transport,
351
- label: "child process",
352
- onRelease: async (lease, reusable) => await lease.release(reusable),
353
- runSession: async (transport, code, providers) => await this.runTransportSession(transport, code, providers),
354
- shells: leases
355
- });
356
- }
357
- /**
358
- * Executes guest code in a child-process-hosted QuickJS shell.
359
- */
360
- async execute(code, providers, options = {}) {
361
- if (options.signal?.aborted) return createTimeoutExecuteResult();
362
- await this.warmup;
363
- if (this.pool) {
364
- const lease = await this.pool.acquire();
365
- return await this.runTransportSession(createBorrowedTransport(lease.value.transport), code, providers, options, async (result) => {
366
- await lease.release(isReusableResult(result));
367
- });
368
- }
369
- let child;
370
- try {
371
- child = createChildProcess();
372
- } catch (error) {
373
- return {
374
- durationMs: 0,
375
- error: {
376
- code: "internal_error",
377
- message: error instanceof Error ? error.message : String(error)
378
- },
379
- logs: [],
380
- ok: false
381
- };
382
- }
383
- return await this.runTransportSession(createProcessTransport(child), code, providers, options);
384
- }
385
- };
386
-
387
101
  //#endregion
388
102
  //#region src/hosted/workerHostedExecutor.ts
389
103
  const DEFAULT_POOLED_WORKER_MAX_SIZE = 4;
@@ -487,7 +201,7 @@ var WorkerHostedQuickJsExecutor = class {
487
201
  poolOptions;
488
202
  warmup;
489
203
  /**
490
- * Creates a hosted QuickJS executor that launches worker-thread shells on demand.
204
+ * Creates a QuickJS executor that launches worker-thread shells on demand.
491
205
  */
492
206
  constructor(options) {
493
207
  this.cancelGraceMs = options.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;
@@ -578,28 +292,28 @@ var WorkerHostedQuickJsExecutor = class {
578
292
  function isWorkerOptions(options) {
579
293
  return options.host === "worker";
580
294
  }
581
- function isProcessOptions(options) {
582
- return options.host === "process";
295
+ function getUnsupportedHost(options) {
296
+ const host = options.host;
297
+ if (host === void 0 || host === "inline" || host === "worker") return;
298
+ return String(host);
583
299
  }
584
300
  /**
585
- * QuickJS-backed executor for inline, worker-backed, or process-backed JavaScript runs.
301
+ * QuickJS-backed executor for inline or worker-backed JavaScript runs.
586
302
  */
587
303
  var QuickJsExecutor = class {
588
304
  hostedExecutor;
589
305
  options;
590
306
  /**
591
307
  * Creates a QuickJS executor with inline QuickJS by default, or a hosted
592
- * worker/process shell when `host` is explicitly set.
308
+ * worker shell when `host` is explicitly set.
593
309
  */
594
310
  constructor(options = {}) {
311
+ const unsupportedHost = getUnsupportedHost(options);
312
+ if (unsupportedHost !== void 0) throw new Error(`QuickJsExecutor host "${unsupportedHost}" is no longer supported. Use host "worker" for local hosted execution, or @execbox/remote for process, container, or VM boundaries.`);
595
313
  if (isWorkerOptions(options)) {
596
314
  this.hostedExecutor = new WorkerHostedQuickJsExecutor(options);
597
315
  return;
598
316
  }
599
- if (isProcessOptions(options)) {
600
- this.hostedExecutor = new ProcessHostedQuickJsExecutor(options);
601
- return;
602
- }
603
317
  this.options = options;
604
318
  }
605
319
  /**
@@ -609,8 +323,8 @@ var QuickJsExecutor = class {
609
323
  await this.hostedExecutor?.dispose?.();
610
324
  }
611
325
  /**
612
- * Prewarms pooled hosted shells when the executor is running in worker or
613
- * process mode. Inline mode treats this as a no-op.
326
+ * Prewarms pooled hosted shells when the executor is running in worker mode.
327
+ * Inline mode treats this as a no-op.
614
328
  */
615
329
  async prewarm(count) {
616
330
  await this.hostedExecutor?.prewarm?.(count);