wasm-idle 0.7.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/README.md +760 -81
  2. package/dist/index.d.ts +4 -9
  3. package/dist/index.js +2 -4
  4. package/dist/playground/applicationAssets.d.ts +4 -0
  5. package/dist/playground/applicationAssets.js +277 -0
  6. package/dist/playground/assemblyscript.d.ts +41 -0
  7. package/dist/playground/assemblyscript.js +630 -0
  8. package/dist/playground/assetBridge.d.ts +18 -7
  9. package/dist/playground/assetBridge.js +824 -100
  10. package/dist/playground/assets.d.ts +813 -19
  11. package/dist/playground/assets.js +2096 -156
  12. package/dist/playground/awk.d.ts +5 -0
  13. package/dist/playground/awk.js +60 -0
  14. package/dist/playground/bash.d.ts +53 -0
  15. package/dist/playground/bash.js +1096 -0
  16. package/dist/playground/bashWorkerProtocol.d.ts +88 -0
  17. package/dist/playground/bashWorkerProtocol.js +135 -0
  18. package/dist/playground/bqn.d.ts +5 -0
  19. package/dist/playground/bqn.js +57 -0
  20. package/dist/playground/bqnPreflight.d.ts +26 -0
  21. package/dist/playground/bqnPreflight.js +399 -0
  22. package/dist/playground/c3.d.ts +15 -0
  23. package/dist/playground/c3.js +154 -0
  24. package/dist/playground/clang.d.ts +35 -19
  25. package/dist/playground/clang.js +241 -52
  26. package/dist/playground/clangAssetIntegrity.d.ts +32 -0
  27. package/dist/playground/clangAssetIntegrity.js +8 -0
  28. package/dist/playground/clojurescript.d.ts +5 -0
  29. package/dist/playground/clojurescript.js +59 -0
  30. package/dist/playground/clojurescriptPreflight.d.ts +26 -0
  31. package/dist/playground/clojurescriptPreflight.js +383 -0
  32. package/dist/playground/cobol.d.ts +46 -0
  33. package/dist/playground/cobol.js +703 -0
  34. package/dist/playground/d.d.ts +47 -0
  35. package/dist/playground/d.js +644 -0
  36. package/dist/playground/dOuterAssets.d.ts +16 -0
  37. package/dist/playground/dOuterAssets.js +163 -0
  38. package/dist/playground/dotnet.d.ts +99 -0
  39. package/dist/playground/dotnet.js +1131 -0
  40. package/dist/playground/duckdb.d.ts +36 -0
  41. package/dist/playground/duckdb.js +542 -0
  42. package/dist/playground/elixir.d.ts +18 -10
  43. package/dist/playground/elixir.js +630 -96
  44. package/dist/playground/elixirAssets.d.ts +6 -0
  45. package/dist/playground/elixirAssets.js +33 -0
  46. package/dist/playground/executionObservation.d.ts +22 -0
  47. package/dist/playground/executionObservation.js +65 -0
  48. package/dist/playground/forth.d.ts +5 -0
  49. package/dist/playground/forth.js +53 -0
  50. package/dist/playground/forthPreflight.d.ts +24 -0
  51. package/dist/playground/forthPreflight.js +198 -0
  52. package/dist/playground/fortran.d.ts +47 -0
  53. package/dist/playground/fortran.js +651 -0
  54. package/dist/playground/fortranAssets.d.ts +6 -0
  55. package/dist/playground/fortranAssets.js +27 -0
  56. package/dist/playground/gleam.d.ts +6 -0
  57. package/dist/playground/gleam.js +33 -0
  58. package/dist/playground/go.d.ts +17 -11
  59. package/dist/playground/go.js +376 -72
  60. package/dist/playground/goDebugInstrumentation.d.ts +1 -0
  61. package/dist/playground/goDebugInstrumentation.js +229 -0
  62. package/dist/playground/haskell.d.ts +44 -0
  63. package/dist/playground/haskell.js +678 -0
  64. package/dist/playground/haskellAssets.d.ts +24 -0
  65. package/dist/playground/haskellAssets.js +93 -0
  66. package/dist/playground/index.d.ts +1 -1
  67. package/dist/playground/index.js +360 -111
  68. package/dist/playground/j.d.ts +5 -0
  69. package/dist/playground/j.js +60 -0
  70. package/dist/playground/jPreflight.d.ts +26 -0
  71. package/dist/playground/jPreflight.js +372 -0
  72. package/dist/playground/janet.d.ts +5 -0
  73. package/dist/playground/janet.js +64 -0
  74. package/dist/playground/java.d.ts +24 -10
  75. package/dist/playground/java.js +706 -84
  76. package/dist/playground/javaSource.d.ts +5 -0
  77. package/dist/playground/javaSource.js +16 -0
  78. package/dist/playground/javaStdin.d.ts +1 -1
  79. package/dist/playground/javaStdin.js +13 -4
  80. package/dist/playground/julia.d.ts +5 -0
  81. package/dist/playground/julia.js +64 -0
  82. package/dist/playground/lfortran.d.ts +8 -0
  83. package/dist/playground/lfortran.js +30 -0
  84. package/dist/playground/lfortranAssets.d.ts +21 -0
  85. package/dist/playground/lfortranAssets.js +118 -0
  86. package/dist/playground/lisp.d.ts +45 -0
  87. package/dist/playground/lisp.js +640 -0
  88. package/dist/playground/lispAssets.d.ts +9 -0
  89. package/dist/playground/lispAssets.js +74 -0
  90. package/dist/playground/lldbManifest.d.ts +3 -0
  91. package/dist/playground/lldbManifest.js +155 -0
  92. package/dist/playground/lldbSession.d.ts +115 -0
  93. package/dist/playground/lldbSession.js +1347 -0
  94. package/dist/playground/loadingProgress.d.ts +16 -0
  95. package/dist/playground/loadingProgress.js +166 -0
  96. package/dist/playground/lua.d.ts +44 -0
  97. package/dist/playground/lua.js +630 -0
  98. package/dist/playground/nim.d.ts +5 -0
  99. package/dist/playground/nim.js +76 -0
  100. package/dist/playground/objectivec.d.ts +39 -0
  101. package/dist/playground/objectivec.js +288 -0
  102. package/dist/playground/ocaml.d.ts +28 -10
  103. package/dist/playground/ocaml.js +815 -253
  104. package/dist/playground/octave.d.ts +43 -0
  105. package/dist/playground/octave.js +783 -0
  106. package/dist/playground/options.d.ts +19 -40
  107. package/dist/playground/options.js +2 -1
  108. package/dist/playground/pascal.d.ts +5 -0
  109. package/dist/playground/pascal.js +60 -0
  110. package/dist/playground/perl.d.ts +5 -0
  111. package/dist/playground/perl.js +61 -0
  112. package/dist/playground/php.d.ts +44 -0
  113. package/dist/playground/php.js +665 -0
  114. package/dist/playground/prolog.d.ts +6 -0
  115. package/dist/playground/prolog.js +75 -0
  116. package/dist/playground/python.d.ts +20 -14
  117. package/dist/playground/python.js +445 -101
  118. package/dist/playground/pythonPackageLock.d.ts +6 -0
  119. package/dist/playground/pythonPackageLock.js +56 -0
  120. package/dist/playground/r.d.ts +44 -0
  121. package/dist/playground/r.js +637 -0
  122. package/dist/playground/ruby.d.ts +46 -0
  123. package/dist/playground/ruby.js +732 -0
  124. package/dist/playground/rubyAssets.d.ts +23 -0
  125. package/dist/playground/rubyAssets.js +68 -0
  126. package/dist/playground/rubyTestPreflight.d.ts +2 -0
  127. package/dist/playground/rubyTestPreflight.js +18 -0
  128. package/dist/playground/runtimeModule.d.ts +1 -0
  129. package/dist/playground/runtimeModule.js +5 -0
  130. package/dist/playground/rust.d.ts +44 -13
  131. package/dist/playground/rust.js +714 -76
  132. package/dist/playground/rustExecutableGraph.d.ts +85 -0
  133. package/dist/playground/rustExecutableGraph.js +946 -0
  134. package/dist/playground/rustWorkerLimits.d.ts +17 -0
  135. package/dist/playground/rustWorkerLimits.js +34 -0
  136. package/dist/playground/sandbox.d.ts +16 -10
  137. package/dist/playground/sharedBuffer.d.ts +6 -0
  138. package/dist/playground/sharedBuffer.js +12 -0
  139. package/dist/playground/sqlite.d.ts +38 -0
  140. package/dist/playground/sqlite.js +550 -0
  141. package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -0
  142. package/dist/playground/staticRuntimeModuleVersion.js +2 -0
  143. package/dist/playground/staticRuntimePreflight.d.ts +13 -0
  144. package/dist/playground/staticRuntimePreflight.js +231 -0
  145. package/dist/playground/staticRuntimePreflightExecute.d.ts +8 -0
  146. package/dist/playground/staticRuntimePreflightExecute.js +66 -0
  147. package/dist/playground/staticRuntimePreflightProtocol.d.ts +68 -0
  148. package/dist/playground/staticRuntimePreflightProtocol.js +339 -0
  149. package/dist/playground/staticStdinRing.d.ts +45 -0
  150. package/dist/playground/staticStdinRing.js +158 -0
  151. package/dist/playground/staticWorkerRuntime.d.ts +154 -0
  152. package/dist/playground/staticWorkerRuntime.js +1917 -0
  153. package/dist/playground/stdinBuffer.d.ts +9 -7
  154. package/dist/playground/stdinBuffer.js +9 -18
  155. package/dist/playground/swift.d.ts +5 -0
  156. package/dist/playground/swift.js +17 -0
  157. package/dist/playground/tcl.d.ts +5 -0
  158. package/dist/playground/tcl.js +62 -0
  159. package/dist/playground/teavmConfig.d.ts +1 -1
  160. package/dist/playground/teavmConfig.js +2 -2
  161. package/dist/playground/tinygo.d.ts +48 -18
  162. package/dist/playground/tinygo.js +1202 -329
  163. package/dist/playground/tinygoExecutableGraph.d.ts +44 -0
  164. package/dist/playground/tinygoExecutableGraph.js +449 -0
  165. package/dist/playground/typescript.d.ts +55 -0
  166. package/dist/playground/typescript.js +924 -0
  167. package/dist/playground/wasm.d.ts +43 -0
  168. package/dist/playground/wasm.js +608 -0
  169. package/dist/playground/wasmAwkVersion.d.ts +59 -0
  170. package/dist/playground/wasmAwkVersion.js +31 -0
  171. package/dist/playground/wasmBashVersion.d.ts +63 -0
  172. package/dist/playground/wasmBashVersion.js +36 -0
  173. package/dist/playground/wasmBqnVersion.d.ts +24 -0
  174. package/dist/playground/wasmBqnVersion.js +24 -0
  175. package/dist/playground/wasmC3Version.d.ts +20 -0
  176. package/dist/playground/wasmC3Version.js +21 -0
  177. package/dist/playground/wasmClojureScriptVersion.d.ts +21 -0
  178. package/dist/playground/wasmClojureScriptVersion.js +21 -0
  179. package/dist/playground/wasmDIntegrity.d.ts +15 -0
  180. package/dist/playground/wasmDIntegrity.js +15 -0
  181. package/dist/playground/wasmDVersion.d.ts +1 -0
  182. package/dist/playground/wasmDVersion.js +1 -0
  183. package/dist/playground/wasmDebugVersion.d.ts +6 -0
  184. package/dist/playground/wasmDebugVersion.js +6 -0
  185. package/dist/playground/wasmDotnetVersion.d.ts +1 -0
  186. package/dist/playground/wasmDotnetVersion.js +1 -0
  187. package/dist/playground/wasmElixirVersion.d.ts +21 -1
  188. package/dist/playground/wasmElixirVersion.js +21 -1
  189. package/dist/playground/wasmForthVersion.d.ts +18 -0
  190. package/dist/playground/wasmForthVersion.js +18 -0
  191. package/dist/playground/wasmFortranExecutionAssets.d.ts +15 -0
  192. package/dist/playground/wasmFortranExecutionAssets.js +15 -0
  193. package/dist/playground/wasmFortranVersion.d.ts +1 -0
  194. package/dist/playground/wasmFortranVersion.js +1 -0
  195. package/dist/playground/wasmGleamVersion.d.ts +5 -0
  196. package/dist/playground/wasmGleamVersion.js +5 -0
  197. package/dist/playground/wasmGoVersion.d.ts +1 -1
  198. package/dist/playground/wasmGoVersion.js +1 -1
  199. package/dist/playground/wasmHaskellVersion.d.ts +1 -0
  200. package/dist/playground/wasmHaskellVersion.js +1 -0
  201. package/dist/playground/wasmJVersion.d.ts +24 -0
  202. package/dist/playground/wasmJVersion.js +24 -0
  203. package/dist/playground/wasmJanetVersion.d.ts +53 -0
  204. package/dist/playground/wasmJanetVersion.js +30 -0
  205. package/dist/playground/wasmJuliaVersion.d.ts +71 -0
  206. package/dist/playground/wasmJuliaVersion.js +39 -0
  207. package/dist/playground/wasmLfortranVersion.d.ts +28 -0
  208. package/dist/playground/wasmLfortranVersion.js +29 -0
  209. package/dist/playground/wasmLispVersion.d.ts +1 -0
  210. package/dist/playground/wasmLispVersion.js +1 -0
  211. package/dist/playground/wasmLuaVersion.d.ts +1 -0
  212. package/dist/playground/wasmLuaVersion.js +1 -0
  213. package/dist/playground/wasmNimVersion.d.ts +125 -0
  214. package/dist/playground/wasmNimVersion.js +66 -0
  215. package/dist/playground/wasmObjectiveCVersion.d.ts +27 -0
  216. package/dist/playground/wasmObjectiveCVersion.js +27 -0
  217. package/dist/playground/wasmOcamlVersion.d.ts +12 -1
  218. package/dist/playground/wasmOcamlVersion.js +12 -1
  219. package/dist/playground/wasmOctaveVersion.d.ts +1 -0
  220. package/dist/playground/wasmOctaveVersion.js +1 -0
  221. package/dist/playground/wasmPascalVersion.d.ts +61 -0
  222. package/dist/playground/wasmPascalVersion.js +34 -0
  223. package/dist/playground/wasmPerlVersion.d.ts +71 -0
  224. package/dist/playground/wasmPerlVersion.js +39 -0
  225. package/dist/playground/wasmPrologVersion.d.ts +31 -0
  226. package/dist/playground/wasmPrologVersion.js +31 -0
  227. package/dist/playground/wasmRVersion.d.ts +1 -0
  228. package/dist/playground/wasmRVersion.js +1 -0
  229. package/dist/playground/wasmRustVersion.d.ts +1306 -1
  230. package/dist/playground/wasmRustVersion.js +1458 -1
  231. package/dist/playground/wasmSwiftVersion.d.ts +1 -0
  232. package/dist/playground/wasmSwiftVersion.js +1 -0
  233. package/dist/playground/wasmTclVersion.d.ts +85 -0
  234. package/dist/playground/wasmTclVersion.js +46 -0
  235. package/dist/playground/wasmTinyGoVersion.d.ts +98 -1
  236. package/dist/playground/wasmTinyGoVersion.js +107 -1
  237. package/dist/playground/wasmTypeScriptVersion.d.ts +5 -0
  238. package/dist/playground/wasmTypeScriptVersion.js +5 -0
  239. package/dist/playground/wasmWatVersion.d.ts +1 -0
  240. package/dist/playground/wasmWatVersion.js +1 -0
  241. package/dist/playground/wasmZigVersion.d.ts +13 -0
  242. package/dist/playground/wasmZigVersion.js +13 -0
  243. package/dist/playground/wat.d.ts +44 -0
  244. package/dist/playground/wat.js +622 -0
  245. package/dist/playground/worker/assemblyscript.js +339 -0
  246. package/dist/playground/worker/assets.d.ts +7 -0
  247. package/dist/playground/worker/assets.js +288 -39
  248. package/dist/playground/worker/bash.js +338 -0
  249. package/dist/playground/worker/bashNestedBootstrap.d.ts +6 -0
  250. package/dist/playground/worker/bashNestedBootstrap.js +59 -0
  251. package/dist/playground/worker/bashRuntime.d.ts +89 -0
  252. package/dist/playground/worker/bashRuntime.js +982 -0
  253. package/dist/playground/worker/clang.js +92 -13
  254. package/dist/playground/worker/cobol.js +107 -0
  255. package/dist/playground/worker/d.js +199 -0
  256. package/dist/playground/worker/dotnet.js +141 -0
  257. package/dist/playground/worker/duckdb.d.ts +1 -0
  258. package/dist/playground/worker/duckdb.js +136 -0
  259. package/dist/playground/worker/elixir.js +307 -41
  260. package/dist/playground/worker/fortran.d.ts +1 -0
  261. package/dist/playground/worker/fortran.js +295 -0
  262. package/dist/playground/worker/go.js +246 -40
  263. package/dist/playground/worker/haskell.d.ts +7 -0
  264. package/dist/playground/worker/haskell.js +465 -0
  265. package/dist/playground/worker/java.js +59 -20
  266. package/dist/playground/worker/lisp.d.ts +1 -0
  267. package/dist/playground/worker/lisp.js +195 -0
  268. package/dist/playground/worker/lua.d.ts +1 -0
  269. package/dist/playground/worker/lua.js +163 -0
  270. package/dist/playground/worker/objectivec.d.ts +1 -0
  271. package/dist/playground/worker/objectivec.js +10 -0
  272. package/dist/playground/worker/ocaml.js +206 -58
  273. package/dist/playground/worker/php.d.ts +1 -0
  274. package/dist/playground/worker/php.js +261 -0
  275. package/dist/playground/worker/python.js +201 -44
  276. package/dist/playground/worker/r.d.ts +1 -0
  277. package/dist/playground/worker/r.js +192 -0
  278. package/dist/playground/worker/ruby.d.ts +1 -0
  279. package/dist/playground/worker/ruby.js +248 -0
  280. package/dist/playground/worker/runtimeAssetFetch.d.ts +15 -0
  281. package/dist/playground/worker/runtimeAssetFetch.js +375 -0
  282. package/dist/playground/worker/rust.js +546 -20
  283. package/dist/playground/worker/sqlite.d.ts +1 -0
  284. package/dist/playground/worker/sqlite.js +112 -0
  285. package/dist/playground/worker/staticRuntimePreflight.d.ts +1 -0
  286. package/dist/playground/worker/staticRuntimePreflight.js +56 -0
  287. package/dist/playground/worker/tinygo.js +34 -9
  288. package/dist/playground/worker/typescript.d.ts +1 -0
  289. package/dist/playground/worker/typescript.js +251 -0
  290. package/dist/playground/worker/wasm.d.ts +1 -0
  291. package/dist/playground/worker/wasm.js +273 -0
  292. package/dist/playground/worker/wat.d.ts +1 -0
  293. package/dist/playground/worker/wat.js +188 -0
  294. package/dist/playground/worker/zig.d.ts +8 -0
  295. package/dist/playground/worker/zig.js +578 -0
  296. package/dist/playground/workerProgress.d.ts +15 -0
  297. package/dist/playground/workerProgress.js +72 -0
  298. package/dist/playground/workerSession.d.ts +28 -0
  299. package/dist/playground/workerSession.js +164 -0
  300. package/dist/playground/zig.d.ts +46 -0
  301. package/dist/playground/zig.js +690 -0
  302. package/dist/playground/zigAssets.d.ts +6 -0
  303. package/dist/playground/zigAssets.js +49 -0
  304. package/package.json +234 -105
  305. package/dist/clang/app.d.ts +0 -75
  306. package/dist/clang/app.js +0 -744
  307. package/dist/clang/apply.d.ts +0 -2
  308. package/dist/clang/apply.js +0 -11
  309. package/dist/clang/color.d.ts +0 -3
  310. package/dist/clang/color.js +0 -3
  311. package/dist/clang/encode.d.ts +0 -4
  312. package/dist/clang/encode.js +0 -20
  313. package/dist/clang/error.d.ts +0 -14
  314. package/dist/clang/error.js +0 -27
  315. package/dist/clang/gccCompat.d.ts +0 -15
  316. package/dist/clang/gccCompat.js +0 -767
  317. package/dist/clang/index.d.ts +0 -85
  318. package/dist/clang/index.js +0 -1077
  319. package/dist/clang/memory/index.d.ts +0 -4
  320. package/dist/clang/memory/index.js +0 -4
  321. package/dist/clang/memory/memFs.d.ts +0 -35
  322. package/dist/clang/memory/memFs.js +0 -132
  323. package/dist/clang/memory/memory.d.ts +0 -22
  324. package/dist/clang/memory/memory.js +0 -73
  325. package/dist/clang/memory/tar.d.ts +0 -2
  326. package/dist/clang/memory/tar.js +0 -59
  327. package/dist/clang/url.d.ts +0 -4
  328. package/dist/clang/url.js +0 -5
  329. package/dist/clang/wasm.d.ts +0 -4
  330. package/dist/clang/wasm.js +0 -50
  331. package/dist/clangd/config.d.ts +0 -18
  332. package/dist/clangd/config.js +0 -14
  333. package/dist/clangd/jsonStream.d.ts +0 -9
  334. package/dist/clangd/jsonStream.js +0 -48
  335. package/dist/clangd/session.d.ts +0 -18
  336. package/dist/clangd/session.js +0 -112
  337. package/dist/clangd/worker.js +0 -131
  338. package/dist/debug/controller.svelte.d.ts +0 -43
  339. package/dist/debug/controller.svelte.js +0 -268
  340. package/dist/debug/editor/index.d.ts +0 -2
  341. package/dist/debug/editor/index.js +0 -1
  342. package/dist/debug/editor/monaco.d.ts +0 -26
  343. package/dist/debug/editor/monaco.js +0 -128
  344. package/dist/debug/expression.d.ts +0 -26
  345. package/dist/debug/expression.js +0 -547
  346. package/dist/debug/index.d.ts +0 -8
  347. package/dist/debug/index.js +0 -5
  348. package/dist/debug/language/cpp.d.ts +0 -2
  349. package/dist/debug/language/cpp.js +0 -7
  350. package/dist/debug/language/index.d.ts +0 -3
  351. package/dist/debug/language/index.js +0 -2
  352. package/dist/debug/language/python.d.ts +0 -2
  353. package/dist/debug/language/python.js +0 -14
  354. package/dist/debug/language/types.d.ts +0 -6
  355. package/dist/debug/locals.d.ts +0 -2
  356. package/dist/debug/locals.js +0 -8
  357. package/dist/lsp/cpp/server.d.ts +0 -2
  358. package/dist/lsp/cpp/server.js +0 -68
  359. package/dist/lsp/index.d.ts +0 -5
  360. package/dist/lsp/index.js +0 -4
  361. package/dist/lsp/python/main.worker.js +0 -92
  362. package/dist/lsp/python/package/arcturus_python_lsp/__init__.py +0 -3
  363. package/dist/lsp/python/package/arcturus_python_lsp/server.py +0 -462
  364. package/dist/lsp/python/server.d.ts +0 -2
  365. package/dist/lsp/python/server.js +0 -54
  366. package/dist/lsp/registry.d.ts +0 -2
  367. package/dist/lsp/registry.js +0 -12
  368. package/dist/lsp/runtime.d.ts +0 -5
  369. package/dist/lsp/runtime.js +0 -31
  370. package/dist/lsp/types.d.ts +0 -17
  371. package/dist/terminal/Terminal.svelte +0 -422
  372. package/dist/terminal/Terminal.svelte.d.ts +0 -26
  373. package/dist/terminal/index.d.ts +0 -7
  374. package/dist/terminal/index.js +0 -5
  375. package/dist/terminal/plugin/index.d.ts +0 -9
  376. package/dist/terminal/plugin/index.js +0 -19
  377. package/dist/terminal/theme.d.ts +0 -49
  378. package/dist/terminal/theme.js +0 -49
  379. package/dist/terminal/types.d.ts +0 -18
  380. package/dist/utils/vscodeJsonrpcBrowser.d.ts +0 -5
  381. package/dist/utils/vscodeJsonrpcBrowser.js +0 -4
  382. /package/dist/{clangd/worker.d.ts → playground/worker/assemblyscript.d.ts} +0 -0
  383. /package/dist/{debug/language/types.js → playground/worker/bash.d.ts} +0 -0
  384. /package/dist/{lsp/python/main.worker.d.ts → playground/worker/cobol.d.ts} +0 -0
  385. /package/dist/{lsp/types.js → playground/worker/d.d.ts} +0 -0
  386. /package/dist/{terminal/types.js → playground/worker/dotnet.d.ts} +0 -0
@@ -0,0 +1,1917 @@
1
+ import { AssetNotFoundError, AssetTooLargeError, BusyError, CancelledError, DEFAULT_WORKSPACE_LIMITS, DiagnosticLimitError, OutputLimitError, ProtocolError, RuntimeConfigurationError, RuntimeExecutionError, RuntimeProgressController, RuntimeWorkerLifetimeController, TimeoutError, WorkerStartupError, isWasmIdleError, resolveExecutionLimits, validateExecutionWorkspace, verifyRuntimeAssetIntegrity } from '@wasm-idle/core';
2
+ import { resolveSandboxExecutionArgs } from './options';
3
+ import { StaticStdinRingHost } from './staticStdinRing';
4
+ import { deserializeStaticRuntimePreflightError, isStaticRuntimePreflightSerializedError, inspectStaticRuntimePreflightBytes } from './staticRuntimePreflightProtocol';
5
+ import { reportWorkerProgress } from './workerProgress';
6
+ const ownedDeliveryStateByTicket = new WeakMap();
7
+ const WORKER_READY_MESSAGE = '__wasmIdleStaticWorkerReady';
8
+ const outputEncoder = new TextEncoder();
9
+ function cancelWorkerScriptResponse(response, reason) {
10
+ try {
11
+ void Promise.resolve(response.body?.cancel(reason)).catch(() => undefined);
12
+ }
13
+ catch {
14
+ // Preserve the boundary failure that caused cancellation.
15
+ }
16
+ }
17
+ export class StaticWorkerRuntimeSandbox {
18
+ config;
19
+ output = null;
20
+ worker = null;
21
+ pendingInput = [];
22
+ begin = 0;
23
+ elapse = 0;
24
+ uid = 0;
25
+ exit = true;
26
+ baseUrl = '';
27
+ workerUrl = '';
28
+ manifestUrl = '';
29
+ manifestFingerprint = '';
30
+ preflightKey = '';
31
+ workerReceipt = null;
32
+ activeReject = null;
33
+ oncompilerdiagnostic;
34
+ pendingEof = false;
35
+ stdinWaiters = [];
36
+ activeRun = null;
37
+ bootstrapUrl = '';
38
+ disposed = false;
39
+ disposePromise = null;
40
+ disposeReason = null;
41
+ lifecycleProgress;
42
+ progressController = new RuntimeProgressController();
43
+ progressUid = 0;
44
+ startingRunId = null;
45
+ startupReject = null;
46
+ workerLease = null;
47
+ workerLifetimeController;
48
+ workerStartAbortController = null;
49
+ workerGeneration = 0;
50
+ workerStartPromise = null;
51
+ resolvedRuntimeUrls = null;
52
+ workerRuntimePreflight = new WeakMap();
53
+ workerRuntimePreflightMaxAssetBytes = new WeakMap();
54
+ workersWithCachedRuntimePreflight = new WeakSet();
55
+ workerStartMaxAssetBytes = null;
56
+ constructor(config) {
57
+ this.config = config;
58
+ const workerLifetime = config.workerLifetime ?? { mode: 'per-run' };
59
+ if (this.usesOwnedRuntimePreflight() && !config.preflightRuntimeAssets) {
60
+ throw new RuntimeConfigurationError(`${config.displayName} transfer-owned runtime preflight requires a runtime preflight callback.`, { phase: 'startup', runtimeId: config.languageId });
61
+ }
62
+ if (config.runtimePreflightDelivery === 'transfer-owned' &&
63
+ workerLifetime.mode !== 'per-run') {
64
+ throw new RuntimeConfigurationError(`${config.displayName} transfer-owned runtime preflight requires per-run workers.`, { phase: 'startup', runtimeId: config.languageId });
65
+ }
66
+ if (config.runtimePreflightDelivery === 'transfer-owned-worker-cache' &&
67
+ workerLifetime.mode !== 'persistent') {
68
+ throw new RuntimeConfigurationError(`${config.displayName} transfer-owned worker-cache preflight requires persistent workers.`, { phase: 'startup', runtimeId: config.languageId });
69
+ }
70
+ this.workerLifetimeController = new RuntimeWorkerLifetimeController({
71
+ policy: workerLifetime,
72
+ runtimeId: config.languageId,
73
+ createWorker: (context) => {
74
+ context.generation = ++this.workerGeneration;
75
+ return this.startWorker(context.generation, context.progress, context.controls);
76
+ },
77
+ disposeWorker: (worker) => this.retireManagedWorker(worker)
78
+ });
79
+ }
80
+ usesOwnedRuntimePreflight() {
81
+ return (this.config.runtimePreflightDelivery === 'transfer-owned' ||
82
+ this.config.runtimePreflightDelivery === 'transfer-owned-worker-cache');
83
+ }
84
+ usesWorkerCachedRuntimePreflight() {
85
+ return this.config.runtimePreflightDelivery === 'transfer-owned-worker-cache';
86
+ }
87
+ resetWorkerForLowerAssetLimit(maxAssetBytes) {
88
+ if (!this.usesOwnedRuntimePreflight())
89
+ return;
90
+ const currentLimit = this.worker
91
+ ? this.workerRuntimePreflightMaxAssetBytes.get(this.worker)
92
+ : this.workerStartPromise
93
+ ? (this.workerStartMaxAssetBytes ?? undefined)
94
+ : undefined;
95
+ if (currentLimit !== undefined && maxAssetBytes < currentLimit) {
96
+ this.disposeWorker(new CancelledError(`${this.config.displayName} worker reset for a lower runtime asset limit`, { phase: 'asset', runtimeId: this.config.languageId }));
97
+ }
98
+ }
99
+ getDisposeReason() {
100
+ if (!this.disposeReason) {
101
+ this.disposeReason = new CancelledError(`${this.config.displayName} runtime was disposed`, {
102
+ phase: 'dispose',
103
+ runtimeId: this.config.languageId
104
+ });
105
+ }
106
+ return this.disposeReason;
107
+ }
108
+ assertNotDisposed() {
109
+ if (!this.disposed)
110
+ return;
111
+ throw new RuntimeConfigurationError(`${this.config.displayName} runtime is disposed`, {
112
+ phase: 'dispose',
113
+ runtimeId: this.config.languageId
114
+ });
115
+ }
116
+ assertOperationNotDisposed() {
117
+ if (this.disposed)
118
+ throw this.getDisposeReason();
119
+ }
120
+ preserveDisposeReason(error) {
121
+ return this.disposed ? this.getDisposeReason() : error;
122
+ }
123
+ get stdinMode() {
124
+ if (this.config.stdin.mode !== 'streaming')
125
+ return this.config.stdin.mode;
126
+ const isolated = globalThis.crossOriginIsolated;
127
+ return typeof SharedArrayBuffer === 'function' &&
128
+ typeof Atomics === 'object' &&
129
+ typeof Atomics.notify === 'function' &&
130
+ (typeof isolated !== 'boolean' || isolated)
131
+ ? 'streaming'
132
+ : 'prebuffered';
133
+ }
134
+ async load(runtimeAssets = '', code = '', _log = true, _args = [], options = {}, progress) {
135
+ this.assertNotDisposed();
136
+ try {
137
+ const controls = this.resolveExecutionControls(options);
138
+ this.assertOperationNotDisposed();
139
+ if (controls.signal?.aborted) {
140
+ throw new CancelledError(`${this.config.displayName} startup cancelled`, {
141
+ cause: controls.signal.reason,
142
+ phase: 'startup',
143
+ runtimeId: this.config.languageId
144
+ });
145
+ }
146
+ this.validateWorkspace(code, options, controls.limits);
147
+ this.assertOperationNotDisposed();
148
+ const progressSink = this.selectProgress(progress);
149
+ const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
150
+ const urls = this.config.resolveRuntimeAssets(runtimeAssets, currentUrl);
151
+ this.assertOperationNotDisposed();
152
+ const nextManifestUrl = urls.manifestUrl || '';
153
+ const nextManifestFingerprint = urls.manifestFingerprint || '';
154
+ const nextPreflightKey = urls.preflightKey || '';
155
+ const nextWorkerReceipt = urls.workerReceipt
156
+ ? Object.freeze({
157
+ bytes: urls.workerReceipt.bytes,
158
+ sha256: urls.workerReceipt.sha256
159
+ })
160
+ : null;
161
+ if (this.config.inlineVerifiedWorker &&
162
+ (!nextWorkerReceipt ||
163
+ !Number.isSafeInteger(nextWorkerReceipt.bytes) ||
164
+ nextWorkerReceipt.bytes <= 0 ||
165
+ !/^[a-f0-9]{64}$/u.test(nextWorkerReceipt.sha256))) {
166
+ throw new RuntimeConfigurationError(`${this.config.displayName} requires a pinned worker receipt.`, { runtimeId: this.config.languageId });
167
+ }
168
+ const runtimeChanged = this.baseUrl !== urls.baseUrl ||
169
+ this.workerUrl !== urls.workerUrl ||
170
+ this.manifestUrl !== nextManifestUrl ||
171
+ this.manifestFingerprint !== nextManifestFingerprint ||
172
+ this.preflightKey !== nextPreflightKey ||
173
+ this.workerReceipt?.bytes !== nextWorkerReceipt?.bytes ||
174
+ this.workerReceipt?.sha256 !== nextWorkerReceipt?.sha256;
175
+ if (runtimeChanged &&
176
+ (this.worker ||
177
+ this.workerStartPromise ||
178
+ this.activeRun ||
179
+ this.startingRunId ||
180
+ this.workerLifetimeController.totalWorkers > 0)) {
181
+ this.terminate();
182
+ }
183
+ this.baseUrl = urls.baseUrl;
184
+ this.workerUrl = urls.workerUrl;
185
+ this.manifestUrl = nextManifestUrl;
186
+ this.manifestFingerprint = nextManifestFingerprint;
187
+ this.preflightKey = nextPreflightKey;
188
+ this.resolvedRuntimeUrls = urls;
189
+ this.workerReceipt = nextWorkerReceipt;
190
+ this.resetWorkerForLowerAssetLimit(controls.limits.maxAssetBytes);
191
+ if (!this.baseUrl || !this.workerUrl) {
192
+ throw new RuntimeConfigurationError(`${this.config.displayName} runtime is not configured.`, { runtimeId: this.config.languageId });
193
+ }
194
+ if (!runtimeChanged &&
195
+ (this.workerStartPromise || this.workerLifetimeController.idleWorkers > 0)) {
196
+ await this.workerStartPromise;
197
+ this.assertOperationNotDisposed();
198
+ return;
199
+ }
200
+ const lifecycle = this.beginProgressLifecycle(progressSink, `Resolving ${this.config.displayName} runtime`);
201
+ try {
202
+ this.assertOperationNotDisposed();
203
+ this.reportProgress(lifecycle.progress, 0.02, `Resolving ${this.config.displayName} runtime`);
204
+ this.assertOperationNotDisposed();
205
+ await this.ensureWorkerStarted(lifecycle.progress, controls);
206
+ this.assertOperationNotDisposed();
207
+ this.releasePreparedWorkerIfIdle();
208
+ }
209
+ finally {
210
+ lifecycle.end();
211
+ }
212
+ }
213
+ catch (error) {
214
+ throw this.preserveDisposeReason(error);
215
+ }
216
+ }
217
+ write(input) {
218
+ if (this.disposed)
219
+ return;
220
+ const activeRun = this.activeRun;
221
+ if (activeRun?.stdinRing) {
222
+ try {
223
+ activeRun.stdinRing.enqueue(input);
224
+ }
225
+ catch (error) {
226
+ this.rejectRun(activeRun.id, error);
227
+ }
228
+ return;
229
+ }
230
+ this.pendingInput.push(input);
231
+ }
232
+ eof() {
233
+ if (this.disposed)
234
+ return;
235
+ const activeRun = this.activeRun;
236
+ if (activeRun?.stdinRing) {
237
+ try {
238
+ activeRun.stdinRing.close();
239
+ }
240
+ catch (error) {
241
+ this.rejectRun(activeRun.id, error);
242
+ }
243
+ return;
244
+ }
245
+ this.pendingEof = true;
246
+ this.resolveStdinWaiters();
247
+ }
248
+ resolveStdinWaiters() {
249
+ const waiters = this.stdinWaiters.splice(0);
250
+ for (const waiter of waiters)
251
+ waiter.resolve();
252
+ }
253
+ rejectStdinWaiters(reason) {
254
+ const waiters = this.stdinWaiters.splice(0);
255
+ for (const waiter of waiters)
256
+ waiter.reject(reason);
257
+ }
258
+ clearPendingStdin() {
259
+ this.pendingInput = [];
260
+ this.pendingEof = false;
261
+ }
262
+ sourceMayReadStdin(code) {
263
+ if (this.config.stdin.mode === 'none')
264
+ return false;
265
+ const pattern = this.config.stdin.sourceHintPattern;
266
+ pattern.lastIndex = 0;
267
+ return pattern.test(code);
268
+ }
269
+ async collectStdinForRun(code, options, activeRun) {
270
+ if (this.stdinMode === 'none') {
271
+ this.clearPendingStdin();
272
+ return { stdin: undefined, stdinEof: false };
273
+ }
274
+ if (typeof options.stdin === 'string') {
275
+ this.clearPendingStdin();
276
+ return { stdin: options.stdin, stdinEof: true };
277
+ }
278
+ if (!this.sourceMayReadStdin(code) && this.pendingInput.length === 0 && !this.pendingEof) {
279
+ return { stdin: undefined, stdinEof: false };
280
+ }
281
+ if (!this.pendingEof) {
282
+ this.reportRunReady(activeRun, 'waiting-input', 'stdin-request', `${this.config.displayName} runtime ready for input`);
283
+ if (this.activeRun !== activeRun) {
284
+ throw new CancelledError(`${this.config.displayName} run terminated`, {
285
+ phase: 'execute',
286
+ runtimeId: this.config.languageId
287
+ });
288
+ }
289
+ }
290
+ while (!this.pendingEof) {
291
+ await new Promise((resolve, reject) => {
292
+ this.stdinWaiters.push({ resolve, reject });
293
+ });
294
+ }
295
+ const stdin = this.pendingInput.join('');
296
+ this.clearPendingStdin();
297
+ return { stdin, stdinEof: true };
298
+ }
299
+ selectProgress(progress) {
300
+ if (progress)
301
+ this.lifecycleProgress = progress;
302
+ return progress || this.lifecycleProgress;
303
+ }
304
+ beginProgressLifecycle(progress, stage) {
305
+ return this.progressController.begin(`${this.config.languageId.toLowerCase()}-${++this.progressUid}`, progress, stage);
306
+ }
307
+ resolveExecutionControls(options) {
308
+ return {
309
+ limits: resolveExecutionLimits(options.limits),
310
+ ...(options.signal ? { signal: options.signal } : {})
311
+ };
312
+ }
313
+ validateWorkspace(code, options, limits) {
314
+ const workspaceLimits = {
315
+ ...options.workspaceLimits,
316
+ maxFileBytes: Math.min(options.workspaceLimits?.maxFileBytes ?? DEFAULT_WORKSPACE_LIMITS.maxFileBytes, limits.maxWorkspaceBytes),
317
+ maxTotalBytes: Math.min(options.workspaceLimits?.maxTotalBytes ?? DEFAULT_WORKSPACE_LIMITS.maxTotalBytes, limits.maxWorkspaceBytes)
318
+ };
319
+ return validateExecutionWorkspace(code, options.workspaceFiles ?? [], options.activePath ?? this.config.defaultActivePath, workspaceLimits);
320
+ }
321
+ reportProgress(progress, value, stage) {
322
+ if (!progress)
323
+ return;
324
+ const clamped = Number.isFinite(value) ? Math.max(0, Math.min(value, 1)) : 0;
325
+ progress.set?.(clamped, stage);
326
+ }
327
+ reportRunReady(activeRun, state, reason, label) {
328
+ if (activeRun.readyReported || activeRun.settledReported)
329
+ return;
330
+ reportWorkerProgress(activeRun.progress, { kind: 'ready', state, reason, label });
331
+ activeRun.readyReported = true;
332
+ }
333
+ reportRunSettled(activeRun, outcome, label) {
334
+ if (activeRun.settledReported)
335
+ return;
336
+ activeRun.settledReported = true;
337
+ reportWorkerProgress(activeRun.progress, { kind: 'settled', outcome, label });
338
+ }
339
+ async verifyWorkerReceipt(bytes, receipt, signal) {
340
+ const abortReason = () => signal.reason ?? new DOMException('Worker script verification aborted', 'AbortError');
341
+ let onAbort;
342
+ const aborted = new Promise((_resolve, reject) => {
343
+ onAbort = () => reject(abortReason());
344
+ signal.addEventListener('abort', onAbort, { once: true });
345
+ });
346
+ try {
347
+ if (signal.aborted)
348
+ throw abortReason();
349
+ await Promise.race([
350
+ verifyRuntimeAssetIntegrity({
351
+ asset: this.workerUrl,
352
+ bytes,
353
+ expected: receipt,
354
+ runtimeId: this.config.languageId
355
+ }),
356
+ aborted
357
+ ]);
358
+ if (signal.aborted)
359
+ throw abortReason();
360
+ }
361
+ finally {
362
+ if (onAbort)
363
+ signal.removeEventListener('abort', onAbort);
364
+ }
365
+ }
366
+ async preloadWorkerScript(progress, controls) {
367
+ const { limits, signal } = controls;
368
+ const workerReceipt = this.config.inlineVerifiedWorker ? this.workerReceipt : null;
369
+ const workerByteLimit = workerReceipt?.bytes ?? limits.maxAssetBytes;
370
+ if (workerReceipt && workerReceipt.bytes > limits.maxAssetBytes) {
371
+ throw new AssetTooLargeError(`${this.config.displayName} worker script exceeds ${limits.maxAssetBytes} bytes`, {
372
+ actual: workerReceipt.bytes,
373
+ limit: limits.maxAssetBytes,
374
+ runtimeId: this.config.languageId
375
+ });
376
+ }
377
+ if (signal?.aborted) {
378
+ throw new CancelledError(`${this.config.displayName} worker download cancelled`, {
379
+ cause: signal.reason,
380
+ phase: 'asset',
381
+ runtimeId: this.config.languageId
382
+ });
383
+ }
384
+ let workerRequestUrl;
385
+ try {
386
+ workerRequestUrl =
387
+ typeof window === 'undefined'
388
+ ? new URL(this.workerUrl)
389
+ : new URL(this.workerUrl, window.location.href);
390
+ }
391
+ catch {
392
+ throw new RuntimeConfigurationError(`${this.config.displayName} worker script URL is invalid`, { runtimeId: this.config.languageId });
393
+ }
394
+ if (workerRequestUrl.protocol !== 'https:' && workerRequestUrl.protocol !== 'http:') {
395
+ throw new RuntimeConfigurationError(`${this.config.displayName} worker script URL must use HTTP(S)`, { runtimeId: this.config.languageId });
396
+ }
397
+ if (workerRequestUrl.username || workerRequestUrl.password) {
398
+ throw new RuntimeConfigurationError(`${this.config.displayName} worker script URL must not include credentials`, { runtimeId: this.config.languageId });
399
+ }
400
+ if (workerRequestUrl.hash) {
401
+ throw new RuntimeConfigurationError(`${this.config.displayName} worker script URL must not include a fragment`, { runtimeId: this.config.languageId });
402
+ }
403
+ const phaseController = new AbortController();
404
+ let timedOut = false;
405
+ const onAbort = () => phaseController.abort(signal?.reason);
406
+ signal?.addEventListener('abort', onAbort, { once: true });
407
+ const timeout = setTimeout(() => {
408
+ timedOut = true;
409
+ phaseController.abort();
410
+ }, limits.assetTimeoutMs);
411
+ try {
412
+ this.reportProgress(progress, 0.05, `Loading ${this.config.displayName} worker script`);
413
+ if (phaseController.signal.aborted) {
414
+ throw (phaseController.signal.reason ??
415
+ new DOMException('Worker script fetch aborted', 'AbortError'));
416
+ }
417
+ const pendingResponse = Promise.resolve(fetch(workerRequestUrl.href, {
418
+ cache: this.config.inlineVerifiedWorker ? 'no-store' : 'force-cache',
419
+ credentials: 'omit',
420
+ redirect: 'error',
421
+ referrerPolicy: 'no-referrer',
422
+ signal: phaseController.signal
423
+ }));
424
+ const response = await new Promise((resolve, reject) => {
425
+ let settled = false;
426
+ const onPhaseAbort = () => {
427
+ if (settled)
428
+ return;
429
+ settled = true;
430
+ phaseController.signal.removeEventListener('abort', onPhaseAbort);
431
+ reject(phaseController.signal.reason ??
432
+ new DOMException('Worker script fetch aborted', 'AbortError'));
433
+ };
434
+ phaseController.signal.addEventListener('abort', onPhaseAbort, { once: true });
435
+ void pendingResponse.then((candidate) => {
436
+ if (settled) {
437
+ const reason = phaseController.signal.reason ??
438
+ new DOMException('Worker script fetch aborted', 'AbortError');
439
+ cancelWorkerScriptResponse(candidate, reason);
440
+ return;
441
+ }
442
+ settled = true;
443
+ phaseController.signal.removeEventListener('abort', onPhaseAbort);
444
+ resolve(candidate);
445
+ }, (error) => {
446
+ if (settled)
447
+ return;
448
+ settled = true;
449
+ phaseController.signal.removeEventListener('abort', onPhaseAbort);
450
+ reject(error);
451
+ });
452
+ if (phaseController.signal.aborted)
453
+ onPhaseAbort();
454
+ });
455
+ if (!response.url && this.config.requireExactWorkerResponseUrl) {
456
+ const error = new ProtocolError(`${this.config.displayName} worker script response did not expose an exact final URL`, { phase: 'asset', runtimeId: this.config.languageId });
457
+ cancelWorkerScriptResponse(response, error);
458
+ throw error;
459
+ }
460
+ if (response.url) {
461
+ let finalResponseUrl;
462
+ try {
463
+ finalResponseUrl = new URL(response.url).href;
464
+ }
465
+ catch {
466
+ const error = new ProtocolError(`${this.config.displayName} worker script returned an invalid final URL: ${response.url}`, { phase: 'asset', runtimeId: this.config.languageId });
467
+ cancelWorkerScriptResponse(response, error);
468
+ throw error;
469
+ }
470
+ if (finalResponseUrl !== workerRequestUrl.href) {
471
+ const error = new ProtocolError(`${this.config.displayName} worker script response URL mismatch: expected ${workerRequestUrl.href}, received ${finalResponseUrl}`, { phase: 'asset', runtimeId: this.config.languageId });
472
+ cancelWorkerScriptResponse(response, error);
473
+ throw error;
474
+ }
475
+ }
476
+ if (!response.ok) {
477
+ const error = new AssetNotFoundError(`${this.config.displayName} worker script failed to load: HTTP ${response.status}`, { runtimeId: this.config.languageId });
478
+ cancelWorkerScriptResponse(response, error);
479
+ throw error;
480
+ }
481
+ const rawContentLength = response.headers.get('content-length');
482
+ let total = 0;
483
+ if (rawContentLength !== null) {
484
+ const normalizedContentLength = rawContentLength.trim();
485
+ const declaredLength = Number(normalizedContentLength);
486
+ if (!/^\d+$/u.test(normalizedContentLength) ||
487
+ !Number.isSafeInteger(declaredLength)) {
488
+ const error = new ProtocolError(`${this.config.displayName} worker script has an invalid Content-Length: ${rawContentLength}`, { phase: 'asset', runtimeId: this.config.languageId });
489
+ cancelWorkerScriptResponse(response, error);
490
+ throw error;
491
+ }
492
+ total = declaredLength;
493
+ }
494
+ if (total > workerByteLimit) {
495
+ const error = new AssetTooLargeError(`${this.config.displayName} worker script exceeds ${workerByteLimit} bytes`, {
496
+ actual: total,
497
+ limit: workerByteLimit,
498
+ runtimeId: this.config.languageId
499
+ });
500
+ cancelWorkerScriptResponse(response, error);
501
+ throw error;
502
+ }
503
+ if (!response.body) {
504
+ let cancelOnAbort;
505
+ const aborted = new Promise((_resolve, reject) => {
506
+ cancelOnAbort = () => reject(phaseController.signal.reason ??
507
+ new DOMException('Worker script read aborted', 'AbortError'));
508
+ phaseController.signal.addEventListener('abort', cancelOnAbort, {
509
+ once: true
510
+ });
511
+ });
512
+ try {
513
+ if (phaseController.signal.aborted) {
514
+ throw (phaseController.signal.reason ??
515
+ new DOMException('Worker script read aborted', 'AbortError'));
516
+ }
517
+ const materialized = response.arrayBuffer();
518
+ const buffer = await Promise.race([materialized, aborted]);
519
+ if (phaseController.signal.aborted) {
520
+ throw (phaseController.signal.reason ??
521
+ new DOMException('Worker script read aborted', 'AbortError'));
522
+ }
523
+ if (buffer.byteLength > workerByteLimit) {
524
+ throw new AssetTooLargeError(`${this.config.displayName} worker script exceeds ${workerByteLimit} bytes`, {
525
+ actual: buffer.byteLength,
526
+ limit: workerByteLimit,
527
+ runtimeId: this.config.languageId
528
+ });
529
+ }
530
+ this.reportProgress(progress, 0.2, `${this.config.displayName} worker downloaded`);
531
+ const bytes = new Uint8Array(buffer);
532
+ if (workerReceipt) {
533
+ await this.verifyWorkerReceipt(bytes, workerReceipt, phaseController.signal);
534
+ return bytes;
535
+ }
536
+ return undefined;
537
+ }
538
+ finally {
539
+ if (cancelOnAbort) {
540
+ phaseController.signal.removeEventListener('abort', cancelOnAbort);
541
+ }
542
+ }
543
+ }
544
+ const reader = response.body.getReader();
545
+ const chunks = [];
546
+ let readerCancelled = false;
547
+ let cancelOnAbort;
548
+ const aborted = new Promise((_resolve, reject) => {
549
+ cancelOnAbort = () => {
550
+ const reason = phaseController.signal.reason ??
551
+ new DOMException('Worker script read aborted', 'AbortError');
552
+ if (!readerCancelled) {
553
+ readerCancelled = true;
554
+ try {
555
+ void reader.cancel(reason).catch(() => undefined);
556
+ }
557
+ catch { }
558
+ }
559
+ reject(reason);
560
+ };
561
+ phaseController.signal.addEventListener('abort', cancelOnAbort, { once: true });
562
+ });
563
+ let loaded = 0;
564
+ let releaseError;
565
+ try {
566
+ while (true) {
567
+ if (phaseController.signal.aborted) {
568
+ throw (phaseController.signal.reason ??
569
+ new DOMException('Worker script read aborted', 'AbortError'));
570
+ }
571
+ const pendingRead = reader.read();
572
+ const { done, value } = await Promise.race([pendingRead, aborted]);
573
+ if (phaseController.signal.aborted) {
574
+ throw (phaseController.signal.reason ??
575
+ new DOMException('Worker script read aborted', 'AbortError'));
576
+ }
577
+ if (done)
578
+ break;
579
+ loaded += value.byteLength;
580
+ if (loaded > workerByteLimit) {
581
+ const error = new AssetTooLargeError(`${this.config.displayName} worker script exceeds ${workerByteLimit} bytes`, {
582
+ actual: loaded,
583
+ limit: workerByteLimit,
584
+ runtimeId: this.config.languageId
585
+ });
586
+ readerCancelled = true;
587
+ try {
588
+ void reader.cancel(error).catch(() => undefined);
589
+ }
590
+ catch { }
591
+ throw error;
592
+ }
593
+ if (workerReceipt)
594
+ chunks.push(value.slice());
595
+ const ratio = total > 0 ? Math.min(loaded / total, 1) : 0.5;
596
+ this.reportProgress(progress, 0.05 + ratio * 0.15, `Loading ${this.config.displayName} worker script`);
597
+ }
598
+ this.reportProgress(progress, 0.2, `${this.config.displayName} worker downloaded`);
599
+ }
600
+ catch (error) {
601
+ if (phaseController.signal.aborted) {
602
+ const reason = phaseController.signal.reason ??
603
+ new DOMException('Worker script read aborted', 'AbortError');
604
+ if (!readerCancelled) {
605
+ readerCancelled = true;
606
+ try {
607
+ void reader.cancel(reason).catch(() => undefined);
608
+ }
609
+ catch { }
610
+ }
611
+ throw reason;
612
+ }
613
+ if (!readerCancelled) {
614
+ readerCancelled = true;
615
+ try {
616
+ void reader.cancel(error).catch(() => undefined);
617
+ }
618
+ catch { }
619
+ }
620
+ throw error;
621
+ }
622
+ finally {
623
+ if (cancelOnAbort) {
624
+ phaseController.signal.removeEventListener('abort', cancelOnAbort);
625
+ }
626
+ try {
627
+ reader.releaseLock();
628
+ }
629
+ catch (error) {
630
+ if (!phaseController.signal.aborted)
631
+ releaseError = error;
632
+ }
633
+ }
634
+ if (releaseError)
635
+ throw releaseError;
636
+ if (workerReceipt) {
637
+ const bytes = new Uint8Array(loaded);
638
+ let offset = 0;
639
+ for (const chunk of chunks) {
640
+ bytes.set(chunk, offset);
641
+ offset += chunk.byteLength;
642
+ }
643
+ await this.verifyWorkerReceipt(bytes, workerReceipt, phaseController.signal);
644
+ return bytes;
645
+ }
646
+ return undefined;
647
+ }
648
+ catch (error) {
649
+ if (this.disposed)
650
+ throw this.getDisposeReason();
651
+ if (isWasmIdleError(error))
652
+ throw error;
653
+ if (timedOut) {
654
+ throw new TimeoutError(`${this.config.displayName} worker download timed out after ${limits.assetTimeoutMs} ms`, {
655
+ phase: 'asset',
656
+ runtimeId: this.config.languageId,
657
+ timeoutMs: limits.assetTimeoutMs
658
+ });
659
+ }
660
+ if (signal?.aborted) {
661
+ throw new CancelledError(`${this.config.displayName} worker download cancelled`, {
662
+ cause: signal.reason,
663
+ phase: 'asset',
664
+ runtimeId: this.config.languageId
665
+ });
666
+ }
667
+ throw new Error(`${this.config.displayName} worker script failed to load: ${this.errorMessage(error)}`);
668
+ }
669
+ finally {
670
+ clearTimeout(timeout);
671
+ try {
672
+ signal?.removeEventListener('abort', onAbort);
673
+ }
674
+ catch {
675
+ // Caller-owned signal cleanup must not replace the download result.
676
+ }
677
+ }
678
+ }
679
+ createBootstrapUrl(verifiedWorkerBytes) {
680
+ if (typeof Blob !== 'function' ||
681
+ typeof URL?.createObjectURL !== 'function' ||
682
+ typeof URL?.revokeObjectURL !== 'function') {
683
+ throw new Error(`${this.config.displayName} worker bootstrap is unavailable.`);
684
+ }
685
+ let verifiedWorkerSource;
686
+ if (this.config.inlineVerifiedWorker) {
687
+ if (!verifiedWorkerBytes) {
688
+ throw new RuntimeConfigurationError(`${this.config.displayName} verified worker bytes are unavailable.`, { runtimeId: this.config.languageId });
689
+ }
690
+ try {
691
+ new TextDecoder('utf-8', { fatal: true }).decode(verifiedWorkerBytes);
692
+ }
693
+ catch (error) {
694
+ throw new ProtocolError(`${this.config.displayName} worker script is not valid UTF-8`, {
695
+ cause: error,
696
+ phase: 'asset',
697
+ runtimeId: this.config.languageId
698
+ });
699
+ }
700
+ verifiedWorkerSource = verifiedWorkerBytes;
701
+ }
702
+ const prefix = `const __wasmIdleNativePostMessage = self.postMessage.bind(self);
703
+ let __wasmIdleRunId = null;
704
+ const __wasmIdleExecutionKeys = ['output', 'results', 'error', 'diagnostic', 'progress', 'evidence'];
705
+ self.addEventListener('message', (event) => {
706
+ const message = event.data;
707
+ const runId = message?.runId;
708
+ if (message?.run !== true || typeof runId !== 'string') return;
709
+ if (__wasmIdleRunId !== null) {
710
+ event.stopImmediatePropagation();
711
+ return;
712
+ }
713
+ __wasmIdleRunId = runId;
714
+ }, { capture: true });
715
+ self.postMessage = (message, transferOrOptions) => {
716
+ const executionMessage = __wasmIdleRunId !== null &&
717
+ message !== null && typeof message === 'object' &&
718
+ (__wasmIdleExecutionKeys.some((key) => Object.prototype.hasOwnProperty.call(message, key)) ||
719
+ message.type === 'stdin-request' || message.type === 'execution-ready');
720
+ const correlated = executionMessage
721
+ ? Object.assign({}, message, { runId: __wasmIdleRunId })
722
+ : message;
723
+ const terminalRunId = executionMessage &&
724
+ (Object.prototype.hasOwnProperty.call(message, 'results') ||
725
+ Object.prototype.hasOwnProperty.call(message, 'error'))
726
+ ? __wasmIdleRunId
727
+ : null;
728
+ try {
729
+ return transferOrOptions === undefined
730
+ ? __wasmIdleNativePostMessage(correlated)
731
+ : __wasmIdleNativePostMessage(correlated, transferOrOptions);
732
+ } finally {
733
+ if (terminalRunId !== null && __wasmIdleRunId === terminalRunId) __wasmIdleRunId = null;
734
+ }
735
+ };
736
+ `;
737
+ const suffix = `__wasmIdleNativePostMessage({ ${JSON.stringify(WORKER_READY_MESSAGE)}: true });\n`;
738
+ const workerSource = this.config.moduleWorker
739
+ ? `await import(${JSON.stringify(this.workerUrl)});`
740
+ : `importScripts(${JSON.stringify(this.workerUrl)});`;
741
+ const parts = verifiedWorkerSource
742
+ ? [
743
+ prefix,
744
+ '\n/* wasm-idle verified worker source */\n',
745
+ verifiedWorkerSource,
746
+ '\n',
747
+ suffix
748
+ ]
749
+ : [prefix, workerSource, '\n', suffix];
750
+ return URL.createObjectURL(new Blob(parts, { type: 'text/javascript' }));
751
+ }
752
+ revokeBootstrapUrl() {
753
+ if (!this.bootstrapUrl)
754
+ return;
755
+ const bootstrapUrl = this.bootstrapUrl;
756
+ this.bootstrapUrl = '';
757
+ try {
758
+ URL.revokeObjectURL(bootstrapUrl);
759
+ }
760
+ catch {
761
+ // The bootstrap is already detached; cleanup must not replace the lifecycle result.
762
+ }
763
+ }
764
+ ensureWorkerStarted(progress, controls) {
765
+ this.assertOperationNotDisposed();
766
+ if (this.workerStartPromise)
767
+ return this.workerStartPromise;
768
+ const startAbortController = new AbortController();
769
+ let generation = this.workerGeneration;
770
+ this.workerStartMaxAssetBytes = this.usesOwnedRuntimePreflight()
771
+ ? controls.limits.maxAssetBytes
772
+ : null;
773
+ this.workerStartAbortController = startAbortController;
774
+ const callerSignal = controls.signal;
775
+ let callerListenerAttempted = false;
776
+ const ownsStartup = () => !this.disposed &&
777
+ this.workerGeneration === generation &&
778
+ this.workerStartAbortController === startAbortController;
779
+ const invalidatedReason = () => {
780
+ if (this.disposed)
781
+ return this.getDisposeReason();
782
+ if (startAbortController.signal.aborted) {
783
+ let cause;
784
+ try {
785
+ cause = startAbortController.signal.reason;
786
+ }
787
+ catch (error) {
788
+ cause = error;
789
+ }
790
+ return new CancelledError(`${this.config.displayName} worker startup cancelled`, {
791
+ cause,
792
+ phase: 'startup',
793
+ runtimeId: this.config.languageId
794
+ });
795
+ }
796
+ return new CancelledError(`${this.config.displayName} worker startup terminated`, {
797
+ phase: 'startup',
798
+ runtimeId: this.config.languageId
799
+ });
800
+ };
801
+ const abortStartup = (reason) => {
802
+ if (startAbortController.signal.aborted)
803
+ return;
804
+ try {
805
+ startAbortController.abort(reason);
806
+ }
807
+ catch {
808
+ // Reservation state is detached separately; abort is best effort.
809
+ }
810
+ };
811
+ const forwardAbort = () => {
812
+ if (startAbortController.signal.aborted)
813
+ return;
814
+ let reason;
815
+ try {
816
+ reason = callerSignal?.reason;
817
+ }
818
+ catch (error) {
819
+ reason = error;
820
+ }
821
+ if (!ownsStartup() || startAbortController.signal.aborted)
822
+ return;
823
+ abortStartup(reason);
824
+ };
825
+ const cleanupStartSignal = () => {
826
+ if (callerListenerAttempted) {
827
+ try {
828
+ callerSignal?.removeEventListener('abort', forwardAbort);
829
+ }
830
+ catch {
831
+ // Caller-owned signal cleanup must not replace startup settlement.
832
+ }
833
+ }
834
+ if (this.workerStartAbortController === startAbortController) {
835
+ this.workerStartAbortController = null;
836
+ }
837
+ };
838
+ let startPromise;
839
+ try {
840
+ if (callerSignal) {
841
+ callerListenerAttempted = true;
842
+ callerSignal.addEventListener('abort', forwardAbort, { once: true });
843
+ if (!ownsStartup())
844
+ throw invalidatedReason();
845
+ const callerAborted = callerSignal.aborted;
846
+ if (!ownsStartup())
847
+ throw invalidatedReason();
848
+ if (callerAborted)
849
+ forwardAbort();
850
+ if (!ownsStartup() || startAbortController.signal.aborted) {
851
+ throw invalidatedReason();
852
+ }
853
+ }
854
+ const creationContext = {
855
+ generation,
856
+ progress,
857
+ controls: {
858
+ limits: controls.limits,
859
+ signal: startAbortController.signal
860
+ }
861
+ };
862
+ const acquisition = this.workerLifetimeController.acquire(creationContext);
863
+ generation = creationContext.generation;
864
+ startPromise = acquisition.then((lease) => {
865
+ if (!ownsStartup() || startAbortController.signal.aborted) {
866
+ lease.release({ reusable: false });
867
+ throw invalidatedReason();
868
+ }
869
+ if (this.worker && this.worker !== lease.worker) {
870
+ lease.release({ reusable: false });
871
+ throw new CancelledError(`${this.config.displayName} worker startup was superseded`, { phase: 'startup', runtimeId: this.config.languageId });
872
+ }
873
+ this.worker = lease.worker;
874
+ this.workerLease = lease;
875
+ return lease.worker;
876
+ });
877
+ if (!ownsStartup()) {
878
+ void startPromise.catch(() => undefined);
879
+ throw invalidatedReason();
880
+ }
881
+ this.workerStartPromise = startPromise;
882
+ }
883
+ catch (error) {
884
+ const reason = ownsStartup() ? this.preserveDisposeReason(error) : invalidatedReason();
885
+ abortStartup(reason);
886
+ cleanupStartSignal();
887
+ throw reason;
888
+ }
889
+ void startPromise.then(() => cleanupStartSignal(), (error) => {
890
+ cleanupStartSignal();
891
+ if (this.workerStartPromise === startPromise)
892
+ this.disposeWorker(error);
893
+ });
894
+ return startPromise;
895
+ }
896
+ async startWorker(generation, progress, controls) {
897
+ let runtimePreflight;
898
+ if (this.config.preflightRuntimeAssets) {
899
+ const urls = this.resolvedRuntimeUrls;
900
+ if (!urls) {
901
+ throw new RuntimeConfigurationError(`${this.config.displayName} runtime preflight configuration is unavailable.`, { phase: 'asset', runtimeId: this.config.languageId });
902
+ }
903
+ const preflightKey = urls.preflightKey || urls.manifestFingerprint || '';
904
+ if (this.usesOwnedRuntimePreflight() && preflightKey.length === 0) {
905
+ throw new RuntimeConfigurationError(`${this.config.displayName} transfer-owned runtime preflight requires a stable preflight key.`, { phase: 'asset', runtimeId: this.config.languageId });
906
+ }
907
+ const operation = {
908
+ active: true,
909
+ claimedTicket: null,
910
+ generation,
911
+ owner: this,
912
+ preflightKey,
913
+ runtimeId: this.config.languageId
914
+ };
915
+ this.reportProgress(progress, 0.03, `Preflighting ${this.config.displayName} runtime`);
916
+ try {
917
+ runtimePreflight = await this.config.preflightRuntimeAssets(urls, {
918
+ limits: controls.limits,
919
+ signal: controls.signal,
920
+ reportProgress: (value, stage) => this.reportProgress(progress, value, stage),
921
+ createOwnedDelivery: (payload) => {
922
+ const currentUrls = this.resolvedRuntimeUrls;
923
+ const currentPreflightKey = currentUrls?.preflightKey || currentUrls?.manifestFingerprint || '';
924
+ if (!operation.active ||
925
+ this.disposed ||
926
+ controls.signal?.aborted ||
927
+ generation !== this.workerGeneration ||
928
+ currentPreflightKey !== operation.preflightKey) {
929
+ throw new RuntimeConfigurationError(`${this.config.displayName} runtime preflight delivery operation is stale.`, { phase: 'asset', runtimeId: this.config.languageId });
930
+ }
931
+ if (operation.claimedTicket) {
932
+ this.retireRuntimePreflight(operation.claimedTicket);
933
+ throw new RuntimeConfigurationError(`${this.config.displayName} runtime preflight may create only one owned delivery.`, { phase: 'asset', runtimeId: this.config.languageId });
934
+ }
935
+ const prototype = payload !== null && typeof payload === 'object'
936
+ ? Object.getPrototypeOf(payload)
937
+ : undefined;
938
+ if (payload === null ||
939
+ typeof payload !== 'object' ||
940
+ Array.isArray(payload) ||
941
+ (prototype !== Object.prototype && prototype !== null) ||
942
+ !Object.isFrozen(payload)) {
943
+ throw new RuntimeConfigurationError(`${this.config.displayName} owned runtime preflight payload must be a frozen plain object.`, { phase: 'asset', runtimeId: this.config.languageId });
944
+ }
945
+ const transferables = [];
946
+ const seenBuffers = new Set();
947
+ for (const key of Reflect.ownKeys(payload)) {
948
+ if (typeof key !== 'string') {
949
+ throw new RuntimeConfigurationError(`${this.config.displayName} owned runtime preflight payload cannot contain symbol keys.`, { phase: 'asset', runtimeId: this.config.languageId });
950
+ }
951
+ const descriptor = Object.getOwnPropertyDescriptor(payload, key);
952
+ if (!descriptor || !descriptor.enumerable || !('value' in descriptor)) {
953
+ throw new RuntimeConfigurationError(`${this.config.displayName} owned runtime preflight payload properties must be enumerable data properties.`, { phase: 'asset', runtimeId: this.config.languageId });
954
+ }
955
+ const value = descriptor.value;
956
+ const bytes = inspectStaticRuntimePreflightBytes(value);
957
+ if (bytes) {
958
+ if (bytes.byteLength === 0 ||
959
+ bytes.byteOffset !== 0 ||
960
+ bytes.byteLength !== bytes.bufferByteLength) {
961
+ throw new RuntimeConfigurationError(`${this.config.displayName} owned runtime preflight bytes must span non-empty whole ArrayBuffers.`, { phase: 'asset', runtimeId: this.config.languageId });
962
+ }
963
+ if (seenBuffers.has(bytes.buffer)) {
964
+ throw new RuntimeConfigurationError(`${this.config.displayName} owned runtime preflight ArrayBuffers must be unique.`, { phase: 'asset', runtimeId: this.config.languageId });
965
+ }
966
+ seenBuffers.add(bytes.buffer);
967
+ transferables.push(bytes.buffer);
968
+ continue;
969
+ }
970
+ if (value !== null &&
971
+ (typeof value === 'object' ||
972
+ typeof value === 'function' ||
973
+ typeof value === 'symbol')) {
974
+ throw new RuntimeConfigurationError(`${this.config.displayName} owned runtime preflight payload accepts only primitive scalars and Uint8Arrays.`, { phase: 'asset', runtimeId: this.config.languageId });
975
+ }
976
+ }
977
+ if (transferables.length === 0) {
978
+ throw new RuntimeConfigurationError(`${this.config.displayName} owned runtime preflight payload contains no transferable bytes.`, { phase: 'asset', runtimeId: this.config.languageId });
979
+ }
980
+ const ticket = Object.freeze({});
981
+ ownedDeliveryStateByTicket.set(ticket, {
982
+ operation,
983
+ payload: payload,
984
+ status: 'available',
985
+ transferables
986
+ });
987
+ operation.claimedTicket = ticket;
988
+ return ticket;
989
+ }
990
+ });
991
+ }
992
+ catch (error) {
993
+ operation.active = false;
994
+ if (operation.claimedTicket) {
995
+ this.retireRuntimePreflight(operation.claimedTicket);
996
+ }
997
+ throw error;
998
+ }
999
+ operation.active = false;
1000
+ const returnedDelivery = runtimePreflight !== null && typeof runtimePreflight === 'object'
1001
+ ? ownedDeliveryStateByTicket.get(runtimePreflight)
1002
+ : undefined;
1003
+ if (this.usesOwnedRuntimePreflight()) {
1004
+ const currentUrls = this.resolvedRuntimeUrls;
1005
+ const currentPreflightKey = currentUrls?.preflightKey || currentUrls?.manifestFingerprint || '';
1006
+ if (!returnedDelivery ||
1007
+ returnedDelivery.operation !== operation ||
1008
+ returnedDelivery.status !== 'available' ||
1009
+ operation.claimedTicket !== runtimePreflight ||
1010
+ generation !== this.workerGeneration ||
1011
+ currentPreflightKey !== operation.preflightKey) {
1012
+ if (operation.claimedTicket) {
1013
+ this.retireRuntimePreflight(operation.claimedTicket);
1014
+ }
1015
+ throw new RuntimeConfigurationError(`${this.config.displayName} transfer-owned runtime preflight must return this operation's owned delivery ticket.`, { phase: 'asset', runtimeId: this.config.languageId });
1016
+ }
1017
+ }
1018
+ else if (operation.claimedTicket || returnedDelivery) {
1019
+ if (operation.claimedTicket) {
1020
+ this.retireRuntimePreflight(operation.claimedTicket);
1021
+ }
1022
+ throw new RuntimeConfigurationError(`${this.config.displayName} structured-clone runtime preflight cannot return an owned delivery ticket.`, { phase: 'asset', runtimeId: this.config.languageId });
1023
+ }
1024
+ if (runtimePreflight === undefined || runtimePreflight === null) {
1025
+ throw new RuntimeConfigurationError(`${this.config.displayName} runtime preflight returned no verified assets.`, { phase: 'asset', runtimeId: this.config.languageId });
1026
+ }
1027
+ try {
1028
+ this.reportProgress(progress, 0.18, `${this.config.displayName} runtime preflight complete`);
1029
+ }
1030
+ catch (error) {
1031
+ this.retireRuntimePreflight(runtimePreflight);
1032
+ throw error;
1033
+ }
1034
+ }
1035
+ let worker;
1036
+ let workerCreated = false;
1037
+ try {
1038
+ if (this.disposed)
1039
+ throw this.getDisposeReason();
1040
+ if (generation !== this.workerGeneration) {
1041
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1042
+ phase: 'startup',
1043
+ runtimeId: this.config.languageId
1044
+ });
1045
+ }
1046
+ const verifiedWorkerBytes = await this.preloadWorkerScript(progress, controls);
1047
+ if (this.disposed)
1048
+ throw this.getDisposeReason();
1049
+ if (generation !== this.workerGeneration) {
1050
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1051
+ phase: 'startup',
1052
+ runtimeId: this.config.languageId
1053
+ });
1054
+ }
1055
+ try {
1056
+ this.reportProgress(progress, 0.22, `Starting ${this.config.displayName} worker`);
1057
+ }
1058
+ catch (error) {
1059
+ throw this.preserveDisposeReason(error);
1060
+ }
1061
+ if (this.disposed)
1062
+ throw this.getDisposeReason();
1063
+ if (generation !== this.workerGeneration) {
1064
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1065
+ phase: 'startup',
1066
+ runtimeId: this.config.languageId
1067
+ });
1068
+ }
1069
+ this.bootstrapUrl = this.createBootstrapUrl(verifiedWorkerBytes);
1070
+ if (this.disposed || generation !== this.workerGeneration) {
1071
+ this.revokeBootstrapUrl();
1072
+ if (this.disposed)
1073
+ throw this.getDisposeReason();
1074
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1075
+ phase: 'startup',
1076
+ runtimeId: this.config.languageId
1077
+ });
1078
+ }
1079
+ try {
1080
+ worker = this.config.moduleWorker
1081
+ ? new Worker(this.bootstrapUrl, { type: 'module' })
1082
+ : new Worker(this.bootstrapUrl);
1083
+ workerCreated = true;
1084
+ }
1085
+ catch (error) {
1086
+ this.revokeBootstrapUrl();
1087
+ if (this.disposed)
1088
+ throw this.getDisposeReason();
1089
+ if (generation !== this.workerGeneration) {
1090
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1091
+ phase: 'startup',
1092
+ runtimeId: this.config.languageId
1093
+ });
1094
+ }
1095
+ throw new WorkerStartupError(`${this.config.displayName} worker failed to start: ${this.errorMessage(error)}`, { cause: error, runtimeId: this.config.languageId });
1096
+ }
1097
+ if (runtimePreflight !== undefined) {
1098
+ this.workerRuntimePreflight.set(worker, runtimePreflight);
1099
+ }
1100
+ if (this.usesOwnedRuntimePreflight()) {
1101
+ this.workerRuntimePreflightMaxAssetBytes.set(worker, controls.limits.maxAssetBytes);
1102
+ }
1103
+ }
1104
+ catch (error) {
1105
+ if (workerCreated)
1106
+ this.detachAndTerminateWorker(worker);
1107
+ this.retireRuntimePreflight(runtimePreflight);
1108
+ throw error;
1109
+ }
1110
+ if (this.disposed || generation !== this.workerGeneration) {
1111
+ this.detachAndTerminateWorker(worker);
1112
+ this.revokeBootstrapUrl();
1113
+ if (this.disposed)
1114
+ throw this.getDisposeReason();
1115
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1116
+ phase: 'startup',
1117
+ runtimeId: this.config.languageId
1118
+ });
1119
+ }
1120
+ return await new Promise((resolve, reject) => {
1121
+ let settled = false;
1122
+ let timeout;
1123
+ const cleanup = () => {
1124
+ if (timeout !== undefined) {
1125
+ try {
1126
+ clearTimeout(timeout);
1127
+ }
1128
+ catch {
1129
+ // Timer cleanup is best effort once startup has settled.
1130
+ }
1131
+ }
1132
+ try {
1133
+ controls.signal?.removeEventListener('abort', onAbort);
1134
+ }
1135
+ catch {
1136
+ // Caller-owned signal cleanup must not prevent startup settlement.
1137
+ }
1138
+ };
1139
+ const rejectStartup = (reason) => {
1140
+ if (settled)
1141
+ return false;
1142
+ settled = true;
1143
+ cleanup();
1144
+ if (this.startupReject === rejectStartup)
1145
+ this.startupReject = null;
1146
+ reject(reason);
1147
+ return true;
1148
+ };
1149
+ const retireStartedWorker = () => {
1150
+ if (generation === this.workerGeneration && this.worker === worker) {
1151
+ this.disposeWorker();
1152
+ return;
1153
+ }
1154
+ this.detachAndTerminateWorker(worker);
1155
+ };
1156
+ const failStartup = (reason) => {
1157
+ if (!rejectStartup(this.preserveDisposeReason(reason)))
1158
+ return;
1159
+ retireStartedWorker();
1160
+ };
1161
+ const onAbort = () => {
1162
+ let signalReason;
1163
+ try {
1164
+ signalReason = controls.signal?.reason;
1165
+ }
1166
+ catch (error) {
1167
+ signalReason = error;
1168
+ }
1169
+ failStartup(signalReason === this.disposeReason
1170
+ ? this.getDisposeReason()
1171
+ : new CancelledError(`${this.config.displayName} worker startup cancelled`, {
1172
+ cause: signalReason,
1173
+ phase: 'startup',
1174
+ runtimeId: this.config.languageId
1175
+ }));
1176
+ };
1177
+ this.worker = worker;
1178
+ this.startupReject = rejectStartup;
1179
+ try {
1180
+ timeout = setTimeout(() => {
1181
+ failStartup(new TimeoutError(`${this.config.displayName} worker startup timed out after ${controls.limits.startupTimeoutMs} ms`, {
1182
+ phase: 'startup',
1183
+ runtimeId: this.config.languageId,
1184
+ timeoutMs: controls.limits.startupTimeoutMs
1185
+ }));
1186
+ }, controls.limits.startupTimeoutMs);
1187
+ worker.onmessage = (event) => {
1188
+ if (generation !== this.workerGeneration || this.worker !== worker)
1189
+ return;
1190
+ if (event.data?.__wasmIdleStaticWorkerReady) {
1191
+ if (settled || this.startupReject !== rejectStartup)
1192
+ return;
1193
+ try {
1194
+ this.reportProgress(progress, 0.25, `${this.config.displayName} worker ready`);
1195
+ }
1196
+ catch (error) {
1197
+ failStartup(error);
1198
+ return;
1199
+ }
1200
+ if (settled ||
1201
+ generation !== this.workerGeneration ||
1202
+ this.worker !== worker ||
1203
+ this.startupReject !== rejectStartup) {
1204
+ return;
1205
+ }
1206
+ settled = true;
1207
+ cleanup();
1208
+ this.startupReject = null;
1209
+ this.revokeBootstrapUrl();
1210
+ resolve(worker);
1211
+ return;
1212
+ }
1213
+ this.handleWorkerMessage(event);
1214
+ };
1215
+ worker.onerror = (event) => {
1216
+ if (generation !== this.workerGeneration || this.worker !== worker)
1217
+ return;
1218
+ event.preventDefault?.();
1219
+ const message = this.formatWorkerError(event);
1220
+ const options = {
1221
+ cause: event.error ?? event,
1222
+ runtimeId: this.config.languageId
1223
+ };
1224
+ this.handleWorkerFailure(this.startupReject
1225
+ ? new WorkerStartupError(message, options)
1226
+ : new RuntimeExecutionError(message, options));
1227
+ };
1228
+ worker.onmessageerror = (event) => {
1229
+ if (generation !== this.workerGeneration || this.worker !== worker)
1230
+ return;
1231
+ this.handleWorkerFailure(new ProtocolError(`${this.config.displayName} worker message deserialization failed`, {
1232
+ cause: event,
1233
+ phase: 'protocol',
1234
+ runtimeId: this.config.languageId
1235
+ }));
1236
+ };
1237
+ controls.signal?.addEventListener('abort', onAbort, { once: true });
1238
+ if (controls.signal?.aborted)
1239
+ onAbort();
1240
+ }
1241
+ catch (error) {
1242
+ failStartup(error);
1243
+ }
1244
+ });
1245
+ }
1246
+ handleWorkerMessage(event) {
1247
+ const activeRun = this.activeRun;
1248
+ if (!activeRun)
1249
+ return;
1250
+ if (event.data?.runId !== activeRun.id)
1251
+ return;
1252
+ try {
1253
+ if (event.data?.type === 'execution-ready') {
1254
+ activeRun.startExecutionDeadline?.();
1255
+ activeRun.startExecutionDeadline = undefined;
1256
+ this.reportRunReady(activeRun, 'running', 'started', `${this.config.displayName} program started`);
1257
+ return;
1258
+ }
1259
+ if (event.data?.type === 'stdin-request') {
1260
+ activeRun.stdinRing?.consumerRequestedInput();
1261
+ if (this.activeRun === activeRun) {
1262
+ this.reportRunReady(activeRun, 'waiting-input', 'stdin-request', `${this.config.displayName} runtime ready for input`);
1263
+ }
1264
+ return;
1265
+ }
1266
+ const { output, stream, results, error, diagnostic, progress, failure, evidence } = event.data || {};
1267
+ if (evidence !== undefined)
1268
+ this.config.onEvidence?.(evidence);
1269
+ if (this.activeRun !== activeRun)
1270
+ return;
1271
+ if (progress && typeof progress === 'object' && 'kind' in progress) {
1272
+ if (progress.kind !== 'settled') {
1273
+ const lifecycleEvent = reportWorkerProgress(activeRun.progress, progress);
1274
+ if (lifecycleEvent?.kind === 'ready')
1275
+ activeRun.readyReported = true;
1276
+ if (this.activeRun !== activeRun)
1277
+ return;
1278
+ }
1279
+ }
1280
+ else if (progress && typeof progress.percent === 'number') {
1281
+ const runtimeProgress = Math.max(0, Math.min(progress.percent / 100, 1));
1282
+ this.reportProgress(activeRun.progress, 0.3 + runtimeProgress * 0.65, progress.stage || `Running ${this.config.displayName}`);
1283
+ if (this.activeRun !== activeRun)
1284
+ return;
1285
+ }
1286
+ if (typeof output === 'string' && output.length > 0) {
1287
+ const outputBytes = activeRun.outputBytes + outputEncoder.encode(output).byteLength;
1288
+ if (outputBytes > activeRun.limits.maxOutputBytes) {
1289
+ this.rejectRun(activeRun.id, new OutputLimitError(`${this.config.displayName} output exceeded ${activeRun.limits.maxOutputBytes} bytes`, {
1290
+ actual: outputBytes,
1291
+ limit: activeRun.limits.maxOutputBytes,
1292
+ phase: 'execute',
1293
+ runtimeId: this.config.languageId
1294
+ }));
1295
+ return;
1296
+ }
1297
+ this.reportRunReady(activeRun, 'running', stream === 'stderr' ? 'stderr' : 'stdout', `${this.config.displayName} program output received`);
1298
+ if (this.activeRun !== activeRun)
1299
+ return;
1300
+ activeRun.outputBytes = outputBytes;
1301
+ this.output?.(output);
1302
+ if (this.activeRun !== activeRun)
1303
+ return;
1304
+ }
1305
+ if (diagnostic) {
1306
+ const diagnosticCount = activeRun.diagnosticCount + 1;
1307
+ if (diagnosticCount > activeRun.limits.maxDiagnostics) {
1308
+ this.rejectRun(activeRun.id, new DiagnosticLimitError(`${this.config.displayName} diagnostics exceeded ${activeRun.limits.maxDiagnostics} messages`, {
1309
+ actual: diagnosticCount,
1310
+ limit: activeRun.limits.maxDiagnostics,
1311
+ phase: 'execute',
1312
+ runtimeId: this.config.languageId
1313
+ }));
1314
+ return;
1315
+ }
1316
+ activeRun.diagnosticCount = diagnosticCount;
1317
+ this.oncompilerdiagnostic?.(diagnostic);
1318
+ if (this.activeRun !== activeRun)
1319
+ return;
1320
+ }
1321
+ if (typeof error === 'string') {
1322
+ this.rejectRun(activeRun.id, isStaticRuntimePreflightSerializedError(failure)
1323
+ ? deserializeStaticRuntimePreflightError(failure, this.config.languageId)
1324
+ : error);
1325
+ return;
1326
+ }
1327
+ if (results !== undefined) {
1328
+ this.resolveRun(activeRun.id, typeof results === 'string' ? results : results);
1329
+ }
1330
+ }
1331
+ catch (error) {
1332
+ if (this.activeRun === activeRun)
1333
+ this.rejectRun(activeRun.id, error);
1334
+ }
1335
+ }
1336
+ formatWorkerError(event) {
1337
+ const location = event.filename && event.lineno
1338
+ ? ` (${event.filename}:${event.lineno}:${event.colno})`
1339
+ : '';
1340
+ return `${this.config.displayName} worker script error: ${event.message || 'unknown error'}${location}`;
1341
+ }
1342
+ errorMessage(error) {
1343
+ if (error instanceof Error)
1344
+ return error.message;
1345
+ if (error !== null &&
1346
+ typeof error === 'object' &&
1347
+ 'message' in error &&
1348
+ typeof error.message === 'string') {
1349
+ return error.message;
1350
+ }
1351
+ return String(error);
1352
+ }
1353
+ handleWorkerFailure(reason) {
1354
+ this.startupReject?.(reason);
1355
+ this.startupReject = null;
1356
+ if (this.activeRun)
1357
+ this.rejectRun(this.activeRun.id, reason);
1358
+ else
1359
+ this.disposeWorker();
1360
+ }
1361
+ resolveRun(id, result) {
1362
+ const activeRun = this.activeRun;
1363
+ if (!activeRun || activeRun.id !== id)
1364
+ return;
1365
+ try {
1366
+ if (!activeRun.readyReported && !activeRun.settledReported) {
1367
+ this.reportRunReady(activeRun, 'running', 'result', `${this.config.displayName} run complete`);
1368
+ if (this.activeRun !== activeRun)
1369
+ return;
1370
+ }
1371
+ this.reportRunSettled(activeRun, 'completed', `${this.config.displayName} run complete`);
1372
+ }
1373
+ catch (error) {
1374
+ if (this.activeRun === activeRun)
1375
+ this.rejectRun(id, error);
1376
+ return;
1377
+ }
1378
+ if (this.activeRun !== activeRun)
1379
+ return;
1380
+ const claimedRun = this.claimRun(id);
1381
+ if (claimedRun !== activeRun)
1382
+ return;
1383
+ this.elapse = Date.now() - this.begin;
1384
+ this.exit = true;
1385
+ this.clearPendingStdin();
1386
+ this.releaseWorkerLease(true);
1387
+ this.cleanupRun(activeRun);
1388
+ activeRun.resolve(result);
1389
+ }
1390
+ rejectRun(id, reason) {
1391
+ const activeRun = this.claimRun(id);
1392
+ if (!activeRun)
1393
+ return;
1394
+ try {
1395
+ this.reportRunSettled(activeRun, reason instanceof TimeoutError
1396
+ ? 'timed-out'
1397
+ : reason instanceof CancelledError
1398
+ ? 'cancelled'
1399
+ : 'failed', `${this.config.displayName} run ended`);
1400
+ }
1401
+ catch {
1402
+ // Progress observers must not prevent a failed run from releasing its worker.
1403
+ }
1404
+ this.elapse = Date.now() - this.begin;
1405
+ this.exit = true;
1406
+ this.clearPendingStdin();
1407
+ this.startupReject?.(reason);
1408
+ this.disposeWorker();
1409
+ this.cleanupRun(activeRun);
1410
+ activeRun.reject(reason);
1411
+ }
1412
+ claimRun(id) {
1413
+ const activeRun = this.activeRun;
1414
+ if (!activeRun || activeRun.id !== id)
1415
+ return null;
1416
+ this.activeRun = null;
1417
+ this.activeReject = null;
1418
+ return activeRun;
1419
+ }
1420
+ cleanupRun(activeRun) {
1421
+ try {
1422
+ activeRun.cleanup();
1423
+ }
1424
+ catch {
1425
+ // Lifecycle cleanup is best effort and must not replace the run result.
1426
+ }
1427
+ try {
1428
+ activeRun.stdinRing?.cancel();
1429
+ }
1430
+ catch {
1431
+ // The stdin channel is already detached; preserve the run result.
1432
+ }
1433
+ }
1434
+ releasePreparedWorkerIfIdle() {
1435
+ if (this.workerLifetimeController.policy.mode === 'per-run')
1436
+ return;
1437
+ if (this.activeRun || this.startingRunId)
1438
+ return;
1439
+ this.releaseWorkerLease(true);
1440
+ }
1441
+ releaseWorkerLease(reusable) {
1442
+ const lease = this.workerLease;
1443
+ this.workerLease = null;
1444
+ this.workerStartPromise = null;
1445
+ this.workerStartMaxAssetBytes = null;
1446
+ if (!lease)
1447
+ return;
1448
+ try {
1449
+ lease.release({ reusable });
1450
+ }
1451
+ catch {
1452
+ // A hostile timer implementation must not replace a completed run.
1453
+ this.workerLifetimeController.evictIdle();
1454
+ }
1455
+ }
1456
+ handleMemoryPressure() {
1457
+ return this.workerLifetimeController.handleMemoryPressure();
1458
+ }
1459
+ retireManagedWorker(worker) {
1460
+ if (this.worker === worker) {
1461
+ delete this.worker;
1462
+ this.workerStartPromise = null;
1463
+ this.workerStartMaxAssetBytes = null;
1464
+ this.workerGeneration += 1;
1465
+ }
1466
+ this.detachAndTerminateWorker(worker);
1467
+ }
1468
+ retireRuntimePreflight(runtimePreflight) {
1469
+ if (runtimePreflight === null || typeof runtimePreflight !== 'object')
1470
+ return;
1471
+ const state = ownedDeliveryStateByTicket.get(runtimePreflight);
1472
+ if (!state || state.operation.owner !== this || state.status === 'retired')
1473
+ return;
1474
+ state.status = 'retired';
1475
+ state.payload = null;
1476
+ state.transferables = null;
1477
+ }
1478
+ detachAndTerminateWorker(worker) {
1479
+ this.retireRuntimePreflight(this.workerRuntimePreflight.get(worker));
1480
+ this.workerRuntimePreflight.delete(worker);
1481
+ this.workerRuntimePreflightMaxAssetBytes.delete(worker);
1482
+ this.workersWithCachedRuntimePreflight.delete(worker);
1483
+ try {
1484
+ worker.onmessage = null;
1485
+ }
1486
+ catch {
1487
+ // Continue detaching and terminating even if a custom worker setter fails.
1488
+ }
1489
+ try {
1490
+ worker.onerror = null;
1491
+ }
1492
+ catch {
1493
+ // Continue detaching and terminating even if a custom worker setter fails.
1494
+ }
1495
+ try {
1496
+ worker.onmessageerror = null;
1497
+ }
1498
+ catch {
1499
+ // Continue detaching and terminating even if a custom worker setter fails.
1500
+ }
1501
+ try {
1502
+ worker.terminate();
1503
+ }
1504
+ catch {
1505
+ // The worker is detached before cleanup, so a throwing terminate remains harmless.
1506
+ }
1507
+ }
1508
+ disposeWorker(reason) {
1509
+ const startAbortController = this.workerStartAbortController;
1510
+ this.workerStartAbortController = null;
1511
+ this.workerGeneration += 1;
1512
+ this.workerStartPromise = null;
1513
+ this.workerStartMaxAssetBytes = null;
1514
+ this.startupReject = null;
1515
+ const lease = this.workerLease;
1516
+ this.workerLease = null;
1517
+ const worker = this.worker;
1518
+ delete this.worker;
1519
+ this.revokeBootstrapUrl();
1520
+ if (startAbortController && !startAbortController.signal.aborted) {
1521
+ try {
1522
+ startAbortController.abort(reason);
1523
+ }
1524
+ catch {
1525
+ // Startup state is already detached; abort cleanup is best effort.
1526
+ }
1527
+ }
1528
+ if (lease) {
1529
+ lease.release({ reusable: false });
1530
+ if (worker && worker !== lease.worker)
1531
+ this.detachAndTerminateWorker(worker);
1532
+ }
1533
+ else if (worker && !this.workerLifetimeController.retireWorker(worker)) {
1534
+ this.detachAndTerminateWorker(worker);
1535
+ }
1536
+ this.workerLifetimeController.evictIdle();
1537
+ }
1538
+ run(code, prepare, _log = true, _prog, args = [], options = {}) {
1539
+ try {
1540
+ this.assertNotDisposed();
1541
+ }
1542
+ catch (error) {
1543
+ return Promise.reject(error);
1544
+ }
1545
+ if (!this.baseUrl || !this.workerUrl) {
1546
+ return Promise.reject(new RuntimeConfigurationError(`${this.config.displayName} runtime is not configured.`, { runtimeId: this.config.languageId }));
1547
+ }
1548
+ if (this.activeRun || this.startingRunId) {
1549
+ return Promise.reject(new BusyError(`${this.config.displayName} runtime already has an active run`, {
1550
+ runtimeId: this.config.languageId
1551
+ }));
1552
+ }
1553
+ let controls;
1554
+ let workspace;
1555
+ try {
1556
+ controls = this.resolveExecutionControls(options);
1557
+ this.assertOperationNotDisposed();
1558
+ workspace = this.validateWorkspace(code, options, controls.limits);
1559
+ this.assertOperationNotDisposed();
1560
+ }
1561
+ catch (error) {
1562
+ return Promise.reject(this.preserveDisposeReason(error));
1563
+ }
1564
+ try {
1565
+ if (controls.signal?.aborted) {
1566
+ return Promise.reject(new CancelledError(`${this.config.displayName} run cancelled`, {
1567
+ cause: controls.signal.reason,
1568
+ phase: 'execute',
1569
+ runtimeId: this.config.languageId
1570
+ }));
1571
+ }
1572
+ }
1573
+ catch (error) {
1574
+ return Promise.reject(this.preserveDisposeReason(error));
1575
+ }
1576
+ this.resetWorkerForLowerAssetLimit(controls.limits.maxAssetBytes);
1577
+ const id = `static-${++this.uid}`;
1578
+ this.startingRunId = id;
1579
+ const progressSink = this.selectProgress(_prog);
1580
+ let lifecycle;
1581
+ try {
1582
+ lifecycle = this.beginProgressLifecycle(progressSink, prepare
1583
+ ? `Preparing ${this.config.displayName} runtime`
1584
+ : `Starting ${this.config.displayName} run`);
1585
+ }
1586
+ catch (error) {
1587
+ if (this.startingRunId === id)
1588
+ this.startingRunId = null;
1589
+ return Promise.reject(this.preserveDisposeReason(error));
1590
+ }
1591
+ if (this.startingRunId !== id) {
1592
+ lifecycle.end();
1593
+ return Promise.reject(this.disposed
1594
+ ? this.getDisposeReason()
1595
+ : new CancelledError(prepare
1596
+ ? `${this.config.displayName} worker startup terminated`
1597
+ : `${this.config.displayName} run terminated`, {
1598
+ phase: prepare ? 'startup' : 'execute',
1599
+ runtimeId: this.config.languageId
1600
+ }));
1601
+ }
1602
+ const progress = lifecycle.progress;
1603
+ if (prepare) {
1604
+ let startup;
1605
+ try {
1606
+ startup = this.ensureWorkerStarted(progress, controls);
1607
+ }
1608
+ catch (error) {
1609
+ startup = Promise.reject(error);
1610
+ }
1611
+ return startup
1612
+ .then(() => {
1613
+ if (this.startingRunId !== id) {
1614
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1615
+ phase: 'startup',
1616
+ runtimeId: this.config.languageId
1617
+ });
1618
+ }
1619
+ this.assertOperationNotDisposed();
1620
+ this.reportProgress(progress, 0.25, `${this.config.displayName} worker ready`);
1621
+ this.assertOperationNotDisposed();
1622
+ if (this.startingRunId !== id) {
1623
+ throw new CancelledError(`${this.config.displayName} worker startup terminated`, {
1624
+ phase: 'startup',
1625
+ runtimeId: this.config.languageId
1626
+ });
1627
+ }
1628
+ return true;
1629
+ })
1630
+ .catch((error) => {
1631
+ throw this.preserveDisposeReason(error);
1632
+ })
1633
+ .finally(() => {
1634
+ if (this.startingRunId === id)
1635
+ this.startingRunId = null;
1636
+ this.releasePreparedWorkerIfIdle();
1637
+ lifecycle.end();
1638
+ });
1639
+ }
1640
+ this.exit = false;
1641
+ return new Promise((resolve, reject) => {
1642
+ let stdinRing;
1643
+ if (this.stdinMode === 'streaming') {
1644
+ try {
1645
+ const maxBufferedBytes = Math.min(128 * 1024, controls.limits.maxWorkspaceBytes);
1646
+ stdinRing = new StaticStdinRingHost({
1647
+ capacity: Math.min(64 * 1024, maxBufferedBytes),
1648
+ maxBufferedBytes
1649
+ });
1650
+ const explicitStdin = typeof options.stdin === 'string';
1651
+ const initialInput = explicitStdin
1652
+ ? (options.stdin ?? '')
1653
+ : this.pendingInput.join('');
1654
+ const initialEof = explicitStdin || this.pendingEof;
1655
+ this.assertOperationNotDisposed();
1656
+ this.clearPendingStdin();
1657
+ stdinRing.enqueue(initialInput);
1658
+ if (initialEof)
1659
+ stdinRing.close();
1660
+ }
1661
+ catch (error) {
1662
+ try {
1663
+ stdinRing?.cancel();
1664
+ }
1665
+ catch {
1666
+ // A local stdin channel must not outlive a rejected reservation.
1667
+ }
1668
+ if (this.startingRunId === id)
1669
+ this.startingRunId = null;
1670
+ this.exit = true;
1671
+ reject(this.preserveDisposeReason(error));
1672
+ return;
1673
+ }
1674
+ }
1675
+ let deadline;
1676
+ const onAbort = () => {
1677
+ if (this.activeRun?.id !== id)
1678
+ return;
1679
+ const error = new CancelledError(`${this.config.displayName} run cancelled`, {
1680
+ cause: controls.signal?.reason,
1681
+ phase: 'execute',
1682
+ runtimeId: this.config.languageId
1683
+ });
1684
+ this.rejectStdinWaiters(error);
1685
+ this.rejectRun(id, error);
1686
+ };
1687
+ const cleanup = () => {
1688
+ if (deadline !== undefined)
1689
+ clearTimeout(deadline);
1690
+ controls.signal?.removeEventListener('abort', onAbort);
1691
+ };
1692
+ this.activeRun = {
1693
+ cleanup,
1694
+ diagnosticCount: 0,
1695
+ id,
1696
+ limits: controls.limits,
1697
+ outputBytes: 0,
1698
+ progress,
1699
+ readyReported: false,
1700
+ resolve,
1701
+ reject,
1702
+ settledReported: false,
1703
+ ...(stdinRing ? { stdinRing } : {})
1704
+ };
1705
+ this.activeReject = reject;
1706
+ this.startingRunId = null;
1707
+ this.begin = Date.now();
1708
+ try {
1709
+ controls.signal?.addEventListener('abort', onAbort, { once: true });
1710
+ }
1711
+ catch (error) {
1712
+ this.rejectRun(id, error);
1713
+ return;
1714
+ }
1715
+ if (controls.signal?.aborted) {
1716
+ onAbort();
1717
+ return;
1718
+ }
1719
+ void (async () => {
1720
+ try {
1721
+ const worker = await this.ensureWorkerStarted(progress, controls);
1722
+ const activeRun = this.activeRun;
1723
+ if (!activeRun || activeRun.id !== id)
1724
+ return;
1725
+ const { stdin, stdinEof } = activeRun.stdinRing
1726
+ ? { stdin: undefined, stdinEof: false }
1727
+ : await this.collectStdinForRun(code, options, activeRun);
1728
+ if (this.activeRun?.id !== id)
1729
+ return;
1730
+ const setDeadline = (timeoutMs, phase) => {
1731
+ timeoutMs = Math.min(2_147_483_647, timeoutMs);
1732
+ if (deadline !== undefined)
1733
+ clearTimeout(deadline);
1734
+ deadline = setTimeout(() => this.rejectRun(id, new TimeoutError(`${this.config.displayName} ${this.config.enforcePhaseTimeouts ? phase : 'execution'} timed out after ${timeoutMs} ms`, { phase, runtimeId: this.config.languageId, timeoutMs })), timeoutMs);
1735
+ };
1736
+ if (this.config.enforcePhaseTimeouts) {
1737
+ setDeadline(controls.limits.compileTimeoutMs, 'compile');
1738
+ activeRun.startExecutionDeadline = () => setDeadline(controls.limits.runTimeoutMs, 'execute');
1739
+ }
1740
+ else {
1741
+ setDeadline(Math.min(2_147_483_647, controls.limits.compileTimeoutMs + controls.limits.runTimeoutMs), 'execute');
1742
+ }
1743
+ const { programArgs } = resolveSandboxExecutionArgs(this.config.languageId, args, options);
1744
+ this.reportProgress(progress, 0.3, `Loading ${this.config.displayName} runtime`);
1745
+ if (this.disposed || this.activeRun !== activeRun || this.worker !== worker) {
1746
+ return;
1747
+ }
1748
+ try {
1749
+ const storedRuntimePreflight = this.workerRuntimePreflight.get(worker);
1750
+ let runtimePreflight = storedRuntimePreflight;
1751
+ let transferList;
1752
+ let deliveredOwnedPreflight = false;
1753
+ try {
1754
+ if (this.usesOwnedRuntimePreflight()) {
1755
+ const state = storedRuntimePreflight !== null &&
1756
+ typeof storedRuntimePreflight === 'object'
1757
+ ? ownedDeliveryStateByTicket.get(storedRuntimePreflight)
1758
+ : undefined;
1759
+ const currentUrls = this.resolvedRuntimeUrls;
1760
+ const currentPreflightKey = currentUrls?.preflightKey ||
1761
+ currentUrls?.manifestFingerprint ||
1762
+ '';
1763
+ if (state &&
1764
+ state.operation.owner === this &&
1765
+ state.operation.runtimeId === this.config.languageId &&
1766
+ state.operation.generation === this.workerGeneration &&
1767
+ state.operation.preflightKey === currentPreflightKey &&
1768
+ state.status === 'available' &&
1769
+ state.payload &&
1770
+ state.transferables) {
1771
+ runtimePreflight = state.payload;
1772
+ transferList = state.transferables;
1773
+ state.status = 'consumed';
1774
+ state.payload = null;
1775
+ state.transferables = null;
1776
+ deliveredOwnedPreflight = true;
1777
+ }
1778
+ else if (this.usesWorkerCachedRuntimePreflight() &&
1779
+ storedRuntimePreflight === undefined &&
1780
+ this.workersWithCachedRuntimePreflight.has(worker)) {
1781
+ runtimePreflight = undefined;
1782
+ }
1783
+ else {
1784
+ throw new RuntimeConfigurationError(`${this.config.displayName} runtime preflight owned delivery is unavailable or stale.`, { phase: 'protocol', runtimeId: this.config.languageId });
1785
+ }
1786
+ }
1787
+ else if (storedRuntimePreflight !== null &&
1788
+ typeof storedRuntimePreflight === 'object' &&
1789
+ ownedDeliveryStateByTicket.has(storedRuntimePreflight)) {
1790
+ throw new RuntimeConfigurationError(`${this.config.displayName} structured-clone runtime preflight cannot dispatch an owned delivery ticket.`, { phase: 'protocol', runtimeId: this.config.languageId });
1791
+ }
1792
+ const message = {
1793
+ run: true,
1794
+ runId: id,
1795
+ baseUrl: this.baseUrl,
1796
+ manifestUrl: this.manifestUrl,
1797
+ manifestFingerprint: this.manifestFingerprint,
1798
+ ...(runtimePreflight === undefined ? {} : { runtimePreflight }),
1799
+ maxAssetBytes: controls.limits.maxAssetBytes,
1800
+ ...(this.config.includeExecutionLimits
1801
+ ? { limits: controls.limits }
1802
+ : {}),
1803
+ code,
1804
+ args: programArgs,
1805
+ stdin,
1806
+ stdinEof,
1807
+ ...(activeRun.stdinRing
1808
+ ? { stdinChannel: activeRun.stdinRing.descriptor }
1809
+ : {}),
1810
+ activePath: workspace.activePath,
1811
+ workspaceFiles: workspace.workspaceFiles,
1812
+ log: _log
1813
+ };
1814
+ if (transferList)
1815
+ worker.postMessage(message, transferList);
1816
+ else
1817
+ worker.postMessage(message);
1818
+ if (deliveredOwnedPreflight &&
1819
+ this.usesWorkerCachedRuntimePreflight()) {
1820
+ this.workersWithCachedRuntimePreflight.add(worker);
1821
+ }
1822
+ }
1823
+ finally {
1824
+ if (this.usesOwnedRuntimePreflight()) {
1825
+ this.workerRuntimePreflight.delete(worker);
1826
+ this.retireRuntimePreflight(storedRuntimePreflight);
1827
+ }
1828
+ }
1829
+ }
1830
+ catch (error) {
1831
+ throw new ProtocolError(`${this.config.displayName} worker run dispatch failed: ${this.errorMessage(error)}`, {
1832
+ cause: error,
1833
+ phase: 'protocol',
1834
+ runtimeId: this.config.languageId
1835
+ });
1836
+ }
1837
+ }
1838
+ catch (error) {
1839
+ const reason = this.preserveDisposeReason(error);
1840
+ this.rejectRun(id, isWasmIdleError(reason) ? reason : this.errorMessage(reason));
1841
+ }
1842
+ })();
1843
+ }).finally(() => lifecycle.end());
1844
+ }
1845
+ kill() {
1846
+ this.terminate();
1847
+ }
1848
+ terminateLifecycle(startupReason, runReason) {
1849
+ const activeRun = this.activeRun;
1850
+ if (activeRun) {
1851
+ try {
1852
+ this.reportRunSettled(activeRun, 'cancelled', `${this.config.displayName} run ended`);
1853
+ }
1854
+ catch {
1855
+ // Progress observers must not prevent explicit runtime termination.
1856
+ }
1857
+ if (this.activeRun !== activeRun)
1858
+ return;
1859
+ }
1860
+ const workerReason = this.activeRun ? runReason : startupReason;
1861
+ this.progressController.invalidate();
1862
+ this.uid += 1;
1863
+ this.startingRunId = null;
1864
+ this.startupReject?.(startupReason);
1865
+ this.startupReject = null;
1866
+ this.rejectStdinWaiters(runReason);
1867
+ if (this.activeRun) {
1868
+ const activeRun = this.claimRun(this.activeRun.id);
1869
+ if (activeRun) {
1870
+ this.cleanupRun(activeRun);
1871
+ activeRun.reject(runReason);
1872
+ }
1873
+ }
1874
+ this.activeReject = null;
1875
+ this.clearPendingStdin();
1876
+ this.exit = true;
1877
+ this.disposeWorker(workerReason);
1878
+ }
1879
+ terminate() {
1880
+ if (this.disposed)
1881
+ return;
1882
+ const startupReason = new CancelledError(`${this.config.displayName} worker startup terminated`, {
1883
+ phase: 'startup',
1884
+ runtimeId: this.config.languageId
1885
+ });
1886
+ const runReason = new CancelledError(`${this.config.displayName} run terminated`, {
1887
+ phase: 'execute',
1888
+ runtimeId: this.config.languageId
1889
+ });
1890
+ this.terminateLifecycle(startupReason, runReason);
1891
+ }
1892
+ dispose() {
1893
+ if (this.disposePromise)
1894
+ return this.disposePromise;
1895
+ this.disposed = true;
1896
+ this.disposePromise = Promise.resolve();
1897
+ const reason = this.getDisposeReason();
1898
+ this.terminateLifecycle(reason, reason);
1899
+ this.workerLifetimeController.dispose();
1900
+ this.lifecycleProgress = undefined;
1901
+ this.output = null;
1902
+ this.oncompilerdiagnostic = undefined;
1903
+ this.baseUrl = '';
1904
+ this.workerUrl = '';
1905
+ this.manifestUrl = '';
1906
+ this.manifestFingerprint = '';
1907
+ this.preflightKey = '';
1908
+ this.resolvedRuntimeUrls = null;
1909
+ this.workerReceipt = null;
1910
+ return this.disposePromise;
1911
+ }
1912
+ async clear() {
1913
+ if (!this.disposed)
1914
+ this.terminate();
1915
+ this.lifecycleProgress = undefined;
1916
+ }
1917
+ }