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
@@ -1,29 +1,88 @@
1
- import { resolveRustCompilerUrl, resolveTinyGoHostCompileUrls, resolveTinyGoModuleUrl } from './assets';
2
- import { resolveSandboxExecutionArgs } from './options';
1
+ import { resolveRustCompilerUrl, resolveTinyGoModuleUrl } from './assets';
2
+ import { loadVerifiedTinyGoExecutableGraph } from './tinygoExecutableGraph';
3
+ import { WASM_TINYGO_EXECUTABLE_GRAPH_PROFILE, WASM_TINYGO_RUNTIME_PROFILE } from './wasmTinyGoVersion';
3
4
  import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
5
+ import { createWasmIdleSharedBuffer } from './sharedBuffer';
6
+ import { WorkerSession } from './workerSession';
7
+ import { reportWorkerProgress } from './workerProgress';
8
+ import { BusyError, CancelledError, DEFAULT_EXECUTION_LIMITS, DEFAULT_WORKSPACE_LIMITS, DiagnosticLimitError, OutputLimitError, RuntimeConfigurationError, TimeoutError, WorkspaceValidationError, resolveExecutionLimits, validateExecutionWorkspace } from '@wasm-idle/core';
4
9
  const ACTIVITY_PREFIX_PATTERN = /^\[\d{2}:\d{2}:\d{2}\]\s?/gm;
10
+ const MAX_TIMER_DELAY_MS = 2_147_483_647;
11
+ const TINYGO_BROWSER_COMPILER_DEFAULT_MAX_WASM_MEMORY_BYTES = 2 * 1024 * 1024 * 1024;
12
+ const EXECUTION_LIMIT_KEYS = Object.keys(DEFAULT_EXECUTION_LIMITS);
13
+ const OUTPUT_ENCODER = new TextEncoder();
14
+ const TINYGO_TARGETS = new Set(['wasm', 'wasip1', 'wasip2', 'wasip3']);
15
+ function snapshotTinyGoRuntimeProfile(config) {
16
+ const profileFields = [
17
+ 'profileId',
18
+ 'protocolVersion',
19
+ 'manifestPath',
20
+ 'manifestFingerprint',
21
+ 'manifestReceipt',
22
+ 'assetReceipts'
23
+ ];
24
+ const hasOverride = profileFields.some((field) => config?.[field] !== undefined);
25
+ const source = hasOverride ? config : WASM_TINYGO_RUNTIME_PROFILE;
26
+ if (!source ||
27
+ typeof source.profileId !== 'string' ||
28
+ typeof source.protocolVersion !== 'number' ||
29
+ typeof source.manifestPath !== 'string' ||
30
+ typeof source.manifestFingerprint !== 'string' ||
31
+ !source.manifestReceipt ||
32
+ !source.assetReceipts) {
33
+ throw new RuntimeConfigurationError('TinyGo runtime profile overrides must provide the complete profile and receipt set', { runtimeId: 'TINYGO' });
34
+ }
35
+ const assetReceipts = Object.fromEntries(Object.entries(source.assetReceipts).map(([assetPath, receipt]) => [
36
+ assetPath,
37
+ Object.freeze(typeof receipt === 'string' ? { sha256: receipt } : { ...receipt })
38
+ ]));
39
+ return Object.freeze({
40
+ profileId: source.profileId,
41
+ protocolVersion: source.protocolVersion,
42
+ manifestPath: source.manifestPath,
43
+ manifestFingerprint: source.manifestFingerprint,
44
+ manifestReceipt: Object.freeze({ ...source.manifestReceipt }),
45
+ assetReceipts: Object.freeze(assetReceipts)
46
+ });
47
+ }
48
+ function snapshotTinyGoExecutableGraphFingerprint(config) {
49
+ const configuredFingerprint = config?.executableGraphFingerprint;
50
+ if (configuredFingerprint !== undefined &&
51
+ configuredFingerprint !== WASM_TINYGO_EXECUTABLE_GRAPH_PROFILE.fingerprint) {
52
+ throw new RuntimeConfigurationError('TinyGo executable graph overrides must match the bundled receipt profile', { phase: 'asset', runtimeId: 'TINYGO' });
53
+ }
54
+ return WASM_TINYGO_EXECUTABLE_GRAPH_PROFILE.fingerprint;
55
+ }
56
+ const abortReason = (signal, phase) => {
57
+ const reason = signal.reason;
58
+ return reason !== undefined
59
+ ? reason
60
+ : new DOMException(phase === 'startup' ? 'TinyGo startup aborted' : 'TinyGo execution aborted', 'AbortError');
61
+ };
5
62
  class TinyGo {
6
63
  output = null;
7
64
  worker = null;
8
- buffer = new SharedArrayBuffer(1024);
65
+ buffer = createWasmIdleSharedBuffer(1024);
9
66
  pendingInput = [];
10
67
  begin = 0;
11
68
  elapse = 0;
12
69
  uid = 0;
13
70
  exit = true;
14
71
  moduleUrl = '';
15
- hostCompileUrl = '';
16
- hostCompileUrls = [];
72
+ executableGraphFingerprint = '';
17
73
  rustRuntimeBaseUrl = '';
74
+ oncompilerdiagnostic;
18
75
  assetLoader = undefined;
19
- assetPacks = undefined;
76
+ runtimeProfile = undefined;
77
+ executableGraph = null;
20
78
  runtime = null;
79
+ runtimeToken = null;
21
80
  runtimePromise = null;
81
+ runtimePromiseToken = null;
22
82
  loadPromise = null;
23
83
  compiledArtifact = null;
24
84
  compiledArtifactExecutionError = '';
25
85
  compiledCacheKey = '';
26
- activeReject = null;
27
86
  waitingForInput = false;
28
87
  pendingEof = false;
29
88
  lastActivityLog = '';
@@ -32,195 +91,817 @@ class TinyGo {
32
91
  runtimeProgressEnd = 0;
33
92
  runtimeProgressValue = 0;
34
93
  runtimeProgressAssets = new Map();
35
- load(runtimeAssets = '', _code = '', _log = true, _args = [], _options = {}, progress) {
36
- return new Promise(async (resolve, reject) => {
37
- this.pendingInput = [];
38
- this.waitingForInput = false;
39
- this.pendingEof = false;
40
- const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
41
- const nextModuleUrl = resolveTinyGoModuleUrl(runtimeAssets, currentUrl);
42
- const nextHostCompileUrls = resolveTinyGoHostCompileUrls(runtimeAssets, currentUrl);
43
- const nextRustCompilerUrl = resolveRustCompilerUrl(runtimeAssets, currentUrl);
44
- const nextRustRuntimeBaseUrl = nextRustCompilerUrl
45
- ? new URL('./runtime/', nextRustCompilerUrl).toString()
46
- : '';
47
- if (!nextModuleUrl && nextHostCompileUrls.length === 0) {
48
- return reject('TinyGo runtime is not configured. Set PUBLIC_WASM_TINYGO_MODULE_URL, PUBLIC_WASM_TINYGO_HOST_COMPILE_URL, runtimeAssets.tinygo.moduleUrl, or runtimeAssets.tinygo.hostCompileUrl.');
49
- }
50
- if ((this.moduleUrl && this.moduleUrl !== nextModuleUrl) ||
51
- this.hostCompileUrls.join('\n') !== nextHostCompileUrls.join('\n') ||
52
- this.rustRuntimeBaseUrl !== nextRustRuntimeBaseUrl) {
53
- this.disposeRuntime();
54
- this.compiledArtifact = null;
55
- this.compiledArtifactExecutionError = '';
56
- this.compiledCacheKey = '';
57
- }
58
- const nextAssetLoader = typeof runtimeAssets === 'object' ? runtimeAssets?.tinygo?.assetLoader : undefined;
59
- const nextAssetPacks = typeof runtimeAssets === 'object' ? runtimeAssets?.tinygo?.assetPacks : undefined;
60
- this.moduleUrl = nextModuleUrl;
61
- this.hostCompileUrl = nextHostCompileUrls[0] || '';
62
- this.hostCompileUrls = nextHostCompileUrls;
63
- this.rustRuntimeBaseUrl = nextRustRuntimeBaseUrl;
64
- this.assetLoader = nextAssetLoader;
65
- this.assetPacks = nextAssetPacks;
94
+ runtimeProgressOwner = null;
95
+ activeOperation = null;
96
+ disposed = false;
97
+ disposePromise = null;
98
+ disposeCancellation = new CancelledError('TinyGo sandbox disposed', {
99
+ phase: 'dispose',
100
+ runtimeId: 'TINYGO',
101
+ recoverable: false
102
+ });
103
+ workerSession = new WorkerSession({
104
+ label: 'TinyGo',
105
+ onDispose: (worker) => {
106
+ if (this.worker === worker)
107
+ delete this.worker;
108
+ this.exit = true;
109
+ this.clearPendingStdin();
110
+ }
111
+ });
112
+ disposedConfigurationError() {
113
+ return new RuntimeConfigurationError('TinyGo sandbox is disposed', {
114
+ phase: 'dispose',
115
+ runtimeId: 'TINYGO'
116
+ });
117
+ }
118
+ load(runtimeAssets = '', _code = '', _log = true, _args = [], options = {}, progress) {
119
+ return this.executeOperation('startup', options, async (operation) => {
66
120
  try {
67
- progress?.set?.(0.25);
68
- await this.ensureWorker();
69
- progress?.set?.(0.5);
70
- if (nextHostCompileUrls.length === 0 && nextModuleUrl) {
71
- await this.ensureRuntime();
121
+ this.assertOperation(operation);
122
+ this.clearPendingStdin();
123
+ const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
124
+ this.assertOperation(operation);
125
+ const nextModuleUrl = resolveTinyGoModuleUrl(runtimeAssets, currentUrl);
126
+ this.assertOperation(operation);
127
+ const nextRustCompilerUrl = resolveRustCompilerUrl(runtimeAssets, currentUrl);
128
+ this.assertOperation(operation);
129
+ const nextRustRuntimeBaseUrl = nextRustCompilerUrl
130
+ ? new URL('./runtime/', nextRustCompilerUrl).toString()
131
+ : '';
132
+ this.assertOperation(operation);
133
+ let nextAssetLoader;
134
+ let tinyGoAssets;
135
+ if (typeof runtimeAssets === 'object' && runtimeAssets !== null) {
136
+ tinyGoAssets = runtimeAssets.tinygo;
137
+ this.assertOperation(operation);
138
+ nextAssetLoader = tinyGoAssets?.assetLoader;
139
+ this.assertOperation(operation);
140
+ }
141
+ const nextRuntimeProfile = snapshotTinyGoRuntimeProfile(tinyGoAssets);
142
+ this.assertOperation(operation);
143
+ const nextExecutableGraphFingerprint = snapshotTinyGoExecutableGraphFingerprint(tinyGoAssets);
144
+ this.assertOperation(operation);
145
+ if (!nextModuleUrl) {
146
+ throw new Error('TinyGo runtime is not configured. Set PUBLIC_WASM_TINYGO_MODULE_URL or runtimeAssets.tinygo.moduleUrl.');
72
147
  }
148
+ if ((this.moduleUrl && this.moduleUrl !== nextModuleUrl) ||
149
+ this.rustRuntimeBaseUrl !== nextRustRuntimeBaseUrl ||
150
+ this.assetLoader !== nextAssetLoader ||
151
+ this.executableGraphFingerprint !== nextExecutableGraphFingerprint ||
152
+ this.runtimeProfile?.manifestFingerprint !==
153
+ nextRuntimeProfile.manifestFingerprint) {
154
+ this.disposeRuntime();
155
+ this.assertOperation(operation);
156
+ this.compiledArtifact = null;
157
+ this.compiledArtifactExecutionError = '';
158
+ this.compiledCacheKey = '';
159
+ }
160
+ this.assetLoader = nextAssetLoader;
161
+ this.runtimeProfile = nextRuntimeProfile;
162
+ this.executableGraphFingerprint = nextExecutableGraphFingerprint;
163
+ this.moduleUrl = nextModuleUrl;
164
+ this.rustRuntimeBaseUrl = nextRustRuntimeBaseUrl;
165
+ progress?.set?.(0.25);
166
+ this.assertOperation(operation);
167
+ await this.ensureRuntime(operation);
168
+ this.assertOperation(operation);
169
+ progress?.set?.(0.75);
170
+ this.assertOperation(operation);
171
+ await this.ensureWorker(operation);
172
+ this.assertOperation(operation);
73
173
  progress?.set?.(1);
74
- resolve();
174
+ this.assertOperation(operation);
175
+ }
176
+ catch (error) {
177
+ throw error instanceof Error ? error : new Error(String(error));
178
+ }
179
+ });
180
+ }
181
+ beginOperation(phase) {
182
+ if (this.disposed)
183
+ throw this.disposedConfigurationError();
184
+ if (this.activeOperation) {
185
+ throw new BusyError('TinyGo runtime already has an active operation', {
186
+ runtimeId: 'TINYGO',
187
+ phase: this.activeOperation.phase
188
+ });
189
+ }
190
+ const operation = {
191
+ token: Symbol(phase),
192
+ phase,
193
+ controller: new AbortController(),
194
+ cancelled: false,
195
+ diagnosticCount: 0,
196
+ outputBytes: 0,
197
+ hasExplicitWasmMemoryLimit: false
198
+ };
199
+ this.activeOperation = operation;
200
+ return operation;
201
+ }
202
+ completeOperation(operation) {
203
+ if (this.activeOperation?.token === operation.token) {
204
+ this.activeOperation = null;
205
+ }
206
+ }
207
+ isOperationActive(operation) {
208
+ return this.activeOperation?.token === operation.token && !operation.cancelled;
209
+ }
210
+ assertOperation(operation) {
211
+ if (!this.isOperationActive(operation)) {
212
+ throw operation.reason ?? 'Process terminated';
213
+ }
214
+ }
215
+ snapshotExecutionLimits(operation, configured) {
216
+ const snapshot = {};
217
+ if (configured) {
218
+ for (const key of EXECUTION_LIMIT_KEYS) {
219
+ this.assertOperation(operation);
220
+ const enumerable = Object.prototype.propertyIsEnumerable.call(configured, key);
221
+ this.assertOperation(operation);
222
+ if (!enumerable)
223
+ continue;
224
+ const value = configured[key];
225
+ this.assertOperation(operation);
226
+ if (value !== undefined)
227
+ snapshot[key] = value;
228
+ }
229
+ }
230
+ operation.hasExplicitWasmMemoryLimit = Object.prototype.hasOwnProperty.call(snapshot, 'maxWasmMemoryBytes');
231
+ const limits = resolveExecutionLimits(snapshot);
232
+ this.assertOperation(operation);
233
+ return limits;
234
+ }
235
+ executeOperation(phase, options, execute, snapshot) {
236
+ let operation;
237
+ try {
238
+ operation = this.beginOperation(phase);
239
+ }
240
+ catch (error) {
241
+ return Promise.reject(error);
242
+ }
243
+ return new Promise((resolve, reject) => {
244
+ let settled = false;
245
+ let signal;
246
+ let onAbort;
247
+ let deadline;
248
+ const cleanup = () => {
249
+ delete operation.reject;
250
+ this.completeOperation(operation);
251
+ if (deadline !== undefined) {
252
+ const settledDeadline = deadline;
253
+ deadline = undefined;
254
+ try {
255
+ clearTimeout(settledDeadline);
256
+ }
257
+ catch {
258
+ // Timer cleanup must not replace the operation result.
259
+ }
260
+ }
261
+ if (signal && onAbort) {
262
+ try {
263
+ signal.removeEventListener('abort', onAbort);
264
+ }
265
+ catch {
266
+ // Cleanup must not replace the operation result.
267
+ }
268
+ }
269
+ };
270
+ const resolveOperation = (value) => {
271
+ if (settled)
272
+ return;
273
+ settled = true;
274
+ cleanup();
275
+ resolve(value);
276
+ };
277
+ const rejectOperation = (reason) => {
278
+ if (settled)
279
+ return;
280
+ settled = true;
281
+ cleanup();
282
+ reject(reason);
283
+ };
284
+ operation.reject = rejectOperation;
285
+ try {
286
+ signal = options.signal;
287
+ }
288
+ catch (error) {
289
+ rejectOperation(operation.cancelled ? operation.reason : error);
290
+ return;
291
+ }
292
+ if (settled)
293
+ return;
294
+ let preAborted = false;
295
+ try {
296
+ preAborted = signal?.aborted === true;
297
+ }
298
+ catch (error) {
299
+ rejectOperation(error);
300
+ return;
301
+ }
302
+ if (settled)
303
+ return;
304
+ if (preAborted && signal) {
305
+ try {
306
+ rejectOperation(abortReason(signal, phase));
307
+ }
308
+ catch (error) {
309
+ rejectOperation(error);
310
+ }
311
+ return;
312
+ }
313
+ onAbort = signal
314
+ ? () => {
315
+ if (!this.isOperationActive(operation))
316
+ return;
317
+ let reason;
318
+ try {
319
+ reason = abortReason(signal, phase);
320
+ }
321
+ catch (error) {
322
+ reason = error;
323
+ }
324
+ if (this.isOperationActive(operation)) {
325
+ this.cancelOperation(operation, reason);
326
+ }
327
+ }
328
+ : undefined;
329
+ if (signal && onAbort) {
330
+ try {
331
+ signal.addEventListener('abort', onAbort, { once: true });
332
+ }
333
+ catch (error) {
334
+ rejectOperation(error);
335
+ return;
336
+ }
337
+ if (settled)
338
+ return;
339
+ try {
340
+ if (signal.aborted)
341
+ onAbort();
342
+ }
343
+ catch (error) {
344
+ rejectOperation(error);
345
+ return;
346
+ }
347
+ }
348
+ if (settled)
349
+ return;
350
+ let limits;
351
+ try {
352
+ const configuredLimits = options.limits;
353
+ if (settled)
354
+ return;
355
+ limits = this.snapshotExecutionLimits(operation, configuredLimits);
356
+ }
357
+ catch (error) {
358
+ rejectOperation(operation.cancelled ? operation.reason : error);
359
+ return;
360
+ }
361
+ if (settled)
362
+ return;
363
+ operation.limits = limits;
364
+ const timeoutMs = Math.min(MAX_TIMER_DELAY_MS, phase === 'startup'
365
+ ? limits.assetTimeoutMs + limits.startupTimeoutMs
366
+ : limits.compileTimeoutMs + limits.runTimeoutMs);
367
+ let scheduledDeadline;
368
+ try {
369
+ scheduledDeadline = setTimeout(() => {
370
+ if (!this.isOperationActive(operation))
371
+ return;
372
+ const label = phase === 'startup' ? 'runtime startup' : 'execution';
373
+ this.cancelOperation(operation, new TimeoutError(`TinyGo ${label} timed out after ${timeoutMs} ms`, {
374
+ phase,
375
+ runtimeId: 'TINYGO',
376
+ timeoutMs
377
+ }));
378
+ }, timeoutMs);
379
+ }
380
+ catch (error) {
381
+ rejectOperation(error);
382
+ return;
383
+ }
384
+ if (settled || !this.isOperationActive(operation)) {
385
+ try {
386
+ clearTimeout(scheduledDeadline);
387
+ }
388
+ catch {
389
+ // A synchronously settled deadline is already detached.
390
+ }
391
+ return;
392
+ }
393
+ deadline = scheduledDeadline;
394
+ let request;
395
+ try {
396
+ this.assertOperation(operation);
397
+ request = snapshot ? snapshot(operation) : undefined;
75
398
  }
76
399
  catch (error) {
77
- reject(error instanceof Error ? error.message : String(error));
400
+ rejectOperation(operation.cancelled ? operation.reason : error);
401
+ return;
78
402
  }
403
+ if (settled || !this.isOperationActive(operation))
404
+ return;
405
+ void Promise.resolve()
406
+ .then(() => {
407
+ this.assertOperation(operation);
408
+ return execute(operation, request);
409
+ })
410
+ .then((value) => {
411
+ if (this.isOperationActive(operation))
412
+ resolveOperation(value);
413
+ }, (error) => {
414
+ if (this.isOperationActive(operation))
415
+ rejectOperation(error);
416
+ });
79
417
  });
80
418
  }
419
+ emitOutput(operation, data) {
420
+ this.assertOperation(operation);
421
+ const limit = operation.limits?.maxOutputBytes ?? DEFAULT_EXECUTION_LIMITS.maxOutputBytes;
422
+ const actual = operation.outputBytes + OUTPUT_ENCODER.encode(data).byteLength;
423
+ this.assertOperation(operation);
424
+ if (actual > limit) {
425
+ operation.outputBytes = actual;
426
+ this.cancelOperation(operation, new OutputLimitError(`TinyGo output exceeded ${limit} bytes`, {
427
+ actual,
428
+ limit,
429
+ phase: 'execute',
430
+ runtimeId: 'TINYGO'
431
+ }));
432
+ return false;
433
+ }
434
+ operation.outputBytes = actual;
435
+ try {
436
+ const output = this.output;
437
+ this.assertOperation(operation);
438
+ if (output)
439
+ Reflect.apply(output, this, [data]);
440
+ }
441
+ catch (error) {
442
+ if (this.isOperationActive(operation))
443
+ this.cancelOperation(operation, error);
444
+ return false;
445
+ }
446
+ return this.isOperationActive(operation);
447
+ }
448
+ emitCompilerDiagnostic(operation, diagnostic) {
449
+ this.assertOperation(operation);
450
+ try {
451
+ if (!diagnostic || typeof diagnostic !== 'object') {
452
+ throw new RuntimeConfigurationError('TinyGo runtime emitted an invalid compiler diagnostic', { phase: operation.phase, runtimeId: 'TINYGO' });
453
+ }
454
+ const message = diagnostic.message;
455
+ this.assertOperation(operation);
456
+ const rawSeverity = diagnostic.severity;
457
+ this.assertOperation(operation);
458
+ const rawFileName = diagnostic.fileName;
459
+ this.assertOperation(operation);
460
+ const rawLineNumber = diagnostic.lineNumber;
461
+ this.assertOperation(operation);
462
+ const rawColumnNumber = diagnostic.columnNumber;
463
+ this.assertOperation(operation);
464
+ const rawEndColumnNumber = diagnostic.endColumnNumber;
465
+ this.assertOperation(operation);
466
+ if (typeof message !== 'string' || message.length === 0) {
467
+ throw new RuntimeConfigurationError('TinyGo runtime emitted a compiler diagnostic without a message', { phase: operation.phase, runtimeId: 'TINYGO' });
468
+ }
469
+ const actual = operation.diagnosticCount + 1;
470
+ const limit = operation.limits?.maxDiagnostics ?? DEFAULT_EXECUTION_LIMITS.maxDiagnostics;
471
+ if (actual > limit) {
472
+ operation.diagnosticCount = actual;
473
+ this.cancelOperation(operation, new DiagnosticLimitError(`TinyGo diagnostics exceeded ${limit} messages`, {
474
+ actual,
475
+ limit,
476
+ phase: operation.phase,
477
+ runtimeId: 'TINYGO'
478
+ }));
479
+ this.assertOperation(operation);
480
+ }
481
+ operation.diagnosticCount = actual;
482
+ const compilerDiagnostic = {
483
+ message,
484
+ severity: rawSeverity === 'error' || rawSeverity === 'warning' ? rawSeverity : 'other',
485
+ lineNumber: Number.isSafeInteger(rawLineNumber) && Number(rawLineNumber) >= 0
486
+ ? Number(rawLineNumber)
487
+ : 1
488
+ };
489
+ if (rawFileName === null || typeof rawFileName === 'string') {
490
+ compilerDiagnostic.fileName = rawFileName;
491
+ }
492
+ if (Number.isSafeInteger(rawColumnNumber) && Number(rawColumnNumber) >= 0) {
493
+ compilerDiagnostic.columnNumber = Number(rawColumnNumber);
494
+ }
495
+ if (Number.isSafeInteger(rawEndColumnNumber) && Number(rawEndColumnNumber) >= 0) {
496
+ compilerDiagnostic.endColumnNumber = Number(rawEndColumnNumber);
497
+ }
498
+ const callback = this.oncompilerdiagnostic;
499
+ this.assertOperation(operation);
500
+ if (callback)
501
+ Reflect.apply(callback, this, [compilerDiagnostic]);
502
+ this.assertOperation(operation);
503
+ }
504
+ catch (error) {
505
+ if (this.isOperationActive(operation))
506
+ this.cancelOperation(operation, error);
507
+ this.assertOperation(operation);
508
+ }
509
+ }
510
+ clearPendingStdin() {
511
+ this.pendingInput = [];
512
+ this.pendingEof = false;
513
+ this.waitingForInput = false;
514
+ }
81
515
  write(input) {
516
+ if (this.disposed)
517
+ return;
82
518
  this.pendingInput.push(input);
83
519
  this.pendingEof = false;
84
520
  this.flushPendingInput();
85
521
  }
86
522
  eof() {
523
+ if (this.disposed)
524
+ return;
87
525
  this.pendingEof = true;
88
526
  this.flushPendingInput();
89
527
  }
90
528
  flushPendingInput() {
91
529
  if (!this.waitingForInput)
92
530
  return;
93
- if (flushQueuedStdin(this.pendingInput, this.buffer)) {
531
+ const buffer = this.activeOperation?.buffer ?? this.buffer;
532
+ if (flushQueuedStdin(this.pendingInput, buffer)) {
94
533
  this.waitingForInput = false;
95
534
  return;
96
535
  }
97
536
  if (this.pendingEof) {
98
- flushBufferedEof(this.buffer);
537
+ flushBufferedEof(buffer);
99
538
  this.pendingEof = false;
100
539
  this.waitingForInput = false;
101
540
  }
102
541
  }
103
- async ensureWorker() {
542
+ async ensureWorker(operation) {
543
+ this.assertOperation(operation);
104
544
  if (this.worker)
105
545
  return;
106
- if (this.loadPromise) {
107
- await this.loadPromise;
546
+ const pendingLoad = this.loadPromise;
547
+ if (pendingLoad) {
548
+ await pendingLoad;
549
+ this.assertOperation(operation);
108
550
  return;
109
551
  }
110
- this.loadPromise = new Promise(async (resolve, reject) => {
111
- this.worker = new (await import('./worker/tinygo?worker')).default();
112
- this.worker.onerror = (event) => {
113
- const location = event.filename && event.lineno
114
- ? ` (${event.filename}:${event.lineno}:${event.colno})`
115
- : '';
116
- reject(`TinyGo worker script error: ${event.message || 'unknown error'}${location}`);
117
- };
118
- this.worker.onmessageerror = () => {
119
- reject('TinyGo worker message deserialization failed');
120
- };
121
- this.worker.onmessage = (event) => {
122
- if (event.data?.load)
123
- resolve();
124
- if (event.data?.error)
125
- reject(event.data.error);
126
- };
127
- this.worker.postMessage({ load: true });
128
- }).finally(() => {
129
- this.loadPromise = null;
130
- });
131
- await this.loadPromise;
552
+ const loadPromise = (async () => {
553
+ const WorkerConstructor = (await import('./worker/tinygo?worker'))
554
+ .default;
555
+ this.assertOperation(operation);
556
+ const worker = new WorkerConstructor();
557
+ if (!this.isOperationActive(operation)) {
558
+ worker.terminate();
559
+ this.assertOperation(operation);
560
+ }
561
+ this.worker = worker;
562
+ const workerLoad = this.workerSession.waitForLoad(worker, (resolve, reject) => {
563
+ if (!this.isOperationActive(operation) || this.worker !== worker) {
564
+ return reject(operation.reason ?? 'Worker not loaded');
565
+ }
566
+ worker.onmessage = (event) => {
567
+ if (!this.isOperationActive(operation) || this.worker !== worker)
568
+ return;
569
+ const message = event.data ?? {};
570
+ if (message.load) {
571
+ resolve();
572
+ return;
573
+ }
574
+ if (Object.prototype.hasOwnProperty.call(message, 'error')) {
575
+ reject(message.error);
576
+ }
577
+ };
578
+ worker.postMessage({ load: true });
579
+ });
580
+ if (!this.isOperationActive(operation) || this.worker !== worker) {
581
+ this.workerSession.terminate(operation.reason ?? 'Worker not loaded');
582
+ }
583
+ await workerLoad;
584
+ this.assertOperation(operation);
585
+ if (this.worker !== worker)
586
+ throw operation.reason ?? 'Worker not loaded';
587
+ })();
588
+ this.loadPromise = loadPromise;
589
+ try {
590
+ await loadPromise;
591
+ }
592
+ finally {
593
+ if (this.loadPromise === loadPromise)
594
+ this.loadPromise = null;
595
+ }
132
596
  }
133
- disposeRuntime() {
134
- this.runtime?.dispose?.();
597
+ detachRuntime() {
598
+ const runtime = this.runtime;
599
+ const executableGraph = this.executableGraph;
135
600
  this.runtime = null;
601
+ this.executableGraph = null;
602
+ this.runtimeToken = null;
136
603
  this.runtimePromise = null;
604
+ this.runtimePromiseToken = null;
137
605
  this.lastActivityLog = '';
138
606
  this.compiledArtifactExecutionError = '';
607
+ this.runtimeProgress = undefined;
608
+ this.runtimeProgressOwner = null;
609
+ this.runtimeProgressAssets.clear();
610
+ try {
611
+ executableGraph?.dispose();
612
+ }
613
+ catch {
614
+ // Executable graph cleanup must not replace the lifecycle result.
615
+ }
616
+ return runtime;
617
+ }
618
+ disposeRuntimeHooks(runtime) {
619
+ try {
620
+ runtime?.dispose?.();
621
+ }
622
+ catch {
623
+ // Runtime cleanup must not replace the lifecycle result.
624
+ }
625
+ }
626
+ disposeRuntime() {
627
+ this.disposeRuntimeHooks(this.detachRuntime());
139
628
  }
140
- async ensureRuntime() {
629
+ reportRuntimeProgress(runtimeToken, progress) {
630
+ const owner = this.runtimeProgressOwner;
631
+ if (!owner ||
632
+ owner.runtimeToken !== runtimeToken ||
633
+ this.activeOperation?.token !== owner.operationToken ||
634
+ !this.runtimeProgress) {
635
+ return;
636
+ }
637
+ const total = progress.total && progress.total > 0 ? progress.total : progress.loaded;
638
+ const key = progress.assetUrl || progress.assetPath;
639
+ this.runtimeProgressAssets.set(key, {
640
+ loaded: Math.max(0, progress.loaded),
641
+ total: Math.max(1, total)
642
+ });
643
+ let loaded = 0;
644
+ let size = 0;
645
+ for (const entry of this.runtimeProgressAssets.values()) {
646
+ loaded += Math.min(entry.loaded, entry.total);
647
+ size += entry.total;
648
+ }
649
+ if (size <= 0)
650
+ return;
651
+ const nextValue = this.runtimeProgressStart +
652
+ ((this.runtimeProgressEnd - this.runtimeProgressStart) * loaded) / size;
653
+ if (nextValue <= this.runtimeProgressValue)
654
+ return;
655
+ this.runtimeProgressValue = nextValue;
656
+ this.runtimeProgress.set?.(nextValue);
657
+ }
658
+ requireRuntimeAssetLimitSetter(runtime) {
659
+ const setMaxAssetBytes = runtime.setMaxAssetBytes;
660
+ if (typeof setMaxAssetBytes !== 'function') {
661
+ throw new RuntimeConfigurationError('TinyGo runtime module must implement setMaxAssetBytes()', { runtimeId: 'TINYGO' });
662
+ }
663
+ return (maxAssetBytes) => setMaxAssetBytes.call(runtime, maxAssetBytes);
664
+ }
665
+ async ensureRuntime(operation) {
666
+ this.assertOperation(operation);
141
667
  if (this.runtime) {
142
668
  return this.runtime;
143
669
  }
144
- if (this.runtimePromise) {
145
- return await this.runtimePromise;
670
+ const pendingRuntime = this.runtimePromise;
671
+ if (pendingRuntime) {
672
+ const runtime = await pendingRuntime;
673
+ this.assertOperation(operation);
674
+ return runtime;
146
675
  }
147
676
  const moduleUrl = this.moduleUrl;
148
- this.runtimePromise = (async () => {
149
- const runtimeModule = (await import(
150
- /* @vite-ignore */ moduleUrl));
151
- if (typeof runtimeModule.createBundledTinyGoRuntime === 'function') {
152
- this.runtime = runtimeModule.createBundledTinyGoRuntime({
153
- assetLoader: this.assetLoader,
154
- assetPacks: this.assetPacks,
155
- rustRuntimeBaseUrl: this.rustRuntimeBaseUrl || undefined,
156
- onProgress: (progress) => {
157
- if (!this.runtimeProgress)
158
- return;
159
- const total = progress.total && progress.total > 0 ? progress.total : progress.loaded;
160
- const key = progress.assetUrl || progress.assetPath;
161
- this.runtimeProgressAssets.set(key, {
162
- loaded: Math.max(0, progress.loaded),
163
- total: Math.max(1, total)
164
- });
165
- let loaded = 0;
166
- let size = 0;
167
- for (const entry of this.runtimeProgressAssets.values()) {
168
- loaded += Math.min(entry.loaded, entry.total);
169
- size += entry.total;
170
- }
171
- if (size <= 0)
172
- return;
173
- const nextValue = this.runtimeProgressStart +
174
- ((this.runtimeProgressEnd - this.runtimeProgressStart) * loaded) / size;
175
- if (nextValue <= this.runtimeProgressValue)
176
- return;
177
- this.runtimeProgressValue = nextValue;
178
- this.runtimeProgress.set?.(nextValue);
179
- }
677
+ const runtimeToken = Symbol('runtime');
678
+ const runtimePromiseToken = Symbol('runtime-startup');
679
+ this.runtimePromiseToken = runtimePromiseToken;
680
+ const assetLoader = this.assetLoader;
681
+ const runtimeProfile = this.runtimeProfile;
682
+ const rustRuntimeBaseUrl = this.rustRuntimeBaseUrl;
683
+ const maxAssetBytes = operation.limits?.maxAssetBytes ?? DEFAULT_EXECUTION_LIMITS.maxAssetBytes;
684
+ const assetTimeoutMs = operation.limits?.assetTimeoutMs ?? DEFAULT_EXECUTION_LIMITS.assetTimeoutMs;
685
+ let nextRuntime = null;
686
+ let nextExecutableGraph = null;
687
+ const runtimePromise = (async () => {
688
+ try {
689
+ if (!runtimeProfile) {
690
+ throw new RuntimeConfigurationError('TinyGo runtime profile is not configured', {
691
+ runtimeId: 'TINYGO'
692
+ });
693
+ }
694
+ nextExecutableGraph = await loadVerifiedTinyGoExecutableGraph({
695
+ moduleUrl,
696
+ profile: WASM_TINYGO_EXECUTABLE_GRAPH_PROFILE,
697
+ signal: operation.controller.signal,
698
+ maxAssetBytes,
699
+ assetTimeoutMs
180
700
  });
181
- return this.runtime;
182
- }
183
- if (typeof runtimeModule.createTinyGoRuntime === 'function') {
184
- this.runtime = runtimeModule.createTinyGoRuntime({
185
- assetBaseUrl: new URL('./', moduleUrl).toString(),
186
- assetLoader: this.assetLoader,
187
- assetPacks: this.assetPacks,
188
- rustRuntimeBaseUrl: this.rustRuntimeBaseUrl || undefined,
189
- onProgress: (progress) => {
190
- if (!this.runtimeProgress)
701
+ this.assertOperation(operation);
702
+ const executableGraph = nextExecutableGraph;
703
+ const runtimeModule = (await import(
704
+ /* @vite-ignore */ executableGraph.entryUrl));
705
+ this.assertOperation(operation);
706
+ const commonOptions = {
707
+ assetLoader,
708
+ maxAssetBytes,
709
+ rustRuntimeBaseUrl: rustRuntimeBaseUrl || undefined,
710
+ onCompilerDiagnostic: (diagnostic) => {
711
+ const owner = this.runtimeProgressOwner;
712
+ const activeOperation = this.activeOperation;
713
+ const runtime = this.runtime;
714
+ if (!owner ||
715
+ !activeOperation ||
716
+ owner.operationToken !== activeOperation.token ||
717
+ owner.runtimeToken !== runtimeToken ||
718
+ this.runtimeToken !== runtimeToken ||
719
+ !runtime ||
720
+ !this.isOperationActive(activeOperation)) {
191
721
  return;
192
- const total = progress.total && progress.total > 0 ? progress.total : progress.loaded;
193
- const key = progress.assetUrl || progress.assetPath;
194
- this.runtimeProgressAssets.set(key, {
195
- loaded: Math.max(0, progress.loaded),
196
- total: Math.max(1, total)
197
- });
198
- let loaded = 0;
199
- let size = 0;
200
- for (const entry of this.runtimeProgressAssets.values()) {
201
- loaded += Math.min(entry.loaded, entry.total);
202
- size += entry.total;
203
722
  }
204
- if (size <= 0)
205
- return;
206
- const nextValue = this.runtimeProgressStart +
207
- ((this.runtimeProgressEnd - this.runtimeProgressStart) * loaded) / size;
208
- if (nextValue <= this.runtimeProgressValue)
723
+ this.emitCompilerDiagnostic(activeOperation, diagnostic);
724
+ },
725
+ onLogAppended: (_entry) => {
726
+ const owner = this.runtimeProgressOwner;
727
+ const activeOperation = this.activeOperation;
728
+ const runtime = this.runtime;
729
+ if (!owner ||
730
+ !activeOperation ||
731
+ owner.operationToken !== activeOperation.token ||
732
+ owner.runtimeToken !== runtimeToken ||
733
+ this.runtimeToken !== runtimeToken ||
734
+ !runtime ||
735
+ !this.isOperationActive(activeOperation)) {
209
736
  return;
210
- this.runtimeProgressValue = nextValue;
211
- this.runtimeProgress.set?.(nextValue);
212
- }
213
- });
214
- return this.runtime;
737
+ }
738
+ this.emitActivityLog(runtime, activeOperation);
739
+ },
740
+ onProgress: (progress) => this.reportRuntimeProgress(runtimeToken, progress)
741
+ };
742
+ if (typeof runtimeModule.loadTinyGoUpstreamToolchainAssets === 'function' &&
743
+ typeof runtimeModule.compileTinyGoInDisposableWorker === 'function') {
744
+ let activityLog = '';
745
+ let artifact = null;
746
+ let workspaceFiles = null;
747
+ let target = 'wasip1';
748
+ let assetLimit = maxAssetBytes;
749
+ let wasmMemoryLimit = DEFAULT_EXECUTION_LIMITS.maxWasmMemoryBytes;
750
+ let controller = null;
751
+ let assetsPromise = null;
752
+ const loadUpstreamAssets = runtimeModule.loadTinyGoUpstreamToolchainAssets;
753
+ const compileUpstream = runtimeModule.compileTinyGoInDisposableWorker;
754
+ const appendLog = (line) => {
755
+ activityLog += `[${new Date().toTimeString().slice(0, 8)}] ${line}\n`;
756
+ commonOptions.onLogAppended({ line });
757
+ };
758
+ nextRuntime = {
759
+ async boot() {
760
+ if (!assetsPromise) {
761
+ controller = new AbortController();
762
+ assetsPromise = loadUpstreamAssets({
763
+ assetBaseUrl: executableGraph.assetBaseUrl,
764
+ profile: runtimeProfile,
765
+ ...(assetLoader ? { loader: assetLoader } : {}),
766
+ onProgress: commonOptions.onProgress,
767
+ signal: controller.signal,
768
+ maxAssetBytes: assetLimit
769
+ });
770
+ }
771
+ const pendingAssets = assetsPromise;
772
+ try {
773
+ await pendingAssets;
774
+ }
775
+ catch (error) {
776
+ if (assetsPromise === pendingAssets)
777
+ assetsPromise = null;
778
+ throw error;
779
+ }
780
+ appendLog('upstream TinyGo toolchain assets loaded');
781
+ },
782
+ async plan() {
783
+ if (!assetsPromise)
784
+ throw new Error('upstream TinyGo assets are not loaded');
785
+ appendLog('upstream TinyGo receipt validation scheduled in compiler worker');
786
+ return { target: 'wasip1', implementation: 'upstream-tinygo-0.40.1' };
787
+ },
788
+ async execute() {
789
+ if (target !== 'wasip1') {
790
+ throw new Error('The upstream TinyGo browser compiler supports only wasip1');
791
+ }
792
+ if (!workspaceFiles)
793
+ throw new Error('TinyGo workspace is not configured');
794
+ const assets = await assetsPromise;
795
+ if (!assets)
796
+ throw new Error('upstream TinyGo assets are not loaded');
797
+ controller = new AbortController();
798
+ const compileFiles = { ...workspaceFiles };
799
+ if (!Object.prototype.hasOwnProperty.call(compileFiles, 'go.mod')) {
800
+ compileFiles['go.mod'] =
801
+ 'module wasm-idle.local/main\n\ngo 1.24.0\n';
802
+ }
803
+ const result = await compileUpstream(assets, { workspaceFiles: compileFiles, package: '.' }, {
804
+ signal: controller.signal,
805
+ maxWasmMemoryBytes: wasmMemoryLimit,
806
+ onPhase: (phase) => appendLog(`upstream TinyGo phase: ${phase}`)
807
+ });
808
+ artifact = {
809
+ path: '/work/program.wasm',
810
+ bytes: Uint8Array.from(result.wasm),
811
+ artifactKind: 'execution',
812
+ runnable: true,
813
+ entrypoint: '_start'
814
+ };
815
+ appendLog(`upstream TinyGo artifact ready: ${artifact.path}`);
816
+ },
817
+ reset() {
818
+ controller?.abort(new Error('TinyGo runtime reset'));
819
+ controller = null;
820
+ artifact = null;
821
+ activityLog = '';
822
+ },
823
+ readActivityLog: () => activityLog,
824
+ readBuildArtifact: () => artifact,
825
+ setBuildRequestOverrides(overrides) {
826
+ target = overrides?.target ?? 'wasip1';
827
+ },
828
+ setMaxAssetBytes(value) {
829
+ if (assetLimit !== value) {
830
+ controller?.abort(new Error('TinyGo asset quota changed'));
831
+ controller = null;
832
+ assetsPromise = null;
833
+ }
834
+ assetLimit = value;
835
+ },
836
+ setMaxWasmMemoryBytes(value) {
837
+ wasmMemoryLimit = value;
838
+ },
839
+ setWorkspaceFiles(files) {
840
+ workspaceFiles = files ? { ...files } : null;
841
+ },
842
+ dispose() {
843
+ controller?.abort(new Error('TinyGo runtime disposed'));
844
+ controller = null;
845
+ workspaceFiles = null;
846
+ artifact = null;
847
+ }
848
+ };
849
+ }
850
+ else if (typeof runtimeModule.createBundledTinyGoRuntime === 'function') {
851
+ nextRuntime = runtimeModule.createBundledTinyGoRuntime(commonOptions);
852
+ }
853
+ else if (typeof runtimeModule.createTinyGoRuntime === 'function') {
854
+ nextRuntime = runtimeModule.createTinyGoRuntime({
855
+ assetBaseUrl: executableGraph.assetBaseUrl,
856
+ ...commonOptions
857
+ });
858
+ }
859
+ else {
860
+ throw new Error('TinyGo runtime module must export createBundledTinyGoRuntime or createTinyGoRuntime');
861
+ }
862
+ this.assertOperation(operation);
863
+ this.requireRuntimeAssetLimitSetter(nextRuntime);
864
+ this.assertOperation(operation);
865
+ if (this.runtimePromiseToken !== runtimePromiseToken) {
866
+ throw operation.reason ?? 'TinyGo runtime startup superseded';
867
+ }
868
+ const runtime = nextRuntime;
869
+ const committedExecutableGraph = nextExecutableGraph;
870
+ nextRuntime = null;
871
+ nextExecutableGraph = null;
872
+ this.runtime = runtime;
873
+ this.executableGraph = committedExecutableGraph;
874
+ this.runtimeToken = runtimeToken;
875
+ return runtime;
215
876
  }
216
- throw new Error('TinyGo runtime module must export createBundledTinyGoRuntime or createTinyGoRuntime');
217
- })().catch((error) => {
218
- this.disposeRuntime();
219
- throw error;
220
- });
221
- return await this.runtimePromise;
877
+ finally {
878
+ try {
879
+ nextRuntime?.dispose?.();
880
+ }
881
+ catch {
882
+ // A stale runtime must not replace the active lifecycle result.
883
+ }
884
+ try {
885
+ nextExecutableGraph?.dispose();
886
+ }
887
+ catch {
888
+ // A stale executable graph must not replace the active lifecycle result.
889
+ }
890
+ }
891
+ })();
892
+ this.runtimePromise = runtimePromise;
893
+ try {
894
+ return await runtimePromise;
895
+ }
896
+ finally {
897
+ if (this.runtimePromise === runtimePromise) {
898
+ this.runtimePromise = null;
899
+ this.runtimePromiseToken = null;
900
+ }
901
+ }
222
902
  }
223
- emitActivityLog(hooks) {
903
+ emitActivityLog(hooks, operation) {
904
+ this.assertOperation(operation);
224
905
  const nextActivityLog = hooks.readActivityLog();
225
906
  const delta = nextActivityLog.startsWith(this.lastActivityLog)
226
907
  ? nextActivityLog.slice(this.lastActivityLog.length)
@@ -229,8 +910,10 @@ class TinyGo {
229
910
  if (!delta)
230
911
  return;
231
912
  const sanitized = delta.replace(ACTIVITY_PREFIX_PATTERN, '');
232
- if (sanitized)
233
- this.output?.(sanitized);
913
+ if (sanitized && !this.emitOutput(operation, sanitized)) {
914
+ this.assertOperation(operation);
915
+ }
916
+ this.assertOperation(operation);
234
917
  }
235
918
  extractCompileFailure() {
236
919
  const sanitized = this.lastActivityLog.replace(ACTIVITY_PREFIX_PATTERN, '');
@@ -245,143 +928,96 @@ class TinyGo {
245
928
  }
246
929
  return 'TinyGo compilation failed';
247
930
  }
248
- async compileArtifact(code, target = 'wasm', log = true, prog) {
249
- const hostCompileTarget = target === 'wasm' ? 'wasip1' : target;
931
+ async compileArtifact(operation, workspaceFiles, target = 'wasm', log = true, prog) {
932
+ this.assertOperation(operation);
933
+ const maxWasmMemoryBytes = operation.hasExplicitWasmMemoryLimit
934
+ ? (operation.limits?.maxWasmMemoryBytes ?? DEFAULT_EXECUTION_LIMITS.maxWasmMemoryBytes)
935
+ : TINYGO_BROWSER_COMPILER_DEFAULT_MAX_WASM_MEMORY_BYTES;
250
936
  const compileCacheKey = JSON.stringify({
251
- code,
252
- hostCompileUrls: this.hostCompileUrls,
253
937
  moduleUrl: this.moduleUrl,
254
- target
938
+ executableGraphFingerprint: this.executableGraphFingerprint,
939
+ maxAssetBytes: operation.limits?.maxAssetBytes ?? DEFAULT_EXECUTION_LIMITS.maxAssetBytes,
940
+ maxWasmMemoryBytes,
941
+ target,
942
+ workspaceFiles
255
943
  });
256
944
  if (this.compiledArtifact && this.compiledCacheKey === compileCacheKey) {
257
945
  return;
258
946
  }
259
- const unavailableHostCompileUrls = [];
260
- if (this.hostCompileUrls.length > 0) {
261
- prog?.set?.(0.05);
262
- for (const hostCompileUrl of this.hostCompileUrls) {
263
- let hostCompileResponse = null;
264
- try {
265
- hostCompileResponse = await fetch(hostCompileUrl, {
266
- method: 'POST',
267
- headers: {
268
- 'content-type': 'application/json'
269
- },
270
- body: JSON.stringify({
271
- source: code,
272
- target: hostCompileTarget
273
- })
274
- });
275
- }
276
- catch (error) {
277
- unavailableHostCompileUrls.push(hostCompileUrl);
278
- if (!this.moduleUrl && hostCompileUrl === this.hostCompileUrls.at(-1)) {
279
- throw error;
280
- }
281
- continue;
282
- }
283
- if (hostCompileResponse?.ok) {
284
- const payload = (await hostCompileResponse.json());
285
- const artifactBase64 = payload.artifact?.bytesBase64 || '';
286
- if (!payload.artifact?.path || !artifactBase64) {
287
- throw new Error('TinyGo host compile did not return a wasm artifact');
288
- }
289
- const artifactBytes = Uint8Array.from(atob(artifactBase64), (char) => char.charCodeAt(0));
290
- this.compiledArtifact = artifactBytes;
291
- this.compiledArtifactExecutionError =
292
- payload.artifact.runnable === false
293
- ? payload.artifact.artifactKind === 'probe'
294
- ? 'TinyGo host compile returned a non-runnable probe artifact without a supported WASI entrypoint.'
295
- : payload.artifact.reason === 'bootstrap-artifact'
296
- ? 'TinyGo host compile returned a bootstrap artifact and cannot execute it yet.'
297
- : 'TinyGo host compile returned a non-runnable artifact without a supported WASI entrypoint.'
298
- : '';
299
- this.compiledCacheKey = compileCacheKey;
300
- prog?.set?.(0.95);
301
- if (log) {
302
- for (const line of payload.logs || []) {
303
- this.output?.(line.endsWith('\n') ? line : `${line}\n`);
304
- }
305
- this.output?.(`tinygo artifact ready: ${payload.artifact.path}\n`);
306
- }
307
- return;
308
- }
309
- if (hostCompileResponse &&
310
- hostCompileResponse.status !== 404 &&
311
- hostCompileResponse.status !== 405 &&
312
- hostCompileResponse.status !== 501) {
313
- let failureMessage = 'TinyGo host compile failed';
314
- try {
315
- const payload = await hostCompileResponse.json();
316
- if (typeof payload?.error === 'string' && payload.error) {
317
- failureMessage = payload.error;
318
- }
319
- }
320
- catch {
321
- const responseText = await hostCompileResponse.text();
322
- if (responseText.trim()) {
323
- failureMessage = responseText.trim();
324
- }
325
- }
326
- throw new Error(failureMessage);
327
- }
328
- if (hostCompileResponse) {
329
- unavailableHostCompileUrls.push(hostCompileUrl);
330
- }
331
- }
947
+ const runtime = await this.ensureRuntime(operation);
948
+ this.assertOperation(operation);
949
+ const runtimeToken = this.runtimeToken;
950
+ if (!runtimeToken || this.runtime !== runtime) {
951
+ throw operation.reason ?? 'TinyGo compiler runtime is not available';
332
952
  }
333
- if (!this.moduleUrl) {
334
- if (unavailableHostCompileUrls.length > 0) {
335
- throw new Error(`TinyGo host compile endpoints were unavailable: ${unavailableHostCompileUrls.join(', ')}.`);
336
- }
337
- throw new Error('TinyGo host compile endpoint is unavailable.');
338
- }
339
- const runtime = await this.ensureRuntime();
953
+ this.requireRuntimeAssetLimitSetter(runtime)(operation.limits?.maxAssetBytes ?? DEFAULT_EXECUTION_LIMITS.maxAssetBytes);
954
+ runtime.setMaxWasmMemoryBytes?.(maxWasmMemoryBytes);
955
+ this.assertOperation(operation);
340
956
  runtime.reset();
957
+ this.assertOperation(operation);
341
958
  this.lastActivityLog = runtime.readActivityLog();
342
- runtime.setWorkspaceFiles({ 'main.go': code });
959
+ this.assertOperation(operation);
960
+ runtime.setWorkspaceFiles(workspaceFiles);
961
+ this.assertOperation(operation);
343
962
  runtime.setBuildRequestOverrides?.({ target });
963
+ this.assertOperation(operation);
344
964
  this.runtimeProgress = prog;
965
+ this.runtimeProgressOwner = {
966
+ operationToken: operation.token,
967
+ runtimeToken
968
+ };
345
969
  this.runtimeProgressAssets.clear();
346
970
  this.runtimeProgressStart = 0.05;
347
971
  this.runtimeProgressEnd = 0.35;
348
972
  this.runtimeProgressValue = 0.05;
349
973
  try {
350
974
  prog?.set?.(0.05);
975
+ this.assertOperation(operation);
351
976
  await runtime.boot();
352
- this.emitActivityLog(runtime);
977
+ this.assertOperation(operation);
978
+ this.emitActivityLog(runtime, operation);
353
979
  this.runtimeProgressAssets.clear();
354
980
  this.runtimeProgressStart = 0.35;
355
981
  this.runtimeProgressEnd = 0.65;
356
982
  this.runtimeProgressValue = Math.max(this.runtimeProgressValue, 0.35);
357
983
  prog?.set?.(this.runtimeProgressValue);
984
+ this.assertOperation(operation);
358
985
  await runtime.plan();
359
- this.emitActivityLog(runtime);
986
+ this.assertOperation(operation);
987
+ this.emitActivityLog(runtime, operation);
360
988
  this.runtimeProgressAssets.clear();
361
989
  this.runtimeProgressStart = 0.65;
362
990
  this.runtimeProgressEnd = 0.92;
363
991
  this.runtimeProgressValue = Math.max(this.runtimeProgressValue, 0.65);
364
992
  prog?.set?.(this.runtimeProgressValue);
993
+ this.assertOperation(operation);
365
994
  await runtime.execute();
366
- this.emitActivityLog(runtime);
995
+ this.assertOperation(operation);
996
+ this.emitActivityLog(runtime, operation);
367
997
  prog?.set?.(0.95);
998
+ this.assertOperation(operation);
368
999
  }
369
1000
  finally {
370
- this.runtimeProgress = undefined;
371
- this.runtimeProgressAssets.clear();
1001
+ if (this.runtimeProgressOwner?.operationToken === operation.token &&
1002
+ this.runtimeProgressOwner.runtimeToken === runtimeToken) {
1003
+ this.runtimeProgress = undefined;
1004
+ this.runtimeProgressOwner = null;
1005
+ this.runtimeProgressAssets.clear();
1006
+ }
372
1007
  }
1008
+ this.assertOperation(operation);
373
1009
  const artifact = runtime.readBuildArtifact();
1010
+ this.assertOperation(operation);
374
1011
  if (!artifact) {
375
1012
  const compileFailure = this.extractCompileFailure();
376
- if (/(?:probe-only|supported WASI entrypoint|no host compile seam is configured)/i.test(compileFailure)) {
377
- throw new Error(unavailableHostCompileUrls.length > 0
378
- ? `TinyGo host compile endpoints were unavailable: ${unavailableHostCompileUrls.join(', ')}. TinyGo browser runtime could not produce a runnable execution artifact: ${compileFailure}.`
379
- : `TinyGo browser runtime could not produce a runnable execution artifact: ${compileFailure}.`);
1013
+ if (/(?:probe-only|supported WASI entrypoint)/i.test(compileFailure)) {
1014
+ throw new Error(`TinyGo browser runtime could not produce a runnable execution artifact: ${compileFailure}.`);
380
1015
  }
381
1016
  throw new Error(compileFailure);
382
1017
  }
383
- const runtimeLogLines = runtime
384
- .readActivityLog()
1018
+ const runtimeActivityLog = runtime.readActivityLog();
1019
+ this.assertOperation(operation);
1020
+ const runtimeLogLines = runtimeActivityLog
385
1021
  .replace(ACTIVITY_PREFIX_PATTERN, '')
386
1022
  .split('\n')
387
1023
  .map((line) => line.trim())
@@ -394,122 +1030,359 @@ class TinyGo {
394
1030
  break;
395
1031
  }
396
1032
  }
397
- this.compiledArtifact = new Uint8Array(artifact.bytes);
398
- this.compiledArtifactExecutionError =
399
- artifact.runnable === false
400
- ? browserRuntimeFailure !== ''
401
- ? unavailableHostCompileUrls.length > 0
402
- ? `TinyGo host compile endpoints were unavailable: ${unavailableHostCompileUrls.join(', ')}. TinyGo browser runtime could not produce a runnable execution artifact: ${browserRuntimeFailure}.`
403
- : `TinyGo browser runtime could not produce a runnable execution artifact: ${browserRuntimeFailure}.`
404
- : artifact.reason === 'bootstrap-artifact'
405
- ? unavailableHostCompileUrls.length > 0
406
- ? `TinyGo host compile endpoints were unavailable: ${unavailableHostCompileUrls.join(', ')}. TinyGo browser runtime produced a bootstrap artifact and cannot execute it yet.`
407
- : 'TinyGo browser runtime produced a bootstrap artifact and cannot execute it yet.'
408
- : artifact.artifactKind === 'probe'
409
- ? unavailableHostCompileUrls.length > 0
410
- ? `TinyGo host compile endpoints were unavailable: ${unavailableHostCompileUrls.join(', ')}. TinyGo browser runtime produced a non-runnable probe artifact without a supported WASI entrypoint.`
411
- : 'TinyGo browser runtime produced a non-runnable probe artifact without a supported WASI entrypoint.'
412
- : unavailableHostCompileUrls.length > 0
413
- ? `TinyGo host compile endpoints were unavailable: ${unavailableHostCompileUrls.join(', ')}. TinyGo browser runtime produced a non-runnable artifact without a supported WASI entrypoint.`
414
- : 'TinyGo browser runtime produced a non-runnable artifact without a supported WASI entrypoint.'
415
- : '';
1033
+ const compiledArtifact = new Uint8Array(artifact.bytes);
1034
+ const compiledArtifactExecutionError = artifact.runnable === false
1035
+ ? browserRuntimeFailure !== ''
1036
+ ? `TinyGo browser runtime could not produce a runnable execution artifact: ${browserRuntimeFailure}.`
1037
+ : artifact.reason === 'bootstrap-artifact'
1038
+ ? 'TinyGo browser runtime produced a bootstrap artifact and cannot execute it yet.'
1039
+ : artifact.artifactKind === 'probe'
1040
+ ? 'TinyGo browser runtime produced a non-runnable probe artifact without a supported WASI entrypoint.'
1041
+ : 'TinyGo browser runtime produced a non-runnable artifact without a supported WASI entrypoint.'
1042
+ : '';
1043
+ this.assertOperation(operation);
1044
+ this.compiledArtifact = compiledArtifact;
1045
+ this.compiledArtifactExecutionError = compiledArtifactExecutionError;
416
1046
  this.compiledCacheKey = compileCacheKey;
417
1047
  if (log) {
418
- this.output?.(`tinygo artifact ready: ${artifact.path}\n`);
1048
+ this.emitOutput(operation, `tinygo artifact ready: ${artifact.path}\n`);
1049
+ this.assertOperation(operation);
419
1050
  }
420
1051
  }
421
1052
  run(code, prepare, _log = true, _prog, args = [], options = {}) {
422
- this.exit = false;
423
- return new Promise(async (resolve, reject) => {
1053
+ return this.executeOperation('execute', options, async (operation, request) => {
1054
+ this.exit = false;
424
1055
  try {
425
1056
  this.begin = Date.now();
426
- await this.ensureWorker();
427
- const target = options.tinygoTarget || 'wasm';
428
- await this.compileArtifact(code, target, _log, prepare ? _prog : undefined);
1057
+ await this.compileArtifact(operation, request.workspaceFiles, request.target, _log, prepare ? _prog : undefined);
1058
+ this.assertOperation(operation);
429
1059
  if (prepare) {
430
1060
  this.elapse = Date.now() - this.begin;
431
1061
  this.exit = true;
432
- resolve(true);
433
- return;
1062
+ return true;
434
1063
  }
435
1064
  if (this.compiledArtifactExecutionError) {
436
1065
  throw new Error(this.compiledArtifactExecutionError);
437
1066
  }
1067
+ await this.ensureWorker(operation);
1068
+ this.assertOperation(operation);
438
1069
  if (!this.worker || !this.compiledArtifact) {
439
1070
  throw new Error('TinyGo runtime did not prepare an artifact');
440
1071
  }
441
- const { programArgs } = resolveSandboxExecutionArgs('TINYGO', args, options);
442
- const _uid = ++this.uid;
443
- this.activeReject = reject;
444
- this.worker.onmessage = (event) => {
445
- if (!this.worker)
446
- return reject('Worker not loaded');
447
- if (_uid !== this.uid)
448
- return (this.worker.onmessage = null);
449
- const { output, results, error, buffer } = event.data;
450
- if (buffer) {
451
- this.waitingForInput = true;
452
- this.flushPendingInput();
453
- }
454
- if (output)
455
- this.output?.(output);
456
- if (results) {
457
- this.elapse = Date.now() - this.begin;
458
- this.exit = true;
459
- this.waitingForInput = false;
460
- this.pendingEof = false;
461
- this.activeReject = null;
462
- resolve(results);
1072
+ const worker = this.worker;
1073
+ const compiledArtifact = this.compiledArtifact;
1074
+ const buffer = request.buffer;
1075
+ const hasExplicitStdin = request.stdin !== undefined;
1076
+ if (hasExplicitStdin) {
1077
+ this.clearPendingStdin();
1078
+ }
1079
+ const runUid = ++this.uid;
1080
+ return await new Promise((resolve, reject) => {
1081
+ const workerOperation = this.workerSession.beginRun(worker, reject);
1082
+ const handleMessage = (event) => {
1083
+ if (!this.isOperationActive(operation) ||
1084
+ this.worker !== worker ||
1085
+ runUid !== this.uid) {
1086
+ if (worker.onmessage === handleMessage)
1087
+ worker.onmessage = null;
1088
+ return;
1089
+ }
1090
+ const message = event.data ?? {};
1091
+ const hasResults = Object.prototype.hasOwnProperty.call(message, 'results');
1092
+ const hasError = Object.prototype.hasOwnProperty.call(message, 'error');
1093
+ const { output, results, error, buffer, progress } = message;
1094
+ if (buffer && !hasExplicitStdin) {
1095
+ if (!prepare) {
1096
+ _prog?.report?.({
1097
+ kind: 'ready',
1098
+ state: 'waiting-input',
1099
+ reason: 'stdin-request',
1100
+ label: 'TinyGo program is waiting for input'
1101
+ });
1102
+ }
1103
+ this.waitingForInput = true;
1104
+ this.flushPendingInput();
1105
+ }
1106
+ reportWorkerProgress(_prog, progress);
1107
+ if (!this.isOperationActive(operation) || this.worker !== worker)
1108
+ return;
1109
+ if (output) {
1110
+ if (!this.emitOutput(operation, output))
1111
+ return;
1112
+ }
1113
+ if (hasResults) {
1114
+ if (worker.onmessage === handleMessage)
1115
+ worker.onmessage = null;
1116
+ this.elapse = Date.now() - this.begin;
1117
+ this.exit = true;
1118
+ this.clearPendingStdin();
1119
+ this.workerSession.complete(workerOperation);
1120
+ resolve(results);
1121
+ return;
1122
+ }
1123
+ if (hasError) {
1124
+ if (worker.onmessage === handleMessage)
1125
+ worker.onmessage = null;
1126
+ this.elapse = Date.now() - this.begin;
1127
+ this.exit = true;
1128
+ this.clearPendingStdin();
1129
+ this.workerSession.complete(workerOperation);
1130
+ reject(error);
1131
+ }
1132
+ };
1133
+ worker.onmessage = handleMessage;
1134
+ try {
1135
+ worker.postMessage({
1136
+ artifact: new Uint8Array(compiledArtifact),
1137
+ buffer,
1138
+ args: request.programArgs,
1139
+ log: _log,
1140
+ stdin: request.stdin
1141
+ });
463
1142
  }
464
- if (error) {
465
- this.elapse = Date.now() - this.begin;
466
- this.exit = true;
467
- this.waitingForInput = false;
468
- this.pendingEof = false;
469
- this.activeReject = null;
470
- reject(error);
1143
+ catch (error) {
1144
+ this.workerSession.terminate(error);
471
1145
  }
472
- };
473
- this.worker.postMessage({
474
- artifact: new Uint8Array(this.compiledArtifact),
475
- buffer: this.buffer,
476
- args: programArgs,
477
- log: _log
478
1146
  });
479
1147
  }
480
1148
  catch (error) {
481
- this.elapse = Date.now() - this.begin;
482
- this.exit = true;
483
- this.waitingForInput = false;
484
- this.pendingEof = false;
485
- this.activeReject = null;
486
- reject(error instanceof Error ? error.message : String(error));
1149
+ if (this.isOperationActive(operation)) {
1150
+ this.elapse = Date.now() - this.begin;
1151
+ this.exit = true;
1152
+ this.clearPendingStdin();
1153
+ throw error instanceof Error ? error.message : String(error);
1154
+ }
1155
+ throw error;
1156
+ }
1157
+ }, (operation) => {
1158
+ this.assertOperation(operation);
1159
+ if (typeof code !== 'string') {
1160
+ throw new TypeError('TinyGo source code must be a string');
1161
+ }
1162
+ const configuredTarget = options.tinygoTarget;
1163
+ this.assertOperation(operation);
1164
+ const target = configuredTarget ?? 'wasip1';
1165
+ if (!TINYGO_TARGETS.has(target)) {
1166
+ throw new TypeError('TinyGo target must be wasm, wasip1, wasip2, or wasip3');
1167
+ }
1168
+ const workspaceLimitsSource = options.workspaceLimits;
1169
+ this.assertOperation(operation);
1170
+ let workspaceLimits = {};
1171
+ if (workspaceLimitsSource !== undefined) {
1172
+ if (workspaceLimitsSource === null ||
1173
+ typeof workspaceLimitsSource !== 'object' ||
1174
+ Array.isArray(workspaceLimitsSource)) {
1175
+ throw new TypeError('TinyGo workspace limits must be an object');
1176
+ }
1177
+ const maxFiles = workspaceLimitsSource.maxFiles;
1178
+ this.assertOperation(operation);
1179
+ const maxFileBytes = workspaceLimitsSource.maxFileBytes;
1180
+ this.assertOperation(operation);
1181
+ const maxTotalBytes = workspaceLimitsSource.maxTotalBytes;
1182
+ this.assertOperation(operation);
1183
+ const maxPathBytes = workspaceLimitsSource.maxPathBytes;
1184
+ this.assertOperation(operation);
1185
+ const caseSensitive = workspaceLimitsSource.caseSensitive;
1186
+ this.assertOperation(operation);
1187
+ workspaceLimits = {
1188
+ maxFiles,
1189
+ maxFileBytes,
1190
+ maxTotalBytes,
1191
+ maxPathBytes,
1192
+ caseSensitive
1193
+ };
1194
+ }
1195
+ for (const name of [
1196
+ 'maxFiles',
1197
+ 'maxFileBytes',
1198
+ 'maxTotalBytes',
1199
+ 'maxPathBytes'
1200
+ ]) {
1201
+ const value = workspaceLimits[name];
1202
+ if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {
1203
+ throw new WorkspaceValidationError('invalid-limit', `Workspace limit ${name} must be a non-negative safe integer`);
1204
+ }
1205
+ }
1206
+ if (workspaceLimits.caseSensitive !== undefined &&
1207
+ typeof workspaceLimits.caseSensitive !== 'boolean') {
1208
+ throw new WorkspaceValidationError('invalid-limit', 'Workspace limit caseSensitive must be a boolean');
1209
+ }
1210
+ const workspaceFilesSource = options.workspaceFiles;
1211
+ this.assertOperation(operation);
1212
+ const sourceFiles = workspaceFilesSource ?? [];
1213
+ if (!Array.isArray(sourceFiles)) {
1214
+ throw new TypeError('TinyGo workspace files must be an array');
1215
+ }
1216
+ const workspaceFileCount = sourceFiles.length;
1217
+ this.assertOperation(operation);
1218
+ const maxFiles = workspaceLimits.maxFiles ?? DEFAULT_WORKSPACE_LIMITS.maxFiles;
1219
+ if (workspaceFileCount > maxFiles) {
1220
+ throw new WorkspaceValidationError('file-count-limit', `Workspace contains ${workspaceFileCount} files; limit is ${maxFiles}`, { limit: maxFiles, actual: workspaceFileCount });
1221
+ }
1222
+ const workspaceFiles = [];
1223
+ for (let index = 0; index < workspaceFileCount; index += 1) {
1224
+ const file = sourceFiles[index];
1225
+ this.assertOperation(operation);
1226
+ if (file === null || typeof file !== 'object') {
1227
+ throw new TypeError('TinyGo workspace file must be an object');
1228
+ }
1229
+ const path = file.path;
1230
+ this.assertOperation(operation);
1231
+ const content = file.content;
1232
+ this.assertOperation(operation);
1233
+ if (typeof path !== 'string') {
1234
+ throw new TypeError('TinyGo workspace file path must be a string');
1235
+ }
1236
+ if (typeof content !== 'string') {
1237
+ throw new TypeError(`TinyGo workspace file ${path} must contain a string`);
1238
+ }
1239
+ workspaceFiles.push({ path, content });
1240
+ }
1241
+ const configuredActivePath = options.activePath;
1242
+ this.assertOperation(operation);
1243
+ const activePath = configuredActivePath ?? 'main.go';
1244
+ const maxWorkspaceBytes = operation.limits?.maxWorkspaceBytes ??
1245
+ DEFAULT_EXECUTION_LIMITS.maxWorkspaceBytes;
1246
+ const workspace = validateExecutionWorkspace(code, workspaceFiles, activePath, {
1247
+ ...workspaceLimits,
1248
+ maxFileBytes: Math.min(workspaceLimits.maxFileBytes ?? DEFAULT_WORKSPACE_LIMITS.maxFileBytes, maxWorkspaceBytes),
1249
+ maxTotalBytes: Math.min(workspaceLimits.maxTotalBytes ?? DEFAULT_WORKSPACE_LIMITS.maxTotalBytes, maxWorkspaceBytes)
1250
+ });
1251
+ this.assertOperation(operation);
1252
+ if (workspace.activePath !== 'main.go') {
1253
+ throw new RuntimeConfigurationError('TinyGo runtime currently requires activePath to be main.go', { phase: 'execute', runtimeId: 'TINYGO' });
487
1254
  }
1255
+ const runtimeWorkspace = Object.fromEntries([
1256
+ ['main.go', code],
1257
+ ...workspace.workspaceFiles.map((file) => [file.path, file.content])
1258
+ ]);
1259
+ const configuredProgramArgs = options.programArgs;
1260
+ this.assertOperation(operation);
1261
+ const sourceArgs = configuredProgramArgs ?? args;
1262
+ if (!Array.isArray(sourceArgs)) {
1263
+ throw new TypeError('TinyGo program arguments must be an array');
1264
+ }
1265
+ const argCount = sourceArgs.length;
1266
+ this.assertOperation(operation);
1267
+ const programArgs = [];
1268
+ for (let index = 0; index < argCount; index += 1) {
1269
+ const argument = sourceArgs[index];
1270
+ this.assertOperation(operation);
1271
+ if (typeof argument !== 'string') {
1272
+ throw new TypeError(`TinyGo program argument ${index} must be a string`);
1273
+ }
1274
+ programArgs.push(argument);
1275
+ }
1276
+ const stdin = options.stdin;
1277
+ this.assertOperation(operation);
1278
+ if (stdin !== undefined && typeof stdin !== 'string') {
1279
+ throw new TypeError('TinyGo stdin must be a string');
1280
+ }
1281
+ const buffer = this.buffer;
1282
+ this.assertOperation(operation);
1283
+ operation.buffer = buffer;
1284
+ return { buffer, programArgs, stdin, target, workspaceFiles: runtimeWorkspace };
488
1285
  });
489
1286
  }
1287
+ resetOwnedBuffers(operationBuffer) {
1288
+ const buffers = new Set([this.buffer]);
1289
+ if (operationBuffer)
1290
+ buffers.add(operationBuffer);
1291
+ for (const buffer of buffers) {
1292
+ try {
1293
+ resetBufferedStdin(buffer);
1294
+ }
1295
+ catch {
1296
+ // Stdin cleanup must not replace the lifecycle result.
1297
+ }
1298
+ }
1299
+ }
1300
+ cancelOperation(operation, reason) {
1301
+ if (!this.isOperationActive(operation))
1302
+ return;
1303
+ operation.cancelled = true;
1304
+ operation.reason = reason;
1305
+ try {
1306
+ operation.controller.abort(reason);
1307
+ }
1308
+ catch {
1309
+ // Cancellation must continue even if AbortController cleanup fails.
1310
+ }
1311
+ const reject = operation.reject;
1312
+ this.completeOperation(operation);
1313
+ this.uid += 1;
1314
+ this.clearPendingStdin();
1315
+ this.exit = true;
1316
+ this.loadPromise = null;
1317
+ this.runtimeProgress = undefined;
1318
+ this.runtimeProgressOwner = null;
1319
+ this.runtimeProgressAssets.clear();
1320
+ this.compiledArtifact = null;
1321
+ this.compiledArtifactExecutionError = '';
1322
+ this.compiledCacheKey = '';
1323
+ this.resetOwnedBuffers(operation.buffer);
1324
+ this.workerSession.terminate(reason);
1325
+ this.disposeRuntime();
1326
+ reject?.(reason);
1327
+ }
490
1328
  kill() {
491
1329
  this.terminate();
492
1330
  }
493
- terminate() {
494
- this.activeReject?.('Process terminated');
495
- this.activeReject = null;
496
- this.waitingForInput = false;
497
- this.pendingEof = false;
1331
+ terminate(reason = 'Process terminated') {
1332
+ if (this.disposed)
1333
+ return;
1334
+ const operation = this.activeOperation;
1335
+ if (operation) {
1336
+ this.cancelOperation(operation, reason);
1337
+ return;
1338
+ }
1339
+ this.clearPendingStdin();
498
1340
  this.uid += 1;
499
- this.worker?.terminate?.();
500
- delete this.worker;
1341
+ this.resetOwnedBuffers();
1342
+ this.workerSession.terminate(reason);
501
1343
  this.exit = true;
502
1344
  }
503
1345
  async clear() {
504
- this.pendingInput = [];
505
- this.waitingForInput = false;
506
- this.pendingEof = false;
507
- if (this.worker)
508
- this.worker.onmessage = null;
509
- resetBufferedStdin(this.buffer);
510
- if (!this.exit) {
511
- this.terminate();
1346
+ if (this.disposed)
1347
+ return;
1348
+ this.terminate();
1349
+ this.loadPromise = null;
1350
+ this.disposeRuntime();
1351
+ this.compiledArtifact = null;
1352
+ this.compiledArtifactExecutionError = '';
1353
+ this.compiledCacheKey = '';
1354
+ }
1355
+ dispose() {
1356
+ if (this.disposePromise)
1357
+ return this.disposePromise;
1358
+ this.disposed = true;
1359
+ this.disposePromise = Promise.resolve();
1360
+ const operation = this.activeOperation;
1361
+ const runtime = this.detachRuntime();
1362
+ delete this.worker;
1363
+ this.moduleUrl = '';
1364
+ this.executableGraphFingerprint = '';
1365
+ this.rustRuntimeBaseUrl = '';
1366
+ this.assetLoader = undefined;
1367
+ this.runtimeProfile = undefined;
1368
+ this.output = undefined;
1369
+ this.oncompilerdiagnostic = undefined;
1370
+ this.loadPromise = null;
1371
+ this.compiledArtifact = null;
1372
+ this.compiledArtifactExecutionError = '';
1373
+ this.compiledCacheKey = '';
1374
+ this.clearPendingStdin();
1375
+ this.resetOwnedBuffers(operation?.buffer);
1376
+ if (operation) {
1377
+ this.cancelOperation(operation, this.disposeCancellation);
1378
+ }
1379
+ else {
1380
+ this.uid += 1;
1381
+ this.workerSession.terminate(this.disposeCancellation);
1382
+ this.exit = true;
512
1383
  }
1384
+ this.disposeRuntimeHooks(runtime);
1385
+ return this.disposePromise;
513
1386
  }
514
1387
  }
515
1388
  export default TinyGo;