@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,1444 @@
1
+ /**
2
+ * EsbuildService — TypeScript/JSX transform + bundling via esbuild-wasm.
3
+ *
4
+ * Architecture:
5
+ * - esbuild-wasm is imported directly in the supervisor bundle
6
+ * - WASM is compiled during module evaluation (startup phase) — allowed
7
+ * - transform() runs in the supervisor's isolate (fast, no facet needed)
8
+ * - build() also runs in supervisor with a VFS resolver plugin
9
+ *
10
+ * Why not a facet? The esbuild-wasm WASM binary needs to be compiled
11
+ * during module startup (not request time). Dynamic workers created via
12
+ * LOADER.load() have the same restriction. Since esbuild-wasm is bundled
13
+ * into the supervisor, it initializes once at startup and stays warm.
14
+ *
15
+ * Memory: esbuild-wasm uses ~15-20MB heap. Within the DO's 128MB budget
16
+ * this is acceptable for Phase 3. Phase 4+ can move it to a dedicated
17
+ * facet once wasm module passing to dynamic workers is stable.
18
+ */
19
+ import { resolvePackageEntry, resolveExports } from '../_shared/exports-resolver.js';
20
+ import { normalizeVfsPath, stripLeadingSlashes } from '../vfs/path.js';
21
+ /**
22
+ * Bundler version tag. BUMP THIS whenever bundling semantics change —
23
+ * the esbuild plugin's resolver logic, the shared-externals rules, the
24
+ * post-processing pipeline, or anything that would invalidate cached
25
+ * pre-bundles. The version is stored in pkg_esm_bundles.bundle_hash and
26
+ * checked on read; cache entries with a different version are treated
27
+ * as missing and rebuilt from scratch.
28
+ *
29
+ * History:
30
+ * v1 — initial pre-bundling
31
+ * v2 — shared React externals, CJS named exports
32
+ * v3 — Node subpath imports (#foo) support for vfile/unified ecosystem
33
+ * v4 — legacy flat-subpath resolution (pkg/sub without exports field);
34
+ * CDN fallback wrapper no longer crashes on modules without default
35
+ * v5 — normalize `../` segments in joined entry paths (react-remove-scroll-bar
36
+ * style: nested package.json with "module": "../dist/es2015/foo.js")
37
+ * v6 — externals enforced via plugin onResolve only (top-level `external:`
38
+ * dropped). Fixes dual-React-instance bug where jsx-runtime and
39
+ * react-dom/client were inlining their own copy of react because
40
+ * esbuild's entry-point external check rejected the externals when
41
+ * passed at the top level. v5 cache entries are wrong (contain
42
+ * embedded react copies) and must be invalidated.
43
+ */
44
+ export const BUNDLER_VERSION = 'v6';
45
+ // ── Shared-runtime externals ────────────────────────────────────────────
46
+ /**
47
+ * Returns the list of specifiers that must be marked `external` when bundling
48
+ * `specifier` so that React / React-DOM / Scheduler share a single instance
49
+ * across all /@modules/ bundles.
50
+ *
51
+ * Why: React uses an internal module-scoped singleton
52
+ * (`__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`) for current dispatcher,
53
+ * owner, etc. If two bundles each contain their own embedded React, they each
54
+ * have their own singleton, and `createRoot` from one bundle sees JSX elements
55
+ * created by the other as "alien" — silent render failure (root stays empty).
56
+ *
57
+ * The fix: when bundling react-dom/*, mark react/* and scheduler as external.
58
+ * The bundler leaves `import {...} from "react"` in the output; the browser
59
+ * then fetches /preview/@modules/react, which is the SAME URL the jsx-runtime
60
+ * bundle imports — so both react-dom and jsx-runtime share ONE React instance.
61
+ *
62
+ * Similarly for react/jsx-runtime and react/jsx-dev-runtime (they must share
63
+ * react's internals), we externalize `react` (but not `scheduler` — jsx-runtime
64
+ * doesn't need it).
65
+ */
66
+ export function getSharedRuntimeExternals(specifier) {
67
+ // react: the canonical bundle. No externals — it's the source of truth.
68
+ if (specifier === 'react')
69
+ return [];
70
+ // react/jsx-runtime, react/jsx-dev-runtime: import from react's
71
+ // ReactSharedInternals to use the dispatcher. Externalize `react` so
72
+ // the jsx-runtime bundle is just the JSX helpers (~5 KiB) sharing
73
+ // ONE React instance via the browser's module loader.
74
+ if (specifier === 'react/jsx-runtime' || specifier === 'react/jsx-dev-runtime') {
75
+ return ['react'];
76
+ }
77
+ // Other react/* subpaths (e.g., react/server) — externalize react.
78
+ if (specifier.startsWith('react/')) {
79
+ return ['react'];
80
+ }
81
+ // EVERYTHING ELSE — react-dom, framer-motion, lucide-react, zustand,
82
+ // @radix-ui/*, react-router, etc. — must share react's singleton. If any
83
+ // of these embeds its own React copy, elements tagged by that copy get
84
+ // rejected as "alien" by the createRoot from the OTHER React copy
85
+ // (silent render fail / "Objects are not valid as a React child" with
86
+ // $$typeof spelled out). Externalize the entire React runtime.
87
+ //
88
+ // We DO NOT use `react/*` glob here because that has historically tripped
89
+ // esbuild's entry-point check. Instead we list the specific subpath
90
+ // imports React's ecosystem actually emits: jsx-runtime + jsx-dev-runtime.
91
+ // (react-dom subpaths are handled below by 'react-dom/*'.)
92
+ //
93
+ // Filter out patterns that match the spec being bundled — when
94
+ // bundling 'react-dom', drop 'react-dom' / 'react-dom/*' from the list
95
+ // so the entry can be bundled.
96
+ const all = [
97
+ 'react',
98
+ 'react/jsx-runtime',
99
+ 'react/jsx-dev-runtime',
100
+ 'react-dom',
101
+ 'react-dom/*',
102
+ 'scheduler',
103
+ ];
104
+ // Determine the package name for the spec being bundled (handles
105
+ // scoped packages and subpaths: 'react-dom/client' → 'react-dom').
106
+ const specPkg = specifier.startsWith('@')
107
+ ? specifier.split('/').slice(0, 2).join('/')
108
+ : specifier.split('/')[0];
109
+ return all.filter((pat) => {
110
+ if (pat === specifier)
111
+ return false;
112
+ if (pat.endsWith('/*')) {
113
+ const prefix = pat.slice(0, -1); // e.g. 'react-dom/'
114
+ const pkgName = pat.slice(0, -2); // e.g. 'react-dom'
115
+ if (specifier.startsWith(prefix))
116
+ return false;
117
+ if (specifier === pkgName)
118
+ return false;
119
+ if (specPkg === pkgName)
120
+ return false;
121
+ }
122
+ else {
123
+ // Plain (non-glob) external. Drop if the spec being bundled is
124
+ // a subpath of this external's package.
125
+ if (specPkg === pat)
126
+ return false;
127
+ }
128
+ return true;
129
+ });
130
+ }
131
+ /**
132
+ * Cheap heuristic to detect top-level await in source. Used by
133
+ * `EsbuildService.transform` to decide whether to async-IIFE-wrap
134
+ * CJS-target sources (see transform()'s header comment).
135
+ *
136
+ * Why a regex (not a real parser):
137
+ * - We only need to know "is there an `await` outside any
138
+ * function body?". A regex over a comment-stripped source is
139
+ * cheap and the false-positive class is harmless (an async-
140
+ * IIFE wrap around code that didn't need it is a no-op).
141
+ * - Real parsing would require shipping a JS parser to the
142
+ * supervisor isolate — adds tens of KiB to the worker bundle
143
+ * and a fraction-of-a-millisecond per call. Not worth it.
144
+ *
145
+ * Heuristic:
146
+ * 1. Strip line and block comments (avoid matching commented-out
147
+ * `// await foo` strings).
148
+ * 2. Strip string and template literals (avoid matching `"await x"`
149
+ * in error messages or user-data strings).
150
+ * 3. Scan token-by-token tracking brace/paren/function-keyword
151
+ * depth. An `await` at depth-0 OUTSIDE any `function`/`=>` body
152
+ * is top-level.
153
+ *
154
+ * Misses (accepted):
155
+ * - Await inside a class static initializer block at depth 0 —
156
+ * real Node treats that as a syntax error anyway.
157
+ * - Heavily-minified sources where function boundaries are
158
+ * packed onto a single line — we false-positive (wrap when
159
+ * not needed). Harmless.
160
+ *
161
+ * NEVER false-negatives a real top-level await in normal source;
162
+ * the wrap is the safe direction.
163
+ */
164
+ function hasTopLevelAwait(src) {
165
+ if (!src || src.indexOf('await') === -1)
166
+ return false;
167
+ // Strip comments + string/template literals so the depth-tracker
168
+ // only sees real syntax. Shared helper preserves `${...}`
169
+ // interpolation expressions so `\`${await foo}\`` at module top
170
+ // level is still detected as TLA.
171
+ const stripped = stripCommentsAndStrings(src);
172
+ // Now walk tokens. Track function depth: `function` / `=>` opens a
173
+ // function scope; entering `{` increments; matching `}` decrements.
174
+ // For arrow funcs the body may be an expression (no braces) —
175
+ // in that case the function body ends at the next `;` or top-level
176
+ // comma. Approximation: count `function` keyword occurrences as
177
+ // "entered fn scope" and assume the first balanced `{ ... }` after
178
+ // it is the body.
179
+ //
180
+ // We use a simpler approach: scan for the keyword `await`, then
181
+ // count `function`-keywords + `=>` arrows up to that point, minus
182
+ // matching scope-closes via brace depth. If the await is at depth 0
183
+ // (no enclosing function), it's TLA.
184
+ //
185
+ // For robustness across formatting, we just track brace depth and
186
+ // a 'inFunctionAt' stack: when we see `function`, push the next `{`'s
187
+ // depth onto the stack. When we see `}` and it matches the stack's
188
+ // top, pop. Await at depth not matching any function-stack entry
189
+ // is TLA.
190
+ const re = /\b(await|function|class)\b|=>|\{|\}|\(|\)/g;
191
+ let m;
192
+ const fnEntryDepths = [];
193
+ let depth = 0;
194
+ let pendingFnAtNextBrace = 0;
195
+ while ((m = re.exec(stripped)) !== null) {
196
+ const tok = m[0];
197
+ if (tok === '{') {
198
+ depth++;
199
+ if (pendingFnAtNextBrace > 0) {
200
+ fnEntryDepths.push(depth);
201
+ pendingFnAtNextBrace--;
202
+ }
203
+ }
204
+ else if (tok === '}') {
205
+ if (fnEntryDepths.length > 0 &&
206
+ fnEntryDepths[fnEntryDepths.length - 1] === depth) {
207
+ fnEntryDepths.pop();
208
+ }
209
+ depth--;
210
+ }
211
+ else if (tok === 'function' || tok === '=>') {
212
+ // The next `{` opens the function body. Arrow functions may
213
+ // have an expression body (no brace) — accepted false-positive.
214
+ pendingFnAtNextBrace++;
215
+ }
216
+ else if (tok === 'class') {
217
+ // Class bodies use `{}` too, but `await` inside a class field
218
+ // initializer would be inside a method or value — those open
219
+ // their own braces. Treat `class` like `function` for depth.
220
+ pendingFnAtNextBrace++;
221
+ }
222
+ else if (tok === 'await') {
223
+ // TLA iff no enclosing function scope is open at current depth.
224
+ if (fnEntryDepths.length === 0)
225
+ return true;
226
+ }
227
+ }
228
+ return false;
229
+ }
230
+ /**
231
+ * Cheap heuristic: does the source contain a top-level ESM `import`
232
+ * statement? Used by `EsbuildService.transform` to detect sources that
233
+ * cannot be IIFE-wrapped as-is.
234
+ *
235
+ * Bug history (nuxt-esm-in-cjs wave):
236
+ * ─────────────────────────────────
237
+ * The TLA fix (framework-gaps-fix P2) wraps CJS-target sources in an
238
+ * async IIFE:
239
+ *
240
+ * ;(async () => { <source> })().catch(...);
241
+ *
242
+ * For sources with TLA-only, that works: `await` becomes legal inside
243
+ * the async function body. But for sources with BOTH TLA AND ESM
244
+ * `import` statements (real-world example: nuxi's `bin/nuxi.mjs`), the
245
+ * wrap moves `import` statements into a function body — and ESM
246
+ * `import` syntax is only legal at module top-level. esbuild rejects
247
+ * the wrapped source with `Unexpected "<binding>"` at line 3 of stdin
248
+ * (the wrap's line 1 is `;(async () =>...`, line 2 is the open brace,
249
+ * line 3 is the first user import).
250
+ *
251
+ * When TLA AND ESM imports coexist we must extract the imports first,
252
+ * rewrite them as `const X = require(...)` shims at top-level (above
253
+ * the IIFE), then wrap the rest. See `convertEsmImportsToRequire` for
254
+ * the rewrite contract and `transform()` for the integration site.
255
+ *
256
+ * Heuristic match: any of `import "..."` / `import x from "..."` /
257
+ * `import { ... } from "..."` / `import * as ns from "..."` / `import
258
+ * x, { ... } from "..."` appearing on a line whose first non-whitespace
259
+ * token is the `import` keyword. Dynamic `import(...)` calls are
260
+ * EXCLUDED — those are expressions, legal anywhere including IIFE
261
+ * bodies, and need no rewrite.
262
+ *
263
+ * Operates on the comment-and-string-stripped source so commented-out
264
+ * imports and "import" appearing inside string literals don't trigger.
265
+ * We reuse the comment/string stripper from `hasTopLevelAwait`'s pass
266
+ * — see `stripCommentsAndStrings` below.
267
+ */
268
+ function hasEsmImports(src) {
269
+ if (!src || src.indexOf('import') === -1)
270
+ return false;
271
+ const stripped = stripCommentsAndStrings(src);
272
+ // Top-level `import ... from "..."` OR side-effect `import "..."`.
273
+ // Negative lookbehind for `.` (avoids `something.import` member
274
+ // access) is unsupported in some JS engines; we match start-of-line
275
+ // (after whitespace) + the keyword. dynamic import() is matched as
276
+ // `import(` and excluded by negative lookahead.
277
+ const re = /^[ \t]*import\b(?!\s*\()/m;
278
+ return re.test(stripped);
279
+ }
280
+ /**
281
+ * Strip `//` and `/* * /` comments and string / template literals from
282
+ * source, replacing each with a single space. The result is byte-aligned
283
+ * with the input on a per-line basis (newlines are preserved), so error
284
+ * line numbers from downstream parsers still align with the original.
285
+ *
286
+ * Shared by `hasTopLevelAwait` (which had this inline) and
287
+ * `hasEsmImports`. Pure function — no caching needed for the small
288
+ * inputs we see (typical .mjs entry-point: <2KiB).
289
+ */
290
+ function stripCommentsAndStrings(src) {
291
+ let stripped = '';
292
+ let i = 0;
293
+ const N = src.length;
294
+ // Track the last non-whitespace non-comment output character so we
295
+ // can disambiguate `/` as division (after identifier/literal/`)`/`]`)
296
+ // vs regex-literal opener (after operator / punctuator / keyword /
297
+ // start-of-file). Pre-fix the stripper had no regex awareness, so
298
+ // patterns like `var X = /^(?:'…)/` contained an unmatched `'` that
299
+ // bit it as a string opener that didn't close until many lines
300
+ // later — corrupting every downstream classifier (export-scanner,
301
+ // hasEsmImports, hasTopLevelAwait). Real-world bite: sv-utils@0.0.3
302
+ // index.mjs has dozens of these regex literals.
303
+ let lastNonWsChar = '';
304
+ const recordOut = (ch) => {
305
+ if (ch !== ' ' && ch !== '\t' && ch !== '\n' && ch !== '\r') {
306
+ lastNonWsChar = ch;
307
+ }
308
+ };
309
+ // Identifier-suffix detection on lastNonWsChar: any of these means
310
+ // `/` is division. Anything else means `/` opens a regex.
311
+ // Includes ascii word chars + `)` `]` to cover `foo()/x` `a[i]/y`.
312
+ const DIVISION_AFTER = /[A-Za-z0-9_$\)\]]/;
313
+ while (i < N) {
314
+ const c = src[i];
315
+ if (c === '/' && src[i + 1] === '/') {
316
+ while (i < N && src[i] !== '\n')
317
+ i++;
318
+ stripped += ' ';
319
+ continue;
320
+ }
321
+ if (c === '/' && src[i + 1] === '*') {
322
+ i += 2;
323
+ while (i < N && !(src[i] === '*' && src[i + 1] === '/')) {
324
+ // Preserve newlines so line numbers stay aligned.
325
+ if (src[i] === '\n')
326
+ stripped += '\n';
327
+ i++;
328
+ }
329
+ i += 2;
330
+ stripped += ' ';
331
+ continue;
332
+ }
333
+ // Regex literal: `/` not followed by `/` or `*` (already handled
334
+ // above), AND preceded by something that makes regex valid here.
335
+ // The classifier looks at lastNonWsChar — for `(`, `,`, `=`, `;`,
336
+ // `{`, `[`, `:`, `!`, `&`, `|`, `?`, operators, or start-of-file,
337
+ // a slash is a regex opener.
338
+ if (c === '/' && !DIVISION_AFTER.test(lastNonWsChar)) {
339
+ stripped += ' ';
340
+ i++;
341
+ while (i < N) {
342
+ const rc = src[i];
343
+ if (rc === '\\') {
344
+ i += 2;
345
+ continue;
346
+ }
347
+ // Regex character class [...]: `/` inside it is content.
348
+ if (rc === '[') {
349
+ i++;
350
+ while (i < N && src[i] !== ']') {
351
+ if (src[i] === '\\') {
352
+ i += 2;
353
+ continue;
354
+ }
355
+ if (src[i] === '\n') {
356
+ stripped += '\n';
357
+ }
358
+ i++;
359
+ }
360
+ if (i < N)
361
+ i++; // consume ']'
362
+ continue;
363
+ }
364
+ if (rc === '/') {
365
+ i++;
366
+ break;
367
+ }
368
+ if (rc === '\n') {
369
+ // Regex literals can't span newlines. If we hit one without
370
+ // finding the closing `/`, this was probably NOT a regex —
371
+ // bail out gracefully (rare in practice; better than getting
372
+ // stuck in a wrong state).
373
+ break;
374
+ }
375
+ i++;
376
+ }
377
+ // Skip regex flags (g, i, m, s, u, y, d).
378
+ while (i < N && /[gimsuyd]/.test(src[i]))
379
+ i++;
380
+ recordOut('/');
381
+ continue;
382
+ }
383
+ if (c === '"' || c === "'" || c === '`') {
384
+ const q = c;
385
+ stripped += ' ';
386
+ i++;
387
+ while (i < N) {
388
+ const cc = src[i];
389
+ if (cc === '\\') {
390
+ i += 2;
391
+ continue;
392
+ }
393
+ if (cc === q) {
394
+ i++;
395
+ break;
396
+ }
397
+ // Template interpolation: ${...} — preserve the inner
398
+ // expression as raw code so the caller's depth-tracker can
399
+ // see `await` etc. inside it. Strip the wrapping `${`/`}`
400
+ // (those don't affect brace-depth from the caller's POV).
401
+ //
402
+ // CRITICAL: inside the interpolation expression, we must
403
+ // recognise NESTED strings (`'}'`, `"}"`, `` `${...}` ``) so
404
+ // their internal `}` characters don't decrement the depth
405
+ // counter — otherwise we exit the interpolation early and
406
+ // start consuming code as string content, eventually parsing
407
+ // the rest of the file as one massive unclosed string. This
408
+ // bit sv-utils/dist/index.mjs: multi-line backticks with
409
+ // `${url.replace('}', '_')}`-style interpolations corrupted
410
+ // line classification downstream. Recursive-by-loop here.
411
+ if (q === '`' && cc === '$' && src[i + 1] === '{') {
412
+ stripped += '${';
413
+ i += 2;
414
+ let depth = 1;
415
+ while (i < N && depth > 0) {
416
+ const ic = src[i];
417
+ // Nested string inside interpolation: skip its content.
418
+ if (ic === '"' || ic === "'" || ic === '`') {
419
+ const iq = ic;
420
+ stripped += ' ';
421
+ i++;
422
+ while (i < N) {
423
+ const icc = src[i];
424
+ if (icc === '\\') {
425
+ i += 2;
426
+ continue;
427
+ }
428
+ if (icc === iq) {
429
+ i++;
430
+ break;
431
+ }
432
+ // Nested template inside interpolation can also have its
433
+ // own ${...} — recurse once more (the practical depth
434
+ // observed in real code never exceeds 2; deeper nesting
435
+ // falls back to brace counting which is a best-effort).
436
+ if (iq === '`' && icc === '$' && src[i + 1] === '{') {
437
+ stripped += '${';
438
+ i += 2;
439
+ let d2 = 1;
440
+ while (i < N && d2 > 0) {
441
+ const i2 = src[i];
442
+ if (i2 === '{')
443
+ d2++;
444
+ else if (i2 === '}')
445
+ d2--;
446
+ if (d2 > 0)
447
+ stripped += i2;
448
+ i++;
449
+ }
450
+ stripped += '}';
451
+ continue;
452
+ }
453
+ if (icc === '\n')
454
+ stripped += '\n';
455
+ i++;
456
+ }
457
+ continue;
458
+ }
459
+ if (ic === '{')
460
+ depth++;
461
+ else if (ic === '}')
462
+ depth--;
463
+ if (depth > 0)
464
+ stripped += ic;
465
+ i++;
466
+ }
467
+ stripped += '}';
468
+ continue;
469
+ }
470
+ if (cc === '\n')
471
+ stripped += '\n';
472
+ i++;
473
+ }
474
+ continue;
475
+ }
476
+ stripped += c;
477
+ recordOut(c);
478
+ i++;
479
+ }
480
+ return stripped;
481
+ }
482
+ /**
483
+ * Convert ESM `import` statements at the top of `src` to CJS
484
+ * `require()` declarations, returning `{ requires, body }` where
485
+ * `requires` is the require-shim block (a single string of newline-
486
+ * separated declarations) and `body` is the source with the imports
487
+ * removed.
488
+ *
489
+ * Operates on the OUTPUT of an esbuild `format: 'esm'` pre-pass, NOT
490
+ * on raw user source. esbuild normalises imports onto single lines and
491
+ * canonicalises the binding shape, which means a small regex over the
492
+ * normalised output is reliable. Specifically:
493
+ * - Multi-line imports are collapsed to one line per import
494
+ * - `import x from 'm';` always has the semicolon
495
+ * - String quotes are normalised to double-quotes
496
+ * - Whitespace is canonical
497
+ *
498
+ * Supported import shapes (after esbuild normalisation):
499
+ * 1. `import "m";` side-effect
500
+ * 2. `import x from "m";` default
501
+ * 3. `import * as ns from "m";` namespace
502
+ * 4. `import { a, b as c } from "m";` named (with optional rename)
503
+ * 5. `import x, { a } from "m";` default + named
504
+ * 6. `import x, * as ns from "m";` default + namespace
505
+ *
506
+ * Rewrites:
507
+ * 1. `require("m");`
508
+ * 2. `const x = (() => { const _m = require("m"); return _m && _m.__esModule ? _m.default : _m; })();`
509
+ * 3. `const ns = require("m");`
510
+ * 4. `const { a, b: c } = require("m");`
511
+ * 5. `const _m_<n> = require("m"); const x = _m_<n>.__esModule ? _m_<n>.default : _m_<n>; const { a } = _m_<n>;`
512
+ * 6. `const ns = require("m"); const x = ns.__esModule ? ns.default : ns;`
513
+ *
514
+ * Default-binding compat: ESM `import x from "m"` binds the module's
515
+ * default export, OR the whole module if there is no default. Real
516
+ * Node + esbuild's __esModule interop check handle this with the
517
+ * `__esModule ? .default : whole` pattern reproduced above. Same as
518
+ * what esbuild emits inline when targeting CJS for a no-TLA source
519
+ * (verified empirically against `esbuild-wasm 0.24.2`).
520
+ *
521
+ * Unknown shapes are left in `body` unchanged — esbuild will reject
522
+ * them on the second pass and the caller surfaces a clear error.
523
+ * That's the safe failure mode.
524
+ */
525
+ function convertEsmImportsToRequire(src) {
526
+ const lines = src.split('\n');
527
+ // Strip comments + string/template literals so the line scanner only
528
+ // sees real syntax. Without this, import-shaped lines INSIDE template
529
+ // literals (real-world: sv@0.15.3's engine.mjs scaffolds SvelteKit
530
+ // project files via templates containing `import { redirect } from
531
+ // '@sveltejs/kit';`) get parsed as actual imports — emitted twice into
532
+ // the requires block → duplicate const declaration → SyntaxError at
533
+ // facet pre-compile ("Identifier 'redirect' has already been declared").
534
+ //
535
+ // stripCommentsAndStrings preserves newlines, so line indices align
536
+ // between `src` and `strippedLines`. We use the stripped line to
537
+ // CLASSIFY (is this an import line?) and the original line to
538
+ // EXTRACT the actual import shape (specifier, bindings).
539
+ //
540
+ // See .seal-internal/2026-05-11-sk-mjs-fix/audit.md.
541
+ const strippedLines = stripCommentsAndStrings(src).split('\n');
542
+ const requires = [];
543
+ const bodyLines = [];
544
+ let counter = 0;
545
+ for (let li = 0; li < lines.length; li++) {
546
+ const line = lines[li];
547
+ const cls = strippedLines[li] ?? '';
548
+ // Classification check: is this line a real top-level import?
549
+ // The stripped version masks string content, so import-shaped
550
+ // template-literal lines are now whitespace.
551
+ if (!/^[ \t]*import\b/.test(cls)) {
552
+ bodyLines.push(line);
553
+ continue;
554
+ }
555
+ // Side-effect import: `import "m";` / `import 'm';`
556
+ let m = line.match(/^[ \t]*import\s+["']([^"']+)["']\s*;?\s*$/);
557
+ if (m) {
558
+ requires.push(`require(${JSON.stringify(m[1])});`);
559
+ continue;
560
+ }
561
+ // Identifier class: JS spec allows `$` and `_` in addition to `\w`
562
+ // (letters/digits/underscore). esbuild's ESM-pass-1 emits `process$1`
563
+ // when colliding with a global (e.g. `import process from 'node:process'`
564
+ // becomes `process$1`). Pre-fix `\w+` truncated at `$`, all the regexes
565
+ // below missed → line fell through to bodyLines → top-level `import`
566
+ // statement survived into the async-IIFE wrap → SyntaxError
567
+ // "import statement outside module" at facet pre-compile.
568
+ // Default + namespace: `import x, * as ns from "m";`
569
+ m = line.match(/^[ \t]*import\s+([\w$]+)\s*,\s*\*\s+as\s+([\w$]+)\s+from\s+["']([^"']+)["']\s*;?\s*$/);
570
+ if (m) {
571
+ const def = m[1], ns = m[2], mod = m[3];
572
+ requires.push(`const ${ns} = require(${JSON.stringify(mod)}); const ${def} = ${ns}.__esModule ? ${ns}.default : ${ns};`);
573
+ continue;
574
+ }
575
+ // Default + named: `import x, { a, b as c } from "m";`
576
+ m = line.match(/^[ \t]*import\s+([\w$]+)\s*,\s*\{([^}]+)\}\s+from\s+["']([^"']+)["']\s*;?\s*$/);
577
+ if (m) {
578
+ const def = m[1], bindings = m[2], mod = m[3];
579
+ const tmp = `_nimbus_m_${counter++}`;
580
+ const named = bindings.split(',').map((b) => {
581
+ const am = b.trim().match(/^([\w$]+)(?:\s+as\s+([\w$]+))?$/);
582
+ if (!am)
583
+ return b.trim();
584
+ return am[2] ? `${am[1]}: ${am[2]}` : am[1];
585
+ }).join(', ');
586
+ requires.push(`const ${tmp} = require(${JSON.stringify(mod)}); const ${def} = ${tmp}.__esModule ? ${tmp}.default : ${tmp}; const { ${named} } = ${tmp};`);
587
+ continue;
588
+ }
589
+ // Namespace: `import * as ns from "m";`
590
+ m = line.match(/^[ \t]*import\s+\*\s+as\s+([\w$]+)\s+from\s+["']([^"']+)["']\s*;?\s*$/);
591
+ if (m) {
592
+ requires.push(`const ${m[1]} = require(${JSON.stringify(m[2])});`);
593
+ continue;
594
+ }
595
+ // Named only: `import { a, b as c } from "m";`
596
+ m = line.match(/^[ \t]*import\s+\{([^}]+)\}\s+from\s+["']([^"']+)["']\s*;?\s*$/);
597
+ if (m) {
598
+ const bindings = m[1], mod = m[2];
599
+ const named = bindings.split(',').map((b) => {
600
+ const am = b.trim().match(/^([\w$]+)(?:\s+as\s+([\w$]+))?$/);
601
+ if (!am)
602
+ return b.trim();
603
+ return am[2] ? `${am[1]}: ${am[2]}` : am[1];
604
+ }).join(', ');
605
+ requires.push(`const { ${named} } = require(${JSON.stringify(mod)});`);
606
+ continue;
607
+ }
608
+ // Default only: `import x from "m";`
609
+ m = line.match(/^[ \t]*import\s+([\w$]+)\s+from\s+["']([^"']+)["']\s*;?\s*$/);
610
+ if (m) {
611
+ const def = m[1], mod = m[2];
612
+ requires.push(`const ${def} = (() => { const _m = require(${JSON.stringify(mod)}); return _m && _m.__esModule ? _m.default : _m; })();`);
613
+ continue;
614
+ }
615
+ // Stripped-line claimed this was an import, but none of the shape
616
+ // regexes matched. Unknown import form (e.g. multi-line import that
617
+ // esbuild's pass-1 normalization didn't collapse, or a future-syntax
618
+ // variant). Keep in body — esbuild's pass-2 will reject it with a
619
+ // clear error if it's actually invalid, or accept it if it's a form
620
+ // we don't yet recognise.
621
+ bodyLines.push(line);
622
+ }
623
+ // ── Pass 2: scan bodyLines for top-level `export` statements. ──────
624
+ //
625
+ // After import-stripping, the body still has every `export` statement
626
+ // verbatim. The async-IIFE wrap (the caller wraps body in
627
+ // `;(async () => { ... })();`) makes those exports illegal grammar
628
+ // ('export' is module-only, not legal in function bodies) →
629
+ // SyntaxError "Unexpected token 'export'" at facet pre-compile.
630
+ //
631
+ // Rewrite each top-level export to a CJS-compatible equivalent (see
632
+ // .seal-internal/2026-05-11-sk-exports-fix/audit.md for shape table).
633
+ // Same defences as imports:
634
+ // - String-content masking (template-literal exports don't trigger)
635
+ // - $-aware identifier regex ([\w$]+, esbuild emits foo$1 ids)
636
+ //
637
+ // Multi-line `export { ... }` lists are coalesced before shape match.
638
+ const bodySrc = bodyLines.join('\n');
639
+ const bodyLines2 = bodySrc.split('\n');
640
+ const strippedBody = stripCommentsAndStrings(bodySrc).split('\n');
641
+ const out = [];
642
+ let i = 0;
643
+ let exportCounter = 0;
644
+ while (i < bodyLines2.length) {
645
+ const line = bodyLines2[i];
646
+ const cls = strippedBody[i] ?? '';
647
+ if (!/^[ \t]*export\b/.test(cls)) {
648
+ out.push(line);
649
+ i++;
650
+ continue;
651
+ }
652
+ // Multi-line collector: if the stripped line opens a `{` for an
653
+ // `export { ... }` list and doesn't close it on the same line,
654
+ // accumulate subsequent lines until the matching `}` (tracked on
655
+ // the stripped lines so string `}`s don't trip us).
656
+ let coalesced = line;
657
+ let coalescedCls = cls;
658
+ if (/^[ \t]*export\s*\{/.test(cls) && !/\}/.test(cls)) {
659
+ let j = i + 1;
660
+ while (j < bodyLines2.length) {
661
+ coalesced += ' ' + bodyLines2[j];
662
+ coalescedCls += ' ' + (strippedBody[j] ?? '');
663
+ if (/\}/.test(strippedBody[j] ?? '')) {
664
+ j++;
665
+ break;
666
+ }
667
+ j++;
668
+ }
669
+ i = j;
670
+ }
671
+ else {
672
+ i++;
673
+ }
674
+ // Helper: emit a `__esModule = true` marker exactly once.
675
+ // (Mirrors esbuild's own emit; consumers using the __esModule check
676
+ // in convertEsmImportsToRequire's default-import shim then pick
677
+ // .default correctly.)
678
+ const ensureEsmMarker = (() => {
679
+ let emitted = false;
680
+ return () => {
681
+ if (emitted)
682
+ return '';
683
+ emitted = true;
684
+ return 'module.exports.__esModule = true; ';
685
+ };
686
+ })();
687
+ // Shape regexes operate on the COALESCED ORIGINAL line. We use the
688
+ // stripped version only for classification (already done above).
689
+ let m;
690
+ // export default function/class — declaration form
691
+ // `export default function foo(args){...}` (named declaration)
692
+ m = coalesced.match(/^([ \t]*)export\s+default\s+(async\s+)?function\s*([\w$]+)\s*([\s\S]*)$/);
693
+ if (m) {
694
+ const indent = m[1], asyncKw = m[2] || '', name = m[3], rest = m[4];
695
+ out.push(`${indent}${asyncKw}function ${name} ${rest}`);
696
+ out.push(`${ensureEsmMarker()}module.exports.default = ${name};`);
697
+ continue;
698
+ }
699
+ // export default class K {...}
700
+ m = coalesced.match(/^([ \t]*)export\s+default\s+class\s+([\w$]+)\s*([\s\S]*)$/);
701
+ if (m) {
702
+ const indent = m[1], name = m[2], rest = m[3];
703
+ out.push(`${indent}class ${name} ${rest}`);
704
+ out.push(`${ensureEsmMarker()}module.exports.default = ${name};`);
705
+ continue;
706
+ }
707
+ // export default <anonymous-function | anonymous-class | expression>
708
+ // Match any remaining `export default …` shape and emit as assignment.
709
+ m = coalesced.match(/^([ \t]*)export\s+default\s+([\s\S]*)$/);
710
+ if (m) {
711
+ const indent = m[1];
712
+ let rest = m[2];
713
+ // Strip trailing semicolon (we add our own).
714
+ rest = rest.replace(/;\s*$/, '');
715
+ out.push(`${indent}${ensureEsmMarker()}module.exports.default = (${rest});`);
716
+ continue;
717
+ }
718
+ // export named-declaration: const/let/var
719
+ m = coalesced.match(/^([ \t]*)export\s+(const|let|var)\s+([\w$]+)\s*=\s*([\s\S]*)$/);
720
+ if (m) {
721
+ const indent = m[1], kw = m[2], name = m[3];
722
+ let rest = m[4];
723
+ rest = rest.replace(/;\s*$/, '');
724
+ out.push(`${indent}${kw} ${name} = ${rest};`);
725
+ out.push(`${ensureEsmMarker()}module.exports.${name} = ${name};`);
726
+ continue;
727
+ }
728
+ // export function NAME(...) {...}
729
+ m = coalesced.match(/^([ \t]*)export\s+(async\s+)?function\s*\*?\s*([\w$]+)\s*([\s\S]*)$/);
730
+ if (m) {
731
+ const indent = m[1], asyncKw = m[2] || '', name = m[3], rest = m[4];
732
+ // Preserve generator-star if present (function\s*\*).
733
+ const generatorStar = /^export\s+(?:async\s+)?function\s*\*/.test(coalesced.replace(/^[ \t]+/, '')) ? '*' : '';
734
+ out.push(`${indent}${asyncKw}function${generatorStar} ${name} ${rest}`);
735
+ out.push(`${ensureEsmMarker()}module.exports.${name} = ${name};`);
736
+ continue;
737
+ }
738
+ // export class NAME { ... } / export class NAME extends X { ... }
739
+ m = coalesced.match(/^([ \t]*)export\s+class\s+([\w$]+)\s*([\s\S]*)$/);
740
+ if (m) {
741
+ const indent = m[1], name = m[2], rest = m[3];
742
+ out.push(`${indent}class ${name} ${rest}`);
743
+ out.push(`${ensureEsmMarker()}module.exports.${name} = ${name};`);
744
+ continue;
745
+ }
746
+ // export { x, y as z } from 'm' / export * from 'm' / export * as ns from 'm'
747
+ m = coalesced.match(/^([ \t]*)export\s*\*\s+as\s+([\w$]+)\s+from\s+["']([^"']+)["']\s*;?\s*$/);
748
+ if (m) {
749
+ const indent = m[1], ns = m[2], mod = m[3];
750
+ out.push(`${indent}${ensureEsmMarker()}module.exports.${ns} = require(${JSON.stringify(mod)});`);
751
+ continue;
752
+ }
753
+ m = coalesced.match(/^([ \t]*)export\s*\*\s+from\s+["']([^"']+)["']\s*;?\s*$/);
754
+ if (m) {
755
+ const indent = m[1], mod = m[2];
756
+ const tmp = `_nimbus_re_${exportCounter++}`;
757
+ out.push(`${indent}${ensureEsmMarker()}{ const ${tmp} = require(${JSON.stringify(mod)}); for (const _k in ${tmp}) { if (_k !== "default" && _k !== "__esModule") module.exports[_k] = ${tmp}[_k]; } }`);
758
+ continue;
759
+ }
760
+ m = coalesced.match(/^([ \t]*)export\s*\{([^}]*)\}\s+from\s+["']([^"']+)["']\s*;?\s*$/);
761
+ if (m) {
762
+ const indent = m[1], bindings = m[2], mod = m[3];
763
+ const tmp = `_nimbus_re_${exportCounter++}`;
764
+ const parts = bindings.split(',').map((b) => b.trim()).filter(Boolean);
765
+ const assigns = [];
766
+ for (const p of parts) {
767
+ const am = p.match(/^([\w$]+)(?:\s+as\s+([\w$]+))?$/);
768
+ if (!am)
769
+ continue;
770
+ const src = am[1], dst = am[2] || am[1];
771
+ assigns.push(`module.exports.${dst} = ${tmp}.${src};`);
772
+ }
773
+ out.push(`${indent}${ensureEsmMarker()}{ const ${tmp} = require(${JSON.stringify(mod)}); ${assigns.join(' ')} }`);
774
+ continue;
775
+ }
776
+ // export { x, y as z } (binding-only list — no `from`)
777
+ m = coalesced.match(/^([ \t]*)export\s*\{([^}]*)\}\s*;?\s*$/);
778
+ if (m) {
779
+ const indent = m[1], bindings = m[2];
780
+ const parts = bindings.split(',').map((b) => b.trim()).filter(Boolean);
781
+ const assigns = [];
782
+ for (const p of parts) {
783
+ const am = p.match(/^([\w$]+)(?:\s+as\s+([\w$]+))?$/);
784
+ if (!am)
785
+ continue;
786
+ const src = am[1], dst = am[2] || am[1];
787
+ assigns.push(`module.exports.${dst} = ${src};`);
788
+ }
789
+ out.push(`${indent}${ensureEsmMarker()}${assigns.join(' ')}`);
790
+ continue;
791
+ }
792
+ // Unknown export shape — leave in body (esbuild will surface a clear
793
+ // error at the next pass, or this is a future-syntax variant we
794
+ // don't yet recognise).
795
+ out.push(coalesced);
796
+ }
797
+ return { requires: requires.join('\n'), body: out.join('\n') };
798
+ }
799
+ import esbuildWasmUrl from 'esbuild-wasm/esbuild.wasm';
800
+ /**
801
+ * Cached reference to the esbuild namespace. Populated on first
802
+ * `loadEsbuild()` call; nullable until then so module-load code paths
803
+ * that never touch bundling can complete without ever evaluating
804
+ * `esbuild-wasm/lib/main.js`.
805
+ */
806
+ let _esbuildMod = null;
807
+ let _esbuildLoadPromise = null;
808
+ /**
809
+ * Lazily load the esbuild-wasm namespace. Safe to call many times;
810
+ * concurrent callers share a single in-flight Promise. Throws if the
811
+ * CJS main module itself can't run (i.e. the runtime doesn't support
812
+ * the require('fs') pattern esbuild-wasm uses) — callers should catch
813
+ * and surface a helpful error rather than crash the Worker.
814
+ */
815
+ async function loadEsbuild() {
816
+ if (_esbuildMod)
817
+ return _esbuildMod;
818
+ if (_esbuildLoadPromise)
819
+ return _esbuildLoadPromise;
820
+ _esbuildLoadPromise = (async () => {
821
+ const mod = await import('esbuild-wasm');
822
+ _esbuildMod = mod;
823
+ return _esbuildMod;
824
+ })();
825
+ try {
826
+ return await _esbuildLoadPromise;
827
+ }
828
+ catch (e) {
829
+ // Reset so a future call can retry (e.g., after the caller has done
830
+ // environment setup we didn't anticipate).
831
+ _esbuildLoadPromise = null;
832
+ throw e;
833
+ }
834
+ }
835
+ // ── EsbuildService ──────────────────────────────────────────────────────
836
+ export class EsbuildService {
837
+ vfs;
838
+ initialized = false;
839
+ initPromise = null;
840
+ /** Resolved esbuild namespace — populated by ensureInit() after loadEsbuild(). */
841
+ _esbuild = null;
842
+ constructor(vfs) {
843
+ this.vfs = vfs;
844
+ }
845
+ /**
846
+ * Initialize esbuild-wasm (lazy, on first use). Loads the namespace
847
+ * via `loadEsbuild()` (which itself is deferred) and caches it on
848
+ * `this._esbuild` so subsequent calls don't pay the dynamic-import
849
+ * overhead. All call sites that previously used the top-level
850
+ * `esbuild` namespace now use `this._esbuild!` after `await this.ensureInit()`.
851
+ */
852
+ async ensureInit() {
853
+ if (this.initialized && this._esbuild)
854
+ return;
855
+ if (this.initPromise)
856
+ return this.initPromise;
857
+ this.initPromise = (async () => {
858
+ try {
859
+ const esb = await loadEsbuild();
860
+ this._esbuild = esb;
861
+ // The supervisor loads esbuild-wasm via wrangler's static-import
862
+ // resolution (`import esbuildWasmUrl from 'esbuild-wasm/esbuild.wasm'`
863
+ // at the top of this file). At deploy time wrangler bundles the
864
+ // .wasm bytes INTO the worker and resolves the import to a
865
+ // WebAssembly.Module value. If the import didn't resolve to a
866
+ // module — for example, a future bundler regression — we used
867
+ // to silently fall back to fetching from cdn.jsdelivr.net. That
868
+ // fallback violated the 100% edge contract: the supervisor
869
+ // would issue a third-party CDN request mid-request to bring
870
+ // up its bundler. Removed.
871
+ //
872
+ // If the bundled import is missing, fail loud with a clear
873
+ // remediation (rebuild the worker with the wasm asset). The
874
+ // supervisor's pre-bundle path also embeds esbuild-wasm via
875
+ // src/esbuild-wasm-bundle.generated.ts, so a complete loss of
876
+ // wasm support would surface there too.
877
+ if (!esbuildWasmUrl || typeof esbuildWasmUrl !== 'object') {
878
+ throw new Error('esbuild-wasm bundled import is not a WebAssembly.Module. ' +
879
+ 'Rebuild the worker so wrangler resolves ' +
880
+ '`esbuild-wasm/esbuild.wasm` at bundle time. ' +
881
+ 'NO CDN fallback (100% edge contract).');
882
+ }
883
+ // [WRANGLER-DEV-HANG P0b] Time-bound esb.initialize. Workerd
884
+ // has historically had cases where wasm init blocks indefinitely;
885
+ // 30 s is well above the typical ~200 ms init time.
886
+ const INIT_TIMEOUT_MS = 30_000;
887
+ let initTimeout = null;
888
+ await Promise.race([
889
+ esb.initialize({
890
+ wasmModule: esbuildWasmUrl,
891
+ worker: false,
892
+ }),
893
+ new Promise((_, reject) => {
894
+ initTimeout = setTimeout(() => {
895
+ reject(new Error(`esbuild init exceeded ${INIT_TIMEOUT_MS / 1000}s. ` +
896
+ `wasmModule type=${typeof esbuildWasmUrl}; ` +
897
+ `Likely cause: WebAssembly compile/init stall in workerd.`));
898
+ }, INIT_TIMEOUT_MS);
899
+ }),
900
+ ]).finally(() => { if (initTimeout)
901
+ clearTimeout(initTimeout); });
902
+ this.initialized = true;
903
+ }
904
+ catch (e) {
905
+ // "Cannot call initialize more than once" means it's already ready
906
+ if (e?.message?.includes('more than once')) {
907
+ this.initialized = true;
908
+ return;
909
+ }
910
+ this.initPromise = null;
911
+ throw new Error('esbuild init failed: ' + (e?.message || e));
912
+ }
913
+ })();
914
+ return this.initPromise;
915
+ }
916
+ /**
917
+ * Transform a single code string (TS→JS, JSX→JS, minify, etc.)
918
+ *
919
+ * Top-level await note (gap #2 in framework-gaps-fix):
920
+ * ─────────────────────────────────────────────────────
921
+ * esbuild rejects top-level await when output format is 'cjs' or
922
+ * 'iife' — neither has a runtime primitive for it. Real Node
923
+ * supports TLA only in ESM. Nimbus's facet wrapper executes the
924
+ * transformed code via `new Function(...)` which is CJS-shaped.
925
+ *
926
+ * Several modern CLIs (nuxi, vite-cli, oclif's lazy-load bootstrap,
927
+ * many ESM-only-by-default tools) use TLA at the entry point. With
928
+ * format:'cjs' those would crash with "Top-level await is currently
929
+ * not supported with the 'cjs' output format" — an esbuild
930
+ * SyntaxError surfaced as a Nimbus diagnostic. The user can't
931
+ * fix this without rewriting upstream.
932
+ *
933
+ * Fix: when caller asks for format 'cjs' AND the source has a
934
+ * top-level await, wrap the source in an async IIFE:
935
+ *
936
+ * ;(async () => {
937
+ * <original-source>
938
+ * })();
939
+ *
940
+ * Inside the IIFE, await is legal.
941
+ *
942
+ * ESM-imports-in-CJS note (nuxt-esm-in-cjs wave):
943
+ * ─────────────────────────────────────────────────
944
+ * The IIFE wrap above moves the user source INTO a function body.
945
+ * Top-level ESM `import` statements are LEGAL only at module top
946
+ * level — inside a function body they're a SyntaxError. Real-world
947
+ * trigger: nuxi's `bin/nuxi.mjs` opens with `import { performance }
948
+ * from "node:perf_hooks"` and ends with `const { runMain } = await
949
+ * import("./dist/index.mjs"); runMain()` — both ESM imports AND TLA.
950
+ * Pre-fix the IIFE wrap caused esbuild to fail with
951
+ * `Unexpected "<binding>"` at line 3 of stdin.
952
+ *
953
+ * Fix: when TLA AND ESM imports coexist, run a two-stage transform:
954
+ * 1. Pass 1: `esbuild.transform(code, { format: 'esm', ... })` —
955
+ * esbuild accepts TLA + imports cleanly when emitting ESM.
956
+ * Output is JS-canonicalised: multi-line imports collapsed,
957
+ * bindings normalised, etc.
958
+ * 2. Extract top-level imports from the pass-1 output and rewrite
959
+ * them as `const X = require(...)` shims (see
960
+ * `convertEsmImportsToRequire` for the contract / shape).
961
+ * 3. Wrap the remaining body in the async IIFE.
962
+ * 4. Return the assembled string as the transform result.
963
+ *
964
+ * The require-shim emits the standard `__esModule` interop check
965
+ * (matches what esbuild itself emits for ESM→CJS conversions), so
966
+ * default-export binding semantics are preserved.
967
+ *
968
+ * If TLA but no ESM imports → existing single-pass IIFE wrap.
969
+ * If ESM imports but no TLA → existing single-pass esbuild
970
+ * format:cjs (it auto-converts ESM→CJS gracefully).
971
+ *
972
+ * This is bytes-stable for sources outside the TLA+ESM-imports
973
+ * intersection.
974
+ */
975
+ async transform(code, options) {
976
+ await this.ensureInit();
977
+ const format = options?.format || 'esm';
978
+ const loader = options?.loader || 'ts';
979
+ // ── CJS + TLA + ESM imports: two-pass with import rewrite ──
980
+ // This precedes the simple TLA-only IIFE wrap. We test ESM imports
981
+ // first because the IIFE wrap is incompatible with them; if both
982
+ // conditions hold we MUST go through the rewrite path.
983
+ if (format === 'cjs' && hasTopLevelAwait(code) && hasEsmImports(code)) {
984
+ // Pass 1: emit ESM so esbuild accepts TLA + imports without complaint.
985
+ // We use the same loader/target so TS/JSX is handled here too.
986
+ const pass1 = await this._esbuild.transform(code, {
987
+ loader,
988
+ format: 'esm',
989
+ target: options?.target || 'esnext',
990
+ sourcemap: false, // pass-1 source map is discarded; pass-2 doesn't run esbuild
991
+ minify: false, // minify only on the final output if requested
992
+ jsx: options?.jsx,
993
+ jsxFactory: options?.jsxFactory,
994
+ jsxFragment: options?.jsxFragment,
995
+ tsconfigRaw: options?.tsconfigRaw,
996
+ define: options?.define,
997
+ // Dynamic-import lowering: rewrites `import(x)` to
998
+ // `Promise.resolve().then(() => __toESM(require(x)))` so the
999
+ // call routes through Nimbus's scopedRequire → VFS lookup
1000
+ // instead of workerd's worker-module-map resolver (which only
1001
+ // knows {'runner.js': workerCode}). Without this, every user
1002
+ // dynamic import() rejects with "No such module ..." — and if
1003
+ // user code has no .catch() (e.g. create-astro.mjs's
1004
+ // `import('./dist/index.js').then(({main}) => main())`), the
1005
+ // rejection is unhandled and the facet exits silently
1006
+ // exitCode=0. See .seal-internal/2026-05-11-astro-silent-exit/audit.md.
1007
+ supported: { 'dynamic-import': false },
1008
+ });
1009
+ const { requires, body } = convertEsmImportsToRequire(pass1.code);
1010
+ const assembled = requires + '\n' +
1011
+ ';(async () => {\n' +
1012
+ body +
1013
+ '\n})().catch((e) => { console.error(e && e.stack || e); });\n';
1014
+ return {
1015
+ code: assembled,
1016
+ map: '',
1017
+ warnings: pass1.warnings?.map((w) => ({
1018
+ text: w.text,
1019
+ location: w.location,
1020
+ })) || [],
1021
+ };
1022
+ }
1023
+ // ── CJS + TLA (no ESM imports): single-pass IIFE wrap (P2 fix) ──
1024
+ let sourceToTransform = code;
1025
+ if (format === 'cjs' && hasTopLevelAwait(code)) {
1026
+ sourceToTransform =
1027
+ ';(async () => {\n' +
1028
+ code +
1029
+ '\n})().catch((e) => { console.error(e && e.stack || e); });\n';
1030
+ }
1031
+ const result = await this._esbuild.transform(sourceToTransform, {
1032
+ loader,
1033
+ format,
1034
+ target: options?.target || 'esnext',
1035
+ sourcemap: options?.sourcemap ?? false,
1036
+ minify: options?.minify ?? false,
1037
+ jsx: options?.jsx,
1038
+ jsxFactory: options?.jsxFactory,
1039
+ jsxFragment: options?.jsxFragment,
1040
+ tsconfigRaw: options?.tsconfigRaw,
1041
+ define: options?.define,
1042
+ // Dynamic-import lowering — see two-pass branch above for rationale.
1043
+ supported: { 'dynamic-import': false },
1044
+ });
1045
+ return {
1046
+ code: result.code,
1047
+ map: result.map || '',
1048
+ warnings: result.warnings?.map(w => ({
1049
+ text: w.text,
1050
+ location: w.location,
1051
+ })) || [],
1052
+ };
1053
+ }
1054
+ /**
1055
+ * Bundle entry points from the VFS.
1056
+ */
1057
+ async build(entryPoints, options) {
1058
+ await this.ensureInit();
1059
+ // VFS plugin reads directly from VFS (synchronous, co-located)
1060
+ const vfsPlugin = this.makeVfsPlugin();
1061
+ const result = await this._esbuild.build({
1062
+ entryPoints: entryPoints.map(ep => ep.startsWith('/') ? ep : '/' + ep),
1063
+ bundle: options?.bundle ?? true,
1064
+ write: false,
1065
+ format: options?.format || 'esm',
1066
+ target: options?.target || 'esnext',
1067
+ platform: options?.platform || 'browser',
1068
+ outdir: options?.outdir || (options?.outfile ? undefined : '/dist'),
1069
+ outfile: options?.outfile,
1070
+ sourcemap: options?.sourcemap ?? false,
1071
+ minify: options?.minify ?? false,
1072
+ external: options?.external,
1073
+ define: options?.define,
1074
+ globalName: options?.globalName,
1075
+ tsconfigRaw: options?.tsconfigRaw,
1076
+ alias: options?.alias,
1077
+ keepNames: options?.keepNames,
1078
+ // Prefer ESM builds and modern module fields. This matters for packages
1079
+ // like zustand that ship both CJS (main) and ESM (module / exports.import).
1080
+ // Without these, esbuild falls back to CJS which wraps everything in
1081
+ // __commonJS and only emits `export default`, losing named exports.
1082
+ conditions: ['import', 'module', 'browser', 'default'],
1083
+ mainFields: ['module', 'browser', 'main'],
1084
+ plugins: [vfsPlugin],
1085
+ });
1086
+ return {
1087
+ outputFiles: (result.outputFiles || []).map(f => ({
1088
+ path: f.path,
1089
+ contents: f.text,
1090
+ })),
1091
+ errors: result.errors?.map(e => ({ text: e.text, location: e.location })) || [],
1092
+ warnings: result.warnings?.map(w => ({ text: w.text, location: w.location })) || [],
1093
+ };
1094
+ }
1095
+ /**
1096
+ * VFS resolver plugin for esbuild.
1097
+ * Reads directly from the SqliteVFS (synchronous, co-located — no snapshot needed).
1098
+ * Handles: absolute paths, relative paths, bare specifiers (node_modules).
1099
+ */
1100
+ makeVfsPlugin() {
1101
+ const vfs = this.vfs;
1102
+ const EXTS = ['', '.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs', '.cjs', '.json', '.css'];
1103
+ const INDEX_FILES = ['index.ts', 'index.tsx', 'index.js', 'index.jsx', 'index.mjs'];
1104
+ // Path helpers shared with git-commands via ./vfs-path.ts.
1105
+ // Local aliases preserve the existing call-site readability inside this
1106
+ // closure; behavior is identical (the canonical normalizeVfsPath has a
1107
+ // bounds check on `..` that the previous local `normalize` lacked, but
1108
+ // for the well-formed paths esbuild produces this is a no-op).
1109
+ const strip = stripLeadingSlashes;
1110
+ const normalize = normalizeVfsPath;
1111
+ /**
1112
+ * Try to resolve a VFS path with extension/index fallbacks.
1113
+ *
1114
+ * Resolution order (first match wins):
1115
+ * 1. Exact path as given (covers `.ts`, `.js`, `.json`, `.css`, and
1116
+ * any extension on disk) — via `''` being first in EXTS.
1117
+ * 2. Append-extension candidates from EXTS (`.ts`, `.tsx`, `.js`, …)
1118
+ * for extensionless imports like `./foo`.
1119
+ * 3. TypeScript/ESM `moduleResolution: "bundler"` compatibility:
1120
+ * if the input ends in `.js` / `.mjs` / `.cjs` / `.jsx` and
1121
+ * NO file matched above, swap the extension to the TS
1122
+ * equivalent and try those. This is the idiomatic
1123
+ * `import {X} from './y.js'` pattern where on-disk it's `y.ts`.
1124
+ * Order (TS spec): `.ts` → `.tsx` for `.js`/`.jsx`;
1125
+ * `.mts` for `.mjs`;
1126
+ * `.cts` for `.cjs`.
1127
+ * Exact-match (step 1) happens first so a real `.js` on disk
1128
+ * takes precedence over a co-located `.ts` — we never pretend
1129
+ * a `.ts` is canonical when a `.js` actually exists.
1130
+ * 4. Directory index files (e.g. `./foo/index.ts`) as a last step.
1131
+ */
1132
+ function tryResolve(base) {
1133
+ const norm = normalize(base);
1134
+ for (const ext of EXTS) {
1135
+ const candidate = norm + ext;
1136
+ if (vfs.exists(strip(candidate)) && !vfs.isDirectory(strip(candidate))) {
1137
+ return '/' + strip(candidate);
1138
+ }
1139
+ }
1140
+ // Step 3: TypeScript-bundler extension swap. Only runs when no
1141
+ // exact / extension-append match succeeded above — so real `.js`
1142
+ // files on disk always win.
1143
+ const jsExtMatch = norm.match(/\.(js|mjs|cjs|jsx)$/);
1144
+ if (jsExtMatch) {
1145
+ const withoutExt = norm.slice(0, norm.length - jsExtMatch[0].length);
1146
+ const swapMap = {
1147
+ js: ['.ts', '.tsx'],
1148
+ jsx: ['.tsx', '.ts'],
1149
+ mjs: ['.mts', '.ts'],
1150
+ cjs: ['.cts', '.ts'],
1151
+ };
1152
+ const swaps = swapMap[jsExtMatch[1]] || [];
1153
+ for (const tsExt of swaps) {
1154
+ const candidate = withoutExt + tsExt;
1155
+ if (vfs.exists(strip(candidate)) && !vfs.isDirectory(strip(candidate))) {
1156
+ return '/' + strip(candidate);
1157
+ }
1158
+ }
1159
+ }
1160
+ // Step 4: directory index fallback.
1161
+ if (vfs.exists(strip(norm)) && vfs.isDirectory(strip(norm))) {
1162
+ for (const idx of INDEX_FILES) {
1163
+ const candidate = norm + '/' + idx;
1164
+ if (vfs.exists(strip(candidate)))
1165
+ return '/' + strip(candidate);
1166
+ }
1167
+ }
1168
+ return null;
1169
+ }
1170
+ /**
1171
+ * Resolve a Node.js subpath import (`#foo`).
1172
+ *
1173
+ * Per https://nodejs.org/api/packages.html#subpath-imports, a specifier
1174
+ * starting with `#` is looked up in the closest ancestor package.json's
1175
+ * `imports` field (not `exports`). This is used by packages like `vfile`
1176
+ * to switch between node and browser implementations:
1177
+ *
1178
+ * "imports": {
1179
+ * "#minpath": {
1180
+ * "node": "./lib/minpath.js",
1181
+ * "default": "./lib/minpath.browser.js"
1182
+ * }
1183
+ * }
1184
+ *
1185
+ * We walk up from the importer's directory looking for package.json.
1186
+ * Once found, we resolve the subpath using the same condition algorithm
1187
+ * as `exports` (with `import`, `module`, `browser`, `default` — skipping
1188
+ * `node` since we're bundling for the browser).
1189
+ *
1190
+ * The resolved value is a path relative to the owning package root, which
1191
+ * we turn back into a VFS path for esbuild to load.
1192
+ */
1193
+ function resolvePackageImport(specifier, fromDir) {
1194
+ let dir = strip(fromDir);
1195
+ const visited = new Set();
1196
+ while (dir && !visited.has(dir)) {
1197
+ visited.add(dir);
1198
+ const pkgJsonPath = dir + '/package.json';
1199
+ if (vfs.exists(strip(pkgJsonPath))) {
1200
+ try {
1201
+ const pkgJson = JSON.parse(vfs.readFileString(strip(pkgJsonPath)));
1202
+ if (pkgJson.imports) {
1203
+ // resolveExports happens to work for the imports field too —
1204
+ // both are subpath→condition maps using the same format. We
1205
+ // reuse it. The specifier (`#minpath`) IS the subpath key.
1206
+ const resolved = resolveExports(pkgJson.imports, specifier);
1207
+ if (resolved) {
1208
+ // Resolved value is relative to the owning package root
1209
+ const pkgRoot = dir;
1210
+ const absPath = pkgRoot + '/' + resolved.replace(/^\.\//, '');
1211
+ const finalPath = tryResolve(absPath);
1212
+ if (finalPath)
1213
+ return finalPath;
1214
+ }
1215
+ }
1216
+ }
1217
+ catch { /* malformed package.json — try parent */ }
1218
+ }
1219
+ // Stop at node_modules boundary — subpath imports only resolve against
1220
+ // the consuming package's own package.json, not its dependencies'.
1221
+ // But DO go up through node_modules/<pkg>/ to find <pkg>/package.json.
1222
+ if (dir.endsWith('/node_modules') || dir === 'node_modules')
1223
+ break;
1224
+ const lastSlash = dir.lastIndexOf('/');
1225
+ if (lastSlash <= 0)
1226
+ break;
1227
+ dir = dir.substring(0, lastSlash);
1228
+ }
1229
+ return null;
1230
+ }
1231
+ // Conditions per-resolution. CJS `require('X')` callers need the
1232
+ // `require` condition selected so packages that ship a dual-export
1233
+ // CJS trick (e.g. @babel/runtime/helpers/X — `module.exports = fn;
1234
+ // module.exports.default = module.exports;`) resolve to the CJS
1235
+ // file. The ESM helper file declares only `export { fn as default }`,
1236
+ // which esbuild's __toCommonJS wrap surfaces to CJS callers as
1237
+ // `{ default: fn }` — and the downstream callsite calls the
1238
+ // namespace as a function and crashes with
1239
+ // `_objectWithoutPropertiesLoose2 is not a function`.
1240
+ //
1241
+ // This affects every CJS-shipping npm package that depends on
1242
+ // `@babel/runtime/helpers/*` (thousands — anything compiled with
1243
+ // `@babel/preset-env`'s `transform-runtime`).
1244
+ // See pre-bundle-facet.ts for the matching fix in the install-time
1245
+ // pre-bundle plugin. Both code paths must agree.
1246
+ const ESM_CONDITIONS = ['import', 'module', 'browser', 'default'];
1247
+ const CJS_CONDITIONS = ['require', 'node', 'browser', 'default'];
1248
+ /**
1249
+ * Resolve bare specifier (npm package) by walking up node_modules.
1250
+ * Uses the full Node.js exports-field algorithm. `conditions` is
1251
+ * passed through so caller can request CJS-flavoured resolution
1252
+ * (for `require()` calls in bundled CJS code).
1253
+ */
1254
+ function resolveBarePkg(specifier, fromDir, conditions) {
1255
+ // Split scoped packages: @scope/pkg → ["@scope/pkg"]
1256
+ // Split subpath imports: pkg/sub/path → pkg, sub/path
1257
+ let pkgName;
1258
+ let subpath;
1259
+ if (specifier.startsWith('@')) {
1260
+ const parts = specifier.split('/');
1261
+ pkgName = parts.slice(0, 2).join('/');
1262
+ subpath = parts.slice(2).join('/');
1263
+ }
1264
+ else {
1265
+ const parts = specifier.split('/');
1266
+ pkgName = parts[0];
1267
+ subpath = parts.slice(1).join('/');
1268
+ }
1269
+ // Walk up directories looking for node_modules/<pkg>
1270
+ let dir = strip(fromDir);
1271
+ const visited = new Set();
1272
+ while (dir && !visited.has(dir)) {
1273
+ visited.add(dir);
1274
+ const nmDir = dir + '/node_modules/' + pkgName;
1275
+ if (vfs.exists(strip(nmDir)) && vfs.isDirectory(strip(nmDir))) {
1276
+ // Read package.json so we can consult the exports field.
1277
+ const pkgJsonPath = nmDir + '/package.json';
1278
+ let pkgJson = null;
1279
+ if (vfs.exists(strip(pkgJsonPath))) {
1280
+ try {
1281
+ pkgJson = JSON.parse(vfs.readFileString(strip(pkgJsonPath)));
1282
+ }
1283
+ catch { }
1284
+ }
1285
+ if (pkgJson) {
1286
+ // Use the full exports-field resolution. Conditions are
1287
+ // caller-supplied so `require()` and `import` get distinct
1288
+ // resolutions per Node spec.
1289
+ const subpathKey = subpath ? './' + subpath : '.';
1290
+ const entry = resolvePackageEntry(pkgJson, subpathKey, conditions);
1291
+ if (entry) {
1292
+ const resolved = tryResolve(nmDir + '/' + entry.replace(/^\.\//, ''));
1293
+ if (resolved)
1294
+ return resolved;
1295
+ }
1296
+ }
1297
+ // Fallback for subpath: try direct file resolution (e.g. pkg/lib/foo).
1298
+ if (subpath) {
1299
+ const resolved = tryResolve(nmDir + '/' + subpath);
1300
+ if (resolved)
1301
+ return resolved;
1302
+ }
1303
+ // Fallback for root: try index files directly
1304
+ const resolved = tryResolve(nmDir + '/index');
1305
+ if (resolved)
1306
+ return resolved;
1307
+ }
1308
+ // Move up one directory
1309
+ const lastSlash = dir.lastIndexOf('/');
1310
+ if (lastSlash <= 0)
1311
+ break;
1312
+ dir = dir.substring(0, lastSlash);
1313
+ }
1314
+ return null;
1315
+ }
1316
+ function inferLoader(path) {
1317
+ if (path.endsWith('.ts') || path.endsWith('.mts') || path.endsWith('.cts'))
1318
+ return 'ts';
1319
+ if (path.endsWith('.tsx'))
1320
+ return 'tsx';
1321
+ if (path.endsWith('.jsx'))
1322
+ return 'jsx';
1323
+ if (path.endsWith('.json'))
1324
+ return 'json';
1325
+ if (path.endsWith('.css'))
1326
+ return 'css';
1327
+ // Native binaries — load as base64 blobs instead of parsing as JS.
1328
+ // Defense-in-depth: the npm-installer pre-bundler also skips these,
1329
+ // but on-demand bundling or direct `import 'foo.wasm'` could still
1330
+ // hand us a raw WASM/native-addon path.
1331
+ if (path.endsWith('.wasm'))
1332
+ return 'binary';
1333
+ if (path.endsWith('.node'))
1334
+ return 'binary';
1335
+ return 'js';
1336
+ }
1337
+ return {
1338
+ name: 'nimbus-vfs',
1339
+ setup(build) {
1340
+ // Pre-compile the external list into exact matches and prefix patterns.
1341
+ // esbuild's `external` supports glob-like patterns (`react/*`) — we
1342
+ // reproduce that here so our plugin doesn't override the user's
1343
+ // external directive by resolving packages that should stay external.
1344
+ const externalList = build.initialOptions.external || [];
1345
+ const externalExact = new Set();
1346
+ const externalPrefixes = [];
1347
+ for (const pat of externalList) {
1348
+ if (pat.endsWith('/*')) {
1349
+ externalPrefixes.push(pat.slice(0, -1)); // "react/" prefix (for "react/*")
1350
+ }
1351
+ else {
1352
+ externalExact.add(pat);
1353
+ }
1354
+ }
1355
+ const isExternal = (spec) => {
1356
+ if (externalExact.has(spec))
1357
+ return true;
1358
+ for (const pre of externalPrefixes) {
1359
+ if (spec.startsWith(pre))
1360
+ return true;
1361
+ }
1362
+ return false;
1363
+ };
1364
+ build.onResolve({ filter: /.*/ }, (args) => {
1365
+ // 1. Subpath imports (#foo) — Node.js package.json `imports` field.
1366
+ // These MUST be resolved against the owning package's package.json,
1367
+ // not node_modules. Used by vfile, unified, and others to switch
1368
+ // between node/browser implementations.
1369
+ if (args.path.startsWith('#') && args.resolveDir) {
1370
+ const resolved = resolvePackageImport(args.path, strip(args.resolveDir));
1371
+ if (resolved)
1372
+ return { path: resolved, namespace: 'nimbus-vfs' };
1373
+ // If we can't resolve it, fall through — better to leak a bare
1374
+ // import that fails loudly than to pretend it's external.
1375
+ }
1376
+ // 2. Bare specifier + external → leave as-is so the browser resolves
1377
+ // via its own module resolver (which hits /preview/@modules/...).
1378
+ // This MUST come before any vfs resolution, otherwise we'd embed
1379
+ // the package into the bundle and break single-instance invariants
1380
+ // for react/react-dom.
1381
+ if (!args.path.startsWith('/') && !args.path.startsWith('.') && !args.path.startsWith('#')) {
1382
+ if (isExternal(args.path))
1383
+ return { external: true };
1384
+ }
1385
+ // 3. Absolute paths
1386
+ if (args.path.startsWith('/')) {
1387
+ const resolved = tryResolve(args.path);
1388
+ if (resolved)
1389
+ return { path: resolved, namespace: 'nimbus-vfs' };
1390
+ }
1391
+ // 4. Relative paths
1392
+ if (args.path.startsWith('.') && args.resolveDir) {
1393
+ const dir = strip(args.resolveDir);
1394
+ const resolved = tryResolve(dir + '/' + args.path);
1395
+ if (resolved)
1396
+ return { path: resolved, namespace: 'nimbus-vfs' };
1397
+ }
1398
+ // 5. Bare specifier (npm package)
1399
+ if (!args.path.startsWith('/') && !args.path.startsWith('.') && !args.path.startsWith('#')) {
1400
+ const fromDir = args.resolveDir || '/home/user';
1401
+ // Per Node spec: `require()` triggers the 'require' condition,
1402
+ // `import` triggers 'import'. esbuild surfaces this via
1403
+ // args.kind. Without this, packages that ship a dual-export
1404
+ // CJS file alongside a bare ESM file (e.g. @babel/runtime/
1405
+ // helpers/*) get resolved to the ESM variant for CJS callers,
1406
+ // and the `__toCommonJS` wrapper surfaces `{ default: fn }`
1407
+ // to a callsite that expects the function directly — runtime
1408
+ // crash with "<helper>2 is not a function" on the first
1409
+ // route that uses the affected package.
1410
+ const conditions = args.kind === 'require-call' || args.kind === 'require-resolve'
1411
+ ? CJS_CONDITIONS
1412
+ : ESM_CONDITIONS;
1413
+ const resolved = resolveBarePkg(args.path, fromDir, conditions);
1414
+ if (resolved)
1415
+ return { path: resolved, namespace: 'nimbus-vfs' };
1416
+ // Mark as external if not found (common for Node built-ins)
1417
+ return { external: true };
1418
+ }
1419
+ return { external: true };
1420
+ });
1421
+ build.onLoad({ filter: /.*/, namespace: 'nimbus-vfs' }, (args) => {
1422
+ const stripped = strip(args.path);
1423
+ try {
1424
+ const loader = inferLoader(args.path);
1425
+ const lastSlash = stripped.lastIndexOf('/');
1426
+ const resolveDir = lastSlash > 0 ? '/' + stripped.substring(0, lastSlash) : '/';
1427
+ // Binary loaders (wasm, native addons) must receive raw bytes.
1428
+ // TextDecoder would corrupt them with U+FFFD replacement chars.
1429
+ if (loader === 'binary') {
1430
+ const bytes = vfs.readFile(stripped);
1431
+ return { contents: bytes, loader, resolveDir };
1432
+ }
1433
+ const contents = vfs.readFileString(stripped);
1434
+ return { contents, loader, resolveDir };
1435
+ }
1436
+ catch {
1437
+ return { errors: [{ text: 'File not found in VFS: ' + args.path }] };
1438
+ }
1439
+ });
1440
+ },
1441
+ };
1442
+ }
1443
+ get isInitialized() { return this.initialized; }
1444
+ }