@nodetool-ai/sandbox-runtime 0.0.0-stage → 0.8.9-beta.1

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 (218) hide show
  1. package/README.md +24 -2
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/host-access-gate.d.ts +24 -0
  4. package/dist/host-access-gate.d.ts.map +1 -0
  5. package/dist/host-access-gate.js +31 -0
  6. package/dist/host-access-gate.js.map +1 -0
  7. package/dist/index.d.ts +32 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +318 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/js-sandbox-worker/engine.d.ts +4 -0
  12. package/dist/js-sandbox-worker/engine.d.ts.map +1 -0
  13. package/dist/js-sandbox-worker/engine.js +82 -0
  14. package/dist/js-sandbox-worker/engine.js.map +1 -0
  15. package/dist/js-sandbox-worker/host.d.ts +136 -0
  16. package/dist/js-sandbox-worker/host.d.ts.map +1 -0
  17. package/dist/js-sandbox-worker/host.js +482 -0
  18. package/dist/js-sandbox-worker/host.js.map +1 -0
  19. package/dist/js-sandbox-worker/interpreter.d.ts +276 -0
  20. package/dist/js-sandbox-worker/interpreter.d.ts.map +1 -0
  21. package/dist/js-sandbox-worker/interpreter.js +1318 -0
  22. package/dist/js-sandbox-worker/interpreter.js.map +1 -0
  23. package/dist/js-sandbox-worker/protocol.d.ts +168 -0
  24. package/dist/js-sandbox-worker/protocol.d.ts.map +1 -0
  25. package/dist/js-sandbox-worker/protocol.js +217 -0
  26. package/dist/js-sandbox-worker/protocol.js.map +1 -0
  27. package/dist/js-sandbox-worker/worker-entry.d.ts +26 -0
  28. package/dist/js-sandbox-worker/worker-entry.d.ts.map +1 -0
  29. package/dist/js-sandbox-worker/worker-entry.js +308 -0
  30. package/dist/js-sandbox-worker/worker-entry.js.map +1 -0
  31. package/dist/limits.d.ts +77 -0
  32. package/dist/limits.d.ts.map +1 -0
  33. package/dist/limits.js +56 -0
  34. package/dist/limits.js.map +1 -0
  35. package/dist/sandbox-bootstrap-modules.d.ts +54 -0
  36. package/dist/sandbox-bootstrap-modules.d.ts.map +1 -0
  37. package/dist/sandbox-bootstrap-modules.js +104 -0
  38. package/dist/sandbox-bootstrap-modules.js.map +1 -0
  39. package/dist/sandbox-bytes.d.ts +43 -0
  40. package/dist/sandbox-bytes.d.ts.map +1 -0
  41. package/dist/sandbox-bytes.js +61 -0
  42. package/dist/sandbox-bytes.js.map +1 -0
  43. package/dist/sandbox-canvas-api.d.ts +30 -0
  44. package/dist/sandbox-canvas-api.d.ts.map +1 -0
  45. package/dist/sandbox-canvas-api.js +81 -0
  46. package/dist/sandbox-canvas-api.js.map +1 -0
  47. package/dist/sandbox-constants.d.ts +5 -0
  48. package/dist/sandbox-constants.d.ts.map +1 -0
  49. package/dist/sandbox-constants.js +13 -0
  50. package/dist/sandbox-constants.js.map +1 -0
  51. package/dist/sandbox-json-transport.d.ts +107 -0
  52. package/dist/sandbox-json-transport.d.ts.map +1 -0
  53. package/dist/sandbox-json-transport.js +324 -0
  54. package/dist/sandbox-json-transport.js.map +1 -0
  55. package/dist/timeline-capture.d.ts +21 -0
  56. package/dist/timeline-capture.d.ts.map +1 -0
  57. package/dist/timeline-capture.js +564 -0
  58. package/dist/timeline-capture.js.map +1 -0
  59. package/dist/utils/type-guards.d.ts +26 -0
  60. package/dist/utils/type-guards.d.ts.map +1 -0
  61. package/dist/utils/type-guards.js +44 -0
  62. package/dist/utils/type-guards.js.map +1 -0
  63. package/package.json +138 -4
  64. package/vendor/README.md +17 -0
  65. package/vendor/quickjs/LICENSE +21 -0
  66. package/vendor/quickjs/PROVENANCE.json +8 -0
  67. package/vendor/quickjs/adapter/fetch.d.ts +56 -0
  68. package/vendor/quickjs/adapter/fetch.js +140 -0
  69. package/vendor/quickjs/createTimeInterval.d.ts +9 -0
  70. package/vendor/quickjs/createTimeInterval.js +22 -0
  71. package/vendor/quickjs/createVirtualFileSystem.d.ts +13 -0
  72. package/vendor/quickjs/createVirtualFileSystem.js +191 -0
  73. package/vendor/quickjs/index.d.ts +77 -0
  74. package/vendor/quickjs/index.js +77 -0
  75. package/vendor/quickjs/loadAsyncQuickJs.d.ts +12 -0
  76. package/vendor/quickjs/loadAsyncQuickJs.js +66 -0
  77. package/vendor/quickjs/loadQuickJs.d.ts +12 -0
  78. package/vendor/quickjs/loadQuickJs.js +73 -0
  79. package/vendor/quickjs/modules/assert.d.ts +2 -0
  80. package/vendor/quickjs/modules/assert.js +47 -0
  81. package/vendor/quickjs/modules/buffer.d.ts +2 -0
  82. package/vendor/quickjs/modules/buffer.js +106 -0
  83. package/vendor/quickjs/modules/build/test-lib.js +2 -0
  84. package/vendor/quickjs/modules/events.d.ts +2 -0
  85. package/vendor/quickjs/modules/events.js +4 -0
  86. package/vendor/quickjs/modules/fs.d.ts +2 -0
  87. package/vendor/quickjs/modules/fs.js +76 -0
  88. package/vendor/quickjs/modules/fs_promises.d.ts +2 -0
  89. package/vendor/quickjs/modules/fs_promises.js +328 -0
  90. package/vendor/quickjs/modules/module.d.ts +2 -0
  91. package/vendor/quickjs/modules/module.js +33 -0
  92. package/vendor/quickjs/modules/nodeCompatibility/headers.d.ts +2 -0
  93. package/vendor/quickjs/modules/nodeCompatibility/headers.js +58 -0
  94. package/vendor/quickjs/modules/nodeCompatibility/request.d.ts +2 -0
  95. package/vendor/quickjs/modules/nodeCompatibility/request.js +5 -0
  96. package/vendor/quickjs/modules/nodeCompatibility/response.d.ts +2 -0
  97. package/vendor/quickjs/modules/nodeCompatibility/response.js +5 -0
  98. package/vendor/quickjs/modules/path.d.ts +2 -0
  99. package/vendor/quickjs/modules/path.js +504 -0
  100. package/vendor/quickjs/modules/process.d.ts +2 -0
  101. package/vendor/quickjs/modules/process.js +309 -0
  102. package/vendor/quickjs/modules/punycode.d.ts +2 -0
  103. package/vendor/quickjs/modules/punycode.js +443 -0
  104. package/vendor/quickjs/modules/querystring.d.ts +2 -0
  105. package/vendor/quickjs/modules/querystring.js +15 -0
  106. package/vendor/quickjs/modules/string_decoder.d.ts +2 -0
  107. package/vendor/quickjs/modules/string_decoder.js +223 -0
  108. package/vendor/quickjs/modules/timers.d.ts +2 -0
  109. package/vendor/quickjs/modules/timers.js +10 -0
  110. package/vendor/quickjs/modules/timers_promises.d.ts +2 -0
  111. package/vendor/quickjs/modules/timers_promises.js +40 -0
  112. package/vendor/quickjs/modules/url.d.ts +2 -0
  113. package/vendor/quickjs/modules/url.js +104 -0
  114. package/vendor/quickjs/modules/util.d.ts +2 -0
  115. package/vendor/quickjs/modules/util.js +233 -0
  116. package/vendor/quickjs/package.json +3 -0
  117. package/vendor/quickjs/sandbox/asyncVersion/createAsyncEvalCodeFunction.d.ts +4 -0
  118. package/vendor/quickjs/sandbox/asyncVersion/createAsyncEvalCodeFunction.js +76 -0
  119. package/vendor/quickjs/sandbox/asyncVersion/createAsyncValidateCodeFunction.d.ts +3 -0
  120. package/vendor/quickjs/sandbox/asyncVersion/createAsyncValidateCodeFunction.js +22 -0
  121. package/vendor/quickjs/sandbox/asyncVersion/executeAsyncSandboxFunction.d.ts +12 -0
  122. package/vendor/quickjs/sandbox/asyncVersion/executeAsyncSandboxFunction.js +9 -0
  123. package/vendor/quickjs/sandbox/asyncVersion/getAsyncModuleLoader.d.ts +4 -0
  124. package/vendor/quickjs/sandbox/asyncVersion/getAsyncModuleLoader.js +30 -0
  125. package/vendor/quickjs/sandbox/asyncVersion/modulePathNormalizerAsync.d.ts +2 -0
  126. package/vendor/quickjs/sandbox/asyncVersion/modulePathNormalizerAsync.js +12 -0
  127. package/vendor/quickjs/sandbox/asyncVersion/prepareAsyncNodeCompatibility.d.ts +3 -0
  128. package/vendor/quickjs/sandbox/asyncVersion/prepareAsyncNodeCompatibility.js +11 -0
  129. package/vendor/quickjs/sandbox/asyncVersion/prepareAsyncSandbox.d.ts +4 -0
  130. package/vendor/quickjs/sandbox/asyncVersion/prepareAsyncSandbox.js +10 -0
  131. package/vendor/quickjs/sandbox/expose/expose.d.ts +3 -0
  132. package/vendor/quickjs/sandbox/expose/expose.js +155 -0
  133. package/vendor/quickjs/sandbox/expose/isES2015Class.d.ts +1 -0
  134. package/vendor/quickjs/sandbox/expose/isES2015Class.js +4 -0
  135. package/vendor/quickjs/sandbox/expose/isObject.d.ts +1 -0
  136. package/vendor/quickjs/sandbox/expose/isObject.js +4 -0
  137. package/vendor/quickjs/sandbox/expose/pendingHostPromises.d.ts +6 -0
  138. package/vendor/quickjs/sandbox/expose/pendingHostPromises.js +40 -0
  139. package/vendor/quickjs/sandbox/getMaxIntervalAmount.d.ts +8 -0
  140. package/vendor/quickjs/sandbox/getMaxIntervalAmount.js +12 -0
  141. package/vendor/quickjs/sandbox/getMaxTimeoutAmount.d.ts +8 -0
  142. package/vendor/quickjs/sandbox/getMaxTimeoutAmount.js +12 -0
  143. package/vendor/quickjs/sandbox/handleEvalError.d.ts +2 -0
  144. package/vendor/quickjs/sandbox/handleEvalError.js +21 -0
  145. package/vendor/quickjs/sandbox/handleToNative/handleToNative.d.ts +9 -0
  146. package/vendor/quickjs/sandbox/handleToNative/handleToNative.js +153 -0
  147. package/vendor/quickjs/sandbox/handleToNative/serializer/index.d.ts +10 -0
  148. package/vendor/quickjs/sandbox/handleToNative/serializer/index.js +36 -0
  149. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeArrayBuffer.d.ts +2 -0
  150. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeArrayBuffer.js +4 -0
  151. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeBuffer.d.ts +2 -0
  152. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeBuffer.js +16 -0
  153. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeDate.d.ts +2 -0
  154. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeDate.js +16 -0
  155. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeError.d.ts +2 -0
  156. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeError.js +18 -0
  157. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeHeaders.d.ts +2 -0
  158. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeHeaders.js +17 -0
  159. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeMap.d.ts +2 -0
  160. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeMap.js +18 -0
  161. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeSet.d.ts +2 -0
  162. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeSet.js +16 -0
  163. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeURLSearchParams.d.ts +2 -0
  164. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeURLSearchParams.js +17 -0
  165. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeUrl.d.ts +2 -0
  166. package/vendor/quickjs/sandbox/handleToNative/serializer/serializeUrl.js +17 -0
  167. package/vendor/quickjs/sandbox/helper.d.ts +2 -0
  168. package/vendor/quickjs/sandbox/helper.js +14 -0
  169. package/vendor/quickjs/sandbox/provide/provideConsole.d.ts +6 -0
  170. package/vendor/quickjs/sandbox/provide/provideConsole.js +53 -0
  171. package/vendor/quickjs/sandbox/provide/provideEnv.d.ts +3 -0
  172. package/vendor/quickjs/sandbox/provide/provideEnv.js +10 -0
  173. package/vendor/quickjs/sandbox/provide/provideFs.d.ts +4 -0
  174. package/vendor/quickjs/sandbox/provide/provideFs.js +159 -0
  175. package/vendor/quickjs/sandbox/provide/provideHttp.d.ts +9 -0
  176. package/vendor/quickjs/sandbox/provide/provideHttp.js +42 -0
  177. package/vendor/quickjs/sandbox/provide/provideTimingFunctions.d.ts +7 -0
  178. package/vendor/quickjs/sandbox/provide/provideTimingFunctions.js +119 -0
  179. package/vendor/quickjs/sandbox/setupFileSystem.d.ts +3 -0
  180. package/vendor/quickjs/sandbox/setupFileSystem.js +13 -0
  181. package/vendor/quickjs/sandbox/syncVersion/createEvalCodeFunction.d.ts +4 -0
  182. package/vendor/quickjs/sandbox/syncVersion/createEvalCodeFunction.js +76 -0
  183. package/vendor/quickjs/sandbox/syncVersion/createValidateCodeFunction.d.ts +3 -0
  184. package/vendor/quickjs/sandbox/syncVersion/createValidateCodeFunction.js +22 -0
  185. package/vendor/quickjs/sandbox/syncVersion/executeSandboxFunction.d.ts +12 -0
  186. package/vendor/quickjs/sandbox/syncVersion/executeSandboxFunction.js +9 -0
  187. package/vendor/quickjs/sandbox/syncVersion/getModuleLoader.d.ts +4 -0
  188. package/vendor/quickjs/sandbox/syncVersion/getModuleLoader.js +30 -0
  189. package/vendor/quickjs/sandbox/syncVersion/modulePathNormalizer.d.ts +2 -0
  190. package/vendor/quickjs/sandbox/syncVersion/modulePathNormalizer.js +12 -0
  191. package/vendor/quickjs/sandbox/syncVersion/prepareNodeCompatibility.d.ts +3 -0
  192. package/vendor/quickjs/sandbox/syncVersion/prepareNodeCompatibility.js +11 -0
  193. package/vendor/quickjs/sandbox/syncVersion/prepareSandbox.d.ts +4 -0
  194. package/vendor/quickjs/sandbox/syncVersion/prepareSandbox.js +10 -0
  195. package/vendor/quickjs/types/CodeFunctionInput.d.ts +12 -0
  196. package/vendor/quickjs/types/CodeFunctionInput.js +1 -0
  197. package/vendor/quickjs/types/ErrorResponse.d.ts +9 -0
  198. package/vendor/quickjs/types/ErrorResponse.js +1 -0
  199. package/vendor/quickjs/types/LoadQuickJsOptions.d.ts +3 -0
  200. package/vendor/quickjs/types/LoadQuickJsOptions.js +1 -0
  201. package/vendor/quickjs/types/OkResponse.d.ts +4 -0
  202. package/vendor/quickjs/types/OkResponse.js +1 -0
  203. package/vendor/quickjs/types/OkResponseCheck.d.ts +3 -0
  204. package/vendor/quickjs/types/OkResponseCheck.js +1 -0
  205. package/vendor/quickjs/types/Prettify.d.ts +3 -0
  206. package/vendor/quickjs/types/Prettify.js +1 -0
  207. package/vendor/quickjs/types/RuntimeOptions.d.ts +87 -0
  208. package/vendor/quickjs/types/RuntimeOptions.js +1 -0
  209. package/vendor/quickjs/types/SandboxEvalCode.d.ts +5 -0
  210. package/vendor/quickjs/types/SandboxEvalCode.js +1 -0
  211. package/vendor/quickjs/types/SandboxFunction.d.ts +16 -0
  212. package/vendor/quickjs/types/SandboxFunction.js +1 -0
  213. package/vendor/quickjs/types/SandboxOptions.d.ts +152 -0
  214. package/vendor/quickjs/types/SandboxOptions.js +1 -0
  215. package/vendor/quickjs/types/SandboxValidateCode.d.ts +9 -0
  216. package/vendor/quickjs/types/SandboxValidateCode.js +1 -0
  217. package/vendor/quickjs/types/Serializer.d.ts +2 -0
  218. package/vendor/quickjs/types/Serializer.js +1 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Main-thread side of the off-thread QuickJS sandbox.
3
+ *
4
+ * It resolves the worker entry for whichever environment the process is in,
5
+ * keeps a small warm pool, and serves every bridge call the guest makes as an
6
+ * RPC over the port. Cancellation is `worker.terminate()`, immediately: it is
7
+ * equally instant for a spinning guest and a parked one, and the logs and
8
+ * emitted values already live in the main-thread accumulators — port FIFO
9
+ * delivered every RPC the guest made before the abort. The deadline backstop
10
+ * terminates a worker that answers nothing at all.
11
+ *
12
+ * This is the one module in `js-sandbox-worker/` that reaches for Node, and it
13
+ * does so through `importNodeBuiltin`, so importing it off Node resolves
14
+ * nothing and the caller falls back in-process.
15
+ */
16
+ import { SANDBOX_DISPATCHER_BINDINGS, type HostToWorkerMessage, type ResultMessage, type RunMessage, type WorkerToHostMessage } from "./protocol.js";
17
+ /** Workers alive at once. A fifth concurrent run waits for a free one. */
18
+ export declare const MAX_SANDBOX_WORKERS = 4;
19
+ /** Slack on top of the run's own budget before the backstop fires. */
20
+ export declare const DEADLINE_MARGIN_MS = 5000;
21
+ export type WorkerEntry = {
22
+ /** A compiled entry: hand the file URL straight to `new Worker()`. */
23
+ readonly kind: "file";
24
+ readonly href: string;
25
+ } | {
26
+ /**
27
+ * A TypeScript entry (tsx dev, vitest). The worker starts from an eval'd
28
+ * bootstrap that registers tsx's transform and then imports the entry —
29
+ * tsx's own `--import` hook deliberately skips worker threads, and
30
+ * Node's built-in strip-only loader rejects the syntax the workspace
31
+ * packages use, so the explicit `tsx/esm/api` registration is the one
32
+ * path that works.
33
+ */
34
+ readonly kind: "bootstrap";
35
+ readonly href: string;
36
+ /** File URL of `tsx/esm/api`, resolved from this package. */
37
+ readonly tsxApiHref: string;
38
+ readonly execArgv: readonly string[];
39
+ };
40
+ /**
41
+ * The worker entry for this environment, or `null` when there is none.
42
+ *
43
+ * Three shapes, decided by where this module itself was loaded from:
44
+ *
45
+ * | `import.meta.url` ends in | Entry | Mechanism |
46
+ * |---|---|---|
47
+ * | `.ts` (tsx, vitest) | sibling `worker-entry.ts` | explicit `execArgv` loading tsx |
48
+ * | `.js` (compiled `dist/`) | sibling `worker-entry.js` | plain `new Worker(url)` |
49
+ * | `server.mjs` (esbuild bundle) | `js-sandbox-worker/worker-entry.js` next to it | plain `new Worker(url)` |
50
+ *
51
+ * The `.ts` entry wins whenever this module is a `.ts` file, which is what
52
+ * keeps a stale `dist/` from being loaded under tsx. `execArgv` is passed
53
+ * explicitly rather than inherited: a vitest worker does not necessarily carry
54
+ * the loader flags its parent was started with.
55
+ */
56
+ export declare function resolveWorkerEntry(): Promise<WorkerEntry | null>;
57
+ /** The slice of a worker this module uses, so a test can supply a stub. */
58
+ export interface SandboxWorkerHandle {
59
+ postMessage(message: HostToWorkerMessage): void;
60
+ /** Route one message to the active run. Replaces any previous sink. */
61
+ onMessage(handler: (message: WorkerToHostMessage) => void): void;
62
+ /** Called when the thread dies — an `error` event or an unexpected `exit`. */
63
+ onDeath(handler: (error: Error) => void): void;
64
+ terminate(): void;
65
+ /**
66
+ * Hold and release the process for this worker. A leased worker refs, so a
67
+ * run in flight cannot be cut short by the event loop draining; an idle
68
+ * pooled worker unrefs, so a warm pool never keeps the process alive on its
69
+ * own. Optional: a handle with no thread behind it has nothing to manage.
70
+ */
71
+ ref?(): void;
72
+ unref?(): void;
73
+ }
74
+ export type SandboxWorkerFactory = () => Promise<SandboxWorkerHandle | null>;
75
+ /** Spawn a real `worker_threads` worker at the resolved entry. */
76
+ export declare const defaultSandboxWorkerFactory: SandboxWorkerFactory;
77
+ type Lease = {
78
+ readonly handle: SandboxWorkerHandle;
79
+ /** Return the worker to the pool, or drop it when the thread is gone. */
80
+ release(discard: boolean): void;
81
+ };
82
+ /**
83
+ * Warm workers, one run in flight each.
84
+ *
85
+ * Workers are spawned lazily up to the cap and reused after every run: a fresh
86
+ * QuickJS engine costs a WASM instantiation, so the pool is what keeps a short
87
+ * run short. A worker that was terminated is dropped rather than reused, and
88
+ * the next acquire spawns its replacement.
89
+ */
90
+ export declare class SandboxWorkerPool {
91
+ private readonly factory;
92
+ private readonly max;
93
+ private readonly idle;
94
+ private readonly waiting;
95
+ private live;
96
+ constructor(factory?: SandboxWorkerFactory, max?: number);
97
+ acquire(): Promise<Lease | null>;
98
+ /** Terminate every idle worker. In-flight runs keep the ones they hold. */
99
+ destroy(): void;
100
+ private take;
101
+ private spawnChain;
102
+ private give;
103
+ }
104
+ /** The process-wide pool. A test passes its own instead. */
105
+ export declare function defaultSandboxWorkerPool(): SandboxWorkerPool;
106
+ export interface RunInWorkerOptions {
107
+ /** The run payload, minus its `type` tag. */
108
+ readonly run: Omit<RunMessage, "type">;
109
+ /**
110
+ * The main-side bridge table an RPC path is looked up in: the same record
111
+ * `deriveBridgeShape` was given, plus the dispatchers and function globals.
112
+ * A path resolves member by member and must land on a function.
113
+ */
114
+ readonly dispatch: Readonly<Record<string, unknown>>;
115
+ readonly onLog: (line: string) => void;
116
+ readonly onProgress: (percent: number, message?: string) => void;
117
+ readonly signal?: AbortSignal;
118
+ /** Suspended-time credit; pushed to the worker whenever it moves. */
119
+ readonly suspendedMs?: () => number;
120
+ /** Synchronous `stream.open` answer, re-read after every bridge call. */
121
+ readonly isStreamOpen?: (handle: string) => boolean;
122
+ readonly pool?: SandboxWorkerPool;
123
+ }
124
+ /**
125
+ * Run one guest program on a pooled worker and return how it settled.
126
+ *
127
+ * The result is always a `ResultMessage`: the guest's own outcome, a cancelled
128
+ * result synthesized when the abort terminated the thread, or a failed result carrying
129
+ * whatever killed the thread. The caller maps a `failure: "worker"` message
130
+ * through `describeEngineFailure`. Returns `null` when no worker could be
131
+ * acquired at all, which is the caller's signal to run in-process.
132
+ */
133
+ export declare function runInWorker(options: RunInWorkerOptions): Promise<ResultMessage | null>;
134
+ /** Guest binding names for the dispatchers, re-exported for the caller. */
135
+ export { SANDBOX_DISPATCHER_BINDINGS };
136
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/js-sandbox-worker/host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAEL,2BAA2B,EAC3B,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACzB,MAAM,eAAe,CAAC;AAGvB,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AAUxC,MAAM,MAAM,WAAW,GACnB;IACE,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,GACD;IACE;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC,CAAC;AAMN;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAuCtE;AAmCD,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAChD,uEAAuE;IACvE,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,8EAA8E;IAC9E,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/C,SAAS,IAAI,IAAI,CAAC;IAClB;;;;;OAKG;IACH,GAAG,CAAC,IAAI,IAAI,CAAC;IACb,KAAK,CAAC,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;AAiB7E,kEAAkE;AAClE,eAAO,MAAM,2BAA2B,EAAE,oBAyDzC,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,yEAAyE;IACzE,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAM1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2D;IACnF,OAAO,CAAC,IAAI,CAAK;IAEjB,YACmB,OAAO,GAAE,oBAAkD,EAC3D,GAAG,GAAE,MAA4B,EAChD;IAEE,OAAO,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CASrC;IAED,2EAA2E;IAC3E,OAAO,IAAI,IAAI,CAMd;YAEa,IAAI;IA2BlB,OAAO,CAAC,UAAU,CACM;IAExB,OAAO,CAAC,IAAI;CA+Bb;AAID,4DAA4D;AAC5D,wBAAgB,wBAAwB,IAAI,iBAAiB,CAG5D;AAMD,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACvC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAgDD;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAgK/B;AAED,2EAA2E;AAC3E,OAAO,EAAE,2BAA2B,EAAE,CAAC"}
@@ -0,0 +1,482 @@
1
+ /**
2
+ * Main-thread side of the off-thread QuickJS sandbox.
3
+ *
4
+ * It resolves the worker entry for whichever environment the process is in,
5
+ * keeps a small warm pool, and serves every bridge call the guest makes as an
6
+ * RPC over the port. Cancellation is `worker.terminate()`, immediately: it is
7
+ * equally instant for a spinning guest and a parked one, and the logs and
8
+ * emitted values already live in the main-thread accumulators — port FIFO
9
+ * delivered every RPC the guest made before the abort. The deadline backstop
10
+ * terminates a worker that answers nothing at all.
11
+ *
12
+ * This is the one module in `js-sandbox-worker/` that reaches for Node, and it
13
+ * does so through `importNodeBuiltin`, so importing it off Node resolves
14
+ * nothing and the caller falls back in-process.
15
+ */
16
+ import { createLogger, importNodeBuiltin } from "@nodetool-ai/config";
17
+ import { isWorkerToHostMessage, SANDBOX_DISPATCHER_BINDINGS } from "./protocol.js";
18
+ import { isFunction, isObjectLike } from "../utils/type-guards.js";
19
+ /** Workers alive at once. A fifth concurrent run waits for a free one. */
20
+ export const MAX_SANDBOX_WORKERS = 4;
21
+ /** Slack on top of the run's own budget before the backstop fires. */
22
+ export const DEADLINE_MARGIN_MS = 5_000;
23
+ const log = createLogger("nodetool.agents.sandbox-host");
24
+ const SLOW_WORKER_ACQUIRE_MS = 1_000;
25
+ const SLOW_WORKER_ROUND_TRIP_MS = 1_000;
26
+ /**
27
+ * The worker entry for this environment, or `null` when there is none.
28
+ *
29
+ * Three shapes, decided by where this module itself was loaded from:
30
+ *
31
+ * | `import.meta.url` ends in | Entry | Mechanism |
32
+ * |---|---|---|
33
+ * | `.ts` (tsx, vitest) | sibling `worker-entry.ts` | explicit `execArgv` loading tsx |
34
+ * | `.js` (compiled `dist/`) | sibling `worker-entry.js` | plain `new Worker(url)` |
35
+ * | `server.mjs` (esbuild bundle) | `js-sandbox-worker/worker-entry.js` next to it | plain `new Worker(url)` |
36
+ *
37
+ * The `.ts` entry wins whenever this module is a `.ts` file, which is what
38
+ * keeps a stale `dist/` from being loaded under tsx. `execArgv` is passed
39
+ * explicitly rather than inherited: a vitest worker does not necessarily carry
40
+ * the loader flags its parent was started with.
41
+ */
42
+ export async function resolveWorkerEntry() {
43
+ const fs = await importNodeBuiltin("node:fs");
44
+ if (fs === null)
45
+ return null;
46
+ const url = await importNodeBuiltin("node:url");
47
+ if (url === null)
48
+ return null;
49
+ const self = import.meta.url;
50
+ const exists = (candidate) => {
51
+ try {
52
+ return fs.existsSync(url.fileURLToPath(candidate));
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ };
58
+ if (self.endsWith("server.mjs")) {
59
+ const bundled = new URL("js-sandbox-worker/worker-entry.js", self);
60
+ return exists(bundled) ? { kind: "file", href: bundled.href } : null;
61
+ }
62
+ if (self.endsWith(".ts")) {
63
+ const source = new URL("worker-entry.ts", self);
64
+ if (!exists(source))
65
+ return null;
66
+ const tsxApiHref = await resolveTsxApi(url);
67
+ if (tsxApiHref === null)
68
+ return null;
69
+ return {
70
+ kind: "bootstrap",
71
+ href: source.href,
72
+ tsxApiHref,
73
+ // `nodetool-dev` is what makes the workspace `exports` maps resolve to
74
+ // source instead of `dist/`, the same condition the dev server runs
75
+ // under. Passed explicitly: a vitest worker does not carry the flags its
76
+ // parent was started with.
77
+ execArgv: ["--conditions=nodetool-dev"]
78
+ };
79
+ }
80
+ const compiled = new URL("worker-entry.js", self);
81
+ return exists(compiled) ? { kind: "file", href: compiled.href } : null;
82
+ }
83
+ /**
84
+ * Where `tsx/esm/api` lives, as a file URL.
85
+ *
86
+ * tsx is resolved from this package rather than assumed on the path, and a
87
+ * resolution failure returns `null` so the caller falls back in-process
88
+ * instead of spawning a worker that cannot parse its own entry.
89
+ */
90
+ async function resolveTsxApi(url) {
91
+ const nodeModule = await importNodeBuiltin("node:module");
92
+ if (nodeModule === null)
93
+ return null;
94
+ try {
95
+ const api = nodeModule.createRequire(import.meta.url).resolve("tsx/esm/api");
96
+ return url.pathToFileURL(api).href;
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ }
102
+ /**
103
+ * The eval'd bootstrap for a TypeScript entry. CJS on purpose: an eval worker
104
+ * is CJS, and the two dynamic imports are what carry it into ESM.
105
+ */
106
+ const TS_BOOTSTRAP = `
107
+ const { workerData } = require("node:worker_threads");
108
+ import(workerData.tsxApiHref)
109
+ .then((tsx) => { tsx.register(); return import(workerData.entryHref); })
110
+ .catch((error) => { throw error; });
111
+ `;
112
+ /** Spawn a real `worker_threads` worker at the resolved entry. */
113
+ export const defaultSandboxWorkerFactory = async () => {
114
+ const threads = await importNodeBuiltin("node:worker_threads");
115
+ if (threads === null)
116
+ return null;
117
+ const entry = await resolveWorkerEntry();
118
+ if (entry === null)
119
+ return null;
120
+ const worker = entry.kind === "file"
121
+ ? new threads.Worker(new URL(entry.href), {})
122
+ : new threads.Worker(TS_BOOTSTRAP, {
123
+ eval: true,
124
+ workerData: { tsxApiHref: entry.tsxApiHref, entryHref: entry.href },
125
+ execArgv: [...entry.execArgv]
126
+ });
127
+ let sink;
128
+ let death;
129
+ let dead = false;
130
+ const die = (error) => {
131
+ if (dead)
132
+ return;
133
+ dead = true;
134
+ death?.(error);
135
+ };
136
+ worker.on("message", (raw) => {
137
+ if (isWorkerToHostMessage(raw))
138
+ sink?.(raw);
139
+ });
140
+ worker.on("error", (raw) => {
141
+ const error = raw;
142
+ die(error instanceof Error ? error : new Error(String(error)));
143
+ });
144
+ worker.on("exit", (code) => {
145
+ die(new Error(`the sandbox worker exited with code ${String(code)}`));
146
+ });
147
+ // A pooled worker must never hold the process open on its own — and this has
148
+ // to come *after* the listeners above. Attaching a `message` listener starts
149
+ // the worker's public port, which re-refs it, so unreffing first is silently
150
+ // undone: a CLI run that left a worker pooled then hung until its 45-minute
151
+ // CI job timeout instead of exiting.
152
+ worker.unref();
153
+ return {
154
+ postMessage: (message) => worker.postMessage(message),
155
+ onMessage: (handler) => {
156
+ sink = handler;
157
+ },
158
+ onDeath: (handler) => {
159
+ death = handler;
160
+ if (dead)
161
+ handler(new Error("the sandbox worker is already dead"));
162
+ },
163
+ terminate: () => {
164
+ dead = true;
165
+ void worker.terminate();
166
+ },
167
+ ref: () => worker.ref(),
168
+ unref: () => worker.unref()
169
+ };
170
+ };
171
+ /**
172
+ * Warm workers, one run in flight each.
173
+ *
174
+ * Workers are spawned lazily up to the cap and reused after every run: a fresh
175
+ * QuickJS engine costs a WASM instantiation, so the pool is what keeps a short
176
+ * run short. A worker that was terminated is dropped rather than reused, and
177
+ * the next acquire spawns its replacement.
178
+ */
179
+ export class SandboxWorkerPool {
180
+ factory;
181
+ max;
182
+ idle = [];
183
+ waiting = [];
184
+ live = 0;
185
+ constructor(factory = defaultSandboxWorkerFactory, max = MAX_SANDBOX_WORKERS) {
186
+ this.factory = factory;
187
+ this.max = max;
188
+ }
189
+ async acquire() {
190
+ const handle = await this.take();
191
+ if (handle === null)
192
+ return null;
193
+ // Leased: hold the process until the run gives it back.
194
+ handle.ref?.();
195
+ return {
196
+ handle,
197
+ release: (discard) => this.give(handle, discard)
198
+ };
199
+ }
200
+ /** Terminate every idle worker. In-flight runs keep the ones they hold. */
201
+ destroy() {
202
+ while (this.idle.length > 0) {
203
+ const handle = this.idle.pop();
204
+ this.live--;
205
+ handle?.terminate();
206
+ }
207
+ }
208
+ async take() {
209
+ const idle = this.idle.pop();
210
+ if (idle !== undefined)
211
+ return idle;
212
+ if (this.live < this.max) {
213
+ this.live++;
214
+ let handle;
215
+ try {
216
+ // One spawn at a time. A burst of runs would otherwise start several
217
+ // workers in parallel, and under tsx each spawn recompiles the whole
218
+ // sandbox graph — four contending compiles turn a 500 ms warm-up into
219
+ // several seconds. Serialized, the first worker comes up while the
220
+ // rest of the burst queues behind it, then drains at per-run cost.
221
+ this.spawnChain = this.spawnChain
222
+ .catch(() => undefined)
223
+ .then(() => this.factory());
224
+ handle = await this.spawnChain;
225
+ }
226
+ catch {
227
+ handle = null;
228
+ }
229
+ if (handle === null)
230
+ this.live--;
231
+ return handle;
232
+ }
233
+ return new Promise((resolve) => {
234
+ this.waiting.push(resolve);
235
+ });
236
+ }
237
+ spawnChain = Promise.resolve(null);
238
+ give(handle, discard) {
239
+ if (discard) {
240
+ this.live--;
241
+ handle.terminate();
242
+ // A waiter must not be stranded behind a worker that no longer exists;
243
+ // wake it so it spawns the replacement itself.
244
+ const waiter = this.waiting.shift();
245
+ if (waiter !== undefined) {
246
+ this.live++;
247
+ void this.factory()
248
+ .then((replacement) => {
249
+ if (replacement === null)
250
+ this.live--;
251
+ waiter(replacement);
252
+ })
253
+ .catch(() => {
254
+ this.live--;
255
+ waiter(null);
256
+ });
257
+ }
258
+ return;
259
+ }
260
+ const waiter = this.waiting.shift();
261
+ if (waiter !== undefined) {
262
+ // Straight into the next run, so it stays leased and stays ref'd.
263
+ waiter(handle);
264
+ return;
265
+ }
266
+ // Idle again: stop holding the process open.
267
+ handle.unref?.();
268
+ this.idle.push(handle);
269
+ }
270
+ }
271
+ let sharedPool;
272
+ /** The process-wide pool. A test passes its own instead. */
273
+ export function defaultSandboxWorkerPool() {
274
+ if (sharedPool === undefined)
275
+ sharedPool = new SandboxWorkerPool();
276
+ return sharedPool;
277
+ }
278
+ function failure(runId, error) {
279
+ return {
280
+ type: "result",
281
+ runId,
282
+ evalOk: false,
283
+ errorName: error instanceof Error ? error.name : "Error",
284
+ errorMessage: error instanceof Error ? error.message : String(error),
285
+ failure: "worker"
286
+ };
287
+ }
288
+ function cancelled(runId) {
289
+ return {
290
+ type: "result",
291
+ runId,
292
+ evalOk: false,
293
+ errorName: "ExecutionCancelled",
294
+ errorMessage: "Execution cancelled",
295
+ failure: "cancelled"
296
+ };
297
+ }
298
+ /**
299
+ * Resolve an RPC path against the dispatch table and call it.
300
+ *
301
+ * The path is data from the worker, so every hop is checked: a path that does
302
+ * not land on a function is an error the guest sees, not a host crash.
303
+ */
304
+ async function dispatchRpc(table, path, args) {
305
+ let current = table;
306
+ for (const segment of path) {
307
+ if (!isObjectLike(current)) {
308
+ throw new Error(`no sandbox bridge at ${path.join(".")}`);
309
+ }
310
+ current = current[segment];
311
+ }
312
+ if (!isFunction(current)) {
313
+ throw new Error(`no sandbox bridge at ${path.join(".")}`);
314
+ }
315
+ return current(...args);
316
+ }
317
+ /**
318
+ * Run one guest program on a pooled worker and return how it settled.
319
+ *
320
+ * The result is always a `ResultMessage`: the guest's own outcome, a cancelled
321
+ * result synthesized when the abort terminated the thread, or a failed result carrying
322
+ * whatever killed the thread. The caller maps a `failure: "worker"` message
323
+ * through `describeEngineFailure`. Returns `null` when no worker could be
324
+ * acquired at all, which is the caller's signal to run in-process.
325
+ */
326
+ export async function runInWorker(options) {
327
+ const runStartedAt = performance.now();
328
+ const pool = options.pool ?? defaultSandboxWorkerPool();
329
+ const acquireStartedAt = performance.now();
330
+ const lease = await pool.acquire();
331
+ const acquireMs = performance.now() - acquireStartedAt;
332
+ if (acquireMs >= SLOW_WORKER_ACQUIRE_MS) {
333
+ log.warn("Slow sandbox worker acquisition", {
334
+ runId: options.run.runId,
335
+ acquireMs
336
+ });
337
+ }
338
+ if (lease === null)
339
+ return null;
340
+ const { handle } = lease;
341
+ const runId = options.run.runId;
342
+ const openHandles = Object.keys(options.run.streamOpenSeed ?? {});
343
+ let closed = new Set(openHandles.filter((name) => options.run.streamOpenSeed?.[name] !== true));
344
+ let lastSuspendedMs = 0;
345
+ let settled = false;
346
+ let discard = false;
347
+ let deadlineTimer;
348
+ let abortListener;
349
+ const result = await new Promise((resolve) => {
350
+ const settle = (result, dropWorker) => {
351
+ if (settled)
352
+ return;
353
+ settled = true;
354
+ discard = discard || dropWorker;
355
+ if (deadlineTimer !== undefined)
356
+ clearTimeout(deadlineTimer);
357
+ if (abortListener !== undefined) {
358
+ options.signal?.removeEventListener("abort", abortListener);
359
+ }
360
+ handle.onMessage(() => { });
361
+ handle.onDeath(() => { });
362
+ lease.release(discard);
363
+ resolve(result);
364
+ };
365
+ // Pushes that ride along with every reply: a suspend credit the interrupt
366
+ // handler reads, and the close-only stream mirror. Both land while the
367
+ // guest is parked on the RPC it just made.
368
+ const pushSideChannels = () => {
369
+ if (settled)
370
+ return;
371
+ if (options.suspendedMs !== undefined) {
372
+ const suspendedMs = options.suspendedMs();
373
+ if (suspendedMs !== lastSuspendedMs) {
374
+ lastSuspendedMs = suspendedMs;
375
+ handle.postMessage({ type: "suspend-update", runId, suspendedMs });
376
+ }
377
+ }
378
+ if (options.isStreamOpen !== undefined) {
379
+ for (const name of openHandles) {
380
+ if (closed.has(name) || options.isStreamOpen(name))
381
+ continue;
382
+ closed = new Set([...closed, name]);
383
+ handle.postMessage({ type: "stream-closed", runId, handle: name });
384
+ }
385
+ }
386
+ };
387
+ handle.onDeath((error) => settle(failure(runId, error), true));
388
+ handle.onMessage((message) => {
389
+ if (settled)
390
+ return;
391
+ switch (message.type) {
392
+ case "log":
393
+ options.onLog(message.line);
394
+ return;
395
+ case "progress":
396
+ options.onProgress(message.percent, message.message);
397
+ return;
398
+ case "result":
399
+ settle(message, message.failure === "worker");
400
+ return;
401
+ case "rpc": {
402
+ const { id, path, args } = message;
403
+ void (async () => {
404
+ try {
405
+ const value = await dispatchRpc(options.dispatch, path, args);
406
+ if (settled)
407
+ return;
408
+ handle.postMessage({ type: "rpc-reply", id, ok: true, value });
409
+ }
410
+ catch (error) {
411
+ if (settled)
412
+ return;
413
+ handle.postMessage({
414
+ type: "rpc-reply",
415
+ id,
416
+ ok: false,
417
+ name: error instanceof Error ? error.name : "Error",
418
+ message: error instanceof Error ? error.message : String(error)
419
+ });
420
+ }
421
+ pushSideChannels();
422
+ })();
423
+ }
424
+ }
425
+ });
426
+ if (options.signal !== undefined) {
427
+ abortListener = () => {
428
+ if (settled)
429
+ return;
430
+ // Kill the thread. Nothing gentler is worth having: the logs and
431
+ // emitted values already live in the main-thread accumulators (port
432
+ // FIFO delivered every RPC the guest made before this), a cancelled
433
+ // action leaving no partial `state` mutation is the cleaner contract,
434
+ // and `terminate()` is equally instant for a guest that spins and one
435
+ // that awaits. The pool replaces the worker lazily.
436
+ settle(cancelled(runId), true);
437
+ };
438
+ if (options.signal.aborted) {
439
+ abortListener();
440
+ }
441
+ else {
442
+ options.signal.addEventListener("abort", abortListener, { once: true });
443
+ }
444
+ }
445
+ // Backstop for a worker that answers nothing at all — a wedged thread never
446
+ // reaches its own deadline, so the main thread keeps one of its own.
447
+ //
448
+ // The suspend allowance only widens it when the run can actually suspend,
449
+ // the way the engine's own abort is sized in `js-sandbox.ts` and
450
+ // `interpreter.ts`. Adding it unconditionally put a ~30 minute floor
451
+ // (`DEFAULT_SUSPEND_ALLOWANCE_MS`) under every run, so a wedged worker —
452
+ // a guest that OOMs marshaling a host value, say — outlived its
453
+ // `timeoutMs` by half an hour instead of failing.
454
+ const backstop = options.run.timeoutMs +
455
+ (options.run.hasClock ? Math.max(0, options.run.suspendAllowanceMs) : 0) +
456
+ DEADLINE_MARGIN_MS;
457
+ deadlineTimer = setTimeout(() => {
458
+ settle(failure(runId, new Error(`the sandbox worker did not answer within ${backstop} ms and was terminated`)), true);
459
+ }, backstop);
460
+ try {
461
+ handle.postMessage({ type: "run", ...options.run });
462
+ }
463
+ catch (error) {
464
+ // A `DataCloneError` here is the pre-scan having missed something; the
465
+ // worker never started, so the thread is still reusable.
466
+ settle(failure(runId, error), false);
467
+ }
468
+ });
469
+ const totalMs = performance.now() - runStartedAt;
470
+ if (totalMs >= SLOW_WORKER_ROUND_TRIP_MS) {
471
+ log.warn("Slow sandbox worker round trip", {
472
+ runId,
473
+ acquireMs,
474
+ workerRoundTripMs: Math.max(0, totalMs - acquireMs),
475
+ totalMs
476
+ });
477
+ }
478
+ return result;
479
+ }
480
+ /** Guest binding names for the dispatchers, re-exported for the caller. */
481
+ export { SANDBOX_DISPATCHER_BINDINGS };
482
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/js-sandbox-worker/host.ts"],"names":[],"mappings":"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"}