@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,981 @@
1
+ /**
2
+ * cirrus-real.ts — Real Vite inside a Cloudflare DO facet.
3
+ *
4
+ * Ships alongside the in-process Cirrus shim (src/vite-dev-server.ts,
5
+ * untouched). Users opt into real-vite mode via `NIMBUS_REAL_VITE=1`
6
+ * or `nimbusDevServer: 'real'` in vite.config.ts.
7
+ *
8
+ * Phase status (PHASE2-REAL-VITE-PLAN.md):
9
+ * 0 (import + createServer + listen) — GREEN, shipped
10
+ * 1 (VFS-backed fs shim) — implemented here
11
+ * 2 (HMR over our /ws) — implemented here
12
+ * 3 (real @vitejs/plugin-react) — depends on plugin preload
13
+ * 4 (opt-in polish + boot banner) — implemented in nimbus-session
14
+ *
15
+ * Architecture:
16
+ *
17
+ * NimbusSession (supervisor DO)
18
+ * │
19
+ * │ LOADER.load({
20
+ * │ modules: {
21
+ * │ main.js — facet entrypoint (generated)
22
+ * │ vite.bundle.js — 2.3 MB real Vite (pre-bundled)
23
+ * │ cirrus-fs.js — our fs shim (src/real-vite-fs-shim.ts)
24
+ * │ cirrus-fs-promises.js — ditto (fs/promises)
25
+ * │ cirrus-ws.js — our ws-shim (src/real-vite-hmr.ts)
26
+ * │ cirrus-chokidar.js — our chokidar shim (src/real-vite-hmr.ts)
27
+ * │ real-node-fs.js — raw node:fs re-export
28
+ * │ synthetic.js — seeds globalThis.__cirrusRealFs
29
+ * │ with the VFS snapshot
30
+ * │ user-vite-config.js — pre-bundled vite.config.ts
31
+ * │ }
32
+ * │ })
33
+ * ▼
34
+ * Dynamic Worker (facet)
35
+ * - imports synthetic.js (side-effect: populates globalThis.__cirrusRealFs)
36
+ * - imports vite.bundle.js (evaluates, sees the seeded fs Map)
37
+ * - starts Vite server via `createServer().listen()`
38
+ * - exposes fetch via httpServerHandler({port}) from cloudflare:node
39
+ * - runs a long-poll loop against env.SUPERVISOR.hmrNextEvent
40
+ * that delivers VFS change events to the chokidar shim + HMR
41
+ * client messages to the ws shim
42
+ *
43
+ * All traffic in / out:
44
+ * Browser ──/preview/* ──> DO.fetch ──> facetStub.fetch
45
+ * Browser ──/preview/__nimbus_hmr──> DO.fetch (WS upgrade)
46
+ * │
47
+ * ▼
48
+ * HmrBridge (nimbus-session-side)
49
+ * │ long-poll
50
+ * ▼
51
+ * facet loop ──> chokidar / ws shim
52
+ */
53
+ // [sdk-phase-1] Large blobs (REAL_VITE_BUNDLE 4.6 MB, ROLLUP_WASM 2.5 MB,
54
+ // CIRRUS_PLUGIN_REACT_BUNDLE 3.0 MB) now ship via the ASSETS binding
55
+ // instead of inline. We import async getters here; start() became async
56
+ // so it can await them. CIRRUS_NPM_CJS_BUNDLES stays inline (1.2 MB,
57
+ // used inside the sync part of start()).
58
+ import { REAL_VITE_VERSION, VITE_CLIENT_MJS, VITE_ENV_MJS, getRealViteBundle, getRollupWasmBase64, } from '../real-vite-bundle.generated.js';
59
+ import { CIRRUS_PLUGIN_REACT_VERSION, getCirrusPluginReactBundle, } from '../cirrus-plugin-react.generated.js';
60
+ import { CIRRUS_NPM_CJS_BUNDLES, CIRRUS_NPM_CJS_VERSIONS } from '../cirrus-npm-cjs.generated.js';
61
+ import { CF_COMPAT_DATE } from '../constants.js';
62
+ import { getCtxExports } from '../session/ctx-exports.js';
63
+ import { buildFsSnapshot, generateFsShimModuleCode, generateFsPromisesShimModuleCode, generateSyntheticModuleCode, } from './real-vite-fs-shim.js';
64
+ import { HmrBridge, registerHmrBridge, generateWsShimModuleCode, generateChokidarShimModuleCode, } from './real-vite-hmr.js';
65
+ /**
66
+ * Compatibility flags for the real-vite facet.
67
+ *
68
+ * nodejs_compat — base Node polyfills
69
+ * enable_nodejs_http_modules — http.get / http.request
70
+ * enable_nodejs_http_server_modules — http.createServer / Server
71
+ *
72
+ * (expose_global_message_channel is not strictly required for our flow
73
+ * since we don't use Worker in FakeWorker mode yet; add later if needed.)
74
+ */
75
+ const REAL_VITE_COMPAT_FLAGS = [
76
+ 'nodejs_compat',
77
+ 'enable_nodejs_http_modules',
78
+ 'enable_nodejs_http_server_modules',
79
+ ];
80
+ /**
81
+ * Resolve opt-in mode.
82
+ *
83
+ * Priority: env var > vite.config.ts regex sniff > default ('cirrus').
84
+ */
85
+ export function shouldUseRealVite(opts) {
86
+ const env = opts.env || {};
87
+ const v = env.NIMBUS_REAL_VITE;
88
+ if (v != null) {
89
+ const s = String(v).trim().toLowerCase();
90
+ if (s === '1' || s === 'true' || s === 'yes' || s === 'real')
91
+ return true;
92
+ if (s === '0' || s === 'false' || s === 'no' || s === 'cirrus' || s === 'shim')
93
+ return false;
94
+ }
95
+ const cfg = opts.viteConfigSource;
96
+ if (cfg) {
97
+ // Regex-only (safe: no eval). Matches `nimbusDevServer: 'real'` /
98
+ // `'shim'` / `'auto'` with either quote style.
99
+ const m = cfg.match(/nimbusDevServer\s*:\s*['"]([a-z-]+)['"]/i);
100
+ if (m) {
101
+ const mode = m[1].toLowerCase();
102
+ if (mode === 'real' || mode === 'real-vite')
103
+ return true;
104
+ if (mode === 'cirrus' || mode === 'shim')
105
+ return false;
106
+ if (mode === 'auto') {
107
+ // Heuristic: if the config imports any @vitejs/* plugin, prefer
108
+ // real-vite; otherwise stick with Cirrus.
109
+ return /@vitejs\/plugin-[\w-]+/.test(cfg);
110
+ }
111
+ }
112
+ }
113
+ return false;
114
+ }
115
+ // ── Facet entrypoint source generator ─────────────────────────────────
116
+ function generateMainModuleCode(opts) {
117
+ const { port, root, basePath, hasUserViteConfig } = opts;
118
+ const configImportLine = hasUserViteConfig
119
+ ? `import __userConfig from './user-vite-config.js';`
120
+ : `const __userConfig = {};`;
121
+ return `
122
+ // ── Facet entrypoint: real Vite in a DO Facet [D'.1] ───────────────
123
+ // Generated by src/cirrus-real.ts.
124
+ //
125
+ // Track D' / D'.1: this module exports a DurableObject class so the
126
+ // supervisor can spawn it via ctx.facets.get('cirrus-real-vite',
127
+ // {class}). The facet has its own SQLite (this.ctx.storage) which we
128
+ // use to persist a per-facet identity cookie — that's what proves
129
+ // the same facet instance is reused across supervisor reconnects vs.
130
+ // being re-created from scratch.
131
+ //
132
+ // Pre-D'.1 the export was \`export default { fetch(req, env, ctx) }\`
133
+ // — a stateless WorkerEntrypoint shape spawned via env.LOADER.load().
134
+ // That worker had no own storage and was rebuilt on every start().
135
+ import { DurableObject } from "cloudflare:workers";
136
+
137
+ globalThis.__cirrusFsDebug = false;
138
+ globalThis.__cirrusResolveDebug = false;
139
+ // CLN-3 (2026-05-11): umbrella debug flag for hot-path HMR / dispatch /
140
+ // memory-snapshot / WS-accept logs in cirrus-real.ts + real-vite-hmr.ts.
141
+ // Default off in prod. Diagnostic users mutate at runtime
142
+ // (globalThis.__cirrusDebug = true) or ship a temp-deploy with the
143
+ // literal "= true" here. Mirrors the __cirrusFsDebug / __cirrusResolveDebug pattern.
144
+ globalThis.__cirrusDebug = false;
145
+
146
+ // ── Phase-A memory telemetry ──────────────────────────────────────
147
+ // Records process.memoryUsage() at key phases so we can measure
148
+ // exactly where heap grows. Numbers go to the supervisor RPC
149
+ // (telemetry.report) AND stdout for the wrangler log.
150
+ let __cirrusPhaseBaseline = null;
151
+ function __cirrusMem(phase) {
152
+ try {
153
+ const mu = process.memoryUsage();
154
+ const cache = globalThis.__cirrusRealFs?.files?.size ?? 0;
155
+ const cacheBytes = globalThis.__cirrusRealFsLruSize ?? 0;
156
+ const row = {
157
+ phase,
158
+ heapUsed: (mu.heapUsed / 1024 / 1024).toFixed(1) + 'MB',
159
+ heapTotal: (mu.heapTotal / 1024 / 1024).toFixed(1) + 'MB',
160
+ rss: (mu.rss / 1024 / 1024).toFixed(1) + 'MB',
161
+ external: (mu.external / 1024 / 1024).toFixed(1) + 'MB',
162
+ cacheEntries: cache,
163
+ cacheKB: (cacheBytes / 1024).toFixed(0) + 'KB',
164
+ };
165
+ if (__cirrusPhaseBaseline == null) __cirrusPhaseBaseline = mu.heapUsed;
166
+ row.delta = '+' + ((mu.heapUsed - __cirrusPhaseBaseline) / 1024 / 1024).toFixed(1) + 'MB';
167
+ if (globalThis.__cirrusDebug) console.log('[cirrus-mem]', JSON.stringify(row));
168
+ } catch (e) {
169
+ if (globalThis.__cirrusDebug) console.log('[cirrus-mem]', phase, 'err:', e?.message || e);
170
+ }
171
+ }
172
+ __cirrusMem('module-top (pre-imports)');
173
+
174
+ // workerd sometimes terminates the isolate without surfacing the
175
+ // failure on stdout — install uncaught handlers so we at least see
176
+ // the event in the wrangler log.
177
+ try {
178
+ globalThis.addEventListener?.('error', (ev) => {
179
+ try { console.error('[cirrus-real uncaught]', ev.error?.stack || ev.error?.message || ev.message); } catch {}
180
+ });
181
+ globalThis.addEventListener?.('unhandledrejection', (ev) => {
182
+ try { console.error('[cirrus-real unhandledrejection]', ev.reason?.stack || ev.reason?.message || ev.reason); } catch {}
183
+ });
184
+ } catch {}
185
+
186
+ import { createRequire as __cirrusCreateRequire } from 'node:module';
187
+ globalThis.__cirrusNodeCreateRequire = __cirrusCreateRequire;
188
+
189
+ import './synthetic.js';
190
+ __cirrusMem('post synthetic.js');
191
+ import './cirrus-ws.js';
192
+ import './cirrus-chokidar.js';
193
+ __cirrusMem('post ws+chokidar shims');
194
+
195
+ ${configImportLine}
196
+ __cirrusMem('post user-vite-config.js');
197
+
198
+ import * as vite from './vite.bundle.js';
199
+ __cirrusMem('post vite.bundle.js');
200
+ import { httpServerHandler } from 'cloudflare:node';
201
+ __cirrusMem('all imports complete');
202
+
203
+ const PORT = ${port};
204
+ const ROOT = ${JSON.stringify(root)};
205
+ const BASE = ${JSON.stringify(basePath)};
206
+
207
+ let serverReady = null;
208
+ let readyError = null;
209
+ let boot = null;
210
+ let viteServerInstance = null;
211
+
212
+ // Env bindings — made available to the fs shim + HMR loop via
213
+ // globalThis so modules loaded AFTER the first fetch handler can
214
+ // reach them without needing env passed through.
215
+ let _supervisorBinding = null;
216
+ let _hmrBinding = null;
217
+
218
+ function installBindings(env) {
219
+ const sup = env?.SUPERVISOR;
220
+ if (sup && !_supervisorBinding) {
221
+ _supervisorBinding = sup;
222
+ globalThis.__cirrusRealSupervisor = sup;
223
+ }
224
+ const hmr = env?.CIRRUS_HMR;
225
+ if (hmr && !_hmrBinding) {
226
+ _hmrBinding = hmr;
227
+ globalThis.__cirrusRealHmr = hmr;
228
+ }
229
+ }
230
+
231
+ // Pre-extract HMR controls once vite is ready, so the long-poll loop
232
+ // can dispatch events to the bundled-in chokidar-shim watchers and
233
+ // ws-shim connections.
234
+ function dispatchEvents(events) {
235
+ if (!events || events.length === 0) return;
236
+ if (globalThis.__cirrusDebug) console.log('[cirrus-real dispatch]', events.length, 'events. types:', events.map(e => e.type).join(','));
237
+ for (const ev of events) {
238
+ try {
239
+ if (ev.type === 'connection') {
240
+ const wss = globalThis.__cirrusRealWsServer;
241
+ if (globalThis.__cirrusDebug) console.log('[cirrus-real] connection event, wss?', !!wss);
242
+ if (wss) wss._acceptConnection(ev.clientId);
243
+ } else if (ev.type === 'message') {
244
+ const wss = globalThis.__cirrusRealWsServer;
245
+ if (wss) wss._dispatchMessage(ev.clientId, ev.msg);
246
+ } else if (ev.type === 'disconnect') {
247
+ const wss = globalThis.__cirrusRealWsServer;
248
+ if (wss) wss._disconnect(ev.clientId);
249
+ } else if (ev.type === 'vfs') {
250
+ const ws = globalThis.__cirrusRealWatchers;
251
+ if (ws) for (const w of ws) {
252
+ try { w._dispatch(ev.event, ev.path, ev.oldPath); } catch {}
253
+ }
254
+ // CRITICAL: invalidate the fs-shim snapshot cache so
255
+ // subsequent readFile calls hit SUPERVISOR.readFile and
256
+ // fetch the fresh content. Without this, Vite serves the
257
+ // OLD source on the HMR update cycle → browser reloads
258
+ // but sees the same content → user thinks HMR is broken.
259
+ if (globalThis.__cirrusRealFs) {
260
+ if (ev.event === 'unlink' || ev.event === 'unlinkDir') {
261
+ globalThis.__cirrusRealFs.files.delete(ev.path);
262
+ } else if (ev.event === 'change' || ev.event === 'add') {
263
+ globalThis.__cirrusRealFs.files.delete(ev.path);
264
+ } else if (ev.event === 'rename' && ev.oldPath) {
265
+ globalThis.__cirrusRealFs.files.delete(ev.oldPath);
266
+ globalThis.__cirrusRealFs.files.delete(ev.path);
267
+ }
268
+ }
269
+ }
270
+ } catch (e) {
271
+ console.warn('[cirrus-real] dispatchEvents item threw:', e?.message);
272
+ }
273
+ }
274
+ }
275
+
276
+ // Poll for HMR events — drive the pump off request cycles so we
277
+ // don't leave a long-poll dangling when no request is active
278
+ // (workerd may think the request itself is hung). Each fetch kicks
279
+ // the pump: a short-timeout poll (2s) that dispatches events and
280
+ // returns. If clients are connected, the pump schedules itself again
281
+ // via waitUntil.
282
+ async function pumpHmrOnce(ctx) {
283
+ if (!_hmrBinding) return;
284
+ try {
285
+ // Short timeout so we don't hold a request's waitUntil chain for
286
+ // too long. The supervisor returns immediately if there are
287
+ // pending events, so latency is fine.
288
+ const events = await _hmrBinding.hmrNextEvent(2_000);
289
+ dispatchEvents(events);
290
+ // Reschedule: if we have active WS clients or recent events, keep
291
+ // polling. Otherwise one shot per request is enough.
292
+ if (ctx?.waitUntil && (globalThis.__cirrusRealWsClients?.size > 0)) {
293
+ ctx.waitUntil(pumpHmrOnce(ctx));
294
+ }
295
+ } catch {
296
+ // RPC error (rare) — back off; next request will try again.
297
+ }
298
+ }
299
+
300
+ function bootOnce() {
301
+ if (serverReady) return serverReady;
302
+ __cirrusMem('bootOnce.start');
303
+ serverReady = (async () => {
304
+ try {
305
+ const resolvedUserConfig = typeof __userConfig === 'function'
306
+ ? await __userConfig({ command: 'serve', mode: 'development', isSsrBuild: false, isPreview: false })
307
+ : (__userConfig && typeof __userConfig === 'object' ? __userConfig : {});
308
+ const cfg = {
309
+ ...resolvedUserConfig,
310
+ root: ROOT || '/',
311
+ base: BASE,
312
+ configLoader: 'runner',
313
+ configFile: false, // we already loaded the config above
314
+ logLevel: 'info',
315
+ clearScreen: false,
316
+ optimizeDeps: {
317
+ ...(resolvedUserConfig.optimizeDeps || {}),
318
+ noDiscovery: true,
319
+ include: [],
320
+ force: false,
321
+ disabled: true,
322
+ entries: [],
323
+ esbuildOptions: { ...(resolvedUserConfig.optimizeDeps?.esbuildOptions || {}), plugins: [] },
324
+ },
325
+ // legacy.buildSsrCjsExternalHeuristics is a no-op but listed
326
+ // here as a reminder that we want zero esbuild invocations.
327
+ // Disable Vite's esbuild-based TS/JSX transform entirely.
328
+ // esbuild's JS API refuses to run when bundled into another
329
+ // file (it requires spawning a native binary). Plugins like
330
+ // @vitejs/plugin-react handle JSX transforms themselves via
331
+ // Babel, so we don't actually need the built-in esbuild
332
+ // transformer when a plugin is present.
333
+ esbuild: false,
334
+ server: {
335
+ ...(resolvedUserConfig.server || {}),
336
+ port: PORT,
337
+ host: '127.0.0.1',
338
+ strictPort: true,
339
+ fs: { strict: false, ...(resolvedUserConfig.server?.fs || {}) },
340
+ // HMR: path tells the browser @vite/client what URL to open
341
+ // (resolved against window.location.origin). We don't set
342
+ // clientPort/host so the browser uses same-origin — which
343
+ // is how the user reached us in the first place.
344
+ hmr: {
345
+ path: '__nimbus_hmr',
346
+ ...(typeof resolvedUserConfig.server?.hmr === 'object' ? resolvedUserConfig.server.hmr : {}),
347
+ },
348
+ // Enable file watching — our chokidar shim catches the
349
+ // chokidar.watch() call and returns a CirrusWatcher that
350
+ // delivers events from the HmrBridge long-poll. Disabling
351
+ // polling so the shim doesn't waste cycles.
352
+ watch: {
353
+ usePolling: false,
354
+ ...(resolvedUserConfig.server?.watch || {}),
355
+ },
356
+ },
357
+ appType: resolvedUserConfig.appType || 'spa',
358
+ };
359
+
360
+ __cirrusMem('bootOnce.before createServer');
361
+ const server = await vite.createServer(cfg);
362
+ viteServerInstance = server;
363
+ __cirrusMem('bootOnce.after createServer');
364
+ await server.listen();
365
+ __cirrusMem('bootOnce.after listen');
366
+ return server;
367
+ } catch (e) {
368
+ readyError = e;
369
+ console.error('[cirrus-real] Vite boot failed:', e && e.stack ? e.stack : e);
370
+ throw e;
371
+ }
372
+ })();
373
+ return serverReady;
374
+ }
375
+
376
+ // ── DurableObject class — the D'.1 entrypoint ───────────────────────
377
+ //
378
+ // Lifecycle:
379
+ // - First ctx.facets.get(...) call: workerd instantiates this class
380
+ // ONCE per facet name. The constructor runs; this.ctx.storage is
381
+ // a fresh empty SQLite. ensureFacetCookie() writes a UUID row.
382
+ // - Subsequent ctx.facets.get(...) calls in the same supervisor
383
+ // isolate (or after hibernation/wake): workerd reuses the same
384
+ // instance; storage rows survive. ensureFacetCookie() reads
385
+ // the existing UUID.
386
+ //
387
+ // The supervisor's CirrusReal controller calls fetch() for every
388
+ // preview request and getDiag() for the /api/_diag/cirrus surface.
389
+ // HMR pump scheduling now lives on this class (each fetch() kicks
390
+ // pumpHmrOnce via this.ctx.waitUntil).
391
+ export class CirrusRealVite extends DurableObject {
392
+ __bootStartedAt;
393
+ __bootCompletedAt;
394
+ __cookie;
395
+
396
+ constructor(state, env) {
397
+ super(state, env);
398
+ this.__bootStartedAt = Date.now();
399
+ this.__bootCompletedAt = 0;
400
+ this.__cookie = '';
401
+ // Ensure schema + cookie row up front. SQLite operations on the
402
+ // facet's own storage; survives hibernation/wake of THIS facet.
403
+ try {
404
+ const sql = state?.storage?.sql;
405
+ if (sql) {
406
+ sql.exec('CREATE TABLE IF NOT EXISTS cirrus_facet_meta (k TEXT PRIMARY KEY, v TEXT NOT NULL)');
407
+ let found = '';
408
+ for (const row of sql.exec('SELECT v FROM cirrus_facet_meta WHERE k = ?', 'cookie')) {
409
+ found = String(row.v);
410
+ break;
411
+ }
412
+ if (found) {
413
+ this.__cookie = found;
414
+ } else {
415
+ // Mint a fresh UUID-shaped cookie and persist. crypto.randomUUID
416
+ // is available in workerd globals.
417
+ const c = (globalThis.crypto?.randomUUID?.() || ('cookie-' + Math.random().toString(16).slice(2)));
418
+ sql.exec('INSERT OR REPLACE INTO cirrus_facet_meta (k, v) VALUES (?, ?)', 'cookie', c);
419
+ this.__cookie = c;
420
+ }
421
+ }
422
+ } catch (e) {
423
+ console.warn('[cirrus-real-facet] cookie-init failed:', e?.message || e);
424
+ }
425
+ }
426
+
427
+ /** RPC: identity + boot stats so the supervisor can surface them
428
+ * on /api/_diag/cirrus. */
429
+ async getFacetMeta() {
430
+ return {
431
+ cookie: this.__cookie,
432
+ bootMs: this.__bootCompletedAt > 0
433
+ ? this.__bootCompletedAt - this.__bootStartedAt
434
+ : 0,
435
+ bootError: readyError ? String(readyError?.message || readyError) : null,
436
+ viteServerListening: viteServerInstance != null,
437
+ };
438
+ }
439
+
440
+ async fetch(request) {
441
+ return __cirrusFetchImpl(request, this.env, this.ctx, () => {
442
+ if (this.__bootCompletedAt === 0) this.__bootCompletedAt = Date.now();
443
+ });
444
+ }
445
+ }
446
+
447
+ // ── Stateless-fetcher fallback export [d1-fix] ────────────────────────
448
+ // When env.LOADER.get(...) returns a stub WITHOUT
449
+ // getDurableObjectClass (because the \`experimental\` compat flag is
450
+ // absent — the case in production CF deployments since the
451
+ // 2026-05-08 deploy validator change rejecting \$experimental flags
452
+ // for non-CF-team accounts), the supervisor cannot spawn this
453
+ // module as a DO Facet. It falls back to env.LOADER.get(...).
454
+ // getEntrypoint() — a stateless Fetcher.
455
+ //
456
+ // In that mode, the supervisor's fetch() routes here. We share all
457
+ // the module-scope vite-bootstrap state with the DurableObject
458
+ // path (boot, viteServerInstance, readyError, etc.) so the
459
+ // user-visible behavior is identical. The only delta: per-instance
460
+ // state (the cookie + per-instance bootMs) is N/A — the supervisor
461
+ // surfaces \`kind: 'fetcher-fallback'\` in /api/_diag/cirrus and the
462
+ // probe relaxes its assertions accordingly.
463
+ let __statelessBootCompletedAt = 0;
464
+ async function __cirrusFetchImpl(request, env, ctx, onBootComplete) {
465
+ installBindings(env);
466
+ const fetchUrl = request.url;
467
+ const fetchPath = (() => { try { return new URL(fetchUrl).pathname; } catch { return '?'; } })();
468
+ __cirrusMem('fetch.enter ' + fetchPath);
469
+ try {
470
+ await bootOnce();
471
+ if (typeof onBootComplete === 'function') onBootComplete();
472
+ if (__statelessBootCompletedAt === 0) __statelessBootCompletedAt = Date.now();
473
+ } catch {
474
+ // readyError set; fall through to error response.
475
+ }
476
+ if (readyError) {
477
+ const msg = '[cirrus-real] Vite failed to boot:\\n' +
478
+ (readyError && readyError.stack ? readyError.stack : String(readyError));
479
+ return new Response(msg, {
480
+ status: 500,
481
+ headers: { 'Content-Type': 'text/plain; charset=utf-8' },
482
+ });
483
+ }
484
+ // HMR pump: kick once per fetch with a short poll. Events may be
485
+ // queued from a browser WS connection that attached between
486
+ // requests, OR VFS events fired since the last pump. We cap at
487
+ // one iteration per request — pumpHmrOnce re-schedules itself
488
+ // via waitUntil when clients are connected.
489
+ if (ctx?.waitUntil && _hmrBinding) {
490
+ ctx.waitUntil(pumpHmrOnce(ctx));
491
+ }
492
+ if (!boot) boot = httpServerHandler({ port: PORT });
493
+ try {
494
+ const resp = await boot.fetch(request, env, ctx);
495
+ __cirrusMem('fetch.exit ' + fetchPath + ' [' + resp.status + ']');
496
+ return resp;
497
+ } catch (e) {
498
+ return new Response('[cirrus-real] httpServerHandler.fetch threw: ' +
499
+ (e && e.stack ? e.stack : String(e)), {
500
+ status: 500,
501
+ headers: { 'Content-Type': 'text/plain; charset=utf-8' },
502
+ });
503
+ }
504
+ }
505
+
506
+ const __cirrusModuleLoadedAt = Date.now();
507
+
508
+ // Default export: stateless Fetcher shape. Used when the supervisor
509
+ // falls back to env.LOADER.get(...).getEntrypoint() because the DO
510
+ // Facet path is unavailable (no \`experimental\` flag).
511
+ //
512
+ // We use a WorkerEntrypoint subclass (instead of a plain
513
+ // default-export object) so the supervisor can call BOTH
514
+ // .fetch(req) and .getFacetMeta() via the same RPC stub —
515
+ // matching the API surface the DO Facet variant exposes.
516
+ import { WorkerEntrypoint } from 'cloudflare:workers';
517
+ export default class CirrusRealStateless extends WorkerEntrypoint {
518
+ async fetch(request) {
519
+ return __cirrusFetchImpl(request, this.env, this.ctx);
520
+ }
521
+ /** Stateless analog of CirrusRealVite.getFacetMeta(). Cookie is
522
+ * N/A in this mode (no per-facet SQLite); we surface bootMs and
523
+ * viteServerListening so the supervisor's diag still has
524
+ * observability. */
525
+ async getFacetMeta() {
526
+ return {
527
+ cookie: null, // N/A in stateless mode
528
+ bootMs: __statelessBootCompletedAt > 0
529
+ ? __statelessBootCompletedAt - __cirrusModuleLoadedAt
530
+ : 0,
531
+ bootError: readyError ? String(readyError?.message || readyError) : null,
532
+ viteServerListening: viteServerInstance != null,
533
+ };
534
+ }
535
+ }
536
+ `.trim();
537
+ }
538
+ // ── Supervisor-side controller class ──────────────────────────────────
539
+ export class CirrusReal {
540
+ env;
541
+ port;
542
+ root;
543
+ basePath;
544
+ vfs;
545
+ vfsEvents;
546
+ userConfigBundle;
547
+ extraSyntheticFiles;
548
+ facetStub = null;
549
+ pid = 0;
550
+ bootError = null;
551
+ _startedAt = 0;
552
+ /** [D'.1] facet name used with ctx.facets.get/delete. Set in start(),
553
+ * cleared in stop(). */
554
+ _facetName = null;
555
+ /** Dispatch shape:
556
+ * - 'do-facet' (post-D'.1, requires `$experimental` compat flag)
557
+ * - 'fetcher-fallback' (D'.1 graceful-degrade, when
558
+ * getDurableObjectClass is unavailable — the prod and the
559
+ * flag-stripped local dev case after the 2026-05-08
560
+ * deploy-flag-fix tightening) [d1-fix]
561
+ * - null (not started, or stop()'d)
562
+ * Surfaced via /api/_diag/cirrus.kind for the probe.
563
+ */
564
+ _kind = null;
565
+ /** [D'.1] timestamp when the facet stub was successfully obtained
566
+ * (after ctx.facets.get returned). Used to compute the supervisor-
567
+ * side bootMs that includes module compilation + facet binding,
568
+ * but NOT the in-facet vite.createServer.listen() (that's measured
569
+ * separately via getFacetMeta RPC). */
570
+ _bootCompletedAt = 0;
571
+ /** [D'.1] last fetch latency ms — surfaces on diag for warm-reuse
572
+ * perf assertions. */
573
+ _lastFetchMs = 0;
574
+ _snapshotStats = null;
575
+ /** HMR bridge — shared by WS upgrade handler + VFS event pump. */
576
+ hmr = new HmrBridge();
577
+ /** Unsubscribe from vfs events on stop(). */
578
+ _vfsUnsub = null;
579
+ constructor(opts) {
580
+ this.env = opts.env;
581
+ this.port = opts.port;
582
+ this.root = opts.root;
583
+ this.basePath = opts.basePath;
584
+ this.vfs = opts.vfs;
585
+ this.vfsEvents = opts.vfsEvents || null;
586
+ this.userConfigBundle = opts.userConfigBundle || null;
587
+ this.extraSyntheticFiles = opts.extraSyntheticFiles || {};
588
+ }
589
+ get isRunning() {
590
+ return this.facetStub != null && this.bootError == null;
591
+ }
592
+ get stats() {
593
+ return {
594
+ mode: 'real-vite',
595
+ viteVersion: REAL_VITE_VERSION,
596
+ pluginReactVersion: CIRRUS_PLUGIN_REACT_VERSION,
597
+ npmCjsVersions: CIRRUS_NPM_CJS_VERSIONS,
598
+ port: this.port,
599
+ root: this.root,
600
+ basePath: this.basePath,
601
+ bootError: this.bootError,
602
+ uptimeMs: this._startedAt ? Date.now() - this._startedAt : 0,
603
+ snapshot: this._snapshotStats,
604
+ sizeWarning: this._sizeWarning,
605
+ hmrClients: this.hmr.size,
606
+ hmrActive: this.hmr._everAwaitedEvents,
607
+ };
608
+ }
609
+ /** Soft warning set during start() if the project looks too large
610
+ * for the facet's 128 MB isolate budget. Surfaces in `stats` so
611
+ * the banner printed by nimbus-session.ts can show it. Empty
612
+ * string when the project is in the known-good envelope. */
613
+ _sizeWarning = '';
614
+ async start(ctx, pid) {
615
+ if (this.facetStub)
616
+ return;
617
+ this.pid = pid;
618
+ this._startedAt = Date.now();
619
+ // Build the project snapshot for the facet's sync-fs Map.
620
+ // (Lazy: eagerly seeds user project source + every package.json
621
+ // under node_modules. Source files in node_modules are loaded on
622
+ // demand via SUPERVISOR.readFile and cached in-facet.)
623
+ const snapshot = buildFsSnapshot(this.vfs, this.root);
624
+ this._snapshotStats = {
625
+ fileCount: snapshot.fileCount,
626
+ dirCount: snapshot.dirs.length,
627
+ totalBytes: snapshot.totalBytes,
628
+ skipped: snapshot.skipped,
629
+ packageJsonCount: snapshot.packageJsonCount,
630
+ pathIndexCount: snapshot.pathIndexCount,
631
+ };
632
+ // Size-based soft warning. Empirical findings (CIRRUS-OOM-TRACE.txt):
633
+ // - seed project (6307 post-install files, 2.5 MB snapshot,
634
+ // 203 pkg.json) survived 5 min without OOM
635
+ // - AshishKumar4/personal-website (58033 files, 22 MB snapshot,
636
+ // 945 pkg.json) survived 2 min without OOM
637
+ // - workerd isolate limit: 128 MB
638
+ // - static facet footprint: ~40 MB parsed modules + snapshot
639
+ //
640
+ // Above 100k files OR 60 MB snapshot OR 3000 pkg.json, we warn
641
+ // but don't block. Those are empirical — we haven't actually
642
+ // measured the ceiling because the tests held.
643
+ const warn = [];
644
+ if (snapshot.pathIndexCount > 100_000) {
645
+ warn.push(`${snapshot.pathIndexCount} indexed files in node_modules (above 100k may OOM)`);
646
+ }
647
+ if (snapshot.totalBytes > 60 * 1024 * 1024) {
648
+ warn.push(`snapshot is ${(snapshot.totalBytes / 1024 / 1024).toFixed(1)} MB (>60 MB may OOM)`);
649
+ }
650
+ if (snapshot.packageJsonCount > 3000) {
651
+ warn.push(`${snapshot.packageJsonCount} package.json entries (above 3k strains the resolver)`);
652
+ }
653
+ this._sizeWarning = warn.length > 0
654
+ ? 'size warning: ' + warn.join('; ') + '. If vite crashes, fall back to Cirrus (NIMBUS_REAL_VITE=0 vite).'
655
+ : '';
656
+ // Generate all the module sources.
657
+ const mainCode = generateMainModuleCode({
658
+ port: this.port,
659
+ root: '/' + this.root.replace(/^\/+/, ''),
660
+ basePath: this.basePath,
661
+ hasUserViteConfig: this.userConfigBundle != null,
662
+ });
663
+ const fsShim = generateFsShimModuleCode();
664
+ const fsPromisesShim = generateFsPromisesShimModuleCode();
665
+ const wsShim = generateWsShimModuleCode();
666
+ const chokidarShim = generateChokidarShimModuleCode();
667
+ // Merge the extras (plugin-specific asset files the user-config
668
+ // bundler pre-harvested from node_modules) into the snapshot.
669
+ const mergedFiles = { ...snapshot.files, ...this.extraSyntheticFiles };
670
+ // Map CJS bundle specifiers (e.g. "react/jsx-runtime") to the
671
+ // path suffixes Vite produces when resolving a user-project
672
+ // bare import. Vite's resolver walks node_modules and returns
673
+ // e.g. `/<root>/node_modules/react/index.js` or
674
+ // `/<root>/node_modules/react/jsx-runtime.js`. We use the
675
+ // suffix match to intercept those.
676
+ const SPEC_TO_SUFFIXES = {
677
+ 'react': ['/node_modules/react/index.js'],
678
+ 'react/jsx-runtime': ['/node_modules/react/jsx-runtime.js'],
679
+ 'react/jsx-dev-runtime': ['/node_modules/react/jsx-dev-runtime.js'],
680
+ 'react-dom': ['/node_modules/react-dom/index.js'],
681
+ 'react-dom/client': ['/node_modules/react-dom/client.js'],
682
+ 'scheduler': ['/node_modules/scheduler/index.js'],
683
+ };
684
+ const cjsPrebuiltBundles = {};
685
+ for (const [spec, bundle] of Object.entries(CIRRUS_NPM_CJS_BUNDLES)) {
686
+ const suffixes = SPEC_TO_SUFFIXES[spec] || [];
687
+ for (const suffix of suffixes) {
688
+ cjsPrebuiltBundles[suffix] = bundle.code;
689
+ }
690
+ }
691
+ // [sdk-phase-1] Pre-fetch the three large assets from the ASSETS
692
+ // binding before assembling the synthetic module code + loader
693
+ // config. After first call, all three are cached per-isolate, so
694
+ // subsequent start() invocations on the same supervisor pay zero.
695
+ const [realViteBundle, rollupWasmBase64, cirrusPluginReactBundle] = await Promise.all([
696
+ getRealViteBundle(this.env),
697
+ getRollupWasmBase64(this.env),
698
+ getCirrusPluginReactBundle(this.env),
699
+ ]);
700
+ const syntheticCode = generateSyntheticModuleCode({
701
+ viteVersion: REAL_VITE_VERSION,
702
+ snapshotFiles: mergedFiles,
703
+ snapshotDirs: snapshot.dirs,
704
+ existingPaths: snapshot.existingPaths,
705
+ rollupWasmBase64,
706
+ cjsPrebuiltBundles,
707
+ viteClientMjs: VITE_CLIENT_MJS,
708
+ viteEnvMjs: VITE_ENV_MJS,
709
+ });
710
+ const ctxExports = getCtxExports();
711
+ const supervisorBinding = ctxExports?.SupervisorRPC
712
+ ? ctxExports.SupervisorRPC({ props: { doId: ctx.id.toString(), pid } })
713
+ : undefined;
714
+ // Phase 2: separate HMR binding so we don't need to modify
715
+ // supervisor-rpc.ts (off-limits). The CirrusHmrRPC class lives in
716
+ // src/real-vite-hmr.ts and is re-exported from src/index.ts so
717
+ // ctx.exports can build a Service Binding for it.
718
+ const hmrBinding = ctxExports?.CirrusHmrRPC
719
+ ? ctxExports.CirrusHmrRPC({ props: { doId: ctx.id.toString() } })
720
+ : undefined;
721
+ // Register this instance's HmrBridge in the module-level registry
722
+ // so the CirrusHmrRPC service can route facet RPCs back to us.
723
+ registerHmrBridge(ctx.id.toString(), this);
724
+ // [D'.1] Spawn cirrus-real as a DO Facet, not a Worker.
725
+ //
726
+ // Step A: LOADER.get(stableId, configCb) → DynamicWorker stub. The
727
+ // stable ID per-(supervisor-DO + cirrus-real-version) makes the
728
+ // loader cache the bundled vite + plugin code across hibernation.
729
+ // Two restarts within the same supervisor isolate hit the warm
730
+ // cache; a different DO ID gets a fresh slot.
731
+ //
732
+ // Step B: worker.getDurableObjectClass('CirrusRealVite') → the
733
+ // class constructor from the dynamic worker's exports. Same
734
+ // pattern facet-manager.ts uses for NodeProcess.
735
+ //
736
+ // Step C: ctx.facets.get('cirrus-real-vite', { class }) → DO Facet
737
+ // stub. The facet has its own SQLite (used by the cookie row),
738
+ // its own hibernation lifecycle, and is owned by THIS supervisor
739
+ // DO so eviction is coherent. The same name returns the same
740
+ // facet on subsequent calls — that's what makes the cookie
741
+ // persist across supervisor reconnects.
742
+ const stableLoaderId = `${ctx.id.toString()}:cirrus-real-vite:${REAL_VITE_VERSION}`;
743
+ const facetName = 'cirrus-real-vite';
744
+ try {
745
+ const worker = this.env.LOADER.get(stableLoaderId, async () => ({
746
+ compatibilityDate: CF_COMPAT_DATE,
747
+ compatibilityFlags: REAL_VITE_COMPAT_FLAGS,
748
+ mainModule: 'main.js',
749
+ modules: {
750
+ 'main.js': mainCode,
751
+ 'vite.bundle.js': realViteBundle,
752
+ 'synthetic.js': syntheticCode,
753
+ // Phase 1 shims.
754
+ 'cirrus-fs.js': fsShim,
755
+ 'cirrus-fs-promises.js': fsPromisesShim,
756
+ 'real-node-fs.js': `import * as _f from 'node:fs'; export * from 'node:fs'; export default _f.default || _f;`,
757
+ 'real-node-fs-promises.js': `import * as _f from 'node:fs/promises'; export * from 'node:fs/promises'; export default _f.default || _f;`,
758
+ // Phase 2 shims.
759
+ 'cirrus-ws.js': wsShim,
760
+ 'cirrus-chokidar.js': chokidarShim,
761
+ // Phase 3: the user's pre-bundled vite.config.js (if any).
762
+ ...(this.userConfigBundle
763
+ ? {
764
+ 'user-vite-config.js': this.userConfigBundle,
765
+ 'vite-config-helper.js': `
766
+ export * from './vite.bundle.js';
767
+ import * as _v from './vite.bundle.js';
768
+ export default _v.default || _v;
769
+ `,
770
+ 'cirrus-plugin-react.js': cirrusPluginReactBundle,
771
+ }
772
+ : {}),
773
+ },
774
+ env: {
775
+ ...(supervisorBinding ? { SUPERVISOR: supervisorBinding } : {}),
776
+ ...(hmrBinding ? { CIRRUS_HMR: hmrBinding } : {}),
777
+ },
778
+ }));
779
+ // [d1-fix] Two-path bind:
780
+ //
781
+ // PRIMARY (DO Facet) — requires `experimental` compat flag:
782
+ // worker.getDurableObjectClass('CirrusRealVite') →
783
+ // ctx.facets.get(name, {class}) → stub with own-SQLite.
784
+ // Provides the cookie-persistence + identity story.
785
+ //
786
+ // FALLBACK (Fetcher) — used when getDurableObjectClass is
787
+ // unavailable (no `experimental` flag — the prod situation
788
+ // since the 2026-05-08 deploy validator change rejecting
789
+ // $experimental flags for non-CF-team accounts):
790
+ // worker.getEntrypoint('CirrusRealStateless') → stateless
791
+ // WorkerEntrypoint stub. Vite still serves /preview/ via
792
+ // the same module-scope state; cookie persistence is N/A
793
+ // (no per-instance SQLite). Probe surfaces this via
794
+ // `kind: 'fetcher-fallback'`.
795
+ //
796
+ // The detection is by *runtime feature probe* — we try
797
+ // getDurableObjectClass first and catch the classic
798
+ // 'is not a function' / facets-related error, mirroring the
799
+ // pattern at facets/manager.ts:1286-1322. NOT by static
800
+ // env-var check (the flag is invisible from JS at runtime).
801
+ let CirrusRealViteClass = null;
802
+ try {
803
+ CirrusRealViteClass = worker.getDurableObjectClass?.('CirrusRealVite');
804
+ }
805
+ catch (cls) {
806
+ // Caller-side throw means the method exists but the class
807
+ // lookup failed — surface as a real bootError so we don't
808
+ // silently fall through.
809
+ this.bootError = 'getDurableObjectClass(CirrusRealVite) threw: ' +
810
+ (cls?.message || String(cls));
811
+ return;
812
+ }
813
+ if (CirrusRealViteClass && typeof ctx.facets?.get === 'function') {
814
+ // PRIMARY: DO Facet path.
815
+ this._facetName = facetName;
816
+ this.facetStub = ctx.facets.get(facetName, async () => ({
817
+ class: CirrusRealViteClass,
818
+ }));
819
+ this._kind = 'do-facet';
820
+ }
821
+ else {
822
+ // FALLBACK: Fetcher path. The default-exported
823
+ // CirrusRealStateless WorkerEntrypoint exposes both
824
+ // `fetch(req)` and `getFacetMeta()` so the supervisor's
825
+ // handleRequest + getDiag logic Just Works without
826
+ // branching on `kind`.
827
+ //
828
+ // No `experimental` compat flag → no DO-Facet API at runtime.
829
+ // This is the prod path (CF rejects the flag) and the
830
+ // local-dev path post-2026-05-08 deploy-flag-fix wave.
831
+ this._facetName = null; // facets.delete() is N/A here
832
+ // Default export → getEntrypoint() with no name argument.
833
+ // Per workerd's WorkerStub semantics: getEntrypoint() →
834
+ // the default export; getEntrypoint(name) → a named export.
835
+ // The fallback main.js export is `export default class
836
+ // CirrusRealStateless extends WorkerEntrypoint { ... }` —
837
+ // resolved as the DEFAULT, not as a named entrypoint.
838
+ this.facetStub = worker.getEntrypoint?.();
839
+ if (!this.facetStub) {
840
+ this.bootError =
841
+ 'cirrus-real fallback: worker.getEntrypoint() returned no stub. ' +
842
+ 'Worker Loader binding may be missing or incompatible.';
843
+ return;
844
+ }
845
+ this._kind = 'fetcher-fallback';
846
+ }
847
+ this._bootCompletedAt = Date.now();
848
+ }
849
+ catch (e) {
850
+ this.bootError = e?.stack || e?.message || String(e);
851
+ }
852
+ // Wire the VFS event stream into the HMR bridge so the facet's
853
+ // chokidar shim actually sees file changes.
854
+ if (this.vfsEvents) {
855
+ this._vfsUnsub = this.vfsEvents.on((batch) => {
856
+ for (const ev of batch) {
857
+ const absPath = '/' + ev.path.replace(/^\/+/, '');
858
+ // chokidar uses 'addDir'/'unlinkDir' for directory events;
859
+ // VFS emits the same strings, so we can pass through as-is.
860
+ this.hmr.pushVfsEvent(ev.type, absPath, ev.oldPath);
861
+ }
862
+ });
863
+ }
864
+ }
865
+ stop(ctx) {
866
+ // [D'.1] Tear down the DO Facet via ctx.facets.delete so its own
867
+ // SQLite storage is reclaimed. Pre-D'.1 the worker stub was
868
+ // garbage-collected when facetStub was nulled — facets need an
869
+ // explicit delete (otherwise the cookie row + storage slot leak
870
+ // until the supervisor itself is evicted).
871
+ if (this._facetName && ctx) {
872
+ try {
873
+ ctx.facets.delete(this._facetName);
874
+ }
875
+ catch { }
876
+ }
877
+ this.facetStub = null;
878
+ this._facetName = null;
879
+ this._kind = null;
880
+ this.hmr.closeAll();
881
+ if (this._vfsUnsub) {
882
+ try {
883
+ this._vfsUnsub();
884
+ }
885
+ catch { }
886
+ }
887
+ this._vfsUnsub = null;
888
+ // Note: we deliberately do NOT unregister from the HMR bridge
889
+ // map here — if the user runs `vite stop` then `vite` again, the
890
+ // bridge must still be lookup-able by doId during the brief
891
+ // restart window. Unregister happens on DO teardown, not here.
892
+ }
893
+ /**
894
+ * Browser WS upgrade request arrived at /preview/__nimbus_hmr.
895
+ * The DO has already accepted the server-side socket via
896
+ * ctx.acceptWebSocket; we register it with the HmrBridge.
897
+ */
898
+ attachHmrClient(ws) {
899
+ return this.hmr.attachClient(ws);
900
+ }
901
+ detachHmrClient(id) {
902
+ this.hmr.detachClient(id);
903
+ }
904
+ deliverHmrClientMessage(id, msg) {
905
+ this.hmr.deliverClientMessage(id, msg);
906
+ }
907
+ /**
908
+ * Route a (non-WS) request into the facet. `pathname` is the path
909
+ * after stripping the session's `/preview` prefix (e.g. `/`,
910
+ * `/@vite/client`, `/src/main.tsx`).
911
+ */
912
+ async handleRequest(request, pathname) {
913
+ if (this.bootError) {
914
+ return new Response('[cirrus-real] facet spawn failed:\n' + this.bootError, { status: 500, headers: { 'Content-Type': 'text/plain; charset=utf-8' } });
915
+ }
916
+ if (!this.facetStub) {
917
+ return new Response('[cirrus-real] facet not started', {
918
+ status: 503, headers: { 'Content-Type': 'text/plain; charset=utf-8' },
919
+ });
920
+ }
921
+ // Vite is configured with `base: this.basePath` — forward the
922
+ // base-prefixed path so its middleware matches.
923
+ const origUrl = new URL(request.url);
924
+ const joined = this.basePath.replace(/\/+$/, '') + (pathname.startsWith('/') ? '' : '/') + pathname;
925
+ const forwardUrl = 'http://cirrus-real' + joined + (origUrl.search || '');
926
+ const forwardInit = {
927
+ method: request.method,
928
+ headers: request.headers,
929
+ body: (request.method === 'GET' || request.method === 'HEAD')
930
+ ? undefined : await request.arrayBuffer(),
931
+ };
932
+ const forwardReq = new Request(forwardUrl, forwardInit);
933
+ const fetchT0 = Date.now();
934
+ try {
935
+ const resp = await this.facetStub.fetch(forwardReq);
936
+ this._lastFetchMs = Date.now() - fetchT0;
937
+ const out = new Response(resp.body, {
938
+ status: resp.status,
939
+ statusText: resp.statusText,
940
+ headers: resp.headers,
941
+ });
942
+ out.headers.set('Access-Control-Allow-Origin', '*');
943
+ out.headers.set('Cache-Control', 'no-store');
944
+ return out;
945
+ }
946
+ catch (e) {
947
+ return new Response('[cirrus-real] facet.fetch threw: ' + (e?.stack || e?.message || String(e)), { status: 502, headers: { 'Content-Type': 'text/plain; charset=utf-8' } });
948
+ }
949
+ }
950
+ /**
951
+ * [D'.1] Diag bundle for /api/_diag/cirrus. Includes the facet's
952
+ * own-SQLite identity cookie (round-tripped via the facet's
953
+ * getFacetMeta RPC), supervisor-side dispatch kind, supervisor-side
954
+ * bootMs, and last-fetch latency. Returns null when cirrus-real
955
+ * is not running.
956
+ */
957
+ async getDiag() {
958
+ if (!this.facetStub)
959
+ return null;
960
+ let facetMeta = null;
961
+ try {
962
+ facetMeta = await this.facetStub.getFacetMeta();
963
+ }
964
+ catch (e) {
965
+ facetMeta = { rpcError: e?.message || String(e) };
966
+ }
967
+ return {
968
+ kind: this._kind,
969
+ facetName: this._facetName,
970
+ cookie: facetMeta?.cookie ?? null,
971
+ bootMs: this._startedAt > 0 ? this._bootCompletedAt - this._startedAt : 0,
972
+ facetBootMs: facetMeta?.bootMs ?? 0,
973
+ lastFetchMs: this._lastFetchMs,
974
+ bootError: this.bootError,
975
+ facetBootError: facetMeta?.bootError ?? null,
976
+ viteServerListening: facetMeta?.viteServerListening ?? null,
977
+ uptimeMs: this._startedAt ? Date.now() - this._startedAt : 0,
978
+ hmrClients: this.hmr.size,
979
+ };
980
+ }
981
+ }