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,46 +1,306 @@
1
- import { CLANGD_RUNTIME_LOAD_ASSETS, CLANG_RUNTIME_LOAD_ASSETS, JAVA_RUNTIME_LOAD_ASSETS, PYTHON_RUNTIME_LOAD_ASSETS } from './assets';
1
+ import { RUNTIME_LOAD_ASSETS } from './assets';
2
+ import { ProtocolError, verifyRuntimeAssetIntegrity, verifyRuntimeAssetPair } from '@wasm-idle/core';
3
+ import { decompressGzip } from '@wasm-idle/llvm-core';
4
+ import { readPythonPackageAssets } from './pythonPackageLock';
2
5
  const encoder = new TextEncoder();
3
- const transferBuffer = (bytes) => bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength
4
- ? bytes.buffer
5
- : bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
6
- const expectedAssetsForRuntime = (runtime) => new Set(runtime === 'python'
7
- ? [...PYTHON_RUNTIME_LOAD_ASSETS]
8
- : runtime === 'java'
9
- ? [...JAVA_RUNTIME_LOAD_ASSETS]
10
- : runtime === 'clang'
11
- ? [...CLANG_RUNTIME_LOAD_ASSETS]
12
- : [...CLANGD_RUNTIME_LOAD_ASSETS]);
6
+ const DEFAULT_STREAM_BUFFER_BYTES = 64 * 1024;
7
+ const MAX_RUNTIME_ASSET_BYTES = 128 * 1024 * 1024;
8
+ const typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
9
+ const typedArrayTagGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, Symbol.toStringTag)?.get;
10
+ const typedArrayBufferGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'buffer')?.get;
11
+ const typedArrayByteLengthGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'byteLength')?.get;
12
+ const typedArrayByteOffsetGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'byteOffset')?.get;
13
+ const arrayBufferByteLengthGetter = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength')?.get;
14
+ const blobSizeGetter = Object.getOwnPropertyDescriptor(Blob.prototype, 'size')?.get;
15
+ const blobTypeGetter = Object.getOwnPropertyDescriptor(Blob.prototype, 'type')?.get;
16
+ const runtimeAssetSizeError = (asset, maxBytes = MAX_RUNTIME_ASSET_BYTES) => new Error(`Runtime asset ${asset} exceeds the ${maxBytes} byte limit`);
17
+ const requireRuntimeAssetSize = (asset, byteLength, maxBytes = MAX_RUNTIME_ASSET_BYTES) => {
18
+ if (!Number.isSafeInteger(byteLength) || byteLength < 0) {
19
+ throw new Error(`Runtime asset ${asset} has an invalid byte length`);
20
+ }
21
+ if (byteLength > maxBytes)
22
+ throw runtimeAssetSizeError(asset, maxBytes);
23
+ };
24
+ const canonicalUint8Array = (value) => {
25
+ if (!typedArrayTagGetter ||
26
+ !typedArrayBufferGetter ||
27
+ !typedArrayByteLengthGetter ||
28
+ !typedArrayByteOffsetGetter) {
29
+ throw new Error('Uint8Array intrinsic accessors are unavailable');
30
+ }
31
+ if (Reflect.apply(typedArrayTagGetter, value, []) !== 'Uint8Array') {
32
+ throw new TypeError('Runtime asset byte data must be a Uint8Array');
33
+ }
34
+ const buffer = Reflect.apply(typedArrayBufferGetter, value, []);
35
+ const byteLength = Reflect.apply(typedArrayByteLengthGetter, value, []);
36
+ const byteOffset = Reflect.apply(typedArrayByteOffsetGetter, value, []);
37
+ return new Uint8Array(buffer, byteOffset, byteLength);
38
+ };
39
+ const detachedRuntimeAssetBytesError = (asset) => new Error(`Runtime asset ${asset} byte data is detached or invalid`);
40
+ const tryCanonicalUint8Array = (value, asset) => {
41
+ if (!typedArrayTagGetter)
42
+ throw new Error('Uint8Array intrinsic accessors are unavailable');
43
+ let tag;
44
+ try {
45
+ tag = Reflect.apply(typedArrayTagGetter, value, []);
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ if (tag !== 'Uint8Array')
51
+ return undefined;
52
+ try {
53
+ return canonicalUint8Array(value);
54
+ }
55
+ catch {
56
+ throw detachedRuntimeAssetBytesError(asset);
57
+ }
58
+ };
59
+ const tryArrayBufferByteLength = (value) => {
60
+ if (!arrayBufferByteLengthGetter)
61
+ return undefined;
62
+ try {
63
+ return Reflect.apply(arrayBufferByteLengthGetter, value, []);
64
+ }
65
+ catch {
66
+ return undefined;
67
+ }
68
+ };
69
+ const snapshotArrayBufferBytes = (value, asset, maxBytes) => {
70
+ const byteLength = tryArrayBufferByteLength(value);
71
+ if (byteLength === undefined)
72
+ return undefined;
73
+ requireRuntimeAssetSize(asset, byteLength, maxBytes);
74
+ try {
75
+ return Uint8Array.from(new Uint8Array(value));
76
+ }
77
+ catch {
78
+ throw detachedRuntimeAssetBytesError(asset);
79
+ }
80
+ };
81
+ const snapshotLoaderBytes = (value, asset, maxBytes) => {
82
+ const bytes = tryCanonicalUint8Array(value, asset);
83
+ if (!bytes)
84
+ return snapshotArrayBufferBytes(value, asset, maxBytes);
85
+ requireRuntimeAssetSize(asset, bytes.byteLength, maxBytes);
86
+ return Uint8Array.from(bytes);
87
+ };
88
+ const snapshotMaterializedArrayBuffer = (value, asset, maxBytes) => {
89
+ const bytes = snapshotArrayBufferBytes(value, asset, maxBytes);
90
+ if (!bytes) {
91
+ throw new Error(`Runtime asset ${asset} materialization did not return an ArrayBuffer`);
92
+ }
93
+ return bytes;
94
+ };
95
+ const tryCanonicalBlob = (value) => {
96
+ if (!blobSizeGetter || !blobTypeGetter)
97
+ return undefined;
98
+ try {
99
+ return {
100
+ blob: value,
101
+ size: Reflect.apply(blobSizeGetter, value, []),
102
+ type: Reflect.apply(blobTypeGetter, value, [])
103
+ };
104
+ }
105
+ catch {
106
+ return undefined;
107
+ }
108
+ };
109
+ export const boundedUtf8ByteLength = (value, maxBytes = MAX_RUNTIME_ASSET_BYTES) => {
110
+ let byteLength = 0;
111
+ for (let index = 0; index < value.length; index += 1) {
112
+ const codeUnit = value.charCodeAt(index);
113
+ if (codeUnit <= 0x7f) {
114
+ byteLength += 1;
115
+ }
116
+ else if (codeUnit <= 0x7ff) {
117
+ byteLength += 2;
118
+ }
119
+ else if (codeUnit >= 0xd800 &&
120
+ codeUnit <= 0xdbff &&
121
+ index + 1 < value.length &&
122
+ value.charCodeAt(index + 1) >= 0xdc00 &&
123
+ value.charCodeAt(index + 1) <= 0xdfff) {
124
+ byteLength += 4;
125
+ index += 1;
126
+ }
127
+ else {
128
+ byteLength += 3;
129
+ }
130
+ if (byteLength > maxBytes)
131
+ return byteLength;
132
+ }
133
+ return byteLength;
134
+ };
135
+ const runtimeAssetAbortReason = (signal) => signal.reason ?? new DOMException('Runtime asset load aborted', 'AbortError');
136
+ const requireBridgeMaxAssetBytes = (value) => {
137
+ if (!Number.isSafeInteger(value) || value <= 0) {
138
+ throw new TypeError('Worker asset bridge maxAssetBytes must be a positive safe integer');
139
+ }
140
+ return value;
141
+ };
142
+ const cancelResponseBody = (response, reason) => {
143
+ try {
144
+ void Promise.resolve(response.body?.cancel(reason)).catch(() => undefined);
145
+ }
146
+ catch {
147
+ // Preserve the asset failure that caused cancellation.
148
+ }
149
+ };
150
+ const readAbortableArrayBuffer = async (source, signal) => {
151
+ if (signal.aborted)
152
+ throw runtimeAssetAbortReason(signal);
153
+ let cancelOnAbort;
154
+ const aborted = new Promise((_resolve, reject) => {
155
+ cancelOnAbort = () => reject(runtimeAssetAbortReason(signal));
156
+ signal.addEventListener('abort', cancelOnAbort, { once: true });
157
+ });
158
+ try {
159
+ const materialized = source.arrayBuffer();
160
+ const bytes = await Promise.race([materialized, aborted]);
161
+ if (signal.aborted)
162
+ throw runtimeAssetAbortReason(signal);
163
+ return bytes;
164
+ }
165
+ finally {
166
+ if (cancelOnAbort)
167
+ signal.removeEventListener('abort', cancelOnAbort);
168
+ }
169
+ };
170
+ const transferBuffer = (bytes, transferOwnership = false) => {
171
+ const canonicalBytes = canonicalUint8Array(bytes);
172
+ const buffer = canonicalBytes.buffer;
173
+ const transferableBuffer = buffer instanceof ArrayBuffer ? buffer : undefined;
174
+ const transferableByteLength = transferableBuffer && arrayBufferByteLengthGetter
175
+ ? Reflect.apply(arrayBufferByteLengthGetter, transferableBuffer, [])
176
+ : undefined;
177
+ return transferOwnership &&
178
+ transferableBuffer &&
179
+ canonicalBytes.byteOffset === 0 &&
180
+ canonicalBytes.byteLength === transferableByteLength
181
+ ? transferableBuffer
182
+ : Uint8Array.from(canonicalBytes).buffer;
183
+ };
184
+ const expectedAssetsForRuntime = (runtime) => new Set(RUNTIME_LOAD_ASSETS[runtime]);
185
+ const integrityKey = (config) => JSON.stringify(Object.entries(config.integrity || {})
186
+ .sort(([left], [right]) => left.localeCompare(right))
187
+ .map(([asset, entry]) => [
188
+ asset,
189
+ typeof entry === 'string'
190
+ ? entry
191
+ : {
192
+ sha256: entry.sha256,
193
+ bytes: entry.bytes,
194
+ mediaType: entry.mediaType,
195
+ uncompressedSha256: entry.uncompressedSha256,
196
+ uncompressedBytes: entry.uncompressedBytes
197
+ }
198
+ ]));
199
+ const allowedBaseUrlsKey = (config) => JSON.stringify([...(config.allowedBaseUrls || [])].sort());
13
200
  class RuntimeLoadProgress {
14
- fractions = new Map();
201
+ samples = new Map();
15
202
  expectedAssets;
203
+ phaseId;
16
204
  progress;
205
+ lockedTotal;
206
+ measurementInvalid = false;
17
207
  constructor(runtime) {
18
208
  this.expectedAssets = expectedAssetsForRuntime(runtime);
209
+ this.phaseId = `${runtime}:runtime-assets`;
19
210
  this.reset();
20
211
  }
21
212
  reset(progress) {
22
213
  this.progress = progress;
23
- this.fractions.clear();
214
+ this.samples.clear();
215
+ this.lockedTotal = undefined;
216
+ this.measurementInvalid = false;
24
217
  for (const asset of this.expectedAssets)
25
- this.fractions.set(asset, 0);
218
+ this.samples.set(asset, { loaded: 0 });
26
219
  this.emit();
27
220
  }
28
221
  update(asset, loaded, total) {
29
222
  if (!this.expectedAssets.has(asset))
30
223
  return;
31
- const fraction = total && total > 0 ? Math.min(loaded / total, 1) : loaded > 0 ? 1 : 0;
32
- this.fractions.set(asset, fraction);
224
+ if (!Number.isSafeInteger(loaded) || loaded < 0) {
225
+ this.measurementInvalid = true;
226
+ this.emit();
227
+ return;
228
+ }
229
+ const previous = this.samples.get(asset) || { loaded: 0 };
230
+ let nextTotal = previous.total;
231
+ if (total !== undefined) {
232
+ if (!Number.isSafeInteger(total) || total <= 0) {
233
+ this.measurementInvalid = true;
234
+ }
235
+ else if (previous.total !== undefined && previous.total !== total) {
236
+ this.measurementInvalid = true;
237
+ }
238
+ else {
239
+ nextTotal = total;
240
+ }
241
+ }
242
+ const nextLoaded = Math.max(previous.loaded, loaded);
243
+ if (nextTotal !== undefined && nextLoaded > nextTotal) {
244
+ this.measurementInvalid = true;
245
+ }
246
+ this.samples.set(asset, {
247
+ loaded: nextLoaded,
248
+ ...(nextTotal === undefined ? {} : { total: nextTotal })
249
+ });
33
250
  this.emit();
34
251
  }
252
+ activity(phase, asset) {
253
+ if (!this.progress)
254
+ return;
255
+ const action = phase === 'decompressing' ? 'Decompressing' : 'Verifying';
256
+ const label = `${action} ${asset}`;
257
+ if (this.progress.report) {
258
+ this.progress.report({
259
+ kind: 'activity',
260
+ phase,
261
+ phaseId: `${this.phaseId}:${asset}`,
262
+ label
263
+ });
264
+ return;
265
+ }
266
+ this.progress.set?.(0, label);
267
+ }
35
268
  emit() {
36
269
  if (!this.progress)
37
270
  return;
38
- if (!this.fractions.size)
39
- return this.progress.set?.(0);
40
- let total = 0;
41
- for (const fraction of this.fractions.values())
42
- total += fraction;
43
- this.progress.set?.(total / this.fractions.size);
271
+ let completedBytes = 0;
272
+ let totalBytes = 0;
273
+ let allTotalsKnown = this.samples.size > 0;
274
+ for (const sample of this.samples.values()) {
275
+ if (sample.total === undefined) {
276
+ allTotalsKnown = false;
277
+ continue;
278
+ }
279
+ completedBytes += sample.loaded;
280
+ totalBytes += sample.total;
281
+ }
282
+ if (!Number.isSafeInteger(completedBytes) || !Number.isSafeInteger(totalBytes)) {
283
+ this.measurementInvalid = true;
284
+ }
285
+ if (allTotalsKnown && this.lockedTotal === undefined)
286
+ this.lockedTotal = totalBytes;
287
+ if (this.lockedTotal !== undefined && this.lockedTotal !== totalBytes) {
288
+ this.measurementInvalid = true;
289
+ }
290
+ const measurement = allTotalsKnown && !this.measurementInvalid && totalBytes > 0
291
+ ? { kind: 'bytes', completed: completedBytes, total: totalBytes }
292
+ : undefined;
293
+ if (this.progress.report) {
294
+ this.progress.report({
295
+ kind: 'activity',
296
+ phase: 'downloading',
297
+ phaseId: this.phaseId,
298
+ label: 'Downloading runtime assets',
299
+ ...(measurement ? { measurement } : {})
300
+ });
301
+ return;
302
+ }
303
+ this.progress.set?.(measurement ? measurement.completed / measurement.total : 0);
44
304
  }
45
305
  }
46
306
  export class WorkerAssetBridge {
@@ -48,44 +308,190 @@ export class WorkerAssetBridge {
48
308
  runtime;
49
309
  config;
50
310
  progress;
51
- constructor(worker, runtime, config, progress) {
311
+ expectedAssets;
312
+ pythonPackageAssets = new Set();
313
+ generation = 0;
314
+ state = 'active';
315
+ activeLoads = new Set();
316
+ maxAssetBytes;
317
+ constructor(worker, runtime, config, progress, maxAssetBytes = MAX_RUNTIME_ASSET_BYTES) {
52
318
  this.worker = worker;
53
319
  this.runtime = runtime;
54
320
  this.config = config;
321
+ this.maxAssetBytes = requireBridgeMaxAssetBytes(maxAssetBytes);
55
322
  this.progress = new RuntimeLoadProgress(runtime);
323
+ this.expectedAssets = expectedAssetsForRuntime(runtime);
56
324
  this.progress.reset(progress);
57
325
  }
58
- matches(config) {
59
- return (this.config.baseUrl === config.baseUrl &&
326
+ matches(config, maxAssetBytes = this.maxAssetBytes) {
327
+ return (this.state === 'active' &&
328
+ this.maxAssetBytes === requireBridgeMaxAssetBytes(maxAssetBytes) &&
329
+ this.config.baseUrl === config.baseUrl &&
60
330
  this.config.loader === config.loader &&
331
+ integrityKey(this.config) === integrityKey(config) &&
332
+ allowedBaseUrlsKey(this.config) === allowedBaseUrlsKey(config) &&
61
333
  this.config.useAssetBridge === config.useAssetBridge);
62
334
  }
63
- rebind(worker, config, progress) {
64
- this.worker = worker;
65
- this.config = config;
66
- this.progress.reset(progress);
335
+ rebind(worker, config, progress, maxAssetBytes = this.maxAssetBytes) {
336
+ if (this.state === 'disposed') {
337
+ throw new Error('Cannot rebind a disposed worker asset bridge');
338
+ }
339
+ if (this.state === 'rebinding') {
340
+ throw new Error('Cannot rebind a worker asset bridge while another rebind is active');
341
+ }
342
+ const nextMaxAssetBytes = requireBridgeMaxAssetBytes(maxAssetBytes);
343
+ const preservePythonPackageAssets = this.matches(config, nextMaxAssetBytes);
344
+ this.state = 'rebinding';
345
+ const generation = ++this.generation;
346
+ this.progress.reset();
347
+ try {
348
+ this.abortActiveLoads();
349
+ if (!preservePythonPackageAssets)
350
+ this.pythonPackageAssets.clear();
351
+ if (this.state !== 'rebinding' || this.generation !== generation) {
352
+ throw new Error('Cannot rebind a disposed worker asset bridge');
353
+ }
354
+ this.worker = worker;
355
+ this.config = config;
356
+ this.maxAssetBytes = nextMaxAssetBytes;
357
+ this.progress.reset(progress);
358
+ if (this.state !== 'rebinding' || this.generation !== generation) {
359
+ throw new Error('Cannot rebind a disposed worker asset bridge');
360
+ }
361
+ this.state = 'active';
362
+ }
363
+ catch (error) {
364
+ if (this.state === 'rebinding' && this.generation === generation)
365
+ this.dispose();
366
+ throw error;
367
+ }
368
+ }
369
+ dispose() {
370
+ if (this.state === 'disposed')
371
+ return;
372
+ this.state = 'disposed';
373
+ this.generation += 1;
374
+ this.progress.reset();
375
+ this.pythonPackageAssets.clear();
376
+ this.abortActiveLoads();
67
377
  }
68
378
  resetProgress(progress) {
379
+ if (this.state !== 'active')
380
+ return;
69
381
  this.progress.reset(progress);
70
382
  }
383
+ configuredReceiptByteLimit(asset, value) {
384
+ if (value === undefined)
385
+ return undefined;
386
+ if (!Number.isSafeInteger(value) || value < 0) {
387
+ throw new ProtocolError(`Runtime asset ${asset} has an invalid integrity byte count`, {
388
+ phase: 'asset',
389
+ runtimeId: this.runtime
390
+ });
391
+ }
392
+ const byteLimit = value;
393
+ if (byteLimit > this.maxAssetBytes) {
394
+ throw runtimeAssetSizeError(asset, this.maxAssetBytes);
395
+ }
396
+ return byteLimit;
397
+ }
398
+ runtimeAssetByteLimit(asset) {
399
+ const configured = this.config.integrity?.[asset];
400
+ if (!configured || typeof configured === 'string')
401
+ return this.maxAssetBytes;
402
+ return (this.configuredReceiptByteLimit(asset, configured.uncompressedBytes ?? configured.bytes) ?? this.maxAssetBytes);
403
+ }
404
+ sourceAssetByteLimit(asset) {
405
+ const configured = this.config.integrity?.[asset];
406
+ if (!configured || typeof configured === 'string')
407
+ return this.maxAssetBytes;
408
+ const paired = configured.uncompressedBytes !== undefined ||
409
+ configured.uncompressedSha256 !== undefined;
410
+ if (asset.endsWith('.gz')) {
411
+ if (!paired)
412
+ return this.maxAssetBytes;
413
+ const deliveryLimit = this.configuredReceiptByteLimit(asset, configured.bytes);
414
+ const runtimeLimit = this.configuredReceiptByteLimit(asset, configured.uncompressedBytes);
415
+ return deliveryLimit !== undefined || runtimeLimit !== undefined
416
+ ? Math.max(deliveryLimit ?? 0, runtimeLimit ?? 0)
417
+ : this.maxAssetBytes;
418
+ }
419
+ const deliveryLimit = this.configuredReceiptByteLimit(asset, configured.bytes);
420
+ const runtimeLimit = this.configuredReceiptByteLimit(asset, configured.uncompressedBytes);
421
+ return deliveryLimit !== undefined || runtimeLimit !== undefined
422
+ ? Math.max(deliveryLimit ?? 0, runtimeLimit ?? 0)
423
+ : this.maxAssetBytes;
424
+ }
71
425
  handleMessage(event) {
72
426
  const assetRequest = event.data?.assetRequest;
73
427
  if (assetRequest) {
74
- void this.respond(assetRequest);
428
+ if (this.state === 'active')
429
+ void this.respond(assetRequest);
75
430
  return true;
76
431
  }
77
432
  const assetProgress = event.data?.assetProgress;
78
433
  if (assetProgress) {
79
- this.progress.update(assetProgress.asset, assetProgress.loaded, assetProgress.total);
434
+ if (this.state === 'active') {
435
+ this.progress.update(assetProgress.asset, assetProgress.loaded, assetProgress.total);
436
+ }
80
437
  return true;
81
438
  }
82
439
  return false;
83
440
  }
84
441
  async respond(request) {
442
+ if (this.state !== 'active')
443
+ return;
444
+ const worker = this.worker;
445
+ const generation = this.generation;
446
+ const controller = new AbortController();
447
+ this.activeLoads.add(controller);
85
448
  try {
86
- const loaded = await this.loadAsset(request.asset);
87
- const buffer = transferBuffer(loaded.bytes);
88
- this.worker.postMessage({
449
+ const loaded = await this.loadAsset(request.asset, controller.signal);
450
+ const deliveryBytes = canonicalUint8Array(loaded.bytes);
451
+ const sourceAssetByteLimit = this.sourceAssetByteLimit(request.asset);
452
+ const runtimeAssetByteLimit = this.runtimeAssetByteLimit(request.asset);
453
+ requireRuntimeAssetSize(request.asset, deliveryBytes.byteLength, sourceAssetByteLimit);
454
+ let normalizedRuntimeBytes;
455
+ if (request.asset.endsWith('.gz')) {
456
+ this.progress.activity('decompressing', request.asset);
457
+ normalizedRuntimeBytes = await decompressGzip(deliveryBytes, request.asset, runtimeAssetByteLimit, controller.signal);
458
+ }
459
+ else {
460
+ normalizedRuntimeBytes = deliveryBytes;
461
+ }
462
+ const runtimeBytes = canonicalUint8Array(normalizedRuntimeBytes);
463
+ requireRuntimeAssetSize(request.asset, runtimeBytes.byteLength, runtimeAssetByteLimit);
464
+ const httpDecodedGzip = (loaded.contentEncoding || '')
465
+ .toLowerCase()
466
+ .split(',')
467
+ .map((encoding) => encoding.trim())
468
+ .includes('gzip');
469
+ if (controller.signal.aborted || generation !== this.generation)
470
+ return;
471
+ let cancelOnAbort;
472
+ const aborted = new Promise((_resolve, reject) => {
473
+ cancelOnAbort = () => reject(runtimeAssetAbortReason(controller.signal));
474
+ controller.signal.addEventListener('abort', cancelOnAbort, { once: true });
475
+ });
476
+ try {
477
+ if (this.config.integrity?.[request.asset]) {
478
+ this.progress.activity('verifying', request.asset);
479
+ }
480
+ const verification = this.verifyIntegrity(request.asset, deliveryBytes, runtimeBytes, loaded.mimeType, !httpDecodedGzip);
481
+ await Promise.race([verification, aborted]);
482
+ }
483
+ finally {
484
+ if (cancelOnAbort) {
485
+ controller.signal.removeEventListener('abort', cancelOnAbort);
486
+ }
487
+ }
488
+ if (controller.signal.aborted || generation !== this.generation)
489
+ return;
490
+ if (this.runtime === 'python' && request.asset === 'pyodide-lock.json') {
491
+ this.pythonPackageAssets = readPythonPackageAssets(runtimeBytes);
492
+ }
493
+ const buffer = transferBuffer(runtimeBytes, normalizedRuntimeBytes === deliveryBytes ? loaded.transferOwnership : true);
494
+ worker.postMessage({
89
495
  assetResponse: {
90
496
  id: request.id,
91
497
  ok: true,
@@ -95,104 +501,422 @@ export class WorkerAssetBridge {
95
501
  }, [buffer]);
96
502
  }
97
503
  catch (error) {
98
- this.worker.postMessage({
99
- assetResponse: {
100
- id: request.id,
101
- ok: false,
102
- error: error instanceof Error ? error.message : String(error)
103
- }
104
- });
504
+ if (controller.signal.aborted || generation !== this.generation)
505
+ return;
506
+ try {
507
+ worker.postMessage({
508
+ assetResponse: {
509
+ id: request.id,
510
+ ok: false,
511
+ error: error instanceof Error ? error.message : String(error)
512
+ }
513
+ });
514
+ }
515
+ catch {
516
+ // The worker may already be terminated. There is no remaining response channel.
517
+ }
518
+ }
519
+ finally {
520
+ this.activeLoads.delete(controller);
105
521
  }
106
522
  }
107
- async loadAsset(asset) {
108
- const reportProgress = (loaded, total) => this.progress.update(asset, loaded, total);
523
+ async loadAsset(asset, signal) {
524
+ if (!this.expectedAssets.has(asset) && !this.pythonPackageAssets.has(asset)) {
525
+ throw new Error(`Unexpected ${this.runtime} runtime asset: ${asset}`);
526
+ }
527
+ if (this.config.integrity && !Object.hasOwn(this.config.integrity, asset)) {
528
+ throw new Error(`Runtime asset ${asset} is missing integrity metadata`);
529
+ }
530
+ if (signal.aborted) {
531
+ throw runtimeAssetAbortReason(signal);
532
+ }
533
+ const sourceAssetByteLimit = this.sourceAssetByteLimit(asset);
534
+ this.runtimeAssetByteLimit(asset);
535
+ const reportProgress = (loaded, total) => {
536
+ if (!signal.aborted)
537
+ this.progress.update(asset, loaded, total);
538
+ };
109
539
  if (this.config.loader) {
110
- const loaded = await this.normalizeLoaderResult(await this.config.loader({
540
+ const pendingResult = Promise.resolve(this.config.loader({
111
541
  runtime: this.runtime,
112
542
  asset,
113
- reportProgress
114
- }), asset);
543
+ reportProgress,
544
+ signal
545
+ }));
546
+ const result = await new Promise((resolve, reject) => {
547
+ let settled = false;
548
+ const onAbort = () => {
549
+ if (settled)
550
+ return;
551
+ settled = true;
552
+ signal.removeEventListener('abort', onAbort);
553
+ reject(runtimeAssetAbortReason(signal));
554
+ };
555
+ signal.addEventListener('abort', onAbort, { once: true });
556
+ void pendingResult.then((value) => {
557
+ if (settled)
558
+ return;
559
+ settled = true;
560
+ signal.removeEventListener('abort', onAbort);
561
+ resolve(value);
562
+ }, (error) => {
563
+ if (settled)
564
+ return;
565
+ settled = true;
566
+ signal.removeEventListener('abort', onAbort);
567
+ reject(error);
568
+ });
569
+ if (signal.aborted)
570
+ onAbort();
571
+ });
572
+ if (signal.aborted) {
573
+ throw runtimeAssetAbortReason(signal);
574
+ }
575
+ const loaded = await this.normalizeLoaderResult(result, asset, signal, sourceAssetByteLimit);
576
+ if (signal.aborted) {
577
+ throw runtimeAssetAbortReason(signal);
578
+ }
115
579
  if (loaded)
116
580
  return loaded;
117
581
  }
118
- return await this.fetchAsset(new URL(asset, this.config.baseUrl).href, asset);
582
+ return await this.fetchAsset(asset, asset, signal, sourceAssetByteLimit);
119
583
  }
120
- async normalizeLoaderResult(result, asset) {
584
+ async verifyIntegrity(asset, deliveryBytes, runtimeBytes, mimeType, hasDeliveryBytes = true) {
585
+ const configured = this.config.integrity?.[asset];
586
+ if (!configured)
587
+ return;
588
+ const expected = typeof configured === 'string' ? { sha256: configured } : configured;
589
+ if (expected.uncompressedSha256 !== undefined || expected.uncompressedBytes !== undefined) {
590
+ if (hasDeliveryBytes) {
591
+ await verifyRuntimeAssetPair({
592
+ asset,
593
+ compressed: deliveryBytes,
594
+ uncompressed: runtimeBytes,
595
+ expected,
596
+ mimeType
597
+ });
598
+ }
599
+ else {
600
+ await verifyRuntimeAssetIntegrity({
601
+ asset,
602
+ bytes: runtimeBytes,
603
+ expected,
604
+ stage: 'uncompressed',
605
+ mimeType
606
+ });
607
+ }
608
+ return;
609
+ }
610
+ await verifyRuntimeAssetIntegrity({
611
+ asset,
612
+ bytes: runtimeBytes,
613
+ expected: {
614
+ ...expected,
615
+ uncompressedSha256: expected.sha256,
616
+ uncompressedBytes: expected.bytes ?? runtimeBytes.byteLength
617
+ },
618
+ stage: 'uncompressed',
619
+ mimeType
620
+ });
621
+ }
622
+ async normalizeLoaderResult(result, asset, signal, maxAssetBytes) {
121
623
  if (!result)
122
624
  return null;
123
625
  if (typeof result === 'string' || result instanceof URL) {
124
- return await this.fetchAsset(String(result), asset);
125
- }
126
- if (result instanceof ArrayBuffer) {
127
- const bytes = new Uint8Array(result);
128
- this.progress.update(asset, bytes.byteLength, bytes.byteLength);
129
- return { bytes };
626
+ return await this.fetchAsset(String(result), asset, signal, maxAssetBytes);
130
627
  }
131
- if (result instanceof Uint8Array) {
132
- this.progress.update(asset, result.byteLength, result.byteLength);
133
- return { bytes: result };
628
+ const directBytes = snapshotLoaderBytes(result, asset, maxAssetBytes);
629
+ if (directBytes) {
630
+ this.progress.update(asset, directBytes.byteLength, directBytes.byteLength);
631
+ return { bytes: directBytes, transferOwnership: true };
134
632
  }
135
- if (result instanceof Blob) {
136
- const bytes = new Uint8Array(await result.arrayBuffer());
633
+ const directBlob = tryCanonicalBlob(result);
634
+ const wrappedBlob = typeof result === 'object' && result !== null && 'data' in result
635
+ ? {
636
+ value: tryCanonicalBlob(result.data),
637
+ mimeType: result.mimeType
638
+ }
639
+ : undefined;
640
+ const loaderBlob = directBlob
641
+ ? { ...directBlob, mimeType: directBlob.type || undefined }
642
+ : wrappedBlob?.value
643
+ ? {
644
+ ...wrappedBlob.value,
645
+ mimeType: wrappedBlob.mimeType || wrappedBlob.value.type || undefined
646
+ }
647
+ : undefined;
648
+ if (loaderBlob) {
649
+ const { blob, size, mimeType } = loaderBlob;
650
+ requireRuntimeAssetSize(asset, size, maxAssetBytes);
651
+ const source = await readAbortableArrayBuffer(blob, signal);
652
+ const bytes = snapshotMaterializedArrayBuffer(source, asset, maxAssetBytes);
137
653
  this.progress.update(asset, bytes.byteLength, bytes.byteLength);
138
- return { bytes, mimeType: result.type || undefined };
654
+ return { bytes, mimeType, transferOwnership: true };
139
655
  }
140
656
  if ('url' in result && result.url) {
141
- return await this.fetchAsset(String(result.url), asset);
657
+ return await this.fetchAsset(String(result.url), asset, signal, maxAssetBytes);
142
658
  }
143
659
  if ('data' in result) {
144
660
  if (typeof result.data === 'string') {
145
- const bytes = encoder.encode(result.data);
661
+ requireRuntimeAssetSize(asset, boundedUtf8ByteLength(result.data, maxAssetBytes), maxAssetBytes);
662
+ const bytes = canonicalUint8Array(encoder.encode(result.data));
663
+ requireRuntimeAssetSize(asset, bytes.byteLength, maxAssetBytes);
146
664
  this.progress.update(asset, bytes.byteLength, bytes.byteLength);
147
- return { bytes, mimeType: result.mimeType };
665
+ return { bytes, mimeType: result.mimeType, transferOwnership: true };
148
666
  }
149
- if (result.data instanceof ArrayBuffer) {
150
- const bytes = new Uint8Array(result.data);
667
+ const bytes = snapshotLoaderBytes(result.data, asset, maxAssetBytes);
668
+ if (bytes) {
151
669
  this.progress.update(asset, bytes.byteLength, bytes.byteLength);
152
- return { bytes, mimeType: result.mimeType };
153
- }
154
- if (result.data instanceof Uint8Array) {
155
- this.progress.update(asset, result.data.byteLength, result.data.byteLength);
156
- return { bytes: result.data, mimeType: result.mimeType };
670
+ return {
671
+ bytes,
672
+ mimeType: result.mimeType,
673
+ transferOwnership: true
674
+ };
157
675
  }
158
- const bytes = new Uint8Array(await result.data.arrayBuffer());
159
- this.progress.update(asset, bytes.byteLength, bytes.byteLength);
160
- return { bytes, mimeType: result.mimeType || result.data.type || undefined };
161
676
  }
162
677
  return null;
163
678
  }
164
- async fetchAsset(url, asset) {
165
- const response = await fetch(url);
166
- if (!response.ok)
167
- throw new Error(`Failed to load ${asset}: ${response.status}`);
168
- const contentLength = Number(response.headers.get('content-length') || 0) || undefined;
679
+ async fetchAsset(url, asset, signal, maxAssetBytes = this.sourceAssetByteLimit(asset)) {
680
+ const requestUrl = this.requireAllowedAssetUrl(asset, url);
681
+ if (signal.aborted)
682
+ throw runtimeAssetAbortReason(signal);
683
+ const pendingResponse = Promise.resolve(fetch(requestUrl.href, {
684
+ signal,
685
+ credentials: 'omit',
686
+ redirect: 'error',
687
+ referrerPolicy: 'no-referrer'
688
+ }));
689
+ const response = await new Promise((resolve, reject) => {
690
+ let settled = false;
691
+ const onAbort = () => {
692
+ if (settled)
693
+ return;
694
+ settled = true;
695
+ signal.removeEventListener('abort', onAbort);
696
+ reject(runtimeAssetAbortReason(signal));
697
+ };
698
+ signal.addEventListener('abort', onAbort, { once: true });
699
+ void pendingResponse.then((candidate) => {
700
+ if (settled) {
701
+ const reason = runtimeAssetAbortReason(signal);
702
+ cancelResponseBody(candidate, reason);
703
+ return;
704
+ }
705
+ settled = true;
706
+ signal.removeEventListener('abort', onAbort);
707
+ resolve(candidate);
708
+ }, (error) => {
709
+ if (settled)
710
+ return;
711
+ settled = true;
712
+ signal.removeEventListener('abort', onAbort);
713
+ reject(error);
714
+ });
715
+ if (signal.aborted)
716
+ onAbort();
717
+ });
718
+ if (signal.aborted) {
719
+ const reason = runtimeAssetAbortReason(signal);
720
+ cancelResponseBody(response, reason);
721
+ throw reason;
722
+ }
723
+ if (response.url) {
724
+ let finalResponseUrl;
725
+ try {
726
+ finalResponseUrl = new URL(response.url).href;
727
+ }
728
+ catch {
729
+ const error = new Error(`Runtime asset ${asset} final response URL does not match the requested asset`);
730
+ cancelResponseBody(response, error);
731
+ throw error;
732
+ }
733
+ if (response.redirected || finalResponseUrl !== requestUrl.href) {
734
+ const error = new Error(`Runtime asset ${asset} final response URL does not match the requested asset`);
735
+ cancelResponseBody(response, error);
736
+ throw error;
737
+ }
738
+ }
739
+ if (!response.ok) {
740
+ const error = new Error(`Failed to load ${asset}: ${response.status}`);
741
+ cancelResponseBody(response, error);
742
+ throw error;
743
+ }
744
+ const originalContentLength = response.headers.get('x-wasm-idle-original-content-length');
745
+ const contentLengthHeader = originalContentLength !== null
746
+ ? 'x-wasm-idle-original-content-length'
747
+ : 'content-length';
748
+ const rawContentLength = originalContentLength ?? response.headers.get('content-length');
749
+ let contentLength;
750
+ if (rawContentLength !== null) {
751
+ const normalizedContentLength = rawContentLength.trim();
752
+ const parsedContentLength = Number(normalizedContentLength);
753
+ if (!/^\d+$/u.test(normalizedContentLength) ||
754
+ !Number.isSafeInteger(parsedContentLength)) {
755
+ const error = new ProtocolError(`Runtime asset ${asset} has an invalid ${contentLengthHeader}`, { phase: 'asset', runtimeId: this.runtime });
756
+ cancelResponseBody(response, error);
757
+ throw error;
758
+ }
759
+ contentLength = parsedContentLength;
760
+ }
761
+ if (contentLength !== undefined && contentLength > maxAssetBytes) {
762
+ const error = runtimeAssetSizeError(asset, maxAssetBytes);
763
+ cancelResponseBody(response, error);
764
+ throw error;
765
+ }
169
766
  const mimeType = response.headers.get('content-type') || undefined;
767
+ const contentEncoding = response.headers.get('content-encoding') || undefined;
170
768
  if (!response.body) {
171
- const bytes = new Uint8Array(await response.arrayBuffer());
769
+ const bytes = snapshotMaterializedArrayBuffer(await readAbortableArrayBuffer(response, signal), asset, maxAssetBytes);
172
770
  this.progress.update(asset, bytes.byteLength, contentLength ?? bytes.byteLength);
173
- return { bytes, mimeType };
771
+ return { bytes, contentEncoding, mimeType, transferOwnership: true };
174
772
  }
175
773
  const reader = response.body.getReader();
774
+ let readerCancelled = false;
775
+ if (signal.aborted) {
776
+ const reason = runtimeAssetAbortReason(signal);
777
+ readerCancelled = true;
778
+ try {
779
+ void reader.cancel(reason).catch(() => undefined);
780
+ }
781
+ catch { }
782
+ try {
783
+ reader.releaseLock();
784
+ }
785
+ catch { }
786
+ throw reason;
787
+ }
788
+ let cancelOnAbort;
789
+ const aborted = new Promise((_resolve, reject) => {
790
+ cancelOnAbort = () => {
791
+ const reason = runtimeAssetAbortReason(signal);
792
+ if (!readerCancelled) {
793
+ readerCancelled = true;
794
+ try {
795
+ void reader.cancel(reason).catch(() => undefined);
796
+ }
797
+ catch { }
798
+ }
799
+ reject(reason);
800
+ };
801
+ signal.addEventListener('abort', cancelOnAbort, { once: true });
802
+ });
176
803
  let receivedLength = 0;
177
- const chunks = [];
178
- while (true) {
179
- const { done, value } = await reader.read();
180
- if (done)
181
- break;
182
- if (!value)
183
- continue;
184
- const chunk = Uint8Array.from(value);
185
- chunks.push(chunk);
186
- receivedLength += chunk.byteLength;
187
- this.progress.update(asset, receivedLength, contentLength);
188
- }
189
- const bytes = new Uint8Array(receivedLength);
190
- let position = 0;
191
- for (const chunk of chunks) {
192
- bytes.set(chunk, position);
193
- position += chunk.byteLength;
194
- }
195
- this.progress.update(asset, receivedLength, contentLength ?? receivedLength);
196
- return { bytes, mimeType };
804
+ let bytes = new Uint8Array(Math.min(maxAssetBytes, contentLength || DEFAULT_STREAM_BUFFER_BYTES));
805
+ let loadedAsset;
806
+ let releaseError;
807
+ try {
808
+ while (true) {
809
+ if (signal.aborted)
810
+ throw runtimeAssetAbortReason(signal);
811
+ const pendingRead = reader.read();
812
+ const { done, value } = await Promise.race([pendingRead, aborted]);
813
+ if (signal.aborted)
814
+ throw runtimeAssetAbortReason(signal);
815
+ if (done)
816
+ break;
817
+ if (!value)
818
+ continue;
819
+ const chunk = canonicalUint8Array(value);
820
+ const nextLength = receivedLength + chunk.byteLength;
821
+ if (nextLength > maxAssetBytes) {
822
+ const error = runtimeAssetSizeError(asset, maxAssetBytes);
823
+ readerCancelled = true;
824
+ try {
825
+ void reader.cancel(error).catch(() => undefined);
826
+ }
827
+ catch { }
828
+ throw error;
829
+ }
830
+ if (nextLength > bytes.byteLength) {
831
+ const nextCapacity = Math.min(maxAssetBytes, Math.max(nextLength, bytes.byteLength * 2));
832
+ const grown = new Uint8Array(nextCapacity);
833
+ grown.set(bytes.subarray(0, receivedLength));
834
+ bytes = grown;
835
+ }
836
+ bytes.set(chunk, receivedLength);
837
+ receivedLength = nextLength;
838
+ this.progress.update(asset, receivedLength, contentLength);
839
+ }
840
+ if (receivedLength !== bytes.byteLength)
841
+ bytes = bytes.slice(0, receivedLength);
842
+ this.progress.update(asset, receivedLength, contentLength ?? receivedLength);
843
+ loadedAsset = { bytes, contentEncoding, mimeType, transferOwnership: true };
844
+ }
845
+ catch (error) {
846
+ if (signal.aborted) {
847
+ const reason = runtimeAssetAbortReason(signal);
848
+ if (!readerCancelled) {
849
+ readerCancelled = true;
850
+ try {
851
+ void reader.cancel(reason).catch(() => undefined);
852
+ }
853
+ catch { }
854
+ }
855
+ throw reason;
856
+ }
857
+ if (!readerCancelled) {
858
+ readerCancelled = true;
859
+ try {
860
+ void reader.cancel(error).catch(() => undefined);
861
+ }
862
+ catch { }
863
+ }
864
+ throw error;
865
+ }
866
+ finally {
867
+ if (cancelOnAbort)
868
+ signal.removeEventListener('abort', cancelOnAbort);
869
+ try {
870
+ reader.releaseLock();
871
+ }
872
+ catch (error) {
873
+ if (!signal.aborted)
874
+ releaseError = error;
875
+ }
876
+ }
877
+ if (releaseError)
878
+ throw releaseError;
879
+ return loadedAsset;
880
+ }
881
+ requireAllowedAssetUrl(asset, value) {
882
+ let url;
883
+ try {
884
+ url = new URL(value, this.config.baseUrl);
885
+ }
886
+ catch {
887
+ throw new Error(`Runtime asset ${asset} has an invalid URL`);
888
+ }
889
+ if (url.protocol !== 'https:' && url.protocol !== 'http:') {
890
+ throw new Error(`Runtime asset ${asset} uses an unsupported URL scheme: ${url.protocol}`);
891
+ }
892
+ if (url.username || url.password) {
893
+ throw new Error(`Runtime asset ${asset} URL must not include credentials`);
894
+ }
895
+ if (url.hash) {
896
+ throw new Error(`Runtime asset ${asset} URL must not include a fragment`);
897
+ }
898
+ const allowed = [this.config.baseUrl, ...(this.config.allowedBaseUrls || [])].some((baseUrl) => {
899
+ let base;
900
+ try {
901
+ base = new URL(baseUrl, url);
902
+ }
903
+ catch {
904
+ return false;
905
+ }
906
+ if (base.protocol !== 'https:' && base.protocol !== 'http:')
907
+ return false;
908
+ const basePath = base.pathname.endsWith('/') ? base.pathname : `${base.pathname}/`;
909
+ return url.origin === base.origin && url.pathname.startsWith(basePath);
910
+ });
911
+ if (!allowed) {
912
+ throw new Error(`Runtime asset ${asset} URL is outside the allowed asset bases`);
913
+ }
914
+ return url;
915
+ }
916
+ abortActiveLoads() {
917
+ const controllers = [...this.activeLoads];
918
+ this.activeLoads.clear();
919
+ for (const controller of controllers)
920
+ controller.abort();
197
921
  }
198
922
  }