@ricsam/isolate 0.0.1 → 0.1.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 (299) hide show
  1. package/README.md +243 -34
  2. package/dist/cjs/bridge/diagnostics.cjs +58 -0
  3. package/dist/cjs/bridge/diagnostics.cjs.map +10 -0
  4. package/dist/cjs/bridge/legacy-adapters.cjs +242 -0
  5. package/dist/cjs/bridge/legacy-adapters.cjs.map +10 -0
  6. package/dist/cjs/bridge/request-context.cjs +59 -0
  7. package/dist/cjs/bridge/request-context.cjs.map +10 -0
  8. package/dist/cjs/bridge/runtime-bindings.cjs +367 -0
  9. package/dist/cjs/bridge/runtime-bindings.cjs.map +10 -0
  10. package/dist/cjs/browser/browser-runtime.cjs +157 -0
  11. package/dist/cjs/browser/browser-runtime.cjs.map +10 -0
  12. package/dist/cjs/daemon.cjs +91 -0
  13. package/dist/cjs/daemon.cjs.map +10 -0
  14. package/dist/cjs/files/index.cjs +140 -0
  15. package/dist/cjs/files/index.cjs.map +10 -0
  16. package/dist/cjs/host/create-isolate-host.cjs +235 -0
  17. package/dist/cjs/host/create-isolate-host.cjs.map +10 -0
  18. package/dist/cjs/host/index.cjs +47 -0
  19. package/dist/cjs/host/index.cjs.map +10 -0
  20. package/dist/cjs/index.cjs +55 -0
  21. package/dist/cjs/index.cjs.map +10 -0
  22. package/dist/cjs/internal/client/connection.cjs +1919 -0
  23. package/dist/cjs/internal/client/connection.cjs.map +10 -0
  24. package/dist/cjs/internal/client/index.cjs +48 -0
  25. package/dist/cjs/internal/client/index.cjs.map +10 -0
  26. package/dist/cjs/internal/client/types.cjs +30 -0
  27. package/dist/cjs/internal/client/types.cjs.map +9 -0
  28. package/dist/cjs/internal/console/index.cjs +506 -0
  29. package/dist/cjs/internal/console/index.cjs.map +10 -0
  30. package/dist/cjs/internal/console/utils.cjs +70 -0
  31. package/dist/cjs/internal/console/utils.cjs.map +10 -0
  32. package/dist/cjs/internal/core/index.cjs +2745 -0
  33. package/dist/cjs/internal/core/index.cjs.map +10 -0
  34. package/dist/cjs/internal/crypto/index.cjs +470 -0
  35. package/dist/cjs/internal/crypto/index.cjs.map +10 -0
  36. package/dist/cjs/internal/daemon/callback-fs-handler.cjs +355 -0
  37. package/dist/cjs/internal/daemon/callback-fs-handler.cjs.map +10 -0
  38. package/dist/cjs/internal/daemon/connection.cjs +1952 -0
  39. package/dist/cjs/internal/daemon/connection.cjs.map +10 -0
  40. package/dist/cjs/internal/daemon/daemon.cjs +98 -0
  41. package/dist/cjs/internal/daemon/daemon.cjs.map +10 -0
  42. package/dist/cjs/internal/daemon/index.cjs +145 -0
  43. package/dist/cjs/internal/daemon/index.cjs.map +10 -0
  44. package/dist/cjs/internal/daemon/runtime-pool.cjs +106 -0
  45. package/dist/cjs/internal/daemon/runtime-pool.cjs.map +10 -0
  46. package/dist/cjs/internal/daemon/types.cjs +30 -0
  47. package/dist/cjs/internal/daemon/types.cjs.map +9 -0
  48. package/dist/cjs/internal/encoding/index.cjs +419 -0
  49. package/dist/cjs/internal/encoding/index.cjs.map +10 -0
  50. package/dist/cjs/internal/fetch/consistency/origins.cjs +598 -0
  51. package/dist/cjs/internal/fetch/consistency/origins.cjs.map +10 -0
  52. package/dist/cjs/internal/fetch/index.cjs +2640 -0
  53. package/dist/cjs/internal/fetch/index.cjs.map +10 -0
  54. package/dist/cjs/internal/fetch/stream-state.cjs +256 -0
  55. package/dist/cjs/internal/fetch/stream-state.cjs.map +10 -0
  56. package/dist/cjs/internal/fs/index.cjs +847 -0
  57. package/dist/cjs/internal/fs/index.cjs.map +10 -0
  58. package/dist/cjs/internal/fs/node-adapter.cjs +254 -0
  59. package/dist/cjs/internal/fs/node-adapter.cjs.map +10 -0
  60. package/dist/cjs/internal/module-loader/bundle.cjs +482 -0
  61. package/dist/cjs/internal/module-loader/bundle.cjs.map +10 -0
  62. package/dist/cjs/internal/module-loader/index.cjs +240 -0
  63. package/dist/cjs/internal/module-loader/index.cjs.map +10 -0
  64. package/dist/cjs/internal/module-loader/mappings.cjs +120 -0
  65. package/dist/cjs/internal/module-loader/mappings.cjs.map +10 -0
  66. package/dist/cjs/internal/module-loader/resolve.cjs +177 -0
  67. package/dist/cjs/internal/module-loader/resolve.cjs.map +10 -0
  68. package/dist/cjs/internal/module-loader/strip-types.cjs +236 -0
  69. package/dist/cjs/internal/module-loader/strip-types.cjs.map +10 -0
  70. package/dist/cjs/internal/path/index.cjs +503 -0
  71. package/dist/cjs/internal/path/index.cjs.map +10 -0
  72. package/dist/cjs/internal/playwright/client.cjs +49 -0
  73. package/dist/cjs/internal/playwright/client.cjs.map +10 -0
  74. package/dist/cjs/internal/playwright/handler.cjs +1416 -0
  75. package/dist/cjs/internal/playwright/handler.cjs.map +10 -0
  76. package/dist/cjs/internal/playwright/index.cjs +1289 -0
  77. package/dist/cjs/internal/playwright/index.cjs.map +10 -0
  78. package/dist/cjs/internal/playwright/types.cjs +47 -0
  79. package/dist/cjs/internal/playwright/types.cjs.map +10 -0
  80. package/dist/cjs/internal/protocol/codec.cjs +510 -0
  81. package/dist/cjs/internal/protocol/codec.cjs.map +10 -0
  82. package/dist/cjs/internal/protocol/framing.cjs +141 -0
  83. package/dist/cjs/internal/protocol/framing.cjs.map +10 -0
  84. package/dist/cjs/internal/protocol/index.cjs +110 -0
  85. package/dist/cjs/internal/protocol/index.cjs.map +10 -0
  86. package/dist/cjs/internal/protocol/marshalValue.cjs +518 -0
  87. package/dist/cjs/internal/protocol/marshalValue.cjs.map +10 -0
  88. package/dist/cjs/internal/protocol/serialization.cjs +109 -0
  89. package/dist/cjs/internal/protocol/serialization.cjs.map +10 -0
  90. package/dist/cjs/internal/protocol/types.cjs +181 -0
  91. package/dist/cjs/internal/protocol/types.cjs.map +10 -0
  92. package/dist/cjs/internal/runtime/index.cjs +1235 -0
  93. package/dist/cjs/internal/runtime/index.cjs.map +10 -0
  94. package/dist/cjs/internal/server/index.cjs +223 -0
  95. package/dist/cjs/internal/server/index.cjs.map +10 -0
  96. package/dist/cjs/internal/test-environment/index.cjs +1415 -0
  97. package/dist/cjs/internal/test-environment/index.cjs.map +10 -0
  98. package/dist/cjs/internal/timers/index.cjs +200 -0
  99. package/dist/cjs/internal/timers/index.cjs.map +10 -0
  100. package/dist/cjs/internal/transform/index.cjs +361 -0
  101. package/dist/cjs/internal/transform/index.cjs.map +10 -0
  102. package/dist/cjs/internal/typecheck/index.cjs +60 -0
  103. package/dist/cjs/internal/typecheck/index.cjs.map +10 -0
  104. package/dist/cjs/internal/typecheck/isolate-types.cjs +2614 -0
  105. package/dist/cjs/internal/typecheck/isolate-types.cjs.map +10 -0
  106. package/dist/cjs/internal/typecheck/typecheck.cjs +131 -0
  107. package/dist/cjs/internal/typecheck/typecheck.cjs.map +10 -0
  108. package/dist/cjs/modules/index.cjs +160 -0
  109. package/dist/cjs/modules/index.cjs.map +10 -0
  110. package/dist/cjs/package.json +5 -0
  111. package/dist/cjs/runtime/script-runtime.cjs +97 -0
  112. package/dist/cjs/runtime/script-runtime.cjs.map +10 -0
  113. package/dist/cjs/server/app-server.cjs +158 -0
  114. package/dist/cjs/server/app-server.cjs.map +10 -0
  115. package/dist/cjs/testing/integration-helpers.cjs +127 -0
  116. package/dist/cjs/testing/integration-helpers.cjs.map +10 -0
  117. package/dist/cjs/typecheck/index.cjs +96 -0
  118. package/dist/cjs/typecheck/index.cjs.map +10 -0
  119. package/dist/cjs/types.cjs +30 -0
  120. package/dist/cjs/types.cjs.map +9 -0
  121. package/dist/mjs/bridge/diagnostics.mjs +18 -0
  122. package/dist/mjs/bridge/diagnostics.mjs.map +10 -0
  123. package/dist/mjs/bridge/legacy-adapters.mjs +178 -0
  124. package/dist/mjs/bridge/legacy-adapters.mjs.map +10 -0
  125. package/dist/mjs/bridge/request-context.mjs +19 -0
  126. package/dist/mjs/bridge/request-context.mjs.map +10 -0
  127. package/dist/mjs/bridge/runtime-bindings.mjs +303 -0
  128. package/dist/mjs/bridge/runtime-bindings.mjs.map +10 -0
  129. package/dist/mjs/browser/browser-runtime.mjs +93 -0
  130. package/dist/mjs/browser/browser-runtime.mjs.map +10 -0
  131. package/dist/mjs/daemon.mjs +91 -0
  132. package/dist/mjs/daemon.mjs.map +10 -0
  133. package/dist/mjs/files/index.mjs +76 -0
  134. package/dist/mjs/files/index.mjs.map +10 -0
  135. package/dist/mjs/host/create-isolate-host.mjs +171 -0
  136. package/dist/mjs/host/create-isolate-host.mjs.map +10 -0
  137. package/dist/mjs/host/index.mjs +7 -0
  138. package/dist/mjs/host/index.mjs.map +10 -0
  139. package/dist/mjs/index.mjs +15 -0
  140. package/dist/mjs/index.mjs.map +10 -0
  141. package/dist/mjs/internal/client/connection.mjs +1872 -0
  142. package/dist/mjs/internal/client/connection.mjs.map +10 -0
  143. package/dist/mjs/internal/client/index.mjs +8 -0
  144. package/dist/mjs/internal/client/index.mjs.map +10 -0
  145. package/dist/mjs/internal/client/types.mjs +2 -0
  146. package/dist/mjs/internal/client/types.mjs.map +9 -0
  147. package/dist/mjs/internal/console/index.mjs +442 -0
  148. package/dist/mjs/internal/console/index.mjs.map +10 -0
  149. package/dist/mjs/internal/console/utils.mjs +30 -0
  150. package/dist/mjs/internal/console/utils.mjs.map +10 -0
  151. package/dist/mjs/internal/core/index.mjs +2681 -0
  152. package/dist/mjs/internal/core/index.mjs.map +10 -0
  153. package/dist/mjs/internal/crypto/index.mjs +406 -0
  154. package/dist/mjs/internal/crypto/index.mjs.map +10 -0
  155. package/dist/mjs/internal/daemon/callback-fs-handler.mjs +315 -0
  156. package/dist/mjs/internal/daemon/callback-fs-handler.mjs.map +10 -0
  157. package/dist/mjs/internal/daemon/connection.mjs +1931 -0
  158. package/dist/mjs/internal/daemon/connection.mjs.map +10 -0
  159. package/dist/mjs/internal/daemon/daemon.mjs +98 -0
  160. package/dist/mjs/internal/daemon/daemon.mjs.map +10 -0
  161. package/dist/mjs/internal/daemon/index.mjs +105 -0
  162. package/dist/mjs/internal/daemon/index.mjs.map +10 -0
  163. package/dist/mjs/internal/daemon/runtime-pool.mjs +66 -0
  164. package/dist/mjs/internal/daemon/runtime-pool.mjs.map +10 -0
  165. package/dist/mjs/internal/daemon/types.mjs +2 -0
  166. package/dist/mjs/internal/daemon/types.mjs.map +9 -0
  167. package/dist/mjs/internal/encoding/index.mjs +379 -0
  168. package/dist/mjs/internal/encoding/index.mjs.map +10 -0
  169. package/dist/mjs/internal/fetch/consistency/origins.mjs +558 -0
  170. package/dist/mjs/internal/fetch/consistency/origins.mjs.map +10 -0
  171. package/dist/mjs/internal/fetch/index.mjs +2580 -0
  172. package/dist/mjs/internal/fetch/index.mjs.map +10 -0
  173. package/dist/mjs/internal/fetch/stream-state.mjs +216 -0
  174. package/dist/mjs/internal/fetch/stream-state.mjs.map +10 -0
  175. package/dist/mjs/internal/fs/index.mjs +783 -0
  176. package/dist/mjs/internal/fs/index.mjs.map +10 -0
  177. package/dist/mjs/internal/fs/node-adapter.mjs +190 -0
  178. package/dist/mjs/internal/fs/node-adapter.mjs.map +10 -0
  179. package/dist/mjs/internal/module-loader/bundle.mjs +418 -0
  180. package/dist/mjs/internal/module-loader/bundle.mjs.map +10 -0
  181. package/dist/mjs/internal/module-loader/index.mjs +185 -0
  182. package/dist/mjs/internal/module-loader/index.mjs.map +10 -0
  183. package/dist/mjs/internal/module-loader/mappings.mjs +80 -0
  184. package/dist/mjs/internal/module-loader/mappings.mjs.map +10 -0
  185. package/dist/mjs/internal/module-loader/resolve.mjs +113 -0
  186. package/dist/mjs/internal/module-loader/resolve.mjs.map +10 -0
  187. package/dist/mjs/internal/module-loader/strip-types.mjs +172 -0
  188. package/dist/mjs/internal/module-loader/strip-types.mjs.map +10 -0
  189. package/dist/mjs/internal/path/index.mjs +463 -0
  190. package/dist/mjs/internal/path/index.mjs.map +10 -0
  191. package/dist/mjs/internal/playwright/client.mjs +13 -0
  192. package/dist/mjs/internal/playwright/client.mjs.map +10 -0
  193. package/dist/mjs/internal/playwright/handler.mjs +1378 -0
  194. package/dist/mjs/internal/playwright/handler.mjs.map +10 -0
  195. package/dist/mjs/internal/playwright/index.mjs +1234 -0
  196. package/dist/mjs/internal/playwright/index.mjs.map +10 -0
  197. package/dist/mjs/internal/playwright/types.mjs +7 -0
  198. package/dist/mjs/internal/playwright/types.mjs.map +10 -0
  199. package/dist/mjs/internal/protocol/codec.mjs +470 -0
  200. package/dist/mjs/internal/protocol/codec.mjs.map +10 -0
  201. package/dist/mjs/internal/protocol/framing.mjs +101 -0
  202. package/dist/mjs/internal/protocol/framing.mjs.map +10 -0
  203. package/dist/mjs/internal/protocol/index.mjs +98 -0
  204. package/dist/mjs/internal/protocol/index.mjs.map +10 -0
  205. package/dist/mjs/internal/protocol/marshalValue.mjs +494 -0
  206. package/dist/mjs/internal/protocol/marshalValue.mjs.map +10 -0
  207. package/dist/mjs/internal/protocol/serialization.mjs +69 -0
  208. package/dist/mjs/internal/protocol/serialization.mjs.map +10 -0
  209. package/dist/mjs/internal/protocol/types.mjs +141 -0
  210. package/dist/mjs/internal/protocol/types.mjs.map +10 -0
  211. package/dist/mjs/internal/runtime/index.mjs +1198 -0
  212. package/dist/mjs/internal/runtime/index.mjs.map +10 -0
  213. package/dist/mjs/internal/server/index.mjs +183 -0
  214. package/dist/mjs/internal/server/index.mjs.map +10 -0
  215. package/dist/mjs/internal/test-environment/index.mjs +1351 -0
  216. package/dist/mjs/internal/test-environment/index.mjs.map +10 -0
  217. package/dist/mjs/internal/timers/index.mjs +136 -0
  218. package/dist/mjs/internal/timers/index.mjs.map +10 -0
  219. package/dist/mjs/internal/transform/index.mjs +321 -0
  220. package/dist/mjs/internal/transform/index.mjs.map +10 -0
  221. package/dist/mjs/internal/typecheck/index.mjs +35 -0
  222. package/dist/mjs/internal/typecheck/index.mjs.map +10 -0
  223. package/dist/mjs/internal/typecheck/isolate-types.mjs +2574 -0
  224. package/dist/mjs/internal/typecheck/isolate-types.mjs.map +10 -0
  225. package/dist/mjs/internal/typecheck/typecheck.mjs +91 -0
  226. package/dist/mjs/internal/typecheck/typecheck.mjs.map +10 -0
  227. package/dist/mjs/modules/index.mjs +96 -0
  228. package/dist/mjs/modules/index.mjs.map +10 -0
  229. package/dist/mjs/package.json +5 -0
  230. package/dist/mjs/runtime/script-runtime.mjs +57 -0
  231. package/dist/mjs/runtime/script-runtime.mjs.map +10 -0
  232. package/dist/mjs/server/app-server.mjs +118 -0
  233. package/dist/mjs/server/app-server.mjs.map +10 -0
  234. package/dist/mjs/testing/integration-helpers.mjs +63 -0
  235. package/dist/mjs/testing/integration-helpers.mjs.map +10 -0
  236. package/dist/mjs/typecheck/index.mjs +56 -0
  237. package/dist/mjs/typecheck/index.mjs.map +10 -0
  238. package/dist/mjs/types.mjs +2 -0
  239. package/dist/mjs/types.mjs.map +9 -0
  240. package/dist/types/bridge/diagnostics.d.ts +12 -0
  241. package/dist/types/bridge/legacy-adapters.d.ts +14 -0
  242. package/dist/types/bridge/request-context.d.ts +10 -0
  243. package/dist/types/bridge/runtime-bindings.d.ts +14 -0
  244. package/dist/types/browser/browser-runtime.d.ts +3 -0
  245. package/dist/types/daemon.d.ts +2 -0
  246. package/dist/types/files/index.d.ts +5 -0
  247. package/dist/types/host/create-isolate-host.d.ts +2 -0
  248. package/dist/types/host/index.d.ts +1 -0
  249. package/dist/types/index.d.ts +5 -0
  250. package/dist/types/internal/client/connection.d.ts +9 -0
  251. package/dist/types/internal/client/index.d.ts +8 -0
  252. package/dist/types/internal/client/types.d.ts +198 -0
  253. package/dist/types/internal/console/index.d.ts +108 -0
  254. package/dist/types/internal/console/utils.d.ts +27 -0
  255. package/dist/types/internal/core/index.d.ts +119 -0
  256. package/dist/types/internal/crypto/index.d.ts +18 -0
  257. package/dist/types/internal/daemon/callback-fs-handler.d.ts +28 -0
  258. package/dist/types/internal/daemon/connection.d.ts +9 -0
  259. package/dist/types/internal/daemon/daemon.d.ts +2 -0
  260. package/dist/types/internal/daemon/index.d.ts +14 -0
  261. package/dist/types/internal/daemon/runtime-pool.d.ts +16 -0
  262. package/dist/types/internal/daemon/types.d.ts +211 -0
  263. package/dist/types/internal/encoding/index.d.ts +21 -0
  264. package/dist/types/internal/fetch/consistency/origins.d.ts +179 -0
  265. package/dist/types/internal/fetch/index.d.ts +93 -0
  266. package/dist/types/internal/fetch/stream-state.d.ts +65 -0
  267. package/dist/types/internal/fs/index.d.ts +70 -0
  268. package/dist/types/internal/fs/node-adapter.d.ts +24 -0
  269. package/dist/types/internal/module-loader/bundle.d.ts +33 -0
  270. package/dist/types/internal/module-loader/index.d.ts +30 -0
  271. package/dist/types/internal/module-loader/mappings.d.ts +47 -0
  272. package/dist/types/internal/module-loader/resolve.d.ts +26 -0
  273. package/dist/types/internal/module-loader/strip-types.d.ts +19 -0
  274. package/dist/types/internal/path/index.d.ts +23 -0
  275. package/dist/types/internal/playwright/client.d.ts +7 -0
  276. package/dist/types/internal/playwright/handler.d.ts +44 -0
  277. package/dist/types/internal/playwright/index.d.ts +14 -0
  278. package/dist/types/internal/playwright/types.d.ts +145 -0
  279. package/dist/types/internal/protocol/codec.d.ts +242 -0
  280. package/dist/types/internal/protocol/framing.d.ts +89 -0
  281. package/dist/types/internal/protocol/index.d.ts +10 -0
  282. package/dist/types/internal/protocol/marshalValue.d.ts +79 -0
  283. package/dist/types/internal/protocol/serialization.d.ts +23 -0
  284. package/dist/types/internal/protocol/types.d.ts +996 -0
  285. package/dist/types/internal/runtime/index.d.ts +200 -0
  286. package/dist/types/internal/server/index.d.ts +42 -0
  287. package/dist/types/internal/test-environment/index.d.ts +112 -0
  288. package/dist/types/internal/timers/index.d.ts +22 -0
  289. package/dist/types/internal/transform/index.d.ts +36 -0
  290. package/dist/types/internal/typecheck/index.d.ts +7 -0
  291. package/dist/types/internal/typecheck/isolate-types.d.ts +94 -0
  292. package/dist/types/internal/typecheck/typecheck.d.ts +148 -0
  293. package/dist/types/modules/index.d.ts +2 -0
  294. package/dist/types/runtime/script-runtime.d.ts +6 -0
  295. package/dist/types/server/app-server.d.ts +3 -0
  296. package/dist/types/testing/integration-helpers.d.ts +9 -0
  297. package/dist/types/typecheck/index.d.ts +8 -0
  298. package/dist/types/types.d.ts +233 -0
  299. package/package.json +82 -6
@@ -0,0 +1,1872 @@
1
+ // src/internal/client/connection.ts
2
+ import { connect as netConnect } from "node:net";
3
+ import path from "node:path";
4
+ import { getRequestContext, withRequestContext } from "../../bridge/request-context.mjs";
5
+ import {
6
+ createFrameParser,
7
+ buildFrame,
8
+ MessageType,
9
+ STREAM_THRESHOLD,
10
+ STREAM_CHUNK_SIZE,
11
+ STREAM_DEFAULT_CREDIT,
12
+ IsolateEvents,
13
+ ClientEvents,
14
+ marshalValue,
15
+ isPromiseRef,
16
+ isAsyncIteratorRef,
17
+ serializeResponse,
18
+ deserializeResponse
19
+ } from "../protocol/index.mjs";
20
+ import {
21
+ defaultPlaywrightHandler,
22
+ getDefaultPlaywrightHandlerMetadata
23
+ } from "../playwright/client.mjs";
24
+ var isolateWsCallbacks = new Map;
25
+ var isolateClientWebSockets = new Map;
26
+ var isolateWebSocketCallbacks = new Map;
27
+ var isolateEventListeners = new Map;
28
+ async function connect(options = {}) {
29
+ const socket = await createSocket(options);
30
+ const state = {
31
+ socket,
32
+ pendingRequests: new Map,
33
+ callbacks: new Map,
34
+ callbacksNeedingRequestId: new Set,
35
+ nextRequestId: 1,
36
+ nextCallbackId: 1,
37
+ nextStreamId: 1,
38
+ connected: true,
39
+ streamResponses: new Map,
40
+ uploadStreams: new Map,
41
+ moduleSourceCache: new Map,
42
+ callbackStreamReaders: new Map,
43
+ activeCallbackInvocations: new Map,
44
+ callbackAbortControllers: new Map,
45
+ closing: false,
46
+ namespacedRuntimes: new Map
47
+ };
48
+ function setupSocket(sock) {
49
+ const parser = createFrameParser();
50
+ sock.on("data", (data) => {
51
+ try {
52
+ for (const frame of parser.feed(new Uint8Array(data))) {
53
+ handleMessage(frame.message, state);
54
+ }
55
+ } catch (err) {
56
+ console.error("Error parsing frame:", err);
57
+ }
58
+ });
59
+ sock.on("close", () => {
60
+ state.connected = false;
61
+ for (const [, pending] of state.pendingRequests) {
62
+ pending.reject(new Error("Connection closed"));
63
+ }
64
+ state.pendingRequests.clear();
65
+ for (const [, receiver] of state.streamResponses) {
66
+ receiver.state = "errored";
67
+ receiver.error = new Error("Connection closed");
68
+ const resolvers = receiver.pullResolvers.splice(0);
69
+ for (const resolver of resolvers) {
70
+ resolver();
71
+ }
72
+ }
73
+ state.streamResponses.clear();
74
+ for (const [, session] of state.uploadStreams) {
75
+ session.state = "closed";
76
+ if (session.creditResolver) {
77
+ session.creditResolver();
78
+ }
79
+ }
80
+ state.uploadStreams.clear();
81
+ for (const [, controller] of state.callbackAbortControllers) {
82
+ controller.abort();
83
+ }
84
+ state.callbackAbortControllers.clear();
85
+ state.activeCallbackInvocations.clear();
86
+ if (!state.closing && state.namespacedRuntimes.size > 0) {
87
+ state.reconnecting = reconnect(state, options).catch(() => {
88
+ state.namespacedRuntimes.clear();
89
+ state.reconnecting = undefined;
90
+ });
91
+ }
92
+ });
93
+ sock.on("error", (err) => {
94
+ if (!state.closing && state.namespacedRuntimes.size > 0)
95
+ return;
96
+ console.error("Socket error:", err);
97
+ });
98
+ }
99
+ setupSocket(socket);
100
+ async function reconnect(st, opts) {
101
+ try {
102
+ const newSocket = await createSocket(opts);
103
+ st.socket = newSocket;
104
+ st.connected = true;
105
+ setupSocket(newSocket);
106
+ for (const [namespaceId, descriptor] of st.namespacedRuntimes) {
107
+ const runtimeOptions = descriptor.runtimeOptions;
108
+ const callbacks = {};
109
+ if (runtimeOptions.console) {
110
+ callbacks.console = registerConsoleCallbacks(st, runtimeOptions.console);
111
+ }
112
+ if (runtimeOptions.fetch) {
113
+ callbacks.fetch = registerFetchCallback(st, runtimeOptions.fetch);
114
+ }
115
+ if (runtimeOptions.fs) {
116
+ callbacks.fs = registerFsCallbacks(st, runtimeOptions.fs);
117
+ }
118
+ if (runtimeOptions.moduleLoader) {
119
+ callbacks.moduleLoader = registerModuleLoaderCallback(st, runtimeOptions.moduleLoader);
120
+ }
121
+ if (runtimeOptions.customFunctions) {
122
+ callbacks.custom = registerCustomFunctions(st, runtimeOptions.customFunctions);
123
+ }
124
+ if (runtimeOptions.playwright) {
125
+ const playwrightHandler = runtimeOptions.playwright.handler;
126
+ if (playwrightHandler) {
127
+ const handlerCallbackId = st.nextCallbackId++;
128
+ st.callbacks.set(handlerCallbackId, async (opJson) => {
129
+ const op = JSON.parse(opJson);
130
+ const result2 = await playwrightHandler(op);
131
+ return JSON.stringify(result2);
132
+ });
133
+ callbacks.playwright = {
134
+ handlerCallbackId,
135
+ console: runtimeOptions.playwright.console && !runtimeOptions.console?.onEntry
136
+ };
137
+ }
138
+ }
139
+ let testEnvironmentOption;
140
+ if (runtimeOptions.testEnvironment) {
141
+ if (typeof runtimeOptions.testEnvironment === "object") {
142
+ const testEnvOptions = runtimeOptions.testEnvironment;
143
+ const testEnvCallbacks = {};
144
+ if (testEnvOptions.onEvent) {
145
+ const userOnEvent = testEnvOptions.onEvent;
146
+ const onEventCallbackId = registerEventCallback(st, (eventJson) => {
147
+ const event = JSON.parse(eventJson);
148
+ userOnEvent(event);
149
+ });
150
+ testEnvCallbacks.onEvent = {
151
+ callbackId: onEventCallbackId,
152
+ name: "testEnvironment.onEvent",
153
+ type: "sync"
154
+ };
155
+ }
156
+ testEnvironmentOption = {
157
+ callbacks: testEnvCallbacks,
158
+ testTimeout: testEnvOptions.testTimeout
159
+ };
160
+ } else {
161
+ testEnvironmentOption = true;
162
+ }
163
+ }
164
+ const playwrightOption = runtimeOptions.playwright?.timeout !== undefined ? { timeout: runtimeOptions.playwright.timeout } : undefined;
165
+ const requestId = st.nextRequestId++;
166
+ const request = {
167
+ type: MessageType.CREATE_RUNTIME,
168
+ requestId,
169
+ options: {
170
+ memoryLimitMB: runtimeOptions.memoryLimitMB,
171
+ executionTimeout: runtimeOptions.executionTimeout,
172
+ cwd: runtimeOptions.cwd,
173
+ callbacks,
174
+ testEnvironment: testEnvironmentOption,
175
+ playwright: playwrightOption,
176
+ namespaceId
177
+ }
178
+ };
179
+ const result = await sendRequest(st, request);
180
+ descriptor.isolateId = result.isolateId;
181
+ }
182
+ st.reconnecting = undefined;
183
+ } catch {
184
+ st.reconnecting = undefined;
185
+ throw new Error("Failed to reconnect to daemon");
186
+ }
187
+ }
188
+ return {
189
+ createRuntime: (runtimeOptions) => createRuntime(state, runtimeOptions),
190
+ createNamespace: (id) => ({
191
+ id,
192
+ createRuntime: (runtimeOptions) => createRuntime(state, runtimeOptions, id)
193
+ }),
194
+ close: async () => {
195
+ state.closing = true;
196
+ state.connected = false;
197
+ state.socket.destroy();
198
+ },
199
+ isConnected: () => state.connected
200
+ };
201
+ }
202
+ function createSocket(options) {
203
+ return new Promise((resolve, reject) => {
204
+ const timeout = options.timeout;
205
+ let socket;
206
+ const onError = (err) => {
207
+ reject(err);
208
+ };
209
+ const onConnect = () => {
210
+ socket.removeListener("error", onError);
211
+ resolve(socket);
212
+ };
213
+ if (options.socket) {
214
+ socket = netConnect(options.socket, onConnect);
215
+ } else {
216
+ socket = netConnect(options.port ?? 47891, options.host ?? "127.0.0.1", onConnect);
217
+ }
218
+ socket.on("error", onError);
219
+ if (timeout && timeout > 0) {
220
+ const timeoutId = setTimeout(() => {
221
+ socket.destroy();
222
+ reject(new Error("Connection timeout"));
223
+ }, timeout);
224
+ socket.once("connect", () => {
225
+ clearTimeout(timeoutId);
226
+ });
227
+ }
228
+ });
229
+ }
230
+ function handleMessage(message, state) {
231
+ switch (message.type) {
232
+ case MessageType.RESPONSE_OK: {
233
+ const response = message;
234
+ const pending = state.pendingRequests.get(response.requestId);
235
+ if (pending) {
236
+ state.pendingRequests.delete(response.requestId);
237
+ pending.resolve(response.data);
238
+ }
239
+ break;
240
+ }
241
+ case MessageType.RESPONSE_ERROR: {
242
+ const response = message;
243
+ const pending = state.pendingRequests.get(response.requestId);
244
+ if (pending) {
245
+ state.pendingRequests.delete(response.requestId);
246
+ const error = new Error(response.message);
247
+ if (response.details) {
248
+ error.name = response.details.name;
249
+ if (response.details.stack) {
250
+ error.stack = response.details.stack;
251
+ }
252
+ }
253
+ pending.reject(error);
254
+ }
255
+ break;
256
+ }
257
+ case MessageType.CALLBACK_INVOKE: {
258
+ const invoke = message;
259
+ handleCallbackInvoke(invoke, state);
260
+ break;
261
+ }
262
+ case MessageType.PONG:
263
+ break;
264
+ case MessageType.CALLBACK_STREAM_CANCEL: {
265
+ const streamId = message.streamId;
266
+ const reader = state.callbackStreamReaders.get(streamId);
267
+ if (reader) {
268
+ reader.cancel().catch(() => {});
269
+ }
270
+ break;
271
+ }
272
+ case MessageType.CALLBACK_ABORT: {
273
+ const msg = message;
274
+ const invocation = state.activeCallbackInvocations.get(msg.targetRequestId);
275
+ if (invocation) {
276
+ invocation.aborted = true;
277
+ }
278
+ const controller = state.callbackAbortControllers.get(msg.targetRequestId);
279
+ if (controller && !controller.signal.aborted) {
280
+ controller.abort();
281
+ }
282
+ break;
283
+ }
284
+ case MessageType.ISOLATE_EVENT: {
285
+ const msg = message;
286
+ handleIsolateEvent(msg, state);
287
+ break;
288
+ }
289
+ case MessageType.RESPONSE_STREAM_START: {
290
+ const msg = message;
291
+ const receiver = {
292
+ streamId: msg.streamId,
293
+ requestId: msg.requestId,
294
+ metadata: msg.metadata,
295
+ controller: null,
296
+ state: "active",
297
+ pendingChunks: [],
298
+ pullResolvers: [],
299
+ controllerFinalized: false
300
+ };
301
+ const readableStream = new ReadableStream({
302
+ start(controller) {
303
+ receiver.controller = controller;
304
+ },
305
+ pull(_controller) {
306
+ if (receiver.controllerFinalized) {
307
+ return;
308
+ }
309
+ while (receiver.pendingChunks.length > 0) {
310
+ const chunk = receiver.pendingChunks.shift();
311
+ receiver.controller.enqueue(chunk);
312
+ }
313
+ if (receiver.state === "closed") {
314
+ if (!receiver.controllerFinalized) {
315
+ receiver.controllerFinalized = true;
316
+ receiver.controller.close();
317
+ }
318
+ return Promise.resolve();
319
+ }
320
+ if (receiver.state === "errored") {
321
+ if (!receiver.controllerFinalized && receiver.error) {
322
+ receiver.controllerFinalized = true;
323
+ receiver.controller.error(receiver.error);
324
+ }
325
+ return Promise.resolve();
326
+ }
327
+ sendMessage(state.socket, {
328
+ type: MessageType.STREAM_PULL,
329
+ streamId: msg.streamId,
330
+ maxBytes: STREAM_DEFAULT_CREDIT
331
+ });
332
+ return new Promise((resolve) => {
333
+ receiver.pullResolvers.push(resolve);
334
+ });
335
+ },
336
+ cancel(_reason) {
337
+ receiver.state = "closed";
338
+ receiver.controllerFinalized = true;
339
+ const resolvers = receiver.pullResolvers.splice(0);
340
+ for (const resolver of resolvers) {
341
+ resolver();
342
+ }
343
+ sendMessage(state.socket, {
344
+ type: MessageType.STREAM_ERROR,
345
+ streamId: msg.streamId,
346
+ error: "Stream cancelled by consumer"
347
+ });
348
+ state.streamResponses.delete(msg.streamId);
349
+ return new Promise((resolve) => setTimeout(resolve, 0));
350
+ }
351
+ });
352
+ state.streamResponses.set(msg.streamId, receiver);
353
+ const pending = state.pendingRequests.get(msg.requestId);
354
+ if (pending) {
355
+ state.pendingRequests.delete(msg.requestId);
356
+ const response = new Response(readableStream, {
357
+ status: msg.metadata?.status ?? 200,
358
+ statusText: msg.metadata?.statusText ?? "OK",
359
+ headers: msg.metadata?.headers
360
+ });
361
+ pending.resolve({ response, __streaming: true });
362
+ }
363
+ sendMessage(state.socket, {
364
+ type: MessageType.STREAM_PULL,
365
+ streamId: msg.streamId,
366
+ maxBytes: STREAM_DEFAULT_CREDIT
367
+ });
368
+ break;
369
+ }
370
+ case MessageType.RESPONSE_STREAM_CHUNK: {
371
+ const msg = message;
372
+ const receiver = state.streamResponses.get(msg.streamId);
373
+ if (receiver && receiver.state === "active") {
374
+ if (receiver.pullResolvers.length > 0) {
375
+ receiver.controller.enqueue(msg.chunk);
376
+ const resolver = receiver.pullResolvers.shift();
377
+ resolver();
378
+ } else {
379
+ receiver.pendingChunks.push(msg.chunk);
380
+ }
381
+ }
382
+ break;
383
+ }
384
+ case MessageType.RESPONSE_STREAM_END: {
385
+ const msg = message;
386
+ const receiver = state.streamResponses.get(msg.streamId);
387
+ if (receiver) {
388
+ receiver.state = "closed";
389
+ while (receiver.pendingChunks.length > 0) {
390
+ const chunk = receiver.pendingChunks.shift();
391
+ receiver.controller.enqueue(chunk);
392
+ }
393
+ if (!receiver.controllerFinalized) {
394
+ receiver.controllerFinalized = true;
395
+ receiver.controller.close();
396
+ }
397
+ const resolvers = receiver.pullResolvers.splice(0);
398
+ for (const resolver of resolvers) {
399
+ resolver();
400
+ }
401
+ state.streamResponses.delete(msg.streamId);
402
+ }
403
+ break;
404
+ }
405
+ case MessageType.STREAM_PULL: {
406
+ const msg = message;
407
+ const session = state.uploadStreams.get(msg.streamId);
408
+ if (session) {
409
+ session.credit += msg.maxBytes;
410
+ if (session.creditResolver) {
411
+ session.creditResolver();
412
+ session.creditResolver = undefined;
413
+ }
414
+ }
415
+ break;
416
+ }
417
+ case MessageType.STREAM_ERROR: {
418
+ const msg = message;
419
+ const uploadSession = state.uploadStreams.get(msg.streamId);
420
+ if (uploadSession) {
421
+ uploadSession.state = "closed";
422
+ state.uploadStreams.delete(msg.streamId);
423
+ }
424
+ const receiver = state.streamResponses.get(msg.streamId);
425
+ if (receiver) {
426
+ receiver.state = "errored";
427
+ receiver.error = new Error(msg.error);
428
+ while (receiver.pendingChunks.length > 0) {
429
+ const chunk = receiver.pendingChunks.shift();
430
+ receiver.controller.enqueue(chunk);
431
+ }
432
+ const resolvers = receiver.pullResolvers.splice(0);
433
+ for (const resolver of resolvers) {
434
+ resolver();
435
+ }
436
+ state.streamResponses.delete(msg.streamId);
437
+ }
438
+ break;
439
+ }
440
+ default:
441
+ console.warn(`Unexpected message type: ${message.type}`);
442
+ }
443
+ }
444
+ async function handleCallbackInvoke(invoke, state) {
445
+ const callback = state.callbacks.get(invoke.callbackId);
446
+ const invocationState = { aborted: false };
447
+ state.activeCallbackInvocations.set(invoke.requestId, invocationState);
448
+ const abortController = new AbortController;
449
+ state.callbackAbortControllers.set(invoke.requestId, abortController);
450
+ const response = {
451
+ type: MessageType.CALLBACK_RESPONSE,
452
+ requestId: invoke.requestId
453
+ };
454
+ if (!callback) {
455
+ response.error = {
456
+ name: "Error",
457
+ message: `Unknown callback: ${invoke.callbackId}`
458
+ };
459
+ if (!invocationState.aborted) {
460
+ sendMessage(state.socket, response);
461
+ }
462
+ state.activeCallbackInvocations.delete(invoke.requestId);
463
+ state.callbackAbortControllers.delete(invoke.requestId);
464
+ } else {
465
+ try {
466
+ const invokeRegisteredCallback = async () => {
467
+ const needsRequestId = state.callbacksNeedingRequestId.has(invoke.callbackId);
468
+ return needsRequestId ? await callback(...invoke.args, invoke.requestId) : await callback(...invoke.args);
469
+ };
470
+ const result = invoke.context ? await withRequestContext({
471
+ requestId: invoke.context.requestId,
472
+ metadata: invoke.context.metadata,
473
+ signal: abortController.signal
474
+ }, invokeRegisteredCallback) : await withRequestContext({
475
+ signal: abortController.signal
476
+ }, invokeRegisteredCallback);
477
+ if (result && typeof result === "object" && result.__callbackStreaming) {
478
+ return;
479
+ }
480
+ if (invocationState.aborted) {
481
+ return;
482
+ }
483
+ response.result = result;
484
+ sendMessage(state.socket, response);
485
+ } catch (err) {
486
+ if (invocationState.aborted) {
487
+ return;
488
+ }
489
+ const error = err;
490
+ response.error = {
491
+ name: error.name,
492
+ message: error.message,
493
+ stack: error.stack
494
+ };
495
+ sendMessage(state.socket, response);
496
+ } finally {
497
+ state.activeCallbackInvocations.delete(invoke.requestId);
498
+ state.callbackAbortControllers.delete(invoke.requestId);
499
+ }
500
+ }
501
+ }
502
+ function sendMessage(socket, message) {
503
+ const frame = buildFrame(message);
504
+ socket.write(frame);
505
+ }
506
+ function sendRequest(state, message) {
507
+ return new Promise((resolve, reject) => {
508
+ if (!state.connected) {
509
+ reject(new Error("Not connected"));
510
+ return;
511
+ }
512
+ const requestId = message.requestId;
513
+ state.pendingRequests.set(requestId, {
514
+ resolve,
515
+ reject
516
+ });
517
+ sendMessage(state.socket, message);
518
+ });
519
+ }
520
+ function isBenignDisposeError(error) {
521
+ const message = error instanceof Error ? error.message : String(error ?? "");
522
+ return /isolate not owned by this connection|isolate not found|not connected|connection closed/i.test(message);
523
+ }
524
+ function normalizePlaywrightOptions(playwrightOptions) {
525
+ if (!playwrightOptions || playwrightOptions.timeout === undefined) {
526
+ return playwrightOptions;
527
+ }
528
+ const metadata = getDefaultPlaywrightHandlerMetadata(playwrightOptions.handler);
529
+ if (!metadata?.page) {
530
+ return playwrightOptions;
531
+ }
532
+ const currentTimeout = metadata.options?.timeout ?? 30000;
533
+ if (currentTimeout === playwrightOptions.timeout) {
534
+ return playwrightOptions;
535
+ }
536
+ return {
537
+ ...playwrightOptions,
538
+ handler: defaultPlaywrightHandler(metadata.page, {
539
+ ...metadata.options,
540
+ timeout: playwrightOptions.timeout
541
+ })
542
+ };
543
+ }
544
+ async function createRuntime(state, options = {}, namespaceId) {
545
+ const normalizedPlaywrightOptions = normalizePlaywrightOptions(options.playwright);
546
+ const runtimeOptionsForReconnect = normalizedPlaywrightOptions === options.playwright ? options : {
547
+ ...options,
548
+ playwright: normalizedPlaywrightOptions
549
+ };
550
+ const callbacks = {};
551
+ if (options.console) {
552
+ callbacks.console = registerConsoleCallbacks(state, options.console);
553
+ }
554
+ if (options.fetch) {
555
+ callbacks.fetch = registerFetchCallback(state, options.fetch);
556
+ }
557
+ if (options.fs) {
558
+ callbacks.fs = registerFsCallbacks(state, options.fs);
559
+ }
560
+ if (options.moduleLoader) {
561
+ callbacks.moduleLoader = registerModuleLoaderCallback(state, options.moduleLoader);
562
+ }
563
+ if (options.customFunctions) {
564
+ callbacks.custom = registerCustomFunctions(state, options.customFunctions);
565
+ }
566
+ let playwrightHandler;
567
+ const browserConsoleLogs = [];
568
+ const pageErrors = [];
569
+ const networkRequests = [];
570
+ const networkResponses = [];
571
+ const requestFailures = [];
572
+ const pageListenerCleanups = [];
573
+ if (normalizedPlaywrightOptions) {
574
+ playwrightHandler = normalizedPlaywrightOptions.handler;
575
+ if (!playwrightHandler) {
576
+ throw new Error("playwright.handler is required when using playwright options");
577
+ }
578
+ const page = getDefaultPlaywrightHandlerMetadata(playwrightHandler)?.page;
579
+ const handlerCallbackId = state.nextCallbackId++;
580
+ state.callbacks.set(handlerCallbackId, async (opJson) => {
581
+ const op = JSON.parse(opJson);
582
+ const result2 = await playwrightHandler(op);
583
+ return JSON.stringify(result2);
584
+ });
585
+ if (page) {
586
+ const requestIds = new WeakMap;
587
+ let nextRequestId = 1;
588
+ const getRequestId = (request2) => {
589
+ let requestId2 = requestIds.get(request2);
590
+ if (!requestId2) {
591
+ requestId2 = `req_${nextRequestId++}`;
592
+ requestIds.set(request2, requestId2);
593
+ }
594
+ return requestId2;
595
+ };
596
+ const toLocation = (location) => {
597
+ if (!location || !location.url && location.lineNumber == null && location.columnNumber == null) {
598
+ return;
599
+ }
600
+ return {
601
+ url: location.url || undefined,
602
+ lineNumber: location.lineNumber != null ? location.lineNumber + 1 : undefined,
603
+ columnNumber: location.columnNumber != null ? location.columnNumber + 1 : undefined
604
+ };
605
+ };
606
+ const onConsole = (msg) => {
607
+ const entry = {
608
+ level: msg.type(),
609
+ stdout: msg.text(),
610
+ location: toLocation(msg.location()),
611
+ timestamp: Date.now()
612
+ };
613
+ browserConsoleLogs.push(entry);
614
+ if (normalizedPlaywrightOptions.onEvent) {
615
+ normalizedPlaywrightOptions.onEvent({
616
+ type: "browserConsoleLog",
617
+ ...entry
618
+ });
619
+ }
620
+ if (normalizedPlaywrightOptions.console && options.console?.onEntry) {
621
+ options.console.onEntry({
622
+ type: "browserOutput",
623
+ ...entry
624
+ });
625
+ } else if (normalizedPlaywrightOptions.console) {
626
+ const prefix = entry.level === "error" ? "[browser:error]" : "[browser]";
627
+ console.log(prefix, entry.stdout);
628
+ }
629
+ };
630
+ const onRequest = (request2) => {
631
+ const info = {
632
+ requestId: getRequestId(request2),
633
+ url: request2.url(),
634
+ method: request2.method(),
635
+ headers: request2.headers(),
636
+ postData: request2.postData() ?? undefined,
637
+ resourceType: request2.resourceType(),
638
+ timestamp: Date.now()
639
+ };
640
+ networkRequests.push(info);
641
+ if (normalizedPlaywrightOptions.onEvent) {
642
+ normalizedPlaywrightOptions.onEvent({
643
+ type: "networkRequest",
644
+ ...info
645
+ });
646
+ }
647
+ };
648
+ const onResponse = (response) => {
649
+ const request2 = response.request();
650
+ const info = {
651
+ requestId: getRequestId(request2),
652
+ url: response.url(),
653
+ status: response.status(),
654
+ statusText: response.statusText(),
655
+ headers: response.headers(),
656
+ resourceType: request2.resourceType(),
657
+ timestamp: Date.now()
658
+ };
659
+ networkResponses.push(info);
660
+ if (normalizedPlaywrightOptions.onEvent) {
661
+ normalizedPlaywrightOptions.onEvent({
662
+ type: "networkResponse",
663
+ ...info
664
+ });
665
+ }
666
+ };
667
+ const onRequestFailed = (request2) => {
668
+ const info = {
669
+ requestId: getRequestId(request2),
670
+ url: request2.url(),
671
+ method: request2.method(),
672
+ failureText: request2.failure()?.errorText || "request failed",
673
+ resourceType: request2.resourceType(),
674
+ timestamp: Date.now()
675
+ };
676
+ requestFailures.push(info);
677
+ if (normalizedPlaywrightOptions.onEvent) {
678
+ normalizedPlaywrightOptions.onEvent({
679
+ type: "requestFailure",
680
+ ...info
681
+ });
682
+ }
683
+ };
684
+ const onPageError = (error) => {
685
+ const entry = {
686
+ name: error.name,
687
+ message: error.message,
688
+ stack: error.stack,
689
+ timestamp: Date.now()
690
+ };
691
+ pageErrors.push(entry);
692
+ if (normalizedPlaywrightOptions.onEvent) {
693
+ normalizedPlaywrightOptions.onEvent({
694
+ type: "pageError",
695
+ ...entry
696
+ });
697
+ }
698
+ };
699
+ page.on("console", onConsole);
700
+ page.on("request", onRequest);
701
+ page.on("response", onResponse);
702
+ page.on("requestfailed", onRequestFailed);
703
+ page.on("pageerror", onPageError);
704
+ pageListenerCleanups.push(() => page.removeListener("console", onConsole), () => page.removeListener("request", onRequest), () => page.removeListener("response", onResponse), () => page.removeListener("requestfailed", onRequestFailed), () => page.removeListener("pageerror", onPageError));
705
+ }
706
+ callbacks.playwright = {
707
+ handlerCallbackId,
708
+ console: normalizedPlaywrightOptions.console && !options.console?.onEntry
709
+ };
710
+ }
711
+ let testEnvironmentOption;
712
+ if (options.testEnvironment) {
713
+ if (typeof options.testEnvironment === "object") {
714
+ const testEnvOptions = options.testEnvironment;
715
+ const testEnvCallbacks = {};
716
+ if (testEnvOptions.onEvent) {
717
+ const userOnEvent = testEnvOptions.onEvent;
718
+ const onEventCallbackId = registerEventCallback(state, (eventJson) => {
719
+ const event = JSON.parse(eventJson);
720
+ userOnEvent(event);
721
+ });
722
+ testEnvCallbacks.onEvent = {
723
+ callbackId: onEventCallbackId,
724
+ name: "testEnvironment.onEvent",
725
+ type: "sync"
726
+ };
727
+ }
728
+ testEnvironmentOption = {
729
+ callbacks: testEnvCallbacks,
730
+ testTimeout: testEnvOptions.testTimeout
731
+ };
732
+ } else {
733
+ testEnvironmentOption = true;
734
+ }
735
+ }
736
+ const playwrightOption = normalizedPlaywrightOptions?.timeout !== undefined ? { timeout: normalizedPlaywrightOptions.timeout } : undefined;
737
+ const requestId = state.nextRequestId++;
738
+ const request = {
739
+ type: MessageType.CREATE_RUNTIME,
740
+ requestId,
741
+ options: {
742
+ memoryLimitMB: options.memoryLimitMB,
743
+ executionTimeout: options.executionTimeout,
744
+ cwd: options.cwd,
745
+ callbacks,
746
+ testEnvironment: testEnvironmentOption,
747
+ playwright: playwrightOption,
748
+ namespaceId
749
+ }
750
+ };
751
+ const result = await sendRequest(state, request);
752
+ const isolateId = result.isolateId;
753
+ const reused = result.reused ?? false;
754
+ if (namespaceId != null) {
755
+ state.namespacedRuntimes.set(namespaceId, {
756
+ isolateId,
757
+ runtimeOptions: runtimeOptionsForReconnect
758
+ });
759
+ }
760
+ const wsCommandCallbacks = new Set;
761
+ isolateWsCallbacks.set(isolateId, wsCommandCallbacks);
762
+ if (options.onWebSocketCommand) {
763
+ wsCommandCallbacks.add(options.onWebSocketCommand);
764
+ }
765
+ if (options.webSocket) {
766
+ isolateWebSocketCallbacks.set(isolateId, options.webSocket);
767
+ }
768
+ const fetchHandle = {
769
+ async dispatchRequest(req, opts) {
770
+ const signal = opts?.signal;
771
+ const requestSignal = req.signal;
772
+ const requestSignalInitiallyAborted = requestSignal?.aborted ?? false;
773
+ const reqId = state.nextRequestId++;
774
+ const serialized = await serializeRequestWithStreaming(state, req);
775
+ const { bodyStream, ...serializableRequest } = serialized;
776
+ const request2 = {
777
+ type: MessageType.DISPATCH_REQUEST,
778
+ requestId: reqId,
779
+ isolateId,
780
+ request: serializableRequest,
781
+ context: opts?.requestId || opts?.metadata ? {
782
+ requestId: opts.requestId,
783
+ metadata: opts.metadata
784
+ } : undefined
785
+ };
786
+ const handleResponse = (res) => {
787
+ if (res.__streaming && res.response instanceof Response) {
788
+ return res.response;
789
+ }
790
+ return deserializeResponse(res.response);
791
+ };
792
+ let abortSent = false;
793
+ const sendAbort = () => {
794
+ if (abortSent) {
795
+ return;
796
+ }
797
+ abortSent = true;
798
+ const abortMessage = {
799
+ type: MessageType.DISPATCH_REQUEST_ABORT,
800
+ isolateId,
801
+ targetRequestId: reqId
802
+ };
803
+ if (state.connected) {
804
+ sendMessage(state.socket, abortMessage);
805
+ }
806
+ };
807
+ let onAbort;
808
+ if (signal) {
809
+ onAbort = sendAbort;
810
+ signal.addEventListener("abort", onAbort, { once: true });
811
+ if (signal.aborted) {
812
+ sendAbort();
813
+ }
814
+ }
815
+ let onRequestAbort;
816
+ if (requestSignal && !requestSignalInitiallyAborted) {
817
+ onRequestAbort = sendAbort;
818
+ requestSignal.addEventListener("abort", onRequestAbort, { once: true });
819
+ if (requestSignal.aborted) {
820
+ sendAbort();
821
+ }
822
+ }
823
+ request2.request.signalAborted = (request2.request.signalAborted ?? false) || signal?.aborted === true;
824
+ try {
825
+ if (serialized.bodyStreamId !== undefined && bodyStream) {
826
+ const streamId = serialized.bodyStreamId;
827
+ const responsePromise = sendRequest(state, request2);
828
+ await sendBodyStream(state, streamId, bodyStream);
829
+ const res = await responsePromise;
830
+ return handleResponse(res);
831
+ } else {
832
+ const res = await sendRequest(state, request2);
833
+ return handleResponse(res);
834
+ }
835
+ } finally {
836
+ if (signal && onAbort) {
837
+ signal.removeEventListener("abort", onAbort);
838
+ }
839
+ if (requestSignal && onRequestAbort) {
840
+ requestSignal.removeEventListener("abort", onRequestAbort);
841
+ }
842
+ }
843
+ },
844
+ async getUpgradeRequest() {
845
+ const reqId = state.nextRequestId++;
846
+ const req = {
847
+ type: MessageType.FETCH_GET_UPGRADE_REQUEST,
848
+ requestId: reqId,
849
+ isolateId
850
+ };
851
+ return sendRequest(state, req);
852
+ },
853
+ async dispatchWebSocketOpen(connectionId) {
854
+ const reqId = state.nextRequestId++;
855
+ const req = {
856
+ type: MessageType.WS_OPEN,
857
+ requestId: reqId,
858
+ isolateId,
859
+ connectionId
860
+ };
861
+ await sendRequest(state, req);
862
+ },
863
+ async dispatchWebSocketMessage(connectionId, message) {
864
+ const reqId = state.nextRequestId++;
865
+ const data = message instanceof ArrayBuffer ? new Uint8Array(message) : message;
866
+ const req = {
867
+ type: MessageType.WS_MESSAGE,
868
+ requestId: reqId,
869
+ isolateId,
870
+ connectionId,
871
+ data
872
+ };
873
+ await sendRequest(state, req);
874
+ },
875
+ async dispatchWebSocketClose(connectionId, code, reason) {
876
+ const reqId = state.nextRequestId++;
877
+ const req = {
878
+ type: MessageType.WS_CLOSE,
879
+ requestId: reqId,
880
+ isolateId,
881
+ connectionId,
882
+ code,
883
+ reason
884
+ };
885
+ await sendRequest(state, req);
886
+ },
887
+ async dispatchWebSocketError(connectionId, error) {
888
+ const reqId = state.nextRequestId++;
889
+ const req = {
890
+ type: MessageType.FETCH_WS_ERROR,
891
+ requestId: reqId,
892
+ isolateId,
893
+ connectionId,
894
+ error: error.message
895
+ };
896
+ await sendRequest(state, req);
897
+ },
898
+ onWebSocketCommand(callback) {
899
+ wsCommandCallbacks.add(callback);
900
+ return () => {
901
+ wsCommandCallbacks.delete(callback);
902
+ };
903
+ },
904
+ async hasServeHandler() {
905
+ const reqId = state.nextRequestId++;
906
+ const req = {
907
+ type: MessageType.FETCH_HAS_SERVE_HANDLER,
908
+ requestId: reqId,
909
+ isolateId
910
+ };
911
+ return sendRequest(state, req);
912
+ },
913
+ async hasActiveConnections() {
914
+ const reqId = state.nextRequestId++;
915
+ const req = {
916
+ type: MessageType.FETCH_HAS_ACTIVE_CONNECTIONS,
917
+ requestId: reqId,
918
+ isolateId
919
+ };
920
+ return sendRequest(state, req);
921
+ }
922
+ };
923
+ const timersHandle = {
924
+ async clearAll() {
925
+ const reqId = state.nextRequestId++;
926
+ const req = {
927
+ type: MessageType.TIMERS_CLEAR_ALL,
928
+ requestId: reqId,
929
+ isolateId
930
+ };
931
+ await sendRequest(state, req);
932
+ }
933
+ };
934
+ const consoleHandle = {
935
+ async reset() {
936
+ const reqId = state.nextRequestId++;
937
+ const req = {
938
+ type: MessageType.CONSOLE_RESET,
939
+ requestId: reqId,
940
+ isolateId
941
+ };
942
+ await sendRequest(state, req);
943
+ },
944
+ async getTimers() {
945
+ const reqId = state.nextRequestId++;
946
+ const req = {
947
+ type: MessageType.CONSOLE_GET_TIMERS,
948
+ requestId: reqId,
949
+ isolateId
950
+ };
951
+ const result2 = await sendRequest(state, req);
952
+ return new Map(Object.entries(result2));
953
+ },
954
+ async getCounters() {
955
+ const reqId = state.nextRequestId++;
956
+ const req = {
957
+ type: MessageType.CONSOLE_GET_COUNTERS,
958
+ requestId: reqId,
959
+ isolateId
960
+ };
961
+ const result2 = await sendRequest(state, req);
962
+ return new Map(Object.entries(result2));
963
+ },
964
+ async getGroupDepth() {
965
+ const reqId = state.nextRequestId++;
966
+ const req = {
967
+ type: MessageType.CONSOLE_GET_GROUP_DEPTH,
968
+ requestId: reqId,
969
+ isolateId
970
+ };
971
+ return sendRequest(state, req);
972
+ }
973
+ };
974
+ const testEnvironmentEnabled = !!options.testEnvironment;
975
+ const playwrightEnabled = !!normalizedPlaywrightOptions;
976
+ const testEnvironmentHandle = {
977
+ async runTests(timeout) {
978
+ if (!testEnvironmentEnabled) {
979
+ throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
980
+ }
981
+ const reqId = state.nextRequestId++;
982
+ const req = {
983
+ type: MessageType.RUN_TESTS,
984
+ requestId: reqId,
985
+ isolateId,
986
+ timeout
987
+ };
988
+ try {
989
+ return await sendRequest(state, req);
990
+ } catch (err) {
991
+ if (err instanceof Error && /connection closed|not connected/i.test(err.message) && state.reconnecting) {
992
+ await state.reconnecting;
993
+ const retryReqId = state.nextRequestId++;
994
+ const retryReq = {
995
+ type: MessageType.RUN_TESTS,
996
+ requestId: retryReqId,
997
+ isolateId,
998
+ timeout
999
+ };
1000
+ return sendRequest(state, retryReq);
1001
+ }
1002
+ throw err;
1003
+ }
1004
+ },
1005
+ async hasTests() {
1006
+ if (!testEnvironmentEnabled) {
1007
+ throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
1008
+ }
1009
+ const reqId = state.nextRequestId++;
1010
+ const req = {
1011
+ type: MessageType.HAS_TESTS,
1012
+ requestId: reqId,
1013
+ isolateId
1014
+ };
1015
+ return sendRequest(state, req);
1016
+ },
1017
+ async getTestCount() {
1018
+ if (!testEnvironmentEnabled) {
1019
+ throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
1020
+ }
1021
+ const reqId = state.nextRequestId++;
1022
+ const req = {
1023
+ type: MessageType.GET_TEST_COUNT,
1024
+ requestId: reqId,
1025
+ isolateId
1026
+ };
1027
+ return sendRequest(state, req);
1028
+ },
1029
+ async reset() {
1030
+ if (!testEnvironmentEnabled) {
1031
+ throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
1032
+ }
1033
+ const reqId = state.nextRequestId++;
1034
+ const req = {
1035
+ type: MessageType.RESET_TEST_ENV,
1036
+ requestId: reqId,
1037
+ isolateId
1038
+ };
1039
+ await sendRequest(state, req);
1040
+ }
1041
+ };
1042
+ const playwrightHandle = {
1043
+ getCollectedData() {
1044
+ if (!playwrightEnabled) {
1045
+ throw new Error("Playwright not configured. Provide playwright.handler in createRuntime options.");
1046
+ }
1047
+ return {
1048
+ browserConsoleLogs: [...browserConsoleLogs],
1049
+ pageErrors: [...pageErrors],
1050
+ networkRequests: [...networkRequests],
1051
+ networkResponses: [...networkResponses],
1052
+ requestFailures: [...requestFailures]
1053
+ };
1054
+ },
1055
+ clearCollectedData() {
1056
+ if (!playwrightEnabled) {
1057
+ throw new Error("Playwright not configured. Provide playwright.handler in createRuntime options.");
1058
+ }
1059
+ browserConsoleLogs.length = 0;
1060
+ pageErrors.length = 0;
1061
+ networkRequests.length = 0;
1062
+ networkResponses.length = 0;
1063
+ requestFailures.length = 0;
1064
+ }
1065
+ };
1066
+ return {
1067
+ id: isolateId,
1068
+ reused,
1069
+ fetch: fetchHandle,
1070
+ timers: timersHandle,
1071
+ console: consoleHandle,
1072
+ testEnvironment: testEnvironmentHandle,
1073
+ playwright: playwrightHandle,
1074
+ eval: async (code, filenameOrOptions) => {
1075
+ const reqId = state.nextRequestId++;
1076
+ const options2 = typeof filenameOrOptions === "string" ? { filename: filenameOrOptions } : filenameOrOptions;
1077
+ const req = {
1078
+ type: MessageType.EVAL,
1079
+ requestId: reqId,
1080
+ isolateId,
1081
+ code,
1082
+ filename: options2?.filename,
1083
+ executionTimeout: options2?.executionTimeout
1084
+ };
1085
+ await sendRequest(state, req);
1086
+ },
1087
+ on(event, callback) {
1088
+ let listeners = isolateEventListeners.get(isolateId);
1089
+ if (!listeners) {
1090
+ listeners = new Map;
1091
+ isolateEventListeners.set(isolateId, listeners);
1092
+ }
1093
+ let eventListeners = listeners.get(event);
1094
+ if (!eventListeners) {
1095
+ eventListeners = new Set;
1096
+ listeners.set(event, eventListeners);
1097
+ }
1098
+ eventListeners.add(callback);
1099
+ return () => {
1100
+ eventListeners.delete(callback);
1101
+ if (eventListeners.size === 0) {
1102
+ listeners.delete(event);
1103
+ if (listeners.size === 0) {
1104
+ isolateEventListeners.delete(isolateId);
1105
+ }
1106
+ }
1107
+ };
1108
+ },
1109
+ emit(event, payload) {
1110
+ sendMessage(state.socket, {
1111
+ type: MessageType.CLIENT_EVENT,
1112
+ isolateId,
1113
+ event,
1114
+ payload
1115
+ });
1116
+ },
1117
+ dispose: async (options2) => {
1118
+ for (const cleanup of pageListenerCleanups) {
1119
+ cleanup();
1120
+ }
1121
+ isolateWsCallbacks.delete(isolateId);
1122
+ isolateWebSocketCallbacks.delete(isolateId);
1123
+ isolateEventListeners.delete(isolateId);
1124
+ const clientSockets = isolateClientWebSockets.get(isolateId);
1125
+ if (clientSockets) {
1126
+ for (const ws of clientSockets.values()) {
1127
+ if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
1128
+ ws.close(1000, "Isolate disposed");
1129
+ }
1130
+ }
1131
+ isolateClientWebSockets.delete(isolateId);
1132
+ }
1133
+ if (namespaceId != null) {
1134
+ state.namespacedRuntimes.delete(namespaceId);
1135
+ }
1136
+ const reqId = state.nextRequestId++;
1137
+ const req = {
1138
+ type: MessageType.DISPOSE_RUNTIME,
1139
+ requestId: reqId,
1140
+ isolateId,
1141
+ hard: options2?.hard === true ? true : undefined,
1142
+ reason: typeof options2?.reason === "string" && options2.reason.length > 0 ? options2.reason : undefined
1143
+ };
1144
+ try {
1145
+ await sendRequest(state, req);
1146
+ } catch (error) {
1147
+ if (!isBenignDisposeError(error)) {
1148
+ throw error;
1149
+ }
1150
+ }
1151
+ }
1152
+ };
1153
+ }
1154
+ function registerEventCallback(state, handler) {
1155
+ const callbackId = state.nextCallbackId++;
1156
+ state.callbacks.set(callbackId, (data) => {
1157
+ handler(data);
1158
+ return;
1159
+ });
1160
+ return callbackId;
1161
+ }
1162
+ function registerConsoleCallbacks(state, callbacks) {
1163
+ const registrations = {};
1164
+ if (callbacks.onEntry) {
1165
+ const callbackId = state.nextCallbackId++;
1166
+ state.callbacks.set(callbackId, (entry) => {
1167
+ callbacks.onEntry(entry);
1168
+ });
1169
+ registrations.onEntry = { callbackId, name: "onEntry", type: "sync" };
1170
+ }
1171
+ return registrations;
1172
+ }
1173
+ var CALLBACK_STREAM_THRESHOLD = 64 * 1024;
1174
+ var NULL_BODY_STATUSES = new Set([101, 103, 204, 205, 304]);
1175
+ function registerFetchCallback(state, callback) {
1176
+ const callbackId = state.nextCallbackId++;
1177
+ state.callbacksNeedingRequestId.add(callbackId);
1178
+ state.callbacks.set(callbackId, async (serialized, requestId) => {
1179
+ const data = serialized;
1180
+ const requestContext = getRequestContext();
1181
+ const signalController = new AbortController;
1182
+ const onContextAbort = () => {
1183
+ if (!signalController.signal.aborted) {
1184
+ signalController.abort(requestContext.signal?.reason ?? Object.assign(new Error("The operation was aborted."), {
1185
+ name: "AbortError"
1186
+ }));
1187
+ }
1188
+ };
1189
+ if (requestContext.signal) {
1190
+ requestContext.signal.addEventListener("abort", onContextAbort, {
1191
+ once: true
1192
+ });
1193
+ if (requestContext.signal.aborted) {
1194
+ onContextAbort();
1195
+ }
1196
+ }
1197
+ if (data.signalAborted) {
1198
+ signalController.abort();
1199
+ }
1200
+ try {
1201
+ const init = {
1202
+ method: data.method,
1203
+ headers: data.headers,
1204
+ rawBody: data.body ?? null,
1205
+ body: data.body ?? null,
1206
+ signal: signalController.signal
1207
+ };
1208
+ const response = await callback(data.url, init);
1209
+ const contentLength = response.headers.get("content-length");
1210
+ const knownSize = contentLength ? parseInt(contentLength, 10) : null;
1211
+ const isNetworkResponse = response.url && (response.url.startsWith("http://") || response.url.startsWith("https://"));
1212
+ const shouldStream = isNetworkResponse && !NULL_BODY_STATUSES.has(response.status) && !!response.body && (knownSize === null || knownSize > CALLBACK_STREAM_THRESHOLD);
1213
+ if (shouldStream && response.body) {
1214
+ const streamId = state.nextStreamId++;
1215
+ const headers = [];
1216
+ response.headers.forEach((value, key) => {
1217
+ headers.push([key, value]);
1218
+ });
1219
+ sendMessage(state.socket, {
1220
+ type: MessageType.CALLBACK_STREAM_START,
1221
+ requestId,
1222
+ streamId,
1223
+ metadata: {
1224
+ status: response.status,
1225
+ statusText: response.statusText,
1226
+ headers,
1227
+ url: response.url || undefined
1228
+ }
1229
+ });
1230
+ streamCallbackResponseBody(state, streamId, requestId, response.body);
1231
+ return { __callbackStreaming: true, streamId };
1232
+ }
1233
+ return serializeResponse(response);
1234
+ } finally {
1235
+ if (requestContext.signal) {
1236
+ requestContext.signal.removeEventListener("abort", onContextAbort);
1237
+ }
1238
+ }
1239
+ });
1240
+ return { callbackId, name: "fetch", type: "async" };
1241
+ }
1242
+ async function streamCallbackResponseBody(state, streamId, requestId, body) {
1243
+ const reader = body.getReader();
1244
+ state.callbackStreamReaders.set(streamId, reader);
1245
+ try {
1246
+ while (true) {
1247
+ const { done, value } = await reader.read();
1248
+ if (done) {
1249
+ sendMessage(state.socket, {
1250
+ type: MessageType.CALLBACK_STREAM_END,
1251
+ requestId,
1252
+ streamId
1253
+ });
1254
+ break;
1255
+ }
1256
+ for (let offset = 0;offset < value.length; offset += STREAM_CHUNK_SIZE) {
1257
+ const chunk = value.slice(offset, offset + STREAM_CHUNK_SIZE);
1258
+ sendMessage(state.socket, {
1259
+ type: MessageType.CALLBACK_STREAM_CHUNK,
1260
+ requestId,
1261
+ streamId,
1262
+ chunk
1263
+ });
1264
+ }
1265
+ }
1266
+ } catch (err) {
1267
+ if (!(err instanceof Error && err.message.includes("cancel"))) {
1268
+ sendMessage(state.socket, {
1269
+ type: MessageType.STREAM_ERROR,
1270
+ streamId,
1271
+ error: err.message
1272
+ });
1273
+ }
1274
+ } finally {
1275
+ state.callbackStreamReaders.delete(streamId);
1276
+ reader.releaseLock();
1277
+ }
1278
+ }
1279
+ function registerFsCallbacks(state, callbacks) {
1280
+ const registrations = {};
1281
+ if (callbacks.readFile) {
1282
+ const callbackId = state.nextCallbackId++;
1283
+ state.callbacks.set(callbackId, async (path2) => {
1284
+ const result = await callbacks.readFile(path2);
1285
+ return new Uint8Array(result);
1286
+ });
1287
+ registrations.readFile = { callbackId, name: "readFile", type: "async" };
1288
+ }
1289
+ if (callbacks.writeFile) {
1290
+ const callbackId = state.nextCallbackId++;
1291
+ state.callbacks.set(callbackId, async (path2, data) => {
1292
+ let buffer;
1293
+ if (data instanceof Uint8Array) {
1294
+ buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
1295
+ } else if (Array.isArray(data)) {
1296
+ buffer = new Uint8Array(data).buffer;
1297
+ } else if (data instanceof ArrayBuffer) {
1298
+ buffer = data;
1299
+ } else {
1300
+ buffer = new ArrayBuffer(0);
1301
+ }
1302
+ await callbacks.writeFile(path2, buffer);
1303
+ });
1304
+ registrations.writeFile = { callbackId, name: "writeFile", type: "async" };
1305
+ }
1306
+ if (callbacks.unlink) {
1307
+ const callbackId = state.nextCallbackId++;
1308
+ state.callbacks.set(callbackId, async (path2) => {
1309
+ await callbacks.unlink(path2);
1310
+ });
1311
+ registrations.unlink = { callbackId, name: "unlink", type: "async" };
1312
+ }
1313
+ if (callbacks.readdir) {
1314
+ const callbackId = state.nextCallbackId++;
1315
+ state.callbacks.set(callbackId, async (path2) => {
1316
+ return callbacks.readdir(path2);
1317
+ });
1318
+ registrations.readdir = { callbackId, name: "readdir", type: "async" };
1319
+ }
1320
+ if (callbacks.mkdir) {
1321
+ const callbackId = state.nextCallbackId++;
1322
+ state.callbacks.set(callbackId, async (path2, options) => {
1323
+ await callbacks.mkdir(path2, options);
1324
+ });
1325
+ registrations.mkdir = { callbackId, name: "mkdir", type: "async" };
1326
+ }
1327
+ if (callbacks.rmdir) {
1328
+ const callbackId = state.nextCallbackId++;
1329
+ state.callbacks.set(callbackId, async (path2) => {
1330
+ await callbacks.rmdir(path2);
1331
+ });
1332
+ registrations.rmdir = { callbackId, name: "rmdir", type: "async" };
1333
+ }
1334
+ if (callbacks.stat) {
1335
+ const callbackId = state.nextCallbackId++;
1336
+ state.callbacks.set(callbackId, async (path2) => {
1337
+ return callbacks.stat(path2);
1338
+ });
1339
+ registrations.stat = { callbackId, name: "stat", type: "async" };
1340
+ }
1341
+ if (callbacks.rename) {
1342
+ const callbackId = state.nextCallbackId++;
1343
+ state.callbacks.set(callbackId, async (from, to) => {
1344
+ await callbacks.rename(from, to);
1345
+ });
1346
+ registrations.rename = { callbackId, name: "rename", type: "async" };
1347
+ }
1348
+ return registrations;
1349
+ }
1350
+ function registerModuleLoaderCallback(state, callback) {
1351
+ const callbackId = state.nextCallbackId++;
1352
+ state.callbacks.set(callbackId, async (moduleName, importer) => {
1353
+ const specifier = moduleName;
1354
+ const importerInfo = importer;
1355
+ const result = await callback(specifier, importerInfo);
1356
+ const resolvedPath = path.posix.join(result.resolveDir, result.filename);
1357
+ state.moduleSourceCache.set(resolvedPath, result.code);
1358
+ return result;
1359
+ });
1360
+ return { callbackId, name: "moduleLoader", type: "async" };
1361
+ }
1362
+ var clientIteratorSessions = new Map;
1363
+ var nextClientIteratorId = 1;
1364
+ var returnedPromiseRegistry = new Map;
1365
+ var returnedIteratorRegistry = new Map;
1366
+ function registerCustomFunctions(state, customFunctions) {
1367
+ const registrations = {};
1368
+ for (const [name, def] of Object.entries(customFunctions)) {
1369
+ if (def.type === "asyncIterator") {
1370
+ const startCallbackId = state.nextCallbackId++;
1371
+ state.callbacks.set(startCallbackId, async (...args) => {
1372
+ try {
1373
+ const fn = def.fn;
1374
+ const iterator = fn(...args);
1375
+ const iteratorId = nextClientIteratorId++;
1376
+ clientIteratorSessions.set(iteratorId, { iterator });
1377
+ return { iteratorId };
1378
+ } catch (error) {
1379
+ throw error;
1380
+ }
1381
+ });
1382
+ const nextCallbackId = state.nextCallbackId++;
1383
+ state.callbacks.set(nextCallbackId, async (iteratorId) => {
1384
+ const session = clientIteratorSessions.get(iteratorId);
1385
+ if (!session) {
1386
+ throw new Error(`Iterator session ${iteratorId} not found`);
1387
+ }
1388
+ try {
1389
+ const result = await session.iterator.next();
1390
+ if (result.done) {
1391
+ clientIteratorSessions.delete(iteratorId);
1392
+ }
1393
+ return { done: result.done, value: await marshalValue(result.value) };
1394
+ } catch (error) {
1395
+ clientIteratorSessions.delete(iteratorId);
1396
+ throw error;
1397
+ }
1398
+ });
1399
+ const returnCallbackId = state.nextCallbackId++;
1400
+ state.callbacks.set(returnCallbackId, async (iteratorId, value) => {
1401
+ const session = clientIteratorSessions.get(iteratorId);
1402
+ if (!session) {
1403
+ return { done: true, value: await marshalValue(undefined) };
1404
+ }
1405
+ try {
1406
+ const result = await session.iterator.return?.(value);
1407
+ clientIteratorSessions.delete(iteratorId);
1408
+ return { done: true, value: await marshalValue(result?.value) };
1409
+ } catch (error) {
1410
+ clientIteratorSessions.delete(iteratorId);
1411
+ throw error;
1412
+ }
1413
+ });
1414
+ const throwCallbackId = state.nextCallbackId++;
1415
+ state.callbacks.set(throwCallbackId, async (iteratorId, errorData) => {
1416
+ const session = clientIteratorSessions.get(iteratorId);
1417
+ if (!session) {
1418
+ throw new Error(`Iterator session ${iteratorId} not found`);
1419
+ }
1420
+ try {
1421
+ const errInfo = errorData;
1422
+ const error = Object.assign(new Error(errInfo.message), { name: errInfo.name });
1423
+ const result = await session.iterator.throw?.(error);
1424
+ clientIteratorSessions.delete(iteratorId);
1425
+ return { done: result?.done ?? true, value: await marshalValue(result?.value) };
1426
+ } catch (error) {
1427
+ clientIteratorSessions.delete(iteratorId);
1428
+ throw error;
1429
+ }
1430
+ });
1431
+ registrations[`${name}:start`] = { callbackId: startCallbackId, name: `${name}:start`, type: "async" };
1432
+ registrations[`${name}:next`] = { callbackId: nextCallbackId, name: `${name}:next`, type: "async" };
1433
+ registrations[`${name}:return`] = { callbackId: returnCallbackId, name: `${name}:return`, type: "async" };
1434
+ registrations[`${name}:throw`] = { callbackId: throwCallbackId, name: `${name}:throw`, type: "async" };
1435
+ registrations[name] = {
1436
+ callbackId: startCallbackId,
1437
+ name,
1438
+ type: "asyncIterator"
1439
+ };
1440
+ } else {
1441
+ const callbackId = state.nextCallbackId++;
1442
+ state.callbacks.set(callbackId, async (...args) => {
1443
+ const result = await def.fn(...args);
1444
+ const addCallbackIdsToRefs = (value) => {
1445
+ if (value === null || typeof value !== "object") {
1446
+ return value;
1447
+ }
1448
+ if (isPromiseRef(value)) {
1449
+ const resolveCallbackId = state.nextCallbackId++;
1450
+ state.callbacks.set(resolveCallbackId, async (...args2) => {
1451
+ const promiseId = args2[0];
1452
+ const promise = returnedPromiseRegistry.get(promiseId);
1453
+ if (!promise) {
1454
+ throw new Error(`Promise ${promiseId} not found`);
1455
+ }
1456
+ const promiseResult = await promise;
1457
+ returnedPromiseRegistry.delete(promiseId);
1458
+ const marshalledResult = await marshalValue(promiseResult, marshalCtx);
1459
+ return addCallbackIdsToRefs(marshalledResult);
1460
+ });
1461
+ return {
1462
+ ...value,
1463
+ __resolveCallbackId: resolveCallbackId
1464
+ };
1465
+ }
1466
+ if (isAsyncIteratorRef(value)) {
1467
+ const nextCallbackId = state.nextCallbackId++;
1468
+ state.callbacks.set(nextCallbackId, async (...args2) => {
1469
+ const iteratorId = args2[0];
1470
+ const iterator = returnedIteratorRegistry.get(iteratorId);
1471
+ if (!iterator) {
1472
+ throw new Error(`Iterator ${iteratorId} not found`);
1473
+ }
1474
+ const iterResult = await iterator.next();
1475
+ if (iterResult.done) {
1476
+ returnedIteratorRegistry.delete(iteratorId);
1477
+ }
1478
+ const marshalledValue = await marshalValue(iterResult.value, marshalCtx);
1479
+ return {
1480
+ done: iterResult.done,
1481
+ value: addCallbackIdsToRefs(marshalledValue)
1482
+ };
1483
+ });
1484
+ const returnCallbackId = state.nextCallbackId++;
1485
+ state.callbacks.set(returnCallbackId, async (...args2) => {
1486
+ const iteratorId = args2[0];
1487
+ const returnValue = args2[1];
1488
+ const iterator = returnedIteratorRegistry.get(iteratorId);
1489
+ returnedIteratorRegistry.delete(iteratorId);
1490
+ if (!iterator || !iterator.return) {
1491
+ return { done: true, value: undefined };
1492
+ }
1493
+ const iterResult = await iterator.return(returnValue);
1494
+ const marshalledValue = await marshalValue(iterResult.value, marshalCtx);
1495
+ return {
1496
+ done: true,
1497
+ value: addCallbackIdsToRefs(marshalledValue)
1498
+ };
1499
+ });
1500
+ const throwCallbackId = state.nextCallbackId++;
1501
+ state.callbacks.set(throwCallbackId, async (...args2) => {
1502
+ const iteratorId = args2[0];
1503
+ const errorValue = args2[1];
1504
+ const iterator = returnedIteratorRegistry.get(iteratorId);
1505
+ if (!iterator) {
1506
+ throw new Error(`Iterator ${iteratorId} not found`);
1507
+ }
1508
+ try {
1509
+ if (!iterator.throw) {
1510
+ throw Object.assign(new Error(errorValue?.message ?? "Iterator does not support throw()"), { name: errorValue?.name ?? "Error", stack: errorValue?.stack });
1511
+ }
1512
+ const thrownError = Object.assign(new Error(errorValue?.message ?? "Iterator throw()"), { name: errorValue?.name ?? "Error", stack: errorValue?.stack });
1513
+ const iterResult = await iterator.throw(thrownError);
1514
+ if (iterResult.done) {
1515
+ returnedIteratorRegistry.delete(iteratorId);
1516
+ }
1517
+ const marshalledValue = await marshalValue(iterResult.value, marshalCtx);
1518
+ return {
1519
+ done: iterResult.done,
1520
+ value: addCallbackIdsToRefs(marshalledValue)
1521
+ };
1522
+ } catch (error) {
1523
+ returnedIteratorRegistry.delete(iteratorId);
1524
+ throw error;
1525
+ }
1526
+ });
1527
+ return {
1528
+ ...value,
1529
+ __nextCallbackId: nextCallbackId,
1530
+ __returnCallbackId: returnCallbackId,
1531
+ __throwCallbackId: throwCallbackId
1532
+ };
1533
+ }
1534
+ if (Array.isArray(value)) {
1535
+ return value.map((item) => addCallbackIdsToRefs(item));
1536
+ }
1537
+ const objResult = {};
1538
+ for (const key of Object.keys(value)) {
1539
+ objResult[key] = addCallbackIdsToRefs(value[key]);
1540
+ }
1541
+ return objResult;
1542
+ };
1543
+ const marshalCtx = {
1544
+ registerCallback: (fn) => {
1545
+ const returnedCallbackId = state.nextCallbackId++;
1546
+ state.callbacks.set(returnedCallbackId, async (...args2) => {
1547
+ const fnResult = await fn(...args2);
1548
+ const marshalledResult = await marshalValue(fnResult, marshalCtx);
1549
+ return addCallbackIdsToRefs(marshalledResult);
1550
+ });
1551
+ return returnedCallbackId;
1552
+ },
1553
+ registerPromise: (promise) => {
1554
+ const promiseId = state.nextCallbackId++;
1555
+ returnedPromiseRegistry.set(promiseId, promise);
1556
+ return promiseId;
1557
+ },
1558
+ registerIterator: (iterator) => {
1559
+ const iteratorId = state.nextCallbackId++;
1560
+ returnedIteratorRegistry.set(iteratorId, iterator);
1561
+ return iteratorId;
1562
+ }
1563
+ };
1564
+ const marshalled = await marshalValue(result, marshalCtx);
1565
+ const withCallbackIds = addCallbackIdsToRefs(marshalled);
1566
+ return withCallbackIds;
1567
+ });
1568
+ registrations[name] = {
1569
+ callbackId,
1570
+ name,
1571
+ type: def.type
1572
+ };
1573
+ }
1574
+ }
1575
+ return registrations;
1576
+ }
1577
+ async function serializeRequestWithStreaming(state, request) {
1578
+ const headers = [];
1579
+ request.headers.forEach((value, key) => {
1580
+ headers.push([key, value]);
1581
+ });
1582
+ let body = null;
1583
+ let bodyStreamId;
1584
+ let bodyStream;
1585
+ if (request.body) {
1586
+ const contentLength = request.headers.get("content-length");
1587
+ const knownSize = contentLength ? parseInt(contentLength, 10) : null;
1588
+ if (knownSize !== null && knownSize > STREAM_THRESHOLD) {
1589
+ bodyStreamId = state.nextStreamId++;
1590
+ bodyStream = request.body;
1591
+ } else {
1592
+ const clonedRequest = request.clone();
1593
+ try {
1594
+ body = new Uint8Array(await request.arrayBuffer());
1595
+ if (body.length > STREAM_THRESHOLD) {
1596
+ bodyStreamId = state.nextStreamId++;
1597
+ bodyStream = clonedRequest.body;
1598
+ body = null;
1599
+ }
1600
+ } catch {
1601
+ bodyStreamId = state.nextStreamId++;
1602
+ bodyStream = clonedRequest.body;
1603
+ }
1604
+ }
1605
+ }
1606
+ const result = {
1607
+ method: request.method,
1608
+ url: request.url,
1609
+ headers,
1610
+ body,
1611
+ signalAborted: request.signal?.aborted ?? false
1612
+ };
1613
+ if (bodyStreamId !== undefined) {
1614
+ result.bodyStreamId = bodyStreamId;
1615
+ result.bodyStream = bodyStream;
1616
+ }
1617
+ return result;
1618
+ }
1619
+ function waitForUploadCredit(session) {
1620
+ return new Promise((resolve) => {
1621
+ session.creditResolver = resolve;
1622
+ });
1623
+ }
1624
+ async function sendBodyStream(state, streamId, body) {
1625
+ const session = {
1626
+ streamId,
1627
+ requestId: 0,
1628
+ state: "active",
1629
+ bytesTransferred: 0,
1630
+ credit: 0
1631
+ };
1632
+ state.uploadStreams.set(streamId, session);
1633
+ const reader = body.getReader();
1634
+ try {
1635
+ while (true) {
1636
+ if (session.state !== "active") {
1637
+ throw new Error("Stream cancelled");
1638
+ }
1639
+ while (session.credit < STREAM_CHUNK_SIZE && session.state === "active") {
1640
+ await waitForUploadCredit(session);
1641
+ }
1642
+ if (session.state !== "active") {
1643
+ throw new Error("Stream cancelled");
1644
+ }
1645
+ const { done, value } = await reader.read();
1646
+ if (done) {
1647
+ sendMessage(state.socket, {
1648
+ type: MessageType.STREAM_CLOSE,
1649
+ streamId
1650
+ });
1651
+ break;
1652
+ }
1653
+ for (let offset = 0;offset < value.length; offset += STREAM_CHUNK_SIZE) {
1654
+ const chunk = value.slice(offset, offset + STREAM_CHUNK_SIZE);
1655
+ sendMessage(state.socket, {
1656
+ type: MessageType.STREAM_PUSH,
1657
+ streamId,
1658
+ chunk
1659
+ });
1660
+ session.credit -= chunk.length;
1661
+ session.bytesTransferred += chunk.length;
1662
+ }
1663
+ }
1664
+ } catch (err) {
1665
+ sendMessage(state.socket, {
1666
+ type: MessageType.STREAM_ERROR,
1667
+ streamId,
1668
+ error: err.message
1669
+ });
1670
+ throw err;
1671
+ } finally {
1672
+ reader.releaseLock();
1673
+ state.uploadStreams.delete(streamId);
1674
+ }
1675
+ }
1676
+ function handleIsolateEvent(message, state) {
1677
+ switch (message.event) {
1678
+ case IsolateEvents.WS_COMMAND: {
1679
+ const payload = message.payload;
1680
+ const callbacks = isolateWsCallbacks.get(message.isolateId);
1681
+ if (callbacks) {
1682
+ let data;
1683
+ if (payload.data instanceof Uint8Array) {
1684
+ data = payload.data.buffer.slice(payload.data.byteOffset, payload.data.byteOffset + payload.data.byteLength);
1685
+ } else {
1686
+ data = payload.data;
1687
+ }
1688
+ const cmd = {
1689
+ type: payload.type,
1690
+ connectionId: payload.connectionId,
1691
+ data,
1692
+ code: payload.code,
1693
+ reason: payload.reason
1694
+ };
1695
+ for (const cb of callbacks) {
1696
+ cb(cmd);
1697
+ }
1698
+ }
1699
+ break;
1700
+ }
1701
+ case IsolateEvents.WS_CLIENT_CONNECT: {
1702
+ const payload = message.payload;
1703
+ handleClientWsConnect(message.isolateId, payload, state);
1704
+ break;
1705
+ }
1706
+ case IsolateEvents.WS_CLIENT_SEND: {
1707
+ const payload = message.payload;
1708
+ handleClientWsSend(message.isolateId, payload, state);
1709
+ break;
1710
+ }
1711
+ case IsolateEvents.WS_CLIENT_CLOSE: {
1712
+ const payload = message.payload;
1713
+ handleClientWsClose(message.isolateId, payload, state);
1714
+ break;
1715
+ }
1716
+ default: {
1717
+ const listeners = isolateEventListeners.get(message.isolateId);
1718
+ if (listeners) {
1719
+ const eventListeners = listeners.get(message.event);
1720
+ if (eventListeners) {
1721
+ for (const cb of eventListeners) {
1722
+ cb(message.payload);
1723
+ }
1724
+ }
1725
+ }
1726
+ break;
1727
+ }
1728
+ }
1729
+ }
1730
+ function handleClientWsConnect(isolateId, payload, state) {
1731
+ const { socketId, url, protocols } = payload;
1732
+ let sockets = isolateClientWebSockets.get(isolateId);
1733
+ if (!sockets) {
1734
+ sockets = new Map;
1735
+ isolateClientWebSockets.set(isolateId, sockets);
1736
+ }
1737
+ const setupWebSocket = (ws) => {
1738
+ sockets.set(socketId, ws);
1739
+ ws.onopen = () => {
1740
+ sendMessage(state.socket, {
1741
+ type: MessageType.CLIENT_EVENT,
1742
+ isolateId,
1743
+ event: ClientEvents.WS_CLIENT_OPENED,
1744
+ payload: { socketId, protocol: ws.protocol || "", extensions: ws.extensions || "" }
1745
+ });
1746
+ };
1747
+ ws.onmessage = (event) => {
1748
+ let data;
1749
+ if (typeof event.data === "string") {
1750
+ data = event.data;
1751
+ } else if (event.data instanceof ArrayBuffer) {
1752
+ data = new Uint8Array(event.data);
1753
+ } else if (event.data instanceof Blob) {
1754
+ event.data.arrayBuffer().then((buffer) => {
1755
+ sendMessage(state.socket, {
1756
+ type: MessageType.CLIENT_EVENT,
1757
+ isolateId,
1758
+ event: ClientEvents.WS_CLIENT_MESSAGE,
1759
+ payload: { socketId, data: new Uint8Array(buffer) }
1760
+ });
1761
+ });
1762
+ return;
1763
+ } else {
1764
+ data = String(event.data);
1765
+ }
1766
+ sendMessage(state.socket, {
1767
+ type: MessageType.CLIENT_EVENT,
1768
+ isolateId,
1769
+ event: ClientEvents.WS_CLIENT_MESSAGE,
1770
+ payload: { socketId, data }
1771
+ });
1772
+ };
1773
+ ws.onerror = () => {
1774
+ sendMessage(state.socket, {
1775
+ type: MessageType.CLIENT_EVENT,
1776
+ isolateId,
1777
+ event: ClientEvents.WS_CLIENT_ERROR,
1778
+ payload: { socketId }
1779
+ });
1780
+ };
1781
+ ws.onclose = (event) => {
1782
+ sendMessage(state.socket, {
1783
+ type: MessageType.CLIENT_EVENT,
1784
+ isolateId,
1785
+ event: ClientEvents.WS_CLIENT_CLOSED,
1786
+ payload: { socketId, code: event.code, reason: event.reason, wasClean: event.wasClean }
1787
+ });
1788
+ sockets?.delete(socketId);
1789
+ if (sockets?.size === 0) {
1790
+ isolateClientWebSockets.delete(isolateId);
1791
+ }
1792
+ };
1793
+ };
1794
+ const sendConnectionFailed = (reason) => {
1795
+ sendMessage(state.socket, {
1796
+ type: MessageType.CLIENT_EVENT,
1797
+ isolateId,
1798
+ event: ClientEvents.WS_CLIENT_ERROR,
1799
+ payload: { socketId }
1800
+ });
1801
+ sendMessage(state.socket, {
1802
+ type: MessageType.CLIENT_EVENT,
1803
+ isolateId,
1804
+ event: ClientEvents.WS_CLIENT_CLOSED,
1805
+ payload: { socketId, code: 1006, reason, wasClean: false }
1806
+ });
1807
+ };
1808
+ const callback = isolateWebSocketCallbacks.get(isolateId);
1809
+ if (callback) {
1810
+ try {
1811
+ const result = callback(url, protocols || []);
1812
+ if (result instanceof Promise) {
1813
+ result.then((ws) => {
1814
+ if (ws === null) {
1815
+ sendConnectionFailed("Connection blocked");
1816
+ } else {
1817
+ setupWebSocket(ws);
1818
+ }
1819
+ }).catch(() => {
1820
+ sendConnectionFailed("Callback error");
1821
+ });
1822
+ } else if (result === null) {
1823
+ sendConnectionFailed("Connection blocked");
1824
+ } else {
1825
+ setupWebSocket(result);
1826
+ }
1827
+ } catch {
1828
+ sendConnectionFailed("Callback error");
1829
+ }
1830
+ } else {
1831
+ try {
1832
+ const ws = protocols && protocols.length > 0 ? new WebSocket(url, protocols) : new WebSocket(url);
1833
+ setupWebSocket(ws);
1834
+ } catch {
1835
+ sendConnectionFailed("Connection failed");
1836
+ }
1837
+ }
1838
+ }
1839
+ function handleClientWsSend(isolateId, payload, state) {
1840
+ const { socketId, data } = payload;
1841
+ const sockets = isolateClientWebSockets.get(isolateId);
1842
+ const ws = sockets?.get(socketId);
1843
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
1844
+ return;
1845
+ }
1846
+ if (typeof data === "string" && data.startsWith("__BINARY__")) {
1847
+ const base64 = data.slice(10);
1848
+ const binary = Buffer.from(base64, "base64");
1849
+ ws.send(binary);
1850
+ } else if (data instanceof Uint8Array) {
1851
+ ws.send(Buffer.from(data));
1852
+ } else {
1853
+ ws.send(data);
1854
+ }
1855
+ }
1856
+ function handleClientWsClose(isolateId, payload, state) {
1857
+ const { socketId, code, reason } = payload;
1858
+ const sockets = isolateClientWebSockets.get(isolateId);
1859
+ const ws = sockets?.get(socketId);
1860
+ if (!ws) {
1861
+ return;
1862
+ }
1863
+ if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
1864
+ ws.close(code ?? 1000, reason ?? "");
1865
+ }
1866
+ }
1867
+ export {
1868
+ isBenignDisposeError,
1869
+ connect
1870
+ };
1871
+
1872
+ //# debugId=A51B4D1A68FB019F64756E2164756E21