@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,656 @@
1
+ /**
2
+ * ProcessLogStore — per-PID ring buffer for facet stdout/stderr.
3
+ *
4
+ * Problem we solve:
5
+ * Facet stdout/stderr flows through `_rpcStdout`/`_rpcStderr` in
6
+ * NimbusSession. If the WebSocket terminal is attached, data reaches
7
+ * the user. If not — or if a process crashes synchronously before its
8
+ * output has been flushed through — the data is gone.
9
+ *
10
+ * What this does:
11
+ * - Buffer every stdout/stderr chunk in a fixed-byte ring, keyed by PID.
12
+ * - Split oversize chunks at 4 KB so no single write can swamp a PID's
13
+ * allotted 64 KB.
14
+ * - Tag binary chunks (null bytes / high non-printable ratio) as
15
+ * `{type: 'binary', size: N}` so replay shows `[N bytes of binary
16
+ * output]` instead of garbled terminal state.
17
+ * - Track process exit separately from the append stream so `logs` can
18
+ * print a clean footer and `_emitExitDump` can fire exactly once.
19
+ * - Retain logs for `retainAfterExitMs` (default 10 min) past exit —
20
+ * far longer than ProcessTable.reap's 60 s — so users have time to
21
+ * read a crash dump.
22
+ * - Provide pub-sub via `subscribe(pid, cb)` so `logs -f` is O(1) per
23
+ * chunk, not a poll loop.
24
+ *
25
+ * Non-goals:
26
+ * - Routing raw Uint8Array. RPC boundary already strings the data
27
+ * (SupervisorRPC.stdout(data: string)), so we store strings.
28
+ *
29
+ * W9 — hibernation persistence (CF-INTERNAL-OPTIMIZATION-RESEARCH §C.2,
30
+ * Lever 11):
31
+ * The store optionally accepts a `PersistAdapter` (set via
32
+ * `setPersist`). When set:
33
+ * - `append` / `markExit` mark the pid dirty in memory; the actual
34
+ * SQL write is batched into `flush()`. Callers schedule `flush()`
35
+ * from a debounced alarm OR a webSocketClose handler so writes
36
+ * don't run on the hot stdout path.
37
+ * - First read of a pid (`tail`/`all`/`subscribe`/`getExit`/`has`)
38
+ * lazily hydrates from the adapter. Subsequent reads stay in
39
+ * memory until eviction.
40
+ * - Eviction (per-pid byte cap, dropOlderThan, maxPids) cascades
41
+ * to the adapter on the next `flush()` — never inline, so eviction
42
+ * under load doesn't write-amplify.
43
+ * When NOT set: behaviour is byte-identical to pre-W9 (in-memory only).
44
+ */
45
+ /** Detect binary content — rough but good enough for "this is not text". */
46
+ function looksBinary(s) {
47
+ if (s.length === 0)
48
+ return false;
49
+ // Null byte is the strongest signal.
50
+ if (s.indexOf('\x00') !== -1)
51
+ return true;
52
+ // Otherwise sample up to 512 chars for non-printable non-whitespace.
53
+ const sample = s.length > 512 ? s.substring(0, 512) : s;
54
+ let bad = 0;
55
+ for (let i = 0; i < sample.length; i++) {
56
+ const c = sample.charCodeAt(i);
57
+ // Allow tab (9), LF (10), CR (13), ESC (27 — ANSI), and >= 32.
58
+ if (c === 9 || c === 10 || c === 13 || c === 27 || c >= 32)
59
+ continue;
60
+ bad++;
61
+ }
62
+ return bad / sample.length > 0.1;
63
+ }
64
+ /**
65
+ * Strip ANSI CSI escape sequences (colors, cursor, etc.) for --plain mode.
66
+ * Keeps the rest of the text intact.
67
+ */
68
+ export function stripAnsi(s) {
69
+ // Match CSI and OSC sequences.
70
+ return s
71
+ .replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, '')
72
+ .replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, '')
73
+ .replace(/\x1b[=>()]/g, '');
74
+ }
75
+ export class ProcessLogStore {
76
+ perPidBytes;
77
+ maxChunkBytes;
78
+ retainAfterExitMs;
79
+ maxPids;
80
+ pids = new Map();
81
+ /** Cumulative count of PIDs evicted by the cap (STABILITY-AUDIT.md M-S5). */
82
+ _droppedPids = 0;
83
+ // ── W9 persistence state ────────────────────────────────────────────
84
+ /** Optional persistence backend. When null, store is in-memory only. */
85
+ _persist = null;
86
+ /**
87
+ * Pids whose rows are dropped on next flush (eviction queue). Keyed by
88
+ * pid; value is `true` for "pid was evicted from memory; ask adapter to
89
+ * delete all rows". Distinct from dirtyChunks because the adapter call
90
+ * is dropPid, not persistChunks.
91
+ */
92
+ _dropQueue = new Set();
93
+ /**
94
+ * Pids that need pruneBeforeSeq on next flush — keyed by pid → cutoff
95
+ * seq (delete all rows with seq < cutoff). Set whenever an in-memory
96
+ * `_evict` shifts the chunks array; the cutoff is the lowest seq that
97
+ * remains in memory.
98
+ */
99
+ _pruneQueue = new Map();
100
+ /** Cumulative flushed-bytes counter (telemetry). */
101
+ _flushedChunks = 0;
102
+ _flushedBytes = 0;
103
+ _flushCount = 0;
104
+ _lastFlushAt = 0;
105
+ _lastFlushDurationMs = 0;
106
+ /** Cumulative hydrate counters. */
107
+ _hydratedPids = 0;
108
+ _hydratedChunks = 0;
109
+ _hydratedBytes = 0;
110
+ constructor(opts = {}) {
111
+ this.perPidBytes = opts.perPidBytes ?? 64 * 1024;
112
+ this.maxChunkBytes = opts.maxChunkBytes ?? 4 * 1024;
113
+ this.retainAfterExitMs = opts.retainAfterExitMs ?? 10 * 60 * 1000;
114
+ this.maxPids = opts.maxPids ?? 500;
115
+ }
116
+ /**
117
+ * W9: install a persistence adapter. Call once at NimbusSession init,
118
+ * after the SQL tables exist. Pre-existing in-memory state is NOT
119
+ * pushed to the adapter — only state mutated AFTER setPersist is
120
+ * subject to flush. This is fine in practice: NimbusSession sets the
121
+ * adapter in the constructor, before any append happens.
122
+ */
123
+ setPersist(adapter) {
124
+ this._persist = adapter;
125
+ }
126
+ /** Is there ANY state for this pid (including exit-only)? */
127
+ has(pid) {
128
+ if (this.pids.has(pid))
129
+ return true;
130
+ return this._maybeHydrateRead(pid) !== null;
131
+ }
132
+ /** Current buffered bytes for this PID (post-eviction). */
133
+ size(pid) {
134
+ return this.pids.get(pid)?.bytes ?? 0;
135
+ }
136
+ getExit(pid) {
137
+ const s = this._maybeHydrateRead(pid);
138
+ return s?.exit ?? null;
139
+ }
140
+ /**
141
+ * W9: read-side helper. If we have an adapter and the pid has any rows
142
+ * in SQL, lazy-create the in-memory state (which triggers hydrate).
143
+ * Returns the state or null. Performs at most one adapter `load` per
144
+ * pid per isolate-gen by routing through `_getOrCreate` → `_hydrate`,
145
+ * which is guarded by `state.hydrated`.
146
+ */
147
+ _maybeHydrateRead(pid) {
148
+ let s = this.pids.get(pid) ?? null;
149
+ if (s)
150
+ return s;
151
+ if (!this._persist)
152
+ return null;
153
+ // _getOrCreate triggers _hydrate which calls load(). To avoid an
154
+ // extra load() just to decide whether to materialise, we always
155
+ // create and then check whether hydrate populated anything. If it
156
+ // didn't, drop the empty state to keep the maxPids cap clean.
157
+ s = this._getOrCreate(pid);
158
+ if (s.chunks.length === 0 && !s.exit) {
159
+ // Nothing came back from SQL — drop the empty state so we don't
160
+ // pin a cap slot for a pid that never existed.
161
+ this.pids.delete(pid);
162
+ return null;
163
+ }
164
+ return s;
165
+ }
166
+ /**
167
+ * Append a chunk. `data` may be huge or binary; we split / tag as
168
+ * needed. Notifies any `subscribe()`rs for this pid.
169
+ */
170
+ append(pid, stream, data) {
171
+ if (!data)
172
+ return;
173
+ const state = this._getOrCreate(pid);
174
+ // Binary detection on the raw incoming chunk (before splitting).
175
+ if (looksBinary(data)) {
176
+ const placeholder = `[${data.length} bytes of binary output]\n`;
177
+ const chunk = {
178
+ ts: Date.now(),
179
+ stream,
180
+ data: placeholder,
181
+ binary: true,
182
+ };
183
+ this._appendChunk(pid, state, chunk);
184
+ return;
185
+ }
186
+ // Split oversize writes into multiple chunks.
187
+ let offset = 0;
188
+ while (offset < data.length) {
189
+ const slice = data.substring(offset, offset + this.maxChunkBytes);
190
+ const chunk = {
191
+ ts: Date.now(),
192
+ stream,
193
+ data: slice,
194
+ };
195
+ this._appendChunk(pid, state, chunk);
196
+ offset += slice.length;
197
+ }
198
+ }
199
+ /** W9: shared insert path — assigns a seq, marks dirty, evicts, fans out. */
200
+ _appendChunk(pid, state, chunk) {
201
+ const seq = state.nextSeq++;
202
+ state.chunks.push(chunk);
203
+ state.bytes += chunk.data.length;
204
+ state.lastActivity = chunk.ts;
205
+ if (this._persist) {
206
+ state.dirtyChunks.push({ seq, chunk });
207
+ }
208
+ this._evict(state, pid);
209
+ this._fanout(state, chunk);
210
+ }
211
+ /** Return the last N chunks (by line count) in chronological order. */
212
+ tail(pid, opts = {}) {
213
+ const state = this._maybeHydrateRead(pid);
214
+ if (!state)
215
+ return [];
216
+ if (!opts.lines && !opts.bytes)
217
+ return [...state.chunks];
218
+ // Walk from newest → oldest, accumulate until we hit the limit.
219
+ const out = [];
220
+ let lines = 0;
221
+ let bytes = 0;
222
+ for (let i = state.chunks.length - 1; i >= 0; i--) {
223
+ const c = state.chunks[i];
224
+ out.unshift(c);
225
+ bytes += c.data.length;
226
+ if (opts.lines) {
227
+ // Count \n in chunk + 1 if chunk doesn't end with \n but has content.
228
+ for (let j = 0; j < c.data.length; j++)
229
+ if (c.data.charCodeAt(j) === 10)
230
+ lines++;
231
+ if (lines >= opts.lines)
232
+ break;
233
+ }
234
+ if (opts.bytes && bytes >= opts.bytes)
235
+ break;
236
+ }
237
+ return out;
238
+ }
239
+ /** All chunks for a pid, chronological. */
240
+ all(pid) {
241
+ const state = this._maybeHydrateRead(pid);
242
+ return state ? [...state.chunks] : [];
243
+ }
244
+ /** Record exit. Idempotent: second call is ignored (preserves first). */
245
+ markExit(pid, code, reason) {
246
+ const state = this._getOrCreate(pid);
247
+ if (state.exit)
248
+ return;
249
+ const info = { code, at: Date.now(), reason };
250
+ state.exit = info;
251
+ state.lastActivity = info.at;
252
+ if (this._persist)
253
+ state.dirtyExit = true;
254
+ for (const cb of state.exitSubscribers) {
255
+ try {
256
+ cb(info);
257
+ }
258
+ catch { /* swallow subscriber errors */ }
259
+ }
260
+ }
261
+ /**
262
+ * Subscribe to new chunks for this pid. Returns unsubscribe fn.
263
+ * Subscriber is called synchronously from within `append`.
264
+ * W9: also hydrates from SQL on first touch so a post-hibernate
265
+ * subscriber sees pre-hibernate context in the next backlog frame.
266
+ */
267
+ subscribe(pid, cb) {
268
+ const state = this._getOrCreate(pid);
269
+ state.subscribers.add(cb);
270
+ return () => { state.subscribers.delete(cb); };
271
+ }
272
+ /** Subscribe to the exit event. Fires once. */
273
+ subscribeExit(pid, cb) {
274
+ const state = this._getOrCreate(pid);
275
+ state.exitSubscribers.add(cb);
276
+ return () => { state.exitSubscribers.delete(cb); };
277
+ }
278
+ /**
279
+ * Drop all state for any PID whose process exited more than `ageMs`
280
+ * ago. Returns the number of PIDs purged.
281
+ *
282
+ * Optional `isOrphan(pid)` callback identifies PIDs whose owning
283
+ * process vanished without a recorded exit (e.g., a long-running
284
+ * facet that hung and was GC'd). Such entries are dropped after a
285
+ * longer grace window so leaked buffers don't accumulate forever.
286
+ */
287
+ dropOlderThan(ageMs = this.retainAfterExitMs, isOrphan) {
288
+ const now = Date.now();
289
+ const cutoff = now - ageMs;
290
+ const orphanCutoff = now - ageMs * 3; // 30 min default for orphans
291
+ let dropped = 0;
292
+ for (const [pid, state] of this.pids) {
293
+ if (state.subscribers.size !== 0)
294
+ continue;
295
+ if (state.exit && state.exit.at < cutoff) {
296
+ this.pids.delete(pid);
297
+ if (this._persist)
298
+ this._dropQueue.add(pid);
299
+ dropped++;
300
+ continue;
301
+ }
302
+ // Orphan sweep: no exit recorded, no live subscribers, last
303
+ // activity older than the orphan cutoff, AND the process table
304
+ // confirms the process is gone.
305
+ if (!state.exit &&
306
+ state.lastActivity < orphanCutoff &&
307
+ isOrphan?.(pid)) {
308
+ this.pids.delete(pid);
309
+ if (this._persist)
310
+ this._dropQueue.add(pid);
311
+ dropped++;
312
+ }
313
+ }
314
+ return dropped;
315
+ }
316
+ /**
317
+ * W9: drain dirty buffers into the persist adapter. Synchronous from
318
+ * the store's POV (the adapter's calls are sync; the production
319
+ * adapter wraps them in `ctx.storage.transactionSync`). Idempotent —
320
+ * second call without new data is a no-op.
321
+ *
322
+ * Order of operations (matters for crash resilience):
323
+ * 1. dropPid for every pid in the drop queue (frees SQL space first).
324
+ * 2. pruneBeforeSeq for any pid with a queued cutoff.
325
+ * 3. persistChunks for every pid with dirty chunks.
326
+ * 4. persistExit for every pid with a dirty exit.
327
+ *
328
+ * Step 3 BEFORE step 4 is the key crash-resilience invariant: if the
329
+ * actor terminates between (3) and (4), the chunks are persisted but
330
+ * the exit is not — on next hydrate we'll see the chunks but no exit
331
+ * row, which is the same state we'd be in if the process were still
332
+ * running. The reverse (exit row but missing chunks) would surface a
333
+ * misleading "exited cleanly with no output" frame.
334
+ */
335
+ flush() {
336
+ if (!this._persist) {
337
+ // No adapter — clear any dirty markers so the booleans stay sane.
338
+ this._dropQueue.clear();
339
+ this._pruneQueue.clear();
340
+ for (const state of this.pids.values()) {
341
+ state.dirtyChunks.length = 0;
342
+ state.dirtyExit = false;
343
+ }
344
+ return;
345
+ }
346
+ const t0 = Date.now();
347
+ const adapter = this._persist;
348
+ // Step 1: drop evicted pids first — the SQL DELETE for them might
349
+ // free space the chunk INSERTs need under tight memory.
350
+ for (const pid of this._dropQueue) {
351
+ try {
352
+ adapter.dropPid(pid);
353
+ }
354
+ catch { /* fail-soft */ }
355
+ }
356
+ this._dropQueue.clear();
357
+ // Step 2: prune over-capped chunks for still-resident pids.
358
+ for (const [pid, cutoff] of this._pruneQueue) {
359
+ try {
360
+ adapter.pruneBeforeSeq(pid, cutoff);
361
+ }
362
+ catch { /* fail-soft */ }
363
+ }
364
+ this._pruneQueue.clear();
365
+ let chunkBytesFlushed = 0;
366
+ let chunksFlushedCount = 0;
367
+ // Step 3: persist new chunks (per-pid batch).
368
+ for (const [pid, state] of this.pids) {
369
+ if (state.dirtyChunks.length === 0)
370
+ continue;
371
+ const rows = state.dirtyChunks;
372
+ try {
373
+ adapter.persistChunks(pid, rows);
374
+ for (const r of rows) {
375
+ chunkBytesFlushed += r.chunk.data.length;
376
+ if (r.seq > state.flushedHighSeq)
377
+ state.flushedHighSeq = r.seq;
378
+ }
379
+ chunksFlushedCount += rows.length;
380
+ }
381
+ catch { /* fail-soft — leave dirty for next flush */
382
+ continue;
383
+ }
384
+ state.dirtyChunks = [];
385
+ }
386
+ // Step 4: persist exits AFTER chunks (crash resilience).
387
+ for (const [pid, state] of this.pids) {
388
+ if (!state.dirtyExit || !state.exit)
389
+ continue;
390
+ try {
391
+ adapter.persistExit(pid, state.exit);
392
+ state.dirtyExit = false;
393
+ }
394
+ catch { /* fail-soft */ }
395
+ }
396
+ this._flushCount++;
397
+ this._lastFlushAt = t0;
398
+ this._lastFlushDurationMs = Date.now() - t0;
399
+ this._flushedChunks += chunksFlushedCount;
400
+ this._flushedBytes += chunkBytesFlushed;
401
+ }
402
+ /**
403
+ * W9: counters for /api/_diag/memory hibernation telemetry. Cumulative
404
+ * since this isolate-gen started. Reset only when the store itself is
405
+ * reconstructed (i.e., on hibernation/wake).
406
+ */
407
+ hibStats() {
408
+ let pendingDirtyPids = 0;
409
+ for (const state of this.pids.values()) {
410
+ if (state.dirtyChunks.length > 0 || state.dirtyExit)
411
+ pendingDirtyPids++;
412
+ }
413
+ return {
414
+ rehydratedPids: this._hydratedPids,
415
+ rehydratedChunks: this._hydratedChunks,
416
+ rehydratedBytes: this._hydratedBytes,
417
+ flushedChunks: this._flushedChunks,
418
+ flushedBytes: this._flushedBytes,
419
+ flushCount: this._flushCount,
420
+ lastFlushAt: this._lastFlushAt,
421
+ lastFlushDurationMs: this._lastFlushDurationMs,
422
+ pendingDirtyPids,
423
+ pendingDropPids: this._dropQueue.size,
424
+ };
425
+ }
426
+ /** Introspection. Used by `ps -l` for LOGS column. */
427
+ snapshot(pid) {
428
+ const s = this._maybeHydrateRead(pid);
429
+ if (!s)
430
+ return null;
431
+ return { bytes: s.bytes, chunks: s.chunks.length, exit: s.exit };
432
+ }
433
+ // ── Private ──────────────────────────────────────────────────────────
434
+ _getOrCreate(pid) {
435
+ let s = this.pids.get(pid);
436
+ if (!s) {
437
+ // Enforce the global cap BEFORE inserting (STABILITY-AUDIT.md
438
+ // M-S5). A 1000-pid fork-bomb would otherwise pin ~50 MB of
439
+ // buffers for the full 10-min retention window, crowding the
440
+ // 128 MB DO isolate cap alongside npm install / git clone peaks.
441
+ if (this.pids.size >= this.maxPids) {
442
+ this._evictOnePid();
443
+ }
444
+ s = {
445
+ chunks: [],
446
+ bytes: 0,
447
+ exit: null,
448
+ lastActivity: Date.now(),
449
+ subscribers: new Set(),
450
+ exitSubscribers: new Set(),
451
+ nextSeq: 0,
452
+ dirtyChunks: [],
453
+ dirtyExit: false,
454
+ hydrated: false,
455
+ flushedHighSeq: -1,
456
+ };
457
+ this.pids.set(pid, s);
458
+ // W9: lazy hydrate the freshly-created state from persistent
459
+ // storage. If we have an adapter and rows exist for this pid
460
+ // (e.g., DO was hibernated and now woke), pull them into the
461
+ // ring before any caller can observe an empty ring.
462
+ this._hydrate(pid, s);
463
+ }
464
+ return s;
465
+ }
466
+ /**
467
+ * W9: pull rows from the persist adapter for this pid into the in-memory
468
+ * ring. Idempotent — guarded by `state.hydrated`. Bounded by
469
+ * `perPidBytes`: if SQL has more bytes than the in-memory cap, we keep
470
+ * only the newest rows that fit and queue a `pruneBeforeSeq` for the
471
+ * next flush so SQL converges.
472
+ *
473
+ * Called from `_getOrCreate` (covers append/tail/all/has/snapshot/
474
+ * subscribe — any first-touch read or write). Failures are swallowed:
475
+ * a broken adapter must not break the in-memory ring's correctness.
476
+ */
477
+ _hydrate(pid, state) {
478
+ if (state.hydrated)
479
+ return;
480
+ state.hydrated = true;
481
+ if (!this._persist)
482
+ return;
483
+ let loaded;
484
+ try {
485
+ loaded = this._persist.load(pid);
486
+ }
487
+ catch {
488
+ return;
489
+ }
490
+ if (!loaded)
491
+ return;
492
+ // Restore exit first so pid-existence checks are correct even if
493
+ // we drop chunks below.
494
+ if (loaded.exit) {
495
+ state.exit = loaded.exit;
496
+ state.lastActivity = loaded.exit.at;
497
+ }
498
+ if (loaded.chunks.length === 0)
499
+ return;
500
+ // Trim to perPidBytes from the newest end. Each persisted chunk has
501
+ // a `seq` (we appended it during `persistChunks`); fall back to
502
+ // index-based seq when a chunk lacks it (defensive).
503
+ const newest = [];
504
+ let bytes = 0;
505
+ let oldestKeptSeq = Number.POSITIVE_INFINITY;
506
+ let highestSeq = -1;
507
+ for (let i = loaded.chunks.length - 1; i >= 0; i--) {
508
+ const c = loaded.chunks[i];
509
+ const seq = c.seq ?? i;
510
+ if (seq > highestSeq)
511
+ highestSeq = seq;
512
+ const size = c.data.length;
513
+ if (bytes + size > this.perPidBytes && newest.length > 0) {
514
+ // Anything below this seq is overshoot — schedule a prune.
515
+ this._pruneQueue.set(pid, oldestKeptSeq);
516
+ break;
517
+ }
518
+ newest.unshift({ ts: c.ts, stream: c.stream, data: c.data, binary: c.binary });
519
+ bytes += size;
520
+ oldestKeptSeq = seq;
521
+ }
522
+ state.chunks = newest;
523
+ state.bytes = bytes;
524
+ state.nextSeq = highestSeq + 1;
525
+ state.flushedHighSeq = highestSeq;
526
+ if (loaded.chunks[loaded.chunks.length - 1]) {
527
+ state.lastActivity = Math.max(state.lastActivity, loaded.chunks[loaded.chunks.length - 1].ts);
528
+ }
529
+ this._hydratedPids++;
530
+ this._hydratedChunks += newest.length;
531
+ this._hydratedBytes += bytes;
532
+ }
533
+ /**
534
+ * Evict one PID to make room when the map hits its global cap.
535
+ *
536
+ * Policy (in order of preference):
537
+ * 1. Oldest EXITED pid with zero subscribers — safe: nobody's
538
+ * reading, process is done, ring buffer is cold.
539
+ * 2. Oldest pid by `lastActivity` with zero subscribers — any
540
+ * state; covers the case where every exited pid has a live
541
+ * subscriber (log tab open).
542
+ * 3. Give up — an actively-subscribed long-running pid flood is
543
+ * degenerate; we'd rather let the map briefly exceed the cap
544
+ * than silently drop a subscribed stream.
545
+ *
546
+ * Map iteration order in JS is insertion order, so "oldest" here
547
+ * means "earliest inserted." That's a reasonable proxy for
548
+ * `lastActivity` for PIDs that haven't been written to recently.
549
+ * We still check `lastActivity` explicitly so active-write pids
550
+ * beat cold ones even if they were inserted earlier.
551
+ */
552
+ _evictOnePid() {
553
+ // Tier 1: oldest exited + no subscribers.
554
+ let bestPid = null;
555
+ let bestActivity = Infinity;
556
+ for (const [pid, state] of this.pids) {
557
+ if (state.exit && state.subscribers.size === 0 && state.exitSubscribers.size === 0) {
558
+ if (state.lastActivity < bestActivity) {
559
+ bestPid = pid;
560
+ bestActivity = state.lastActivity;
561
+ }
562
+ }
563
+ }
564
+ if (bestPid !== null) {
565
+ this.pids.delete(bestPid);
566
+ this._droppedPids++;
567
+ if (this._persist)
568
+ this._dropQueue.add(bestPid);
569
+ return;
570
+ }
571
+ // Tier 2: oldest by lastActivity with zero subscribers.
572
+ bestPid = null;
573
+ bestActivity = Infinity;
574
+ for (const [pid, state] of this.pids) {
575
+ if (state.subscribers.size === 0 && state.exitSubscribers.size === 0) {
576
+ if (state.lastActivity < bestActivity) {
577
+ bestPid = pid;
578
+ bestActivity = state.lastActivity;
579
+ }
580
+ }
581
+ }
582
+ if (bestPid !== null) {
583
+ this.pids.delete(bestPid);
584
+ this._droppedPids++;
585
+ if (this._persist)
586
+ this._dropQueue.add(bestPid);
587
+ return;
588
+ }
589
+ // Tier 3: every pid has a subscriber. Don't silently drop a
590
+ // subscribed stream — let the cap be briefly exceeded.
591
+ }
592
+ /** Diagnostics snapshot for /api/stats rollup. */
593
+ get stats() {
594
+ let running = 0;
595
+ let exited = 0;
596
+ let totalBytes = 0;
597
+ let subscribers = 0;
598
+ for (const state of this.pids.values()) {
599
+ if (state.exit)
600
+ exited++;
601
+ else
602
+ running++;
603
+ totalBytes += state.bytes;
604
+ subscribers += state.subscribers.size + state.exitSubscribers.size;
605
+ }
606
+ return {
607
+ totalPids: this.pids.size,
608
+ maxPids: this.maxPids,
609
+ runningPids: running,
610
+ exitedPids: exited,
611
+ totalBufferBytes: totalBytes,
612
+ subscribers,
613
+ droppedPids: this._droppedPids,
614
+ };
615
+ }
616
+ _evict(state, pid) {
617
+ let droppedAny = false;
618
+ while (state.bytes > this.perPidBytes && state.chunks.length > 0) {
619
+ const dropped = state.chunks.shift();
620
+ state.bytes -= dropped.data.length;
621
+ droppedAny = true;
622
+ }
623
+ if (!droppedAny || pid === undefined || !this._persist)
624
+ return;
625
+ // W9: cutoff = lowest in-memory seq. Any persisted seq below this is
626
+ // dead weight in SQL (and dead weight in the dirty queue if not yet
627
+ // flushed). Drop them from BOTH:
628
+ //
629
+ // 1. Queue a `pruneBeforeSeq(pid, cutoff)` so already-flushed rows
630
+ // below cutoff are deleted from SQL on next flush.
631
+ // 2. Drop entries from `dirtyChunks` whose seq is below cutoff —
632
+ // they were evicted from memory before they ever made it to SQL,
633
+ // no point persisting now.
634
+ //
635
+ // Without (2), a chatty process whose in-memory ring runs hot would
636
+ // still write every byte to SQL on the first flush, defeating the
637
+ // per-pid byte cap.
638
+ const cutoff = state.nextSeq - state.chunks.length;
639
+ const existing = this._pruneQueue.get(pid) ?? -1;
640
+ if (cutoff > existing)
641
+ this._pruneQueue.set(pid, cutoff);
642
+ if (state.dirtyChunks.length > 0) {
643
+ state.dirtyChunks = state.dirtyChunks.filter((d) => d.seq >= cutoff);
644
+ }
645
+ }
646
+ _fanout(state, chunk) {
647
+ if (state.subscribers.size === 0)
648
+ return;
649
+ for (const cb of state.subscribers) {
650
+ try {
651
+ cb(chunk);
652
+ }
653
+ catch { /* swallow subscriber errors */ }
654
+ }
655
+ }
656
+ }