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,10 +1,50 @@
1
1
  import { resolveOcamlManifestUrl, resolveOcamlModuleUrl } from './assets';
2
2
  import {} from './options';
3
3
  import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
4
+ import { createWasmIdleSharedBuffer } from './sharedBuffer';
5
+ import { WorkerSession } from './workerSession';
6
+ import { reportWorkerInputReady, reportWorkerProgress } from './workerProgress';
7
+ import { WASM_OCAML_RUNTIME_PROFILE } from './wasmOcamlVersion';
8
+ import { BusyError, CancelledError, DEFAULT_WORKSPACE_LIMITS, DiagnosticLimitError, OutputLimitError, ProtocolError, RuntimeConfigurationError, TimeoutError, WorkspaceValidationError, resolveExecutionLimits, validateExecutionWorkspace } from '@wasm-idle/core';
9
+ const OCAML_EXECUTION_LIMIT_KEYS = [
10
+ 'assetTimeoutMs',
11
+ 'startupTimeoutMs',
12
+ 'compileTimeoutMs',
13
+ 'runTimeoutMs',
14
+ 'maxOutputBytes',
15
+ 'maxDiagnostics',
16
+ 'maxWorkspaceBytes',
17
+ 'maxAssetBytes',
18
+ 'maxWasmMemoryBytes',
19
+ 'maxWorkers',
20
+ 'maxThreads'
21
+ ];
22
+ const OCAML_WORKSPACE_LIMIT_KEYS = [
23
+ 'maxFiles',
24
+ 'maxFileBytes',
25
+ 'maxTotalBytes',
26
+ 'maxPathBytes',
27
+ 'caseSensitive'
28
+ ];
29
+ const OUTPUT_ENCODER = new TextEncoder();
30
+ function snapshotOuterAssetReceipt(value, label) {
31
+ if (!value ||
32
+ !Number.isSafeInteger(value.bytes) ||
33
+ value.bytes <= 0 ||
34
+ typeof value.sha256 !== 'string' ||
35
+ !/^[a-f0-9]{64}$/u.test(value.sha256)) {
36
+ throw new RuntimeConfigurationError(`OCaml ${label} receipt is invalid`, {
37
+ phase: 'startup',
38
+ runtimeId: 'OCAML'
39
+ });
40
+ }
41
+ return Object.freeze({ bytes: value.bytes, sha256: value.sha256 });
42
+ }
43
+ const receiptIdentity = (receipt) => `${receipt.bytes}:${receipt.sha256}`;
4
44
  class Ocaml {
5
45
  output = null;
6
46
  worker = null;
7
- buffer = new SharedArrayBuffer(1024);
47
+ buffer = createWasmIdleSharedBuffer(1024);
8
48
  pendingInput = [];
9
49
  begin = 0;
10
50
  elapse = 0;
@@ -12,332 +52,854 @@ class Ocaml {
12
52
  exit = true;
13
53
  moduleUrl = '';
14
54
  manifestUrl = '';
15
- activeReject = null;
55
+ moduleReceiptIdentity = '';
56
+ manifestReceiptIdentity = '';
57
+ maxAssetBytes = 0;
16
58
  oncompilerdiagnostic;
17
59
  waitingForInput = false;
18
60
  pendingEof = false;
19
- load(runtimeAssets = '', _code = '', _log = true, _args = [], _options = {}, progress) {
20
- return new Promise(async (resolve, reject) => {
21
- this.pendingInput = [];
61
+ activeOperation = null;
62
+ disposed = false;
63
+ disposePromise = null;
64
+ disposeCancellation = new CancelledError('OCaml sandbox disposed', {
65
+ phase: 'dispose',
66
+ runtimeId: 'OCAML',
67
+ recoverable: false
68
+ });
69
+ workerSession = new WorkerSession({
70
+ label: 'OCaml',
71
+ onDispose: (worker) => {
72
+ if (this.worker === worker)
73
+ delete this.worker;
74
+ this.exit = true;
22
75
  this.waitingForInput = false;
23
76
  this.pendingEof = false;
24
- resetBufferedStdin(this.buffer);
77
+ }
78
+ });
79
+ disposedConfigurationError() {
80
+ return new RuntimeConfigurationError('OCaml sandbox is disposed', {
81
+ phase: 'dispose',
82
+ runtimeId: 'OCAML'
83
+ });
84
+ }
85
+ beginOperation(phase) {
86
+ if (this.disposed)
87
+ throw this.disposedConfigurationError();
88
+ if (this.activeOperation) {
89
+ throw new BusyError('OCaml runtime already has an active operation', {
90
+ runtimeId: 'OCAML',
91
+ phase: this.activeOperation.phase
92
+ });
93
+ }
94
+ const operation = {
95
+ token: Symbol(phase),
96
+ phase,
97
+ cancelled: false,
98
+ explicitStdin: false,
99
+ sessionActive: false,
100
+ abortReasonReading: false
101
+ };
102
+ this.activeOperation = operation;
103
+ return operation;
104
+ }
105
+ completeOperation(operation) {
106
+ if (this.activeOperation?.token === operation.token)
107
+ this.activeOperation = null;
108
+ const timeout = operation.timeout;
109
+ operation.timeout = undefined;
110
+ if (timeout !== undefined) {
111
+ try {
112
+ clearTimeout(timeout);
113
+ }
114
+ catch {
115
+ // Timer cleanup must not replace the operation result.
116
+ }
117
+ }
118
+ const { signal, onAbort } = operation;
119
+ operation.signal = undefined;
120
+ operation.onAbort = undefined;
121
+ if (signal && onAbort) {
122
+ try {
123
+ signal.removeEventListener('abort', onAbort);
124
+ }
125
+ catch {
126
+ // Listener cleanup must not replace the operation result.
127
+ }
128
+ }
129
+ }
130
+ isOperationActive(operation) {
131
+ return this.activeOperation?.token === operation.token && !operation.cancelled;
132
+ }
133
+ ownsWorkerOperation(operation, worker, handler, uid) {
134
+ return (this.isOperationActive(operation) &&
135
+ this.worker === worker &&
136
+ worker.onmessage === handler &&
137
+ (uid === undefined || uid === this.uid));
138
+ }
139
+ releaseBeforeSession(operation, fallback) {
140
+ const outcome = operation.cancelled ? operation.cancellationReason : fallback;
141
+ this.completeOperation(operation);
142
+ return outcome;
143
+ }
144
+ resolveOperationLimits(operation, configured) {
145
+ if (configured === undefined)
146
+ return resolveExecutionLimits();
147
+ if (configured === null || typeof configured !== 'object') {
148
+ throw new TypeError('OCaml execution limits must be an object');
149
+ }
150
+ const snapshot = {};
151
+ for (const key of OCAML_EXECUTION_LIMIT_KEYS) {
152
+ const value = configured[key];
153
+ if (!this.isOperationActive(operation)) {
154
+ throw operation.cancellationReason ?? 'OCaml operation cancelled';
155
+ }
156
+ if (value !== undefined)
157
+ snapshot[key] = value;
158
+ }
159
+ return resolveExecutionLimits(snapshot);
160
+ }
161
+ resetExplicitStdinState(buffer) {
162
+ this.pendingInput = [];
163
+ this.pendingEof = false;
164
+ this.waitingForInput = false;
165
+ try {
166
+ resetBufferedStdin(buffer);
167
+ }
168
+ catch {
169
+ // Explicit stdin never consumes the shared terminal buffer.
170
+ }
171
+ }
172
+ finishExplicitStdin(operation) {
173
+ if (!operation.explicitStdin)
174
+ return;
175
+ operation.explicitStdin = false;
176
+ const buffer = operation.buffer;
177
+ if (buffer)
178
+ this.resetExplicitStdinState(buffer);
179
+ }
180
+ abortReason(signal, phase) {
181
+ const reason = signal.reason;
182
+ if (reason !== undefined)
183
+ return reason;
184
+ return new DOMException(phase === 'startup' ? 'OCaml runtime startup aborted' : 'OCaml execution aborted', 'AbortError');
185
+ }
186
+ bindAbortSignal(operation, signal) {
187
+ if (!signal || !this.isOperationActive(operation))
188
+ return;
189
+ const onAbort = () => {
190
+ if (this.disposed || !this.isOperationActive(operation) || operation.abortReasonReading)
191
+ return;
192
+ operation.abortReasonReading = true;
193
+ let reason;
194
+ try {
195
+ reason = this.abortReason(signal, operation.phase);
196
+ }
197
+ catch (error) {
198
+ reason = error;
199
+ }
200
+ finally {
201
+ operation.abortReasonReading = false;
202
+ }
203
+ if (!this.isOperationActive(operation))
204
+ return;
205
+ if (operation.sessionActive)
206
+ this.abortOperation(operation, reason);
207
+ else
208
+ this.cancelBeforeSession(operation, reason);
209
+ };
210
+ operation.signal = signal;
211
+ operation.onAbort = onAbort;
212
+ try {
213
+ signal.addEventListener('abort', onAbort, { once: true });
214
+ }
215
+ catch (error) {
216
+ if (!this.isOperationActive(operation))
217
+ return;
218
+ let signalAborted = false;
219
+ try {
220
+ signalAborted = signal.aborted;
221
+ }
222
+ catch {
223
+ if (!this.isOperationActive(operation))
224
+ return;
225
+ }
226
+ if (signalAborted)
227
+ onAbort();
228
+ else
229
+ this.cancelBeforeSession(operation, error);
230
+ return;
231
+ }
232
+ if (!this.isOperationActive(operation))
233
+ return;
234
+ try {
235
+ if (signal.aborted)
236
+ onAbort();
237
+ }
238
+ catch (error) {
239
+ if (this.isOperationActive(operation))
240
+ this.cancelBeforeSession(operation, error);
241
+ }
242
+ }
243
+ bindOperationTimeout(operation, timeoutMs) {
244
+ if (!this.isOperationActive(operation))
245
+ return;
246
+ let timeout;
247
+ try {
248
+ timeout = setTimeout(() => {
249
+ if (operation.timeout === timeout)
250
+ operation.timeout = undefined;
251
+ if (!this.isOperationActive(operation))
252
+ return;
253
+ const label = operation.phase === 'startup' ? 'startup' : 'execution';
254
+ this.abortOperation(operation, new TimeoutError(`OCaml ${label} timed out after ${timeoutMs} ms`, {
255
+ phase: operation.phase,
256
+ runtimeId: 'OCAML',
257
+ timeoutMs
258
+ }));
259
+ }, timeoutMs);
260
+ }
261
+ catch (error) {
262
+ this.abortOperation(operation, error);
263
+ return;
264
+ }
265
+ if (!this.isOperationActive(operation)) {
266
+ try {
267
+ clearTimeout(timeout);
268
+ }
269
+ catch {
270
+ // The superseded timer can no longer own the operation.
271
+ }
272
+ return;
273
+ }
274
+ operation.timeout = timeout;
275
+ }
276
+ cancelBeforeSession(operation, reason) {
277
+ if (!this.isOperationActive(operation))
278
+ return;
279
+ operation.cancelled = true;
280
+ operation.cancellationReason = reason;
281
+ this.completeOperation(operation);
282
+ }
283
+ abortOperation(operation, reason) {
284
+ if (!this.isOperationActive(operation))
285
+ return;
286
+ operation.cancelled = true;
287
+ operation.cancellationReason = reason;
288
+ this.finishExplicitStdin(operation);
289
+ this.waitingForInput = false;
290
+ this.pendingEof = false;
291
+ this.uid += 1;
292
+ this.workerSession.terminate(reason);
293
+ this.exit = true;
294
+ this.completeOperation(operation);
295
+ }
296
+ load(runtimeAssets = '', _code = '', _log = true, _args = [], options = {}, progress) {
297
+ let operation;
298
+ try {
299
+ operation = this.beginOperation('startup');
300
+ }
301
+ catch (error) {
302
+ return Promise.reject(error);
303
+ }
304
+ let signal;
305
+ let limits;
306
+ let nextModuleUrl;
307
+ let nextManifestUrl;
308
+ let nextModuleReceipt;
309
+ let nextManifestReceipt;
310
+ let buffer;
311
+ try {
312
+ signal = options.signal;
313
+ if (!this.isOperationActive(operation)) {
314
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
315
+ }
316
+ this.bindAbortSignal(operation, signal);
317
+ if (!this.isOperationActive(operation)) {
318
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
319
+ }
320
+ const configuredLimits = options.limits;
321
+ if (!this.isOperationActive(operation)) {
322
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
323
+ }
324
+ limits = this.resolveOperationLimits(operation, configuredLimits);
325
+ if (!this.isOperationActive(operation)) {
326
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
327
+ }
25
328
  const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
26
- const nextModuleUrl = resolveOcamlModuleUrl(runtimeAssets, currentUrl);
27
- const nextManifestUrl = resolveOcamlManifestUrl(runtimeAssets, currentUrl);
329
+ if (!this.isOperationActive(operation)) {
330
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
331
+ }
332
+ let resolverAssets = runtimeAssets;
333
+ let configuredModuleReceipt;
334
+ let configuredManifestReceipt;
335
+ if (runtimeAssets === null) {
336
+ resolverAssets = {};
337
+ }
338
+ else if (typeof runtimeAssets === 'object') {
339
+ const source = runtimeAssets.ocaml;
340
+ if (!this.isOperationActive(operation)) {
341
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
342
+ }
343
+ const moduleUrl = source?.moduleUrl;
344
+ if (!this.isOperationActive(operation)) {
345
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
346
+ }
347
+ const manifestUrl = source?.manifestUrl;
348
+ if (!this.isOperationActive(operation)) {
349
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
350
+ }
351
+ configuredModuleReceipt = source?.moduleReceipt;
352
+ if (!this.isOperationActive(operation)) {
353
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
354
+ }
355
+ configuredManifestReceipt = source?.manifestReceipt;
356
+ if (!this.isOperationActive(operation)) {
357
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
358
+ }
359
+ let rootUrl;
360
+ let rootUrlRead = false;
361
+ resolverAssets = { ocaml: source ? { moduleUrl, manifestUrl } : undefined };
362
+ Object.defineProperty(resolverAssets, 'rootUrl', {
363
+ get: () => {
364
+ if (!rootUrlRead) {
365
+ rootUrlRead = true;
366
+ rootUrl = runtimeAssets.rootUrl;
367
+ }
368
+ if (!this.isOperationActive(operation)) {
369
+ throw operation.cancellationReason;
370
+ }
371
+ return rootUrl;
372
+ }
373
+ });
374
+ }
375
+ nextModuleUrl = resolveOcamlModuleUrl(resolverAssets, currentUrl);
376
+ if (!this.isOperationActive(operation)) {
377
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
378
+ }
379
+ nextManifestUrl = resolveOcamlManifestUrl(resolverAssets, currentUrl);
380
+ if (!this.isOperationActive(operation)) {
381
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
382
+ }
28
383
  if (!nextModuleUrl || !nextManifestUrl) {
29
- return reject('OCaml runtime is not configured. Set runtimeAssets.ocaml.moduleUrl and runtimeAssets.ocaml.manifestUrl or sync the bundled wasm-of-js-of-ocaml assets.');
384
+ throw 'OCaml runtime is not configured. Set runtimeAssets.ocaml.moduleUrl and runtimeAssets.ocaml.manifestUrl or sync the bundled wasm-of-js-of-ocaml assets.';
385
+ }
386
+ const hasConfiguredReceipt = configuredModuleReceipt !== undefined || configuredManifestReceipt !== undefined;
387
+ if (hasConfiguredReceipt &&
388
+ (configuredModuleReceipt === undefined || configuredManifestReceipt === undefined)) {
389
+ throw new RuntimeConfigurationError('OCaml custom runtime assets require both module and manifest receipts', { phase: 'startup', runtimeId: 'OCAML' });
30
390
  }
391
+ nextModuleReceipt = snapshotOuterAssetReceipt(configuredModuleReceipt ?? WASM_OCAML_RUNTIME_PROFILE.moduleReceipt, 'module');
392
+ nextManifestReceipt = snapshotOuterAssetReceipt(configuredManifestReceipt ?? WASM_OCAML_RUNTIME_PROFILE.manifestReceipt, 'manifest');
393
+ if (nextModuleReceipt.bytes > limits.maxAssetBytes ||
394
+ nextManifestReceipt.bytes > limits.maxAssetBytes) {
395
+ throw new RuntimeConfigurationError(`OCaml outer runtime asset exceeds the ${limits.maxAssetBytes} byte limit`, { phase: 'startup', runtimeId: 'OCAML' });
396
+ }
397
+ buffer = this.buffer;
398
+ if (!this.isOperationActive(operation)) {
399
+ return Promise.reject(this.releaseBeforeSession(operation, 'OCaml runtime startup cancelled'));
400
+ }
401
+ }
402
+ catch (error) {
403
+ return Promise.reject(this.releaseBeforeSession(operation, error));
404
+ }
405
+ operation.sessionActive = true;
406
+ const loading = this.workerSession.load(async (resolve, reject) => {
407
+ if (!this.isOperationActive(operation))
408
+ return;
409
+ this.pendingInput = [];
410
+ this.waitingForInput = false;
411
+ this.pendingEof = false;
412
+ resetBufferedStdin(buffer);
413
+ if (!this.isOperationActive(operation))
414
+ return;
31
415
  const needsWorkerReset = !this.worker ||
32
416
  this.moduleUrl !== nextModuleUrl ||
33
- this.manifestUrl !== nextManifestUrl;
34
- this.moduleUrl = nextModuleUrl;
35
- this.manifestUrl = nextManifestUrl;
36
- if (needsWorkerReset && this.worker) {
37
- this.worker.terminate();
38
- delete this.worker;
39
- }
40
- if (!this.worker) {
41
- this.worker = new (await import('./worker/ocaml?worker')).default();
42
- this.worker.onerror = (event) => {
43
- const location = event.filename && event.lineno
44
- ? ` (${event.filename}:${event.lineno}:${event.colno})`
45
- : '';
46
- reject(`OCaml worker script error: ${event.message || 'unknown error'}${location}`);
47
- };
48
- this.worker.onmessageerror = () => {
49
- reject('OCaml worker message deserialization failed');
50
- };
51
- this.worker.onmessage = (event) => {
52
- if (event.data?.load) {
53
- progress?.set?.(1);
54
- resolve();
417
+ this.manifestUrl !== nextManifestUrl ||
418
+ this.moduleReceiptIdentity !== receiptIdentity(nextModuleReceipt) ||
419
+ this.manifestReceiptIdentity !== receiptIdentity(nextManifestReceipt) ||
420
+ this.maxAssetBytes !== limits.maxAssetBytes;
421
+ if (needsWorkerReset) {
422
+ const WorkerConstructor = (await import('./worker/ocaml?worker'))
423
+ .default;
424
+ if (!this.isOperationActive(operation))
425
+ return;
426
+ const worker = new WorkerConstructor();
427
+ if (!this.isOperationActive(operation)) {
428
+ worker.terminate();
429
+ return;
430
+ }
431
+ this.worker = worker;
432
+ this.workerSession.attach(worker);
433
+ if (!this.isOperationActive(operation) || this.worker !== worker) {
434
+ if (this.worker === worker)
435
+ delete this.worker;
436
+ this.workerSession.release(worker);
437
+ return;
438
+ }
439
+ const handler = (event) => {
440
+ if (!this.ownsWorkerOperation(operation, worker, handler))
441
+ return;
442
+ try {
443
+ const message = event.data;
444
+ if (!this.ownsWorkerOperation(operation, worker, handler))
445
+ return;
446
+ const loaded = message?.load;
447
+ if (!this.ownsWorkerOperation(operation, worker, handler))
448
+ return;
449
+ const error = message?.error;
450
+ if (!this.ownsWorkerOperation(operation, worker, handler))
451
+ return;
452
+ if (loaded) {
453
+ progress?.set?.(1);
454
+ if (!this.ownsWorkerOperation(operation, worker, handler))
455
+ return;
456
+ worker.onmessage = null;
457
+ this.moduleUrl = nextModuleUrl;
458
+ this.manifestUrl = nextManifestUrl;
459
+ this.moduleReceiptIdentity = receiptIdentity(nextModuleReceipt);
460
+ this.manifestReceiptIdentity = receiptIdentity(nextManifestReceipt);
461
+ this.maxAssetBytes = limits.maxAssetBytes;
462
+ resolve();
463
+ this.completeOperation(operation);
464
+ return;
465
+ }
466
+ if (error !== undefined)
467
+ reject(error);
468
+ }
469
+ catch (error) {
470
+ reject(error);
55
471
  }
56
- if (event.data?.error)
57
- reject(event.data.error);
58
472
  };
59
- this.worker.postMessage({
473
+ worker.onmessage = handler;
474
+ worker.postMessage({
60
475
  load: true,
61
- moduleUrl: this.moduleUrl,
62
- manifestUrl: this.manifestUrl
476
+ moduleUrl: nextModuleUrl,
477
+ manifestUrl: nextManifestUrl,
478
+ moduleReceipt: nextModuleReceipt,
479
+ manifestReceipt: nextManifestReceipt,
480
+ maxAssetBytes: limits.maxAssetBytes
63
481
  });
64
482
  }
65
483
  else {
66
484
  progress?.set?.(1);
485
+ if (!this.isOperationActive(operation))
486
+ return;
67
487
  resolve();
488
+ this.completeOperation(operation);
68
489
  }
69
490
  });
491
+ this.bindOperationTimeout(operation, Math.min(2_147_483_647, limits.assetTimeoutMs + limits.startupTimeoutMs));
492
+ return loading.finally(() => this.completeOperation(operation));
70
493
  }
71
494
  write(input) {
495
+ if (this.disposed)
496
+ return;
72
497
  this.pendingInput.push(input);
73
498
  this.pendingEof = false;
74
499
  this.flushPendingInput();
75
500
  }
76
501
  eof() {
502
+ if (this.disposed)
503
+ return;
77
504
  this.pendingEof = true;
78
505
  this.flushPendingInput();
79
506
  }
80
- flushPendingInput() {
507
+ flushPendingInput(buffer = this.activeOperation?.buffer ?? this.buffer) {
81
508
  if (!this.waitingForInput)
82
509
  return;
83
- if (flushQueuedStdin(this.pendingInput, this.buffer)) {
510
+ if (flushQueuedStdin(this.pendingInput, buffer)) {
84
511
  this.waitingForInput = false;
85
512
  return;
86
513
  }
87
514
  if (this.pendingEof) {
88
- flushBufferedEof(this.buffer);
515
+ flushBufferedEof(buffer);
89
516
  this.pendingEof = false;
90
517
  this.waitingForInput = false;
91
518
  }
92
519
  }
93
- run(code, prepare, _log = true, _prog, _args = [], options = {}) {
94
- this.exit = false;
95
- return new Promise((resolve, reject) => {
96
- if (!this.worker)
97
- return reject('Worker not loaded');
98
- const target = options.ocamlBackend || 'wasm';
99
- const wasmBinaryenMode = options.ocamlWasmBinaryenMode || 'fast';
100
- const _uid = ++this.uid;
101
- this.activeReject = reject;
102
- const handler = async (event) => {
103
- if (!this.worker)
104
- return reject('Worker not loaded');
105
- if (_uid !== this.uid)
106
- return (this.worker.onmessage = null);
107
- const { output, results, error, diagnostic, progress, runtime } = event.data;
108
- if (progress && typeof progress.percent === 'number') {
109
- _prog?.set?.(Math.max(0, Math.min(progress.percent / 100, 1)));
520
+ async run(code, prepare, _log = true, _prog, _args = [], options = {}) {
521
+ const operation = this.beginOperation('execute');
522
+ let signal;
523
+ let worker;
524
+ let target;
525
+ let wasmBinaryenMode;
526
+ let limits;
527
+ let workspace;
528
+ let stdin;
529
+ let buffer;
530
+ let outputCallback;
531
+ let onDiagnostic;
532
+ try {
533
+ signal = options.signal;
534
+ if (!this.isOperationActive(operation)) {
535
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
536
+ }
537
+ this.bindAbortSignal(operation, signal);
538
+ if (!this.isOperationActive(operation)) {
539
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
540
+ }
541
+ const configuredWorker = this.worker;
542
+ if (!this.isOperationActive(operation)) {
543
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
544
+ }
545
+ if (!configuredWorker)
546
+ throw 'Worker not loaded';
547
+ worker = configuredWorker;
548
+ const configuredTarget = options.ocamlBackend;
549
+ if (!this.isOperationActive(operation)) {
550
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
551
+ }
552
+ target = configuredTarget || 'wasm';
553
+ const configuredBinaryenMode = options.ocamlWasmBinaryenMode;
554
+ if (!this.isOperationActive(operation)) {
555
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
556
+ }
557
+ wasmBinaryenMode = configuredBinaryenMode || 'fast';
558
+ const configuredLimits = options.limits;
559
+ if (!this.isOperationActive(operation)) {
560
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
561
+ }
562
+ limits = this.resolveOperationLimits(operation, configuredLimits);
563
+ if (!this.isOperationActive(operation)) {
564
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
565
+ }
566
+ const configuredWorkspaceLimits = options.workspaceLimits;
567
+ if (!this.isOperationActive(operation)) {
568
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
569
+ }
570
+ if (configuredWorkspaceLimits !== undefined &&
571
+ (configuredWorkspaceLimits === null ||
572
+ typeof configuredWorkspaceLimits !== 'object')) {
573
+ throw new TypeError('OCaml workspace limits must be an object');
574
+ }
575
+ const workspaceLimitSnapshot = {};
576
+ if (configuredWorkspaceLimits !== undefined) {
577
+ for (const key of OCAML_WORKSPACE_LIMIT_KEYS) {
578
+ const value = configuredWorkspaceLimits[key];
579
+ if (!this.isOperationActive(operation)) {
580
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
581
+ }
582
+ if (value !== undefined) {
583
+ Object.assign(workspaceLimitSnapshot, { [key]: value });
584
+ }
110
585
  }
111
- if (event.data?.buffer) {
112
- this.waitingForInput = true;
113
- this.flushPendingInput();
586
+ }
587
+ validateExecutionWorkspace('', [], 'main.ml', workspaceLimitSnapshot);
588
+ if (!this.isOperationActive(operation)) {
589
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
590
+ }
591
+ const workspaceFilesSource = options.workspaceFiles;
592
+ if (!this.isOperationActive(operation)) {
593
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
594
+ }
595
+ if (workspaceFilesSource !== undefined && !Array.isArray(workspaceFilesSource)) {
596
+ throw new TypeError('OCaml workspace files must be an array');
597
+ }
598
+ const workspaceFileCount = workspaceFilesSource?.length ?? 0;
599
+ if (!this.isOperationActive(operation)) {
600
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
601
+ }
602
+ const maxFiles = workspaceLimitSnapshot.maxFiles ?? DEFAULT_WORKSPACE_LIMITS.maxFiles;
603
+ if (workspaceFileCount > maxFiles) {
604
+ throw new WorkspaceValidationError('file-count-limit', `Workspace contains ${workspaceFileCount} files; limit is ${maxFiles}`, { limit: maxFiles, actual: workspaceFileCount });
605
+ }
606
+ const workspaceFiles = [];
607
+ for (let index = 0; index < workspaceFileCount; index += 1) {
608
+ const file = workspaceFilesSource?.[index];
609
+ if (!this.isOperationActive(operation)) {
610
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
114
611
  }
115
- if (output)
116
- this.output(output);
117
- if (diagnostic)
118
- this.oncompilerdiagnostic?.(diagnostic);
119
- if (runtime) {
120
- const createdObjectUrls = [];
121
- const originalConsole = window.console;
122
- const originalFetch = window.fetch.bind(window);
123
- const originalInstantiate = WebAssembly.instantiate.bind(WebAssembly);
124
- const originalInstantiateStreaming = WebAssembly.instantiateStreaming
125
- ? WebAssembly.instantiateStreaming.bind(WebAssembly)
126
- : undefined;
127
- const runtimePromiseKey = '__wasm_of_js_of_ocaml_runtime_promise';
128
- const assetResolverKey = '__wasm_of_js_of_ocaml_resolve_asset';
129
- const runtimeGlobal = window;
130
- const hadProcess = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'process');
131
- const hadRequire = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'require');
132
- const hadModule = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'module');
133
- const hadExports = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'exports');
134
- const originalProcess = runtimeGlobal.process;
135
- const originalRequire = runtimeGlobal.require;
136
- const originalModule = runtimeGlobal.module;
137
- const originalExports = runtimeGlobal.exports;
138
- originalConsole.log(`[wasm-idle:ocaml-runtime] start source=${String(runtime.sourcePath || '')} chars=${String(String(runtime.programSource || '').length)} assets=${String(Array.isArray(runtime.assetFiles) ? runtime.assetFiles.length : 0)}`);
139
- const sourceDir = String(runtime.sourcePath || '').replace(/\/[^/]+$/, '');
140
- const assetEntries = Array.isArray(runtime.assetFiles)
141
- ? runtime.assetFiles.map((assetFile) => {
142
- const copiedAssetData = new Uint8Array(assetFile.data.byteLength);
143
- copiedAssetData.set(assetFile.data);
144
- const objectUrl = URL.createObjectURL(new Blob([copiedAssetData], {
145
- type: assetFile.path.endsWith('.wasm')
146
- ? 'application/wasm'
147
- : 'application/octet-stream'
148
- }));
149
- createdObjectUrls.push(objectUrl);
150
- return {
151
- path: assetFile.path,
152
- basename: assetFile.path.split('/').at(-1) || assetFile.path,
153
- relativeFromSourceDir: assetFile.path.startsWith(`${sourceDir}/`)
154
- ? assetFile.path.slice(sourceDir.length + 1)
155
- : assetFile.path.replace(/^\/+/, ''),
156
- objectUrl
157
- };
158
- })
159
- : [];
160
- const emitOutput = (...args) => {
161
- const text = args.map((value) => String(value)).join(' ');
162
- this.output(text.endsWith('\n') ? text : `${text}\n`);
163
- };
164
- const resolveAssetUrl = (requestedAsset) => assetEntries
165
- .map((assetEntry) => {
166
- const candidates = [String(requestedAsset)];
167
- try {
168
- candidates.push(new URL(String(requestedAsset), window.location.href).pathname);
169
- }
170
- catch {
171
- // ignore URL parse errors
172
- }
173
- return candidates.some((candidate) => candidate === assetEntry.path ||
174
- candidate === assetEntry.relativeFromSourceDir ||
175
- candidate.endsWith(`/${assetEntry.relativeFromSourceDir}`) ||
176
- candidate.endsWith(`/${assetEntry.basename}`))
177
- ? assetEntry.objectUrl
178
- : null;
179
- })
180
- .find((candidate) => !!candidate) || null;
181
- window.console = {
182
- ...originalConsole,
183
- log: (...args) => {
184
- emitOutput(...args);
185
- originalConsole.log(...args);
186
- },
187
- info: (...args) => {
188
- emitOutput(...args);
189
- originalConsole.info(...args);
190
- },
191
- warn: (...args) => {
192
- emitOutput(...args);
193
- originalConsole.warn(...args);
194
- },
195
- error: (...args) => {
196
- emitOutput(...args);
197
- originalConsole.error(...args);
198
- }
199
- };
200
- window.fetch = (async (input, init) => {
201
- const requestUrl = typeof input === 'string'
202
- ? input
203
- : input instanceof URL
204
- ? input.toString()
205
- : input.url;
206
- const resolvedAssetUrl = resolveAssetUrl(requestUrl);
207
- if (resolvedAssetUrl) {
208
- return await originalFetch(resolvedAssetUrl, init);
209
- }
210
- return await originalFetch(input, init);
211
- });
212
- WebAssembly.instantiate = (async (source, importObject) => {
213
- return await originalInstantiate(source, importObject);
214
- });
215
- if (originalInstantiateStreaming) {
216
- WebAssembly.instantiateStreaming = (async (source, importObject) => {
217
- return await originalInstantiateStreaming(source, importObject);
218
- });
612
+ if (file === null || typeof file !== 'object' || Array.isArray(file)) {
613
+ throw new TypeError('OCaml workspace file must be an object');
614
+ }
615
+ const path = file.path;
616
+ if (!this.isOperationActive(operation)) {
617
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
618
+ }
619
+ const content = file.content;
620
+ if (!this.isOperationActive(operation)) {
621
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
622
+ }
623
+ if (typeof content !== 'string') {
624
+ throw new TypeError('OCaml workspace file content must be a string');
625
+ }
626
+ workspaceFiles.push({ path, content });
627
+ }
628
+ const configuredActivePath = options.activePath;
629
+ if (!this.isOperationActive(operation)) {
630
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
631
+ }
632
+ workspace = validateExecutionWorkspace(code, workspaceFiles, configuredActivePath ?? 'main.ml', {
633
+ ...workspaceLimitSnapshot,
634
+ maxFileBytes: Math.min(workspaceLimitSnapshot.maxFileBytes ??
635
+ DEFAULT_WORKSPACE_LIMITS.maxFileBytes, limits.maxWorkspaceBytes),
636
+ maxTotalBytes: Math.min(workspaceLimitSnapshot.maxTotalBytes ??
637
+ DEFAULT_WORKSPACE_LIMITS.maxTotalBytes, limits.maxWorkspaceBytes)
638
+ });
639
+ if (!this.isOperationActive(operation)) {
640
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
641
+ }
642
+ stdin = options.stdin;
643
+ if (!this.isOperationActive(operation)) {
644
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
645
+ }
646
+ buffer = this.buffer;
647
+ if (!this.isOperationActive(operation)) {
648
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
649
+ }
650
+ outputCallback = this.output;
651
+ if (!this.isOperationActive(operation)) {
652
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
653
+ }
654
+ onDiagnostic = this.oncompilerdiagnostic;
655
+ if (!this.isOperationActive(operation)) {
656
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
657
+ }
658
+ operation.buffer = buffer;
659
+ if (stdin !== undefined) {
660
+ operation.explicitStdin = true;
661
+ this.resetExplicitStdinState(buffer);
662
+ if (!this.isOperationActive(operation)) {
663
+ throw this.releaseBeforeSession(operation, 'OCaml execution cancelled');
664
+ }
665
+ }
666
+ }
667
+ catch (error) {
668
+ throw this.releaseBeforeSession(operation, error);
669
+ }
670
+ const hasExplicitStdin = stdin !== undefined;
671
+ operation.sessionActive = true;
672
+ try {
673
+ this.exit = false;
674
+ return await new Promise((resolve, reject) => {
675
+ const runUid = ++this.uid;
676
+ let outputBytes = 0;
677
+ let diagnosticCount = 0;
678
+ const workerOperation = this.workerSession.beginRun(worker, reject);
679
+ this.bindOperationTimeout(operation, Math.min(2_147_483_647, limits.compileTimeoutMs + limits.runTimeoutMs));
680
+ if (!this.isOperationActive(operation))
681
+ return;
682
+ let handler;
683
+ const ownsRun = () => this.ownsWorkerOperation(operation, worker, handler, runUid);
684
+ const failRun = (error, disposeWorker = false) => {
685
+ if (!ownsRun())
686
+ return;
687
+ this.finishExplicitStdin(operation);
688
+ if (worker.onmessage === handler)
689
+ worker.onmessage = null;
690
+ this.workerSession.complete(workerOperation);
691
+ if (disposeWorker && this.worker === worker)
692
+ this.workerSession.reset();
693
+ this.elapse = Date.now() - this.begin;
694
+ this.exit = true;
695
+ this.waitingForInput = false;
696
+ this.pendingEof = false;
697
+ this.completeOperation(operation);
698
+ reject(error);
699
+ };
700
+ handler = (event) => {
701
+ if (!ownsRun()) {
702
+ return;
219
703
  }
220
- runtimeGlobal.process = undefined;
221
- runtimeGlobal.require = undefined;
222
- runtimeGlobal.module = undefined;
223
- runtimeGlobal.exports = undefined;
224
- runtimeGlobal[assetResolverKey] = resolveAssetUrl;
225
704
  try {
226
- const normalizedSource = String(runtime.programSource || '').includes('($=>async a=>{')
227
- ? String(runtime.programSource).replace('($=>async a=>{', `globalThis.${runtimePromiseKey}=($=>async a=>{`)
228
- : String(runtime.programSource || '');
229
- const sourceWithAssetResolver = normalizedSource.replace(/function ([A-Za-z$_][\w$]*)\(([A-Za-z$_][\w$]*)\)\{const ([A-Za-z$_][\w$]*)=([A-Za-z$_][\w$]*)\?new URL\(\2,\4\):\2;return fetch\(\3\)\}/, `function $1($2){if(globalThis.${assetResolverKey}){const resolvedAsset=globalThis.${assetResolverKey}($2);if(resolvedAsset)return fetch(resolvedAsset)}const $3=$4?new URL($2,$4):$2;return fetch($3)}`);
230
- new Function(`${sourceWithAssetResolver}\n//# sourceURL=${String(runtime.sourcePath || 'ocaml-runtime.js')}`)();
231
- originalConsole.log('[wasm-idle:ocaml-runtime] script invoked');
232
- const runtimePromise = runtimeGlobal[runtimePromiseKey];
233
- originalConsole.log(`[wasm-idle:ocaml-runtime] runtime promise=${String(runtimePromise instanceof Promise)}`);
234
- if (runtimePromise instanceof Promise) {
235
- await runtimePromise;
236
- }
237
- this.elapse = Date.now() - this.begin;
238
- this.exit = true;
239
- this.activeReject = null;
240
- resolve(true);
241
- }
242
- catch (runtimeError) {
243
- this.elapse = Date.now() - this.begin;
244
- this.exit = true;
245
- this.activeReject = null;
246
- reject(runtimeError?.message || String(runtimeError));
247
- }
248
- finally {
249
- window.console = originalConsole;
250
- window.fetch = originalFetch;
251
- WebAssembly.instantiate = originalInstantiate;
252
- if (originalInstantiateStreaming) {
253
- WebAssembly.instantiateStreaming = originalInstantiateStreaming;
254
- }
255
- delete runtimeGlobal[runtimePromiseKey];
256
- delete runtimeGlobal[assetResolverKey];
257
- if (!hadProcess) {
258
- delete runtimeGlobal.process;
259
- }
260
- else {
261
- runtimeGlobal.process = originalProcess;
705
+ const message = event.data;
706
+ if (!ownsRun())
707
+ return;
708
+ const output = message?.output;
709
+ if (!ownsRun())
710
+ return;
711
+ const results = message?.results;
712
+ if (!ownsRun())
713
+ return;
714
+ const error = message?.error;
715
+ if (!ownsRun())
716
+ return;
717
+ const diagnostic = message?.diagnostic;
718
+ if (!ownsRun())
719
+ return;
720
+ const progress = message?.progress;
721
+ if (!ownsRun())
722
+ return;
723
+ const runtime = message?.runtime;
724
+ if (!ownsRun())
725
+ return;
726
+ const requestsInput = message?.buffer;
727
+ if (!ownsRun())
728
+ return;
729
+ reportWorkerProgress(_prog, progress);
730
+ if (!ownsRun()) {
731
+ return;
262
732
  }
263
- if (!hadRequire) {
264
- delete runtimeGlobal.require;
733
+ if (requestsInput && !hasExplicitStdin) {
734
+ this.waitingForInput = true;
735
+ if (!prepare) {
736
+ reportWorkerInputReady(_prog, 'OCaml runtime ready for input');
737
+ if (!ownsRun())
738
+ return;
739
+ }
740
+ this.flushPendingInput(buffer);
741
+ if (!ownsRun()) {
742
+ return;
743
+ }
265
744
  }
266
- else {
267
- runtimeGlobal.require = originalRequire;
745
+ if (output) {
746
+ const actual = outputBytes + OUTPUT_ENCODER.encode(String(output)).byteLength;
747
+ if (actual > limits.maxOutputBytes) {
748
+ failRun(new OutputLimitError(`OCaml output exceeded ${limits.maxOutputBytes} bytes`, {
749
+ actual,
750
+ limit: limits.maxOutputBytes,
751
+ phase: 'execute',
752
+ runtimeId: 'OCAML'
753
+ }), true);
754
+ return;
755
+ }
756
+ outputBytes = actual;
757
+ if (outputCallback != null) {
758
+ Reflect.apply(outputCallback, this, [output]);
759
+ }
760
+ if (!ownsRun()) {
761
+ return;
762
+ }
268
763
  }
269
- if (!hadModule) {
270
- delete runtimeGlobal.module;
764
+ if (diagnostic) {
765
+ const actual = diagnosticCount + 1;
766
+ if (actual > limits.maxDiagnostics) {
767
+ failRun(new DiagnosticLimitError(`OCaml diagnostics exceeded ${limits.maxDiagnostics} messages`, {
768
+ actual,
769
+ limit: limits.maxDiagnostics,
770
+ phase: 'execute',
771
+ runtimeId: 'OCAML'
772
+ }), true);
773
+ return;
774
+ }
775
+ diagnosticCount = actual;
776
+ if (onDiagnostic != null)
777
+ Reflect.apply(onDiagnostic, this, [diagnostic]);
778
+ if (!ownsRun()) {
779
+ return;
780
+ }
271
781
  }
272
- else {
273
- runtimeGlobal.module = originalModule;
782
+ if (runtime) {
783
+ failRun(new ProtocolError('Unexpected OCaml page runtime message', {
784
+ phase: 'execute',
785
+ runtimeId: 'OCAML'
786
+ }), true);
787
+ return;
274
788
  }
275
- if (!hadExports) {
276
- delete runtimeGlobal.exports;
277
- }
278
- else {
279
- runtimeGlobal.exports = originalExports;
280
- }
281
- for (const objectUrl of createdObjectUrls) {
282
- URL.revokeObjectURL(objectUrl);
789
+ if (results !== undefined) {
790
+ this.finishExplicitStdin(operation);
791
+ if (worker.onmessage === handler)
792
+ worker.onmessage = null;
793
+ this.elapse = Date.now() - this.begin;
794
+ this.exit = true;
795
+ this.waitingForInput = false;
796
+ this.pendingEof = false;
797
+ this.workerSession.complete(workerOperation);
798
+ this.completeOperation(operation);
799
+ resolve(results);
800
+ return;
283
801
  }
802
+ if (error !== undefined)
803
+ failRun(error);
804
+ }
805
+ catch (error) {
806
+ failRun(error, true);
284
807
  }
808
+ };
809
+ worker.onmessage = handler;
810
+ if (!ownsRun()) {
285
811
  return;
286
812
  }
287
- if (results) {
288
- this.elapse = Date.now() - this.begin;
289
- this.exit = true;
290
- this.waitingForInput = false;
291
- this.pendingEof = false;
292
- this.activeReject = null;
293
- resolve(results);
813
+ this.begin = Date.now();
814
+ try {
815
+ worker.postMessage({
816
+ code,
817
+ prepare,
818
+ target,
819
+ wasmBinaryenMode,
820
+ log: _log,
821
+ buffer,
822
+ stdin,
823
+ activePath: workspace.activePath,
824
+ workspaceFiles: workspace.workspaceFiles
825
+ });
294
826
  }
295
- if (error) {
296
- this.elapse = Date.now() - this.begin;
297
- this.exit = true;
298
- this.waitingForInput = false;
299
- this.pendingEof = false;
300
- this.activeReject = null;
301
- reject(error);
827
+ catch (error) {
828
+ failRun(error);
302
829
  }
303
- };
304
- this.worker.onmessage = (event) => {
305
- void handler(event);
306
- };
307
- this.begin = Date.now();
308
- this.worker.postMessage({
309
- code,
310
- prepare,
311
- target,
312
- wasmBinaryenMode,
313
- log: _log,
314
- buffer: this.buffer
315
830
  });
316
- });
831
+ }
832
+ finally {
833
+ this.finishExplicitStdin(operation);
834
+ this.completeOperation(operation);
835
+ }
317
836
  }
318
837
  kill() {
319
838
  this.terminate();
320
839
  }
321
- terminate() {
322
- this.activeReject?.('Process terminated');
323
- this.activeReject = null;
840
+ terminate(reason = 'Process terminated') {
841
+ if (this.disposed)
842
+ return;
843
+ const operation = this.activeOperation;
844
+ if (operation) {
845
+ if (operation.sessionActive)
846
+ this.abortOperation(operation, reason);
847
+ else
848
+ this.cancelBeforeSession(operation, reason);
849
+ return;
850
+ }
324
851
  this.waitingForInput = false;
325
852
  this.pendingEof = false;
326
853
  this.uid += 1;
327
- this.worker?.terminate?.();
328
- delete this.worker;
854
+ this.workerSession.terminate(reason);
329
855
  this.exit = true;
330
856
  }
331
857
  async clear() {
858
+ if (this.disposed)
859
+ return;
332
860
  this.pendingInput = [];
333
861
  this.waitingForInput = false;
334
862
  this.pendingEof = false;
335
863
  if (this.worker)
336
864
  this.worker.onmessage = null;
337
865
  resetBufferedStdin(this.buffer);
338
- if (!this.exit) {
866
+ if (this.activeOperation || !this.exit) {
339
867
  this.terminate();
340
868
  }
341
869
  }
870
+ dispose() {
871
+ if (this.disposePromise)
872
+ return this.disposePromise;
873
+ this.disposed = true;
874
+ this.disposePromise = Promise.resolve();
875
+ const operation = this.activeOperation;
876
+ const operationBuffer = operation?.buffer;
877
+ delete this.worker;
878
+ this.moduleUrl = '';
879
+ this.manifestUrl = '';
880
+ this.moduleReceiptIdentity = '';
881
+ this.manifestReceiptIdentity = '';
882
+ this.maxAssetBytes = 0;
883
+ this.output = undefined;
884
+ this.oncompilerdiagnostic = undefined;
885
+ this.resetExplicitStdinState(this.buffer);
886
+ if (operationBuffer && operationBuffer !== this.buffer) {
887
+ try {
888
+ resetBufferedStdin(operationBuffer);
889
+ }
890
+ catch {
891
+ // A detached operation buffer is already outside the live host state.
892
+ }
893
+ }
894
+ if (operation) {
895
+ this.abortOperation(operation, this.disposeCancellation);
896
+ }
897
+ else {
898
+ this.uid += 1;
899
+ this.workerSession.terminate(this.disposeCancellation);
900
+ this.exit = true;
901
+ }
902
+ return this.disposePromise;
903
+ }
342
904
  }
343
905
  export default Ocaml;