@nimbus-sh/worker 0.1.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 (408) hide show
  1. package/README.md +219 -0
  2. package/dist/_shared/bytes.d.ts +18 -0
  3. package/dist/_shared/bytes.d.ts.map +1 -0
  4. package/dist/_shared/bytes.js +17 -0
  5. package/dist/_shared/cache-stats.d.ts +146 -0
  6. package/dist/_shared/cache-stats.d.ts.map +1 -0
  7. package/dist/_shared/cache-stats.js +162 -0
  8. package/dist/_shared/exports-resolver.d.ts +76 -0
  9. package/dist/_shared/exports-resolver.d.ts.map +1 -0
  10. package/dist/_shared/exports-resolver.js +284 -0
  11. package/dist/_shared/install-phase.d.ts +47 -0
  12. package/dist/_shared/install-phase.d.ts.map +1 -0
  13. package/dist/_shared/install-phase.js +1 -0
  14. package/dist/_shared/real-node-imports.d.ts +38 -0
  15. package/dist/_shared/real-node-imports.d.ts.map +1 -0
  16. package/dist/_shared/real-node-imports.js +46 -0
  17. package/dist/_shared/retry.d.ts +93 -0
  18. package/dist/_shared/retry.d.ts.map +1 -0
  19. package/dist/_shared/retry.js +161 -0
  20. package/dist/_shared/session-id.d.ts +39 -0
  21. package/dist/_shared/session-id.d.ts.map +1 -0
  22. package/dist/_shared/session-id.js +127 -0
  23. package/dist/_shared/session-router.d.ts +104 -0
  24. package/dist/_shared/session-router.d.ts.map +1 -0
  25. package/dist/_shared/session-router.js +165 -0
  26. package/dist/_shared/w7-frame.d.ts +93 -0
  27. package/dist/_shared/w7-frame.d.ts.map +1 -0
  28. package/dist/_shared/w7-frame.js +402 -0
  29. package/dist/auth/index.d.ts +16 -0
  30. package/dist/auth/index.d.ts.map +1 -0
  31. package/dist/auth/index.js +15 -0
  32. package/dist/auth/middleware.d.ts +85 -0
  33. package/dist/auth/middleware.d.ts.map +1 -0
  34. package/dist/auth/middleware.js +150 -0
  35. package/dist/auth/token.d.ts +96 -0
  36. package/dist/auth/token.d.ts.map +1 -0
  37. package/dist/auth/token.js +226 -0
  38. package/dist/auth/types.d.ts +141 -0
  39. package/dist/auth/types.d.ts.map +1 -0
  40. package/dist/auth/types.js +114 -0
  41. package/dist/bindings/d1.d.ts +102 -0
  42. package/dist/bindings/d1.d.ts.map +1 -0
  43. package/dist/bindings/d1.js +549 -0
  44. package/dist/bindings/kv.d.ts +82 -0
  45. package/dist/bindings/kv.d.ts.map +1 -0
  46. package/dist/bindings/kv.js +290 -0
  47. package/dist/bindings/r2.d.ts +137 -0
  48. package/dist/bindings/r2.d.ts.map +1 -0
  49. package/dist/bindings/r2.js +379 -0
  50. package/dist/cirrus-npm-cjs.generated.d.ts +17 -0
  51. package/dist/cirrus-npm-cjs.generated.d.ts.map +1 -0
  52. package/dist/cirrus-npm-cjs.generated.js +41 -0
  53. package/dist/cirrus-plugin-react.generated.d.ts +34 -0
  54. package/dist/cirrus-plugin-react.generated.d.ts.map +1 -0
  55. package/dist/cirrus-plugin-react.generated.js +33 -0
  56. package/dist/constants.d.ts +34 -0
  57. package/dist/constants.d.ts.map +1 -0
  58. package/dist/constants.js +116 -0
  59. package/dist/esbuild-wasm-bundle.generated.d.ts +41 -0
  60. package/dist/esbuild-wasm-bundle.generated.d.ts.map +1 -0
  61. package/dist/esbuild-wasm-bundle.generated.js +40 -0
  62. package/dist/facets/cirrus-real.d.ts +147 -0
  63. package/dist/facets/cirrus-real.d.ts.map +1 -0
  64. package/dist/facets/cirrus-real.js +981 -0
  65. package/dist/facets/inner-do-registry.d.ts +41 -0
  66. package/dist/facets/inner-do-registry.d.ts.map +1 -0
  67. package/dist/facets/inner-do-registry.js +51 -0
  68. package/dist/facets/manager.d.ts +314 -0
  69. package/dist/facets/manager.d.ts.map +1 -0
  70. package/dist/facets/manager.js +2681 -0
  71. package/dist/facets/process.d.ts +318 -0
  72. package/dist/facets/process.d.ts.map +1 -0
  73. package/dist/facets/process.js +567 -0
  74. package/dist/facets/real-vite-fs-shim.d.ts +151 -0
  75. package/dist/facets/real-vite-fs-shim.d.ts.map +1 -0
  76. package/dist/facets/real-vite-fs-shim.js +1279 -0
  77. package/dist/facets/real-vite-hmr.d.ts +142 -0
  78. package/dist/facets/real-vite-hmr.d.ts.map +1 -0
  79. package/dist/facets/real-vite-hmr.js +476 -0
  80. package/dist/facets/vite-dev-server.d.ts +293 -0
  81. package/dist/facets/vite-dev-server.d.ts.map +1 -0
  82. package/dist/facets/vite-dev-server.js +2580 -0
  83. package/dist/facets/wasm-swap-registry.d.ts +261 -0
  84. package/dist/facets/wasm-swap-registry.d.ts.map +1 -0
  85. package/dist/facets/wasm-swap-registry.js +551 -0
  86. package/dist/facets/ws-terminal.d.ts +107 -0
  87. package/dist/facets/ws-terminal.d.ts.map +1 -0
  88. package/dist/facets/ws-terminal.js +207 -0
  89. package/dist/git/commands.d.ts +13 -0
  90. package/dist/git/commands.d.ts.map +1 -0
  91. package/dist/git/commands.js +633 -0
  92. package/dist/git/network-facet.d.ts +61 -0
  93. package/dist/git/network-facet.d.ts.map +1 -0
  94. package/dist/git/network-facet.js +700 -0
  95. package/dist/git-bundle.generated.d.ts +16 -0
  96. package/dist/git-bundle.generated.d.ts.map +1 -0
  97. package/dist/git-bundle.generated.js +15 -0
  98. package/dist/index.d.ts +41 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +73 -0
  101. package/dist/loaders/child-process/spawn-facet.d.ts +90 -0
  102. package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -0
  103. package/dist/loaders/child-process/spawn-facet.js +103 -0
  104. package/dist/loaders/child-process/spawn-pool.d.ts +110 -0
  105. package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -0
  106. package/dist/loaders/child-process/spawn-pool.js +161 -0
  107. package/dist/loaders/fanout-pool.d.ts +195 -0
  108. package/dist/loaders/fanout-pool.d.ts.map +1 -0
  109. package/dist/loaders/fanout-pool.js +326 -0
  110. package/dist/loaders/generated-workers.d.ts +26 -0
  111. package/dist/loaders/generated-workers.d.ts.map +1 -0
  112. package/dist/loaders/generated-workers.js +25 -0
  113. package/dist/loaders/index.d.ts +15 -0
  114. package/dist/loaders/index.d.ts.map +1 -0
  115. package/dist/loaders/index.js +13 -0
  116. package/dist/loaders/loader-pool.d.ts +273 -0
  117. package/dist/loaders/loader-pool.d.ts.map +1 -0
  118. package/dist/loaders/loader-pool.js +624 -0
  119. package/dist/loaders/npm-resolve-preamble.d.ts +34 -0
  120. package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -0
  121. package/dist/loaders/npm-resolve-preamble.js +237 -0
  122. package/dist/loaders/pre-bundle-preamble.d.ts +41 -0
  123. package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -0
  124. package/dist/loaders/pre-bundle-preamble.js +114 -0
  125. package/dist/loaders/vendor/codegen.d.ts +24 -0
  126. package/dist/loaders/vendor/codegen.d.ts.map +1 -0
  127. package/dist/loaders/vendor/codegen.js +44 -0
  128. package/dist/loaders/vendor/errors.d.ts +24 -0
  129. package/dist/loaders/vendor/errors.d.ts.map +1 -0
  130. package/dist/loaders/vendor/errors.js +46 -0
  131. package/dist/loaders/vendor/index.d.ts +16 -0
  132. package/dist/loaders/vendor/index.d.ts.map +1 -0
  133. package/dist/loaders/vendor/index.js +11 -0
  134. package/dist/loaders/vendor/pool.d.ts +88 -0
  135. package/dist/loaders/vendor/pool.d.ts.map +1 -0
  136. package/dist/loaders/vendor/pool.js +353 -0
  137. package/dist/loaders/vendor/primitives.d.ts +11 -0
  138. package/dist/loaders/vendor/primitives.d.ts.map +1 -0
  139. package/dist/loaders/vendor/primitives.js +33 -0
  140. package/dist/loaders/vendor/serialize.d.ts +3 -0
  141. package/dist/loaders/vendor/serialize.d.ts.map +1 -0
  142. package/dist/loaders/vendor/serialize.js +25 -0
  143. package/dist/loaders/vendor/types.d.ts +60 -0
  144. package/dist/loaders/vendor/types.d.ts.map +1 -0
  145. package/dist/loaders/vendor/types.js +4 -0
  146. package/dist/npm/cache.d.ts +136 -0
  147. package/dist/npm/cache.d.ts.map +1 -0
  148. package/dist/npm/cache.js +429 -0
  149. package/dist/npm/install-batch-facet.d.ts +129 -0
  150. package/dist/npm/install-batch-facet.d.ts.map +1 -0
  151. package/dist/npm/install-batch-facet.js +598 -0
  152. package/dist/npm/install-facet.d.ts +29 -0
  153. package/dist/npm/install-facet.d.ts.map +1 -0
  154. package/dist/npm/install-facet.js +9 -0
  155. package/dist/npm/installer.d.ts +239 -0
  156. package/dist/npm/installer.d.ts.map +1 -0
  157. package/dist/npm/installer.js +2022 -0
  158. package/dist/npm/npx-install.d.ts +74 -0
  159. package/dist/npm/npx-install.d.ts.map +1 -0
  160. package/dist/npm/npx-install.js +302 -0
  161. package/dist/npm/pre-bundle-facet.d.ts +168 -0
  162. package/dist/npm/pre-bundle-facet.d.ts.map +1 -0
  163. package/dist/npm/pre-bundle-facet.js +653 -0
  164. package/dist/npm/r2-cache.d.ts +286 -0
  165. package/dist/npm/r2-cache.d.ts.map +1 -0
  166. package/dist/npm/r2-cache.js +506 -0
  167. package/dist/npm/resolve-facet.d.ts +202 -0
  168. package/dist/npm/resolve-facet.d.ts.map +1 -0
  169. package/dist/npm/resolve-facet.js +833 -0
  170. package/dist/npm/resolve-one-facet.d.ts +204 -0
  171. package/dist/npm/resolve-one-facet.d.ts.map +1 -0
  172. package/dist/npm/resolve-one-facet.js +437 -0
  173. package/dist/npm/resolver.d.ts +109 -0
  174. package/dist/npm/resolver.d.ts.map +1 -0
  175. package/dist/npm/resolver.js +899 -0
  176. package/dist/npm/tarball-stream.d.ts +85 -0
  177. package/dist/npm/tarball-stream.d.ts.map +1 -0
  178. package/dist/npm/tarball-stream.js +205 -0
  179. package/dist/npm/tarball.d.ts +51 -0
  180. package/dist/npm/tarball.d.ts.map +1 -0
  181. package/dist/npm/tarball.js +185 -0
  182. package/dist/observability/diag-counters.d.ts +292 -0
  183. package/dist/observability/diag-counters.d.ts.map +1 -0
  184. package/dist/observability/diag-counters.js +302 -0
  185. package/dist/observability/heap-estimate.d.ts +166 -0
  186. package/dist/observability/heap-estimate.d.ts.map +1 -0
  187. package/dist/observability/heap-estimate.js +192 -0
  188. package/dist/observability/heavy-alloc-coord.d.ts +95 -0
  189. package/dist/observability/heavy-alloc-coord.d.ts.map +1 -0
  190. package/dist/observability/heavy-alloc-coord.js +149 -0
  191. package/dist/observability/oom-classify.d.ts +56 -0
  192. package/dist/observability/oom-classify.d.ts.map +1 -0
  193. package/dist/observability/oom-classify.js +118 -0
  194. package/dist/observability/oom-discriminator.d.ts +192 -0
  195. package/dist/observability/oom-discriminator.d.ts.map +1 -0
  196. package/dist/observability/oom-discriminator.js +233 -0
  197. package/dist/real-vite-bundle.generated.d.ts +46 -0
  198. package/dist/real-vite-bundle.generated.d.ts.map +1 -0
  199. package/dist/real-vite-bundle.generated.js +53 -0
  200. package/dist/replica/routing.d.ts +171 -0
  201. package/dist/replica/routing.d.ts.map +1 -0
  202. package/dist/replica/routing.js +288 -0
  203. package/dist/replica/suspension.d.ts +36 -0
  204. package/dist/replica/suspension.d.ts.map +1 -0
  205. package/dist/replica/suspension.js +49 -0
  206. package/dist/router/index.d.ts +156 -0
  207. package/dist/router/index.d.ts.map +1 -0
  208. package/dist/router/index.js +220 -0
  209. package/dist/runtime/assets-loader.d.ts +71 -0
  210. package/dist/runtime/assets-loader.d.ts.map +1 -0
  211. package/dist/runtime/assets-loader.js +128 -0
  212. package/dist/runtime/barrel-detect.d.ts +46 -0
  213. package/dist/runtime/barrel-detect.d.ts.map +1 -0
  214. package/dist/runtime/barrel-detect.js +73 -0
  215. package/dist/runtime/barrel-synthesizer.d.ts +181 -0
  216. package/dist/runtime/barrel-synthesizer.d.ts.map +1 -0
  217. package/dist/runtime/barrel-synthesizer.js +541 -0
  218. package/dist/runtime/bun-repl.d.ts +46 -0
  219. package/dist/runtime/bun-repl.d.ts.map +1 -0
  220. package/dist/runtime/bun-repl.js +326 -0
  221. package/dist/runtime/bun-runner.d.ts +66 -0
  222. package/dist/runtime/bun-runner.d.ts.map +1 -0
  223. package/dist/runtime/bun-runner.js +219 -0
  224. package/dist/runtime/clang-runner.d.ts +38 -0
  225. package/dist/runtime/clang-runner.d.ts.map +1 -0
  226. package/dist/runtime/clang-runner.js +1033 -0
  227. package/dist/runtime/comment-strip.d.ts +37 -0
  228. package/dist/runtime/comment-strip.d.ts.map +1 -0
  229. package/dist/runtime/comment-strip.js +74 -0
  230. package/dist/runtime/esbuild-service.d.ts +201 -0
  231. package/dist/runtime/esbuild-service.d.ts.map +1 -0
  232. package/dist/runtime/esbuild-service.js +1444 -0
  233. package/dist/runtime/esbuild-wasm-bytes.d.ts +87 -0
  234. package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -0
  235. package/dist/runtime/esbuild-wasm-bytes.js +131 -0
  236. package/dist/runtime/framework-detect.d.ts +71 -0
  237. package/dist/runtime/framework-detect.d.ts.map +1 -0
  238. package/dist/runtime/framework-detect.js +178 -0
  239. package/dist/runtime/long-running-handle.d.ts +133 -0
  240. package/dist/runtime/long-running-handle.d.ts.map +1 -0
  241. package/dist/runtime/long-running-handle.js +192 -0
  242. package/dist/runtime/node-repl.d.ts +36 -0
  243. package/dist/runtime/node-repl.d.ts.map +1 -0
  244. package/dist/runtime/node-repl.js +293 -0
  245. package/dist/runtime/node-runner.d.ts +111 -0
  246. package/dist/runtime/node-runner.d.ts.map +1 -0
  247. package/dist/runtime/node-runner.js +194 -0
  248. package/dist/runtime/node-shims.d.ts +24 -0
  249. package/dist/runtime/node-shims.d.ts.map +1 -0
  250. package/dist/runtime/node-shims.js +3019 -0
  251. package/dist/runtime/package-manager.d.ts +118 -0
  252. package/dist/runtime/package-manager.d.ts.map +1 -0
  253. package/dist/runtime/package-manager.js +420 -0
  254. package/dist/runtime/port-registry.d.ts +80 -0
  255. package/dist/runtime/port-registry.d.ts.map +1 -0
  256. package/dist/runtime/port-registry.js +166 -0
  257. package/dist/runtime/process-logs-api.d.ts +102 -0
  258. package/dist/runtime/process-logs-api.d.ts.map +1 -0
  259. package/dist/runtime/process-logs-api.js +253 -0
  260. package/dist/runtime/process-logs.d.ts +311 -0
  261. package/dist/runtime/process-logs.d.ts.map +1 -0
  262. package/dist/runtime/process-logs.js +656 -0
  263. package/dist/runtime/process-table.d.ts +65 -0
  264. package/dist/runtime/process-table.d.ts.map +1 -0
  265. package/dist/runtime/process-table.js +107 -0
  266. package/dist/runtime/project-detect.d.ts +21 -0
  267. package/dist/runtime/project-detect.d.ts.map +1 -0
  268. package/dist/runtime/project-detect.js +46 -0
  269. package/dist/runtime/python-repl.d.ts +66 -0
  270. package/dist/runtime/python-repl.d.ts.map +1 -0
  271. package/dist/runtime/python-repl.js +563 -0
  272. package/dist/runtime/python-runner.d.ts +50 -0
  273. package/dist/runtime/python-runner.d.ts.map +1 -0
  274. package/dist/runtime/python-runner.js +870 -0
  275. package/dist/runtime/repl-session.d.ts +160 -0
  276. package/dist/runtime/repl-session.d.ts.map +1 -0
  277. package/dist/runtime/repl-session.js +393 -0
  278. package/dist/runtime/require-resolver.d.ts +52 -0
  279. package/dist/runtime/require-resolver.d.ts.map +1 -0
  280. package/dist/runtime/require-resolver.js +690 -0
  281. package/dist/runtime/router-basename.d.ts +36 -0
  282. package/dist/runtime/router-basename.d.ts.map +1 -0
  283. package/dist/runtime/router-basename.js +310 -0
  284. package/dist/runtime/ruby-repl.d.ts +43 -0
  285. package/dist/runtime/ruby-repl.d.ts.map +1 -0
  286. package/dist/runtime/ruby-repl.js +229 -0
  287. package/dist/runtime/ruby-runner.d.ts +62 -0
  288. package/dist/runtime/ruby-runner.d.ts.map +1 -0
  289. package/dist/runtime/ruby-runner.js +737 -0
  290. package/dist/runtime/runtime-catalog.d.ts +99 -0
  291. package/dist/runtime/runtime-catalog.d.ts.map +1 -0
  292. package/dist/runtime/runtime-catalog.js +183 -0
  293. package/dist/runtime/runtime-registry.d.ts +136 -0
  294. package/dist/runtime/runtime-registry.d.ts.map +1 -0
  295. package/dist/runtime/runtime-registry.js +318 -0
  296. package/dist/runtime/streams.d.ts +13 -0
  297. package/dist/runtime/streams.d.ts.map +1 -0
  298. package/dist/runtime/streams.js +402 -0
  299. package/dist/runtime/wasi-instance.d.ts +190 -0
  300. package/dist/runtime/wasi-instance.d.ts.map +1 -0
  301. package/dist/runtime/wasi-instance.js +2044 -0
  302. package/dist/runtime/wasm-runner.d.ts +117 -0
  303. package/dist/runtime/wasm-runner.d.ts.map +1 -0
  304. package/dist/runtime/wasm-runner.js +705 -0
  305. package/dist/session/bindings.d.ts +168 -0
  306. package/dist/session/bindings.d.ts.map +1 -0
  307. package/dist/session/bindings.js +524 -0
  308. package/dist/session/ctx-exports.d.ts +16 -0
  309. package/dist/session/ctx-exports.d.ts.map +1 -0
  310. package/dist/session/ctx-exports.js +22 -0
  311. package/dist/session/diag.d.ts +62 -0
  312. package/dist/session/diag.d.ts.map +1 -0
  313. package/dist/session/diag.js +118 -0
  314. package/dist/session/fs-watch.d.ts +132 -0
  315. package/dist/session/fs-watch.d.ts.map +1 -0
  316. package/dist/session/fs-watch.js +255 -0
  317. package/dist/session/helpers.d.ts +150 -0
  318. package/dist/session/helpers.d.ts.map +1 -0
  319. package/dist/session/helpers.js +472 -0
  320. package/dist/session/hibernation.d.ts +145 -0
  321. package/dist/session/hibernation.d.ts.map +1 -0
  322. package/dist/session/hibernation.js +385 -0
  323. package/dist/session/init-phases.d.ts +87 -0
  324. package/dist/session/init-phases.d.ts.map +1 -0
  325. package/dist/session/init-phases.js +137 -0
  326. package/dist/session/init.d.ts +46 -0
  327. package/dist/session/init.d.ts.map +1 -0
  328. package/dist/session/init.js +3579 -0
  329. package/dist/session/keys.d.ts +56 -0
  330. package/dist/session/keys.d.ts.map +1 -0
  331. package/dist/session/keys.js +55 -0
  332. package/dist/session/nimbus-session.d.ts +434 -0
  333. package/dist/session/nimbus-session.d.ts.map +1 -0
  334. package/dist/session/nimbus-session.js +1084 -0
  335. package/dist/session/programmatic.d.ts +105 -0
  336. package/dist/session/programmatic.d.ts.map +1 -0
  337. package/dist/session/programmatic.js +326 -0
  338. package/dist/session/replica-routes.d.ts +68 -0
  339. package/dist/session/replica-routes.d.ts.map +1 -0
  340. package/dist/session/replica-routes.js +77 -0
  341. package/dist/session/routes.d.ts +29 -0
  342. package/dist/session/routes.d.ts.map +1 -0
  343. package/dist/session/routes.js +1331 -0
  344. package/dist/session/rpc.d.ts +323 -0
  345. package/dist/session/rpc.d.ts.map +1 -0
  346. package/dist/session/rpc.js +808 -0
  347. package/dist/session/state-store.d.ts +210 -0
  348. package/dist/session/state-store.d.ts.map +1 -0
  349. package/dist/session/state-store.js +459 -0
  350. package/dist/session/supervisor-rpc.d.ts +269 -0
  351. package/dist/session/supervisor-rpc.d.ts.map +1 -0
  352. package/dist/session/supervisor-rpc.js +437 -0
  353. package/dist/session/ws-hibernation-config.d.ts +64 -0
  354. package/dist/session/ws-hibernation-config.d.ts.map +1 -0
  355. package/dist/session/ws-hibernation-config.js +89 -0
  356. package/dist/session/ws.d.ts +95 -0
  357. package/dist/session/ws.d.ts.map +1 -0
  358. package/dist/session/ws.js +395 -0
  359. package/dist/shell/features.d.ts +410 -0
  360. package/dist/shell/features.d.ts.map +1 -0
  361. package/dist/shell/features.js +1885 -0
  362. package/dist/shell/unix-commands.d.ts +15 -0
  363. package/dist/shell/unix-commands.d.ts.map +1 -0
  364. package/dist/shell/unix-commands.js +3703 -0
  365. package/dist/stubs/lifo-ui.d.ts +10 -0
  366. package/dist/stubs/lifo-ui.d.ts.map +1 -0
  367. package/dist/stubs/lifo-ui.js +1 -0
  368. package/dist/tailwind-play.generated.d.ts +19 -0
  369. package/dist/tailwind-play.generated.d.ts.map +1 -0
  370. package/dist/tailwind-play.generated.js +18 -0
  371. package/dist/vfs/dev-provider.d.ts +64 -0
  372. package/dist/vfs/dev-provider.d.ts.map +1 -0
  373. package/dist/vfs/dev-provider.js +191 -0
  374. package/dist/vfs/events.d.ts +51 -0
  375. package/dist/vfs/events.d.ts.map +1 -0
  376. package/dist/vfs/events.js +127 -0
  377. package/dist/vfs/path.d.ts +30 -0
  378. package/dist/vfs/path.d.ts.map +1 -0
  379. package/dist/vfs/path.js +41 -0
  380. package/dist/vfs/seed-project.d.ts +62 -0
  381. package/dist/vfs/seed-project.d.ts.map +1 -0
  382. package/dist/vfs/seed-project.js +1045 -0
  383. package/dist/vfs/sqlite-vfs.d.ts +435 -0
  384. package/dist/vfs/sqlite-vfs.d.ts.map +1 -0
  385. package/dist/vfs/sqlite-vfs.js +1670 -0
  386. package/dist/vfs/symlink-registry.d.ts +64 -0
  387. package/dist/vfs/symlink-registry.d.ts.map +1 -0
  388. package/dist/vfs/symlink-registry.js +137 -0
  389. package/dist/wrangler/nimbus-wrangler.d.ts +157 -0
  390. package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -0
  391. package/dist/wrangler/nimbus-wrangler.js +931 -0
  392. package/package.json +77 -0
  393. package/public/_assets/cirrus-plugin-react.bundle.js +70740 -0
  394. package/public/_assets/esbuild-0.24.2.wasm +0 -0
  395. package/public/_assets/real-vite-bundle.js +101478 -0
  396. package/public/_assets/rollup.wasm +0 -0
  397. package/public/favicon.svg +8 -0
  398. package/public/index.html +565 -0
  399. package/public/s/index.html +2379 -0
  400. package/scripts/bundle-esbuild-wasm.mjs +244 -0
  401. package/scripts/bundle-facet-workers.mjs +137 -0
  402. package/scripts/bundle-git.mjs +118 -0
  403. package/scripts/bundle-npm-cjs.mjs +363 -0
  404. package/scripts/bundle-plugin-react.mjs +480 -0
  405. package/scripts/bundle-real-vite.mjs +959 -0
  406. package/scripts/bundle-runtime.mjs +600 -0
  407. package/scripts/bundle-tailwind-play.mjs +130 -0
  408. package/scripts/patch-lifo-ui.mjs +131 -0
@@ -0,0 +1,705 @@
1
+ /**
2
+ * wasm-runner.ts — native-WASM runner via the LOADER-modules transport.
3
+ *
4
+ * Re-introduced after the multi-runtime wave's revert. The previous
5
+ * version relied on direct `WebAssembly.instantiate(bytes)` at request
6
+ * time — workerd's CSP blocks that path inside both the supervisor
7
+ * and facet isolates (verified in the multi-runtime feasibility
8
+ * memo). The new version routes through the LOADER's modules map:
9
+ * bytes ride INSIDE the worker code blob, workerd compiles them
10
+ * during the inner worker's MODULE-LOAD phase (the one phase where
11
+ * wasm code generation IS allowed), and the resulting
12
+ * WebAssembly.Module is exposed to the user fn via the
13
+ * NimbusLoaderPool's `globalThis.__NIMBUS_WASM[<name>]` table.
14
+ *
15
+ * The validation that this works on the deployed Cloudflare fleet
16
+ * lives at /workspace/.seal-internal/2026-05-10-wasm-csp/findings.md
17
+ * (`add(3,4) === 7` returned in 11ms warm, 113ms cold).
18
+ *
19
+ * Shell command shape
20
+ * ───────────────────
21
+ *
22
+ * wasm-runner --version
23
+ * wasm-runner <file.wasm> <exportName> [int args...]
24
+ *
25
+ * Each invocation:
26
+ * 1. Reads bytes from VFS (or any caller-supplied source).
27
+ * 2. Allocates a PID via processTable (Process tab integration).
28
+ * 3. NimbusLoaderPool.submit() with wasmModules: { 'user.wasm': bytes }
29
+ * — pool merges per-call wasm with constructor-time entries,
30
+ * generates a worker.js that imports './user.wasm', and ships
31
+ * the modules map to env.LOADER.get(...).
32
+ * 4. The submitted fn runs inside the inner facet:
33
+ * - reads globalThis.__NIMBUS_WASM['user.wasm'] (the precompiled
34
+ * Module the pool registered)
35
+ * - WebAssembly.instantiate(module, {}) — allowed because the
36
+ * Module is precompiled
37
+ * - looks up the export, calls with parsed integer args, returns
38
+ * the result + the export list
39
+ * 5. Supervisor formats and writes stdout/stderr; exit code 0/1.
40
+ *
41
+ * Limitations (documented in --help):
42
+ * - Function args are integers only (parseInt). Float / string /
43
+ * multi-arg-shapes need a wrapper module.
44
+ * - Only WebAssembly.Memory and integer return values are surfaced.
45
+ * - WASI imports are NOT provided. Modules expecting wasi_snapshot
46
+ * won't instantiate (fail at the in-facet instantiate step).
47
+ *
48
+ * Anti-requirements
49
+ * ─────────────────
50
+ * - NO setTimeout / NO retry / NO defensive-catch in the dispatch
51
+ * path. The pool's resilience options handle retries.
52
+ * - The try/catch around vfs.readFile is a legitimate I/O boundary;
53
+ * the diagnostic propagates as exitCode 1 + stderr line.
54
+ * - NO direct WebAssembly.instantiate(bytes) at request time —
55
+ * that's the architectural mistake from the prior wave.
56
+ */
57
+ import { WASI_INSTANCE_PREAMBLE_SRC, WASI_WAVE1_FNS } from './wasi-instance.js';
58
+ export const WASM_RUNNER_VERSION = '0.3.0';
59
+ export const WASM_RUNNER_HELP = 'Usage: wasm-runner [options] <file.wasm> [exportName] [int args...]\n' +
60
+ ' wasm-runner --version\n' +
61
+ ' wasm-runner --wasi-info\n' +
62
+ '\n' +
63
+ 'Loads a .wasm module and runs it. Two modes auto-detected from the\n' +
64
+ 'module\'s imports:\n' +
65
+ '\n' +
66
+ ' WASI mode (imports wasi_snapshot_preview1): invokes _start with a\n' +
67
+ ' Wave-1 WASI shim. stdout/stderr stream to the Process tab.\n' +
68
+ ' exportName argument is optional; defaults to _start.\n' +
69
+ ' Direct mode (no WASI imports): calls the named export with integer\n' +
70
+ ' args and prints the return value.\n' +
71
+ '\n' +
72
+ 'Examples:\n' +
73
+ ' wasm-runner ./hello.wasm # WASI, runs _start\n' +
74
+ ' wasm-runner ./hello.wasm a b c # WASI, args [a,b,c]\n' +
75
+ ' wasm-runner ./add.wasm add 3 4 # direct, → 7\n' +
76
+ ' wasm-runner ./fib.wasm fib 10 # direct, → 55\n' +
77
+ '\n' +
78
+ 'Limitations (direct mode):\n' +
79
+ ' - Function args are integers only (parseInt). Float / string /\n' +
80
+ ' multi-arg-shapes need a wrapper module.\n' +
81
+ ' - Only integer return values are surfaced.\n' +
82
+ '\n' +
83
+ 'Limitations (WASI mode, Wave-1):\n' +
84
+ ' - 16 fns implemented: ' + WASI_WAVE1_FNS.join(', ') + '.\n' +
85
+ ' - path_*, fd_readdir, fd_filestat_*, fd_pread, fd_pwrite, poll_oneoff,\n' +
86
+ ' sock_* return ENOSYS (Wave-2 will add SqliteFS-backed paths).\n' +
87
+ ' - fd 0 (stdin) returns EOF immediately.\n' +
88
+ ' - Transport: bytes ship via the LOADER modules map, NOT\n' +
89
+ ' WebAssembly.instantiate(bytes) at request time (CSP-blocked).';
90
+ /**
91
+ * Cheap supervisor-side WASI-detect: scan the wasm import section
92
+ * header bytes for the literal `wasi_snapshot_preview1` module name.
93
+ * No full parser — we just walk the import section and check the
94
+ * module-name string of each entry. False positives are not possible
95
+ * because import-section module names are length-prefixed UTF-8
96
+ * blocks; a substring match against the raw bytes is sufficient
97
+ * (the literal "wasi_snapshot_preview1" doesn't appear inside any
98
+ * other section's well-formed payload at the import position).
99
+ *
100
+ * This avoids `WebAssembly.Module.imports(mod)` which can only run
101
+ * inside a context that holds a precompiled Module — we don't yet
102
+ * have one in the supervisor (CSP blocks request-time compile).
103
+ */
104
+ function hasWasiImports(bytes) {
105
+ // Recognise BOTH 'wasi_snapshot_preview1' (modern) AND
106
+ // 'wasi_unstable' (older WASI ABI, binji-linked binaries use this).
107
+ // Either substring in the wasm bytes is sufficient — WASI module-
108
+ // name strings are length-prefixed UTF-8 in the import section; a
109
+ // substring match against the raw bytes can't false-positive at the
110
+ // import position. False-positives elsewhere (e.g. in a data
111
+ // section that happens to contain "wasi_unstable" as a string
112
+ // literal) are harmless — the WASI shim won't be invoked unless
113
+ // the wasm actually has `_start` and the imports the shim provides.
114
+ const enc = new TextEncoder();
115
+ const needles = [
116
+ enc.encode('wasi_snapshot_preview1'),
117
+ enc.encode('wasi_unstable'),
118
+ ];
119
+ for (const needle of needles) {
120
+ if (bytes.length < needle.length)
121
+ continue;
122
+ outer: for (let i = 0; i <= bytes.length - needle.length; i++) {
123
+ for (let j = 0; j < needle.length; j++) {
124
+ if (bytes[i + j] !== needle[j])
125
+ continue outer;
126
+ }
127
+ return true;
128
+ }
129
+ }
130
+ return false;
131
+ }
132
+ /**
133
+ * Convert a Uint8Array to a base64 string. Used to encode VFS file
134
+ * contents into the JSON-serializable `context` field of the loader
135
+ * pool. Workerd's btoa is the standard one; we use it directly rather
136
+ * than depending on Node's Buffer (which works in workerd via the
137
+ * nodejs_compat polyfill but adds an import dependency).
138
+ */
139
+ function bytesToB64(bytes) {
140
+ let s = '';
141
+ for (let i = 0; i < bytes.length; i++)
142
+ s += String.fromCharCode(bytes[i]);
143
+ return btoa(s);
144
+ }
145
+ function b64ToBytes(b64) {
146
+ const bin = atob(b64);
147
+ const out = new Uint8Array(bin.length);
148
+ for (let i = 0; i < bin.length; i++)
149
+ out[i] = bin.charCodeAt(i);
150
+ return out;
151
+ }
152
+ /**
153
+ * Snapshot a VFS subtree rooted at `vfsRoot` into a JSON-serializable
154
+ * `WasiFsSnapshot`. Used by the WASI runner to ship the user's session
155
+ * filesystem into the facet isolate.
156
+ *
157
+ * Bounded by:
158
+ * - 32 MiB total bytes (hard cap — bigger sessions need a per-call
159
+ * RPC dispatch architecture; defer to Wave-3).
160
+ * - 5000 file count.
161
+ *
162
+ * Returns null + a diagnostic if bounds are exceeded so the caller
163
+ * can surface a clear error to the user.
164
+ */
165
+ function snapshotVfs(vfs, vfsRoot) {
166
+ const MAX_BYTES = 32 * 1024 * 1024;
167
+ const MAX_FILES = 5000;
168
+ const root = vfsRoot.replace(/^\/+/, '').replace(/\/+$/, '');
169
+ const files = {};
170
+ const dirs = [];
171
+ let totalBytes = 0;
172
+ let fileCount = 0;
173
+ const stack = [root];
174
+ if (!vfs.exists(root)) {
175
+ return { snapshot: { root, preopens: [], files: {}, dirs: [root] }, bytes: 0, files: 0 };
176
+ }
177
+ dirs.push(root);
178
+ // Directory prefixes to skip during snapshot. The user's `~/.nimbus`
179
+ // install root holds nimbus-managed runtime bundles (clang.wasm,
180
+ // lld.wasm, sysroot.tar, Pyodide, …) that easily exceed the
181
+ // 32 MiB per-snapshot cap and don't belong in the WASI sandbox
182
+ // anyway. node_modules is similar — large, irrelevant to user
183
+ // wasm execution.
184
+ const skipSubdirs = new Set(['.nimbus', 'node_modules', '.cache', '.npm']);
185
+ while (stack.length > 0) {
186
+ const dir = stack.pop();
187
+ let entries;
188
+ try {
189
+ entries = vfs.readdir(dir);
190
+ }
191
+ catch {
192
+ continue;
193
+ }
194
+ for (const e of entries) {
195
+ const childPath = dir + '/' + e.name;
196
+ if (e.type === 'directory') {
197
+ // Skip well-known large/irrelevant subdirs.
198
+ if (skipSubdirs.has(e.name))
199
+ continue;
200
+ dirs.push(childPath);
201
+ stack.push(childPath);
202
+ continue;
203
+ }
204
+ let bytes;
205
+ try {
206
+ bytes = vfs.readFile(childPath);
207
+ }
208
+ catch {
209
+ continue;
210
+ }
211
+ totalBytes += bytes.length;
212
+ fileCount++;
213
+ if (totalBytes > MAX_BYTES) {
214
+ return { error: `WASI snapshot exceeded 32 MiB cap (current dir: ${dir})` };
215
+ }
216
+ if (fileCount > MAX_FILES) {
217
+ return { error: `WASI snapshot exceeded 5000 file cap` };
218
+ }
219
+ files[childPath] = bytesToB64(bytes);
220
+ }
221
+ }
222
+ return {
223
+ snapshot: { root, preopens: [], files, dirs },
224
+ bytes: totalBytes,
225
+ files: fileCount,
226
+ };
227
+ }
228
+ /**
229
+ * Apply a WasiFsDiff produced by the facet back into the supervisor's
230
+ * SqliteFS. Each operation is independent; failures on one path don't
231
+ * abort the rest (we log to stderr and continue).
232
+ */
233
+ function flushVfsDiff(vfs, diff) {
234
+ let written = 0, deleted = 0, mkdirs = 0, rmdirs = 0;
235
+ let timesTouched = 0, symlinks = 0;
236
+ for (const path of diff.dirsCreated) {
237
+ try {
238
+ vfs.mkdir(path, { recursive: true });
239
+ mkdirs++;
240
+ }
241
+ catch { }
242
+ }
243
+ for (const [path, b64] of Object.entries(diff.filesWritten)) {
244
+ try {
245
+ const bytes = b64ToBytes(b64);
246
+ // ensure parent dirs exist
247
+ const lastSlash = path.lastIndexOf('/');
248
+ if (lastSlash > 0) {
249
+ const parent = path.substring(0, lastSlash);
250
+ try {
251
+ vfs.mkdir(parent, { recursive: true });
252
+ }
253
+ catch { }
254
+ }
255
+ vfs.writeFile(path, bytes);
256
+ written++;
257
+ }
258
+ catch { }
259
+ }
260
+ for (const path of diff.filesDeleted) {
261
+ try {
262
+ vfs.unlink(path);
263
+ deleted++;
264
+ }
265
+ catch { }
266
+ }
267
+ for (const path of diff.dirsDeleted) {
268
+ try {
269
+ vfs.rmdir(path);
270
+ rmdirs++;
271
+ }
272
+ catch { }
273
+ }
274
+ // Stream-B B1+B3: count timesChanged / symlinks for diagnostics. The
275
+ // current SqliteVFS doesn't expose utime() or symlink() on its public
276
+ // surface, so we don't persist these across calls — they live only
277
+ // within the call (mtimes are read back correctly via stat→filestat_get
278
+ // before the snapshot returns). This is a documented v1 limitation.
279
+ if (diff.timesChanged) {
280
+ timesTouched = Object.keys(diff.timesChanged).length;
281
+ // Future hook: when SqliteVFS gains a utime() method, call it here:
282
+ // for (const [path, t] of Object.entries(diff.timesChanged)) {
283
+ // try { vfs.utime(path, Number(t.atime) / 1e9, Number(t.mtime) / 1e9); } catch {}
284
+ // }
285
+ }
286
+ if (diff.symlinksCreated) {
287
+ symlinks = Object.keys(diff.symlinksCreated).length;
288
+ // Future hook: when SqliteVFS gains a symlink() method, call it here.
289
+ }
290
+ return { written, deleted, mkdirs, rmdirs, timesTouched, symlinks };
291
+ }
292
+ /**
293
+ * Build a `run` function suitable for RuntimeSpec.run(). Parameterised
294
+ * over the VFS, env (for env.LOADER), ctx (for the pool's doId-scoped
295
+ * cache key), and processTable + processLogs (for `ps` / `logs <pid>` /
296
+ * Process tab integration). Returns a fn that matches the runtime-
297
+ * registry's contract.
298
+ */
299
+ export function makeWasmRunner(deps) {
300
+ return async function runWasm(_facetMgr, _code, opts) {
301
+ // opts.filename is the resolved .wasm path (absolute, /-prefixed
302
+ // by the registry's bypassesScriptRead path).
303
+ // opts.argv is:
304
+ // WASI mode: [<extra-args-to-program>...] (or empty)
305
+ // direct mode: [exportName, intArg1, intArg2, ...]
306
+ const wasmPath = (opts.filename || '').replace(/^\/+/, '');
307
+ const argv = opts.argv || [];
308
+ if (!deps.vfs.exists(wasmPath)) {
309
+ return {
310
+ exitCode: 1,
311
+ stdout: '',
312
+ stderr: `wasm-runner: cannot find module '${opts.filename}'\n`,
313
+ };
314
+ }
315
+ let bytes;
316
+ try {
317
+ bytes = deps.vfs.readFile(wasmPath);
318
+ }
319
+ catch (e) {
320
+ return {
321
+ exitCode: 1,
322
+ stdout: '',
323
+ stderr: `wasm-runner: cannot read '${opts.filename}': ${e?.message || e}\n`,
324
+ };
325
+ }
326
+ // Detect WASI imports BEFORE parsing argv as direct-mode integers.
327
+ // WASI mode treats every argv token as a string passed to the
328
+ // program; direct mode treats argv[0] as export name and the rest
329
+ // as integers.
330
+ const isWasi = hasWasiImports(bytes);
331
+ let exportName;
332
+ let parsedArgs = [];
333
+ let wasiArgv = [];
334
+ if (isWasi) {
335
+ // WASI argv convention: argv[0] is the program name. Use the
336
+ // module's filename (without leading slashes) so getopt-style
337
+ // libraries see something sensible.
338
+ const progName = (opts.filename || 'wasm').replace(/^\/+/, '').split('/').pop() || 'wasm';
339
+ wasiArgv = [progName, ...argv];
340
+ // Allow the user to pass `wasm-runner file.wasm _start` as a
341
+ // hint that they really want the _start entry (matches the
342
+ // existing direct-mode invocation shape so probes can be the
343
+ // same). _start is the default for WASI anyway.
344
+ if (argv.length > 0 && argv[0] === '_start') {
345
+ wasiArgv = [progName, ...argv.slice(1)];
346
+ }
347
+ }
348
+ else {
349
+ exportName = argv[0];
350
+ const intArgs = argv.slice(1);
351
+ if (!exportName) {
352
+ return {
353
+ exitCode: 1,
354
+ stdout: '',
355
+ stderr: 'wasm-runner: missing export name\n' +
356
+ `Usage: wasm-runner ${opts.filename} <exportName> [int args...]\n`,
357
+ };
358
+ }
359
+ // Parse integer args. Non-integer values are reported as a clear
360
+ // diagnostic rather than silently coerced (Number() would map
361
+ // 'foo' → NaN which the wasm fn would treat as 0 — confusing).
362
+ for (let i = 0; i < intArgs.length; i++) {
363
+ const n = parseInt(intArgs[i], 10);
364
+ if (!Number.isFinite(n)) {
365
+ return {
366
+ exitCode: 1,
367
+ stdout: '',
368
+ stderr: `wasm-runner: argument ${i + 1} ('${intArgs[i]}') is not an integer\n`,
369
+ };
370
+ }
371
+ parsedArgs.push(n);
372
+ }
373
+ }
374
+ // Convert Uint8Array (SqliteVFS native) into ArrayBuffer.
375
+ // structuredClone-safe ArrayBuffer is required by the pool's
376
+ // wasmModules contract; sub-views aren't accepted by workerd's
377
+ // modules map either. The slice() call always returns a fresh
378
+ // ArrayBuffer regardless of whether bytes.buffer was originally
379
+ // a Shared variant — TS's overload-resolution narrowing here is
380
+ // overly conservative; cast to ArrayBuffer is correct.
381
+ const buf = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
382
+ // Load the pool lazily — its constructor reaches into env.LOADER
383
+ // which we may not have at every wasm-runner construction site
384
+ // (e.g. unit tests that mock the registry). Lazy import keeps
385
+ // module load cheap.
386
+ const { NimbusLoaderPool } = await import('../loaders/loader-pool.js');
387
+ const pool = new NimbusLoaderPool(deps.env, deps.ctx, {
388
+ tag: isWasi ? 'wasm-runner-wasi' : 'wasm-runner',
389
+ concurrency: 1,
390
+ // No SUPERVISOR binding required for compute-only workloads,
391
+ // and omitting it keeps the bindings table minimal so the
392
+ // facet isolate boots fast.
393
+ omitSupervisor: true,
394
+ // WASI mode: ship the WASI shim source as a module-init preamble
395
+ // so `__wasiMakeImports` is in scope when the facet fn runs.
396
+ // Direct mode: no preamble (saves a few KB per submit).
397
+ preamble: isWasi ? WASI_INSTANCE_PREAMBLE_SRC : undefined,
398
+ });
399
+ const facetFn = async function wasmFacetCall(args) {
400
+ const wasmTable = globalThis.__NIMBUS_WASM || {};
401
+ const mod = wasmTable['user.wasm'];
402
+ if (!mod) {
403
+ return {
404
+ ok: false,
405
+ mode: args.mode,
406
+ error: 'globalThis.__NIMBUS_WASM[\'user.wasm\'] not found — the pool ' +
407
+ 'did not register the module. Internal error.',
408
+ };
409
+ }
410
+ // ── WASI mode ──
411
+ if (args.mode === 'wasi') {
412
+ const mk = __wasiMakeImports;
413
+ const runStart = __wasiRunStart;
414
+ // Stream-B P3 / prod-verify-fix: bare lexical reference, matching
415
+ // the runStart pattern above. The earlier `(globalThis as any)
416
+ // .__wasiRunStartAsync` lookup returned undefined at runtime
417
+ // because top-level `function` declarations in the preamble's
418
+ // ES-module scope do NOT auto-attach to globalThis. The result
419
+ // was that sock_*/poll_oneoff (wrapped in WebAssembly.Suspending)
420
+ // were invoked from a sync `_start` call stack → V8 trapped with
421
+ // "trying to suspend without WebAssembly.promising". The 11
422
+ // sync-only Stream-B probes worked because they never hit a
423
+ // Suspending import; the 7 async probes failed because they did.
424
+ // The preamble is statically prepended to this same module body
425
+ // (loader-pool.ts:523-530), so the symbol is guaranteed in
426
+ // scope. typeof guard handles the impossible case of a preamble
427
+ // pre-dating Stream-B (defensive only).
428
+ const runStartAsync = typeof __wasiRunStartAsync === 'function'
429
+ ? __wasiRunStartAsync
430
+ : null;
431
+ const initFS = __wasiInitFS;
432
+ const snapshotFS = __wasiSnapshotFS;
433
+ if (!mk || !runStart || !initFS || !snapshotFS) {
434
+ return {
435
+ ok: false,
436
+ mode: 'wasi',
437
+ error: 'WASI preamble missing: __wasi* helpers not defined. ' +
438
+ 'Pool preamble may have failed to load.',
439
+ };
440
+ }
441
+ // Install the snapshotted VFS state into the WASI shim's
442
+ // virtual filesystem. fd 3 = the user's session root preopen.
443
+ // The shim's fd table is reset by initFS each call.
444
+ if (args.wasiFs) {
445
+ initFS({
446
+ root: args.wasiFs.root,
447
+ preopens: args.wasiFs.preopens,
448
+ files: args.wasiFs.files,
449
+ dirs: args.wasiFs.dirs,
450
+ });
451
+ }
452
+ else {
453
+ // Minimal FS so __wasiFS isn't null when WASI fns are called.
454
+ initFS({ root: '', preopens: [], files: {}, dirs: [] });
455
+ }
456
+ const memRef = { mem: null };
457
+ const wasi = mk({
458
+ argv: args.wasiArgv || [],
459
+ env: args.wasiEnv || {},
460
+ getMemory: () => memRef.mem,
461
+ });
462
+ let inst;
463
+ try {
464
+ // Both modern `wasi_snapshot_preview1` and older
465
+ // `wasi_unstable` namespaces point at the SAME shim
466
+ // import object. The WASI ABIs are near-identical in
467
+ // function signatures (preview1 fixed fd_seek's offset
468
+ // width to i64 and the `filestat` struct layout); our
469
+ // shim implements preview1 and the older binji-linked
470
+ // binaries are tolerant of the wider types via JS
471
+ // BigInt coercion at the wasm boundary.
472
+ const result = await WebAssembly.instantiate(mod, {
473
+ wasi_snapshot_preview1: wasi.wasiImport,
474
+ wasi_unstable: wasi.wasiImport,
475
+ });
476
+ inst = (result instanceof WebAssembly.Instance ? result : result.instance);
477
+ }
478
+ catch (e) {
479
+ return {
480
+ ok: false,
481
+ mode: 'wasi',
482
+ error: `instantiate failed: ${e?.message || e}`,
483
+ };
484
+ }
485
+ memRef.mem = inst.exports.memory;
486
+ if (!memRef.mem) {
487
+ return {
488
+ ok: false,
489
+ mode: 'wasi',
490
+ error: 'wasm module did not export a `memory` — WASI requires one.',
491
+ };
492
+ }
493
+ // Stream-B P3: use async runStart when available so any
494
+ // suspending socket imports can complete via JSPI. The async
495
+ // wrapper falls back to sync invocation internally when
496
+ // WebAssembly.promising isn't available, so this is safe for
497
+ // non-suspending programs too. Legacy preambles (pre-Stream-B)
498
+ // that ship without __wasiRunStartAsync still work via the
499
+ // sync runStart path.
500
+ const r = runStartAsync
501
+ ? await runStartAsync(inst, { memory: memRef.mem })
502
+ : runStart(inst, { memory: memRef.mem });
503
+ const fsDiff = snapshotFS();
504
+ return {
505
+ ok: r.exitCode === 0 && !r.error,
506
+ mode: 'wasi',
507
+ stdout: wasi.getStdout(),
508
+ stderr: wasi.getStderr(),
509
+ exitCode: r.exitCode,
510
+ exports: Object.keys(inst.exports),
511
+ error: r.error,
512
+ fsDiff: fsDiff || undefined,
513
+ };
514
+ }
515
+ // ── Direct mode ──
516
+ let inst;
517
+ try {
518
+ // Single-arg instantiate against a precompiled Module — this
519
+ // is the form workerd's CSP DOES allow. The dynamic-bytes
520
+ // form (instantiate(ArrayBuffer)) is what's blocked.
521
+ const result = await WebAssembly.instantiate(mod, {});
522
+ inst = (result instanceof WebAssembly.Instance ? result : result.instance);
523
+ }
524
+ catch (e) {
525
+ return {
526
+ ok: false,
527
+ mode: 'direct',
528
+ error: `instantiate failed: ${e?.message || e}`,
529
+ };
530
+ }
531
+ const exportNames = Object.keys(inst.exports);
532
+ const fn = inst.exports[args.exportName];
533
+ if (typeof fn !== 'function') {
534
+ return {
535
+ ok: false,
536
+ mode: 'direct',
537
+ exports: exportNames,
538
+ error: `export '${args.exportName}' is not a function (or not exported). ` +
539
+ `Available exports: ${exportNames.join(', ')}`,
540
+ };
541
+ }
542
+ let out;
543
+ try {
544
+ out = fn(...(args.intArgs || []));
545
+ }
546
+ catch (e) {
547
+ return {
548
+ ok: false,
549
+ mode: 'direct',
550
+ exports: exportNames,
551
+ error: `${args.exportName}(${(args.intArgs || []).join(', ')}) threw: ${e?.message || e}`,
552
+ };
553
+ }
554
+ // BigInt (i64) → string; everything else → as-is.
555
+ if (typeof out === 'bigint')
556
+ return { ok: true, mode: 'direct', result: out.toString(), exports: exportNames };
557
+ return { ok: true, mode: 'direct', result: out, exports: exportNames };
558
+ };
559
+ // PID + log integration. The runtime-registry's contract is
560
+ // runtime-agnostic at the PID layer; node + bun get this for
561
+ // free via runFresh → facetMgr.exec which calls
562
+ // processTable.spawn. wasm-runner uses NimbusLoaderPool directly
563
+ // (compute-only, no SUPERVISOR binding needed) so we have to
564
+ // allocate the PID + log entries by hand.
565
+ const cmdLabel = 'wasm-runner ' +
566
+ (opts.filename || '').replace(/^\/+/, '/') +
567
+ ' ' +
568
+ argv.join(' ');
569
+ const procEntry = deps.processTable.spawn(cmdLabel.trim(), ['wasm-runner', ...argv], opts.cwd || '/home/user');
570
+ const pid = procEntry.pid;
571
+ // Pass-through env vars (Nimbus shell sets HOME/USER/PATH/etc.). The
572
+ // runtime-registry's RuntimeRunOpts carries env on the way in; we
573
+ // forward to the WASI shim. Direct mode doesn't use env.
574
+ const wasiEnv = isWasi ? (opts.env || {}) : {};
575
+ // ── Wave-2: snapshot user's session VFS for WASI mode ──
576
+ //
577
+ // The user's cwd at invocation time is our session-root preopen
578
+ // anchor. WASI programs see this as fd 3 mapped to '/'. We
579
+ // snapshot the subtree, ship via the loader-pool `context`, and
580
+ // flush mutations back after _start returns.
581
+ //
582
+ // For direct mode there's no FS exposure — wasm runs in pure
583
+ // compute-only mode, no preopens.
584
+ let wasiFs;
585
+ let wasiFsBytes = 0;
586
+ let wasiFsFiles = 0;
587
+ if (isWasi) {
588
+ // Session root = cwd of the shell invocation. Falls back to /home/user.
589
+ const cwd = (opts.cwd || '/home/user').replace(/^\/+/, '');
590
+ const snap = snapshotVfs(deps.vfs, cwd);
591
+ if ('error' in snap) {
592
+ return {
593
+ exitCode: 1,
594
+ stdout: '',
595
+ stderr: `wasm-runner: ${snap.error}\n`,
596
+ };
597
+ }
598
+ wasiFs = {
599
+ root: snap.snapshot.root,
600
+ preopens: [
601
+ // fd 3 → '/' mapping (covers the user's session subtree).
602
+ { wasiPath: '/', vfsPath: snap.snapshot.root },
603
+ ],
604
+ files: snap.snapshot.files,
605
+ dirs: snap.snapshot.dirs,
606
+ };
607
+ wasiFsBytes = snap.bytes;
608
+ wasiFsFiles = snap.files;
609
+ }
610
+ let outcome;
611
+ try {
612
+ const submitArgs = isWasi
613
+ ? { mode: 'wasi', wasiArgv, wasiEnv, wasiFs }
614
+ : { mode: 'direct', exportName: exportName, intArgs: parsedArgs };
615
+ outcome = (await pool.submit(facetFn, submitArgs, {
616
+ wasmModules: { 'user.wasm': buf },
617
+ // 30s ceiling for compute. Most wasm calls return in
618
+ // microseconds; runaway loops hit this and the pool returns
619
+ // a TimeoutError that surfaces as exitCode 1 + stderr.
620
+ timeoutMs: 30_000,
621
+ }));
622
+ }
623
+ catch (e) {
624
+ outcome = { ok: false, error: `dispatch failed: ${e?.message || e}` };
625
+ }
626
+ // ── Wave-2: flush mutated FS state back into SqliteFS ──
627
+ if (outcome.mode === 'wasi' && outcome.ok && outcome.fsDiff) {
628
+ try {
629
+ flushVfsDiff(deps.vfs, outcome.fsDiff);
630
+ }
631
+ catch (e) {
632
+ // Flush failure is non-fatal; the wasm ran, the user saw stdout.
633
+ // But surface a diagnostic so they know the FS didn't persist.
634
+ console.warn('wasm-runner: FS flush failed:', e?.message || e);
635
+ }
636
+ }
637
+ let exitCode;
638
+ let stdout;
639
+ let stderr;
640
+ // The facet's `ok` field encodes "clean exit (code 0, no trap)" — but
641
+ // for WASI mode, a non-zero proc_exit IS legitimate program output,
642
+ // not a wasm-runner error. Branch on `mode` first so we surface the
643
+ // program's exit code unchanged.
644
+ if (outcome.mode === 'wasi') {
645
+ // WASI mode: pass through stdout/stderr the wasm wrote via
646
+ // fd_write. Exit code from proc_exit (or 0 on natural fall-through).
647
+ // If runStart reported an `error` (wasm trapped, _start missing,
648
+ // …), append it to stderr but still surface its exitCode (default
649
+ // 1 from runStart on trap) so callers can distinguish.
650
+ const wasiOut = outcome;
651
+ // Either branch carries optional stdout/stderr/exitCode/error.
652
+ stdout = wasiOut.stdout || '';
653
+ stderr = wasiOut.stderr || '';
654
+ if (wasiOut.error) {
655
+ stderr = (stderr ? stderr : '') +
656
+ `wasm-runner: wasi trap: ${wasiOut.error}\n`;
657
+ }
658
+ exitCode = wasiOut.exitCode ?? (wasiOut.ok ? 0 : 1);
659
+ }
660
+ else if (!outcome.ok) {
661
+ // Direct-mode failure or pre-instantiate dispatch failure — shell
662
+ // sees rc=1 + stderr.
663
+ exitCode = 1;
664
+ stdout = '';
665
+ stderr = `wasm-runner: ${outcome.error}\n`;
666
+ }
667
+ else {
668
+ // Direct mode success: surface the result on stdout. void-return
669
+ // is success with no output; callers chain `&& echo OK` to detect.
670
+ stdout =
671
+ outcome.result === undefined || outcome.result === null
672
+ ? ''
673
+ : String(outcome.result) + '\n';
674
+ stderr = '';
675
+ exitCode = 0;
676
+ }
677
+ // Mirror stdout/stderr into the per-PID ring so `logs <pid>`
678
+ // and the Process tab WS log stream see the output. The
679
+ // append-then-markExit ordering matches what shellExecuteTracked
680
+ // does in init.ts:1559+ (Fix 5 contract).
681
+ if (stdout) {
682
+ try {
683
+ deps.processLogs.append(pid, 'stdout', stdout);
684
+ }
685
+ catch { }
686
+ }
687
+ if (stderr) {
688
+ try {
689
+ deps.processLogs.append(pid, 'stderr', stderr);
690
+ }
691
+ catch { }
692
+ }
693
+ try {
694
+ deps.processTable.exit(pid, exitCode);
695
+ }
696
+ catch { }
697
+ try {
698
+ if (!deps.processLogs.getExit(pid)) {
699
+ deps.processLogs.markExit(pid, exitCode);
700
+ }
701
+ }
702
+ catch { }
703
+ return { exitCode, stdout, stderr };
704
+ };
705
+ }