@timber-js/app 0.2.0-alpha.9 → 0.2.0-alpha.90

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 (610) hide show
  1. package/dist/_chunks/actions-DLnUaR65.js +421 -0
  2. package/dist/_chunks/actions-DLnUaR65.js.map +1 -0
  3. package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-HS0LGUl2.js} +1 -1
  4. package/dist/_chunks/als-registry-HS0LGUl2.js.map +1 -0
  5. package/dist/_chunks/chunk-BYIpzuS7.js +39 -0
  6. package/dist/_chunks/{debug-gwlJkDuf.js → debug-ECi_61pb.js} +2 -2
  7. package/dist/_chunks/debug-ECi_61pb.js.map +1 -0
  8. package/dist/_chunks/define-C77ScO0m.js +106 -0
  9. package/dist/_chunks/define-C77ScO0m.js.map +1 -0
  10. package/dist/_chunks/define-Itxvcd7F.js +199 -0
  11. package/dist/_chunks/define-Itxvcd7F.js.map +1 -0
  12. package/dist/_chunks/define-cookie-BowvzoP0.js +94 -0
  13. package/dist/_chunks/define-cookie-BowvzoP0.js.map +1 -0
  14. package/dist/_chunks/{format-DviM89f0.js → dev-warnings-DpGRGoDi.js} +5 -44
  15. package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +1 -0
  16. package/dist/_chunks/format-CYBGxKtc.js +14 -0
  17. package/dist/_chunks/format-CYBGxKtc.js.map +1 -0
  18. package/dist/_chunks/{interception-BOoWmLUA.js → interception-DRlhJWbu.js} +219 -97
  19. package/dist/_chunks/interception-DRlhJWbu.js.map +1 -0
  20. package/dist/_chunks/merge-search-params-Cm_KIWDX.js +41 -0
  21. package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +1 -0
  22. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-DS3eKNmf.js} +1 -1
  23. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-DS3eKNmf.js.map} +1 -1
  24. package/dist/_chunks/request-context-CK5tZqIP.js +478 -0
  25. package/dist/_chunks/request-context-CK5tZqIP.js.map +1 -0
  26. package/dist/_chunks/schema-bridge-C3xl_vfb.js +86 -0
  27. package/dist/_chunks/schema-bridge-C3xl_vfb.js.map +1 -0
  28. package/dist/_chunks/segment-classify-BDNn6EzD.js +65 -0
  29. package/dist/_chunks/segment-classify-BDNn6EzD.js.map +1 -0
  30. package/dist/_chunks/segment-context-fHFLF1PE.js +34 -0
  31. package/dist/_chunks/segment-context-fHFLF1PE.js.map +1 -0
  32. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-DzuI0bIV.js} +1 -1
  33. package/dist/_chunks/{ssr-data-MjmprTmO.js.map → ssr-data-DzuI0bIV.js.map} +1 -1
  34. package/dist/_chunks/stale-reload-BX5gL1r-.js +64 -0
  35. package/dist/_chunks/stale-reload-BX5gL1r-.js.map +1 -0
  36. package/dist/_chunks/{tracing-CemImE6h.js → tracing-CCYbKn5n.js} +60 -9
  37. package/dist/_chunks/tracing-CCYbKn5n.js.map +1 -0
  38. package/dist/_chunks/use-params-Br9YSUFV.js +295 -0
  39. package/dist/_chunks/use-params-Br9YSUFV.js.map +1 -0
  40. package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-BiV5GJgm.js} +7 -4
  41. package/dist/_chunks/use-query-states-BiV5GJgm.js.map +1 -0
  42. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  43. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  44. package/dist/adapters/cloudflare-dev.js +73 -0
  45. package/dist/adapters/cloudflare-dev.js.map +1 -0
  46. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  47. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  48. package/dist/adapters/cloudflare-kv-cache.js +95 -0
  49. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  50. package/dist/adapters/cloudflare.d.ts +148 -12
  51. package/dist/adapters/cloudflare.d.ts.map +1 -1
  52. package/dist/adapters/cloudflare.js +135 -11
  53. package/dist/adapters/cloudflare.js.map +1 -1
  54. package/dist/adapters/compress-module.d.ts.map +1 -1
  55. package/dist/adapters/nitro.d.ts +17 -1
  56. package/dist/adapters/nitro.d.ts.map +1 -1
  57. package/dist/adapters/nitro.js +56 -13
  58. package/dist/adapters/nitro.js.map +1 -1
  59. package/dist/cache/cache-api.d.ts +24 -0
  60. package/dist/cache/cache-api.d.ts.map +1 -0
  61. package/dist/cache/handler-store.d.ts +31 -0
  62. package/dist/cache/handler-store.d.ts.map +1 -0
  63. package/dist/cache/index.d.ts +23 -7
  64. package/dist/cache/index.d.ts.map +1 -1
  65. package/dist/cache/index.js +142 -80
  66. package/dist/cache/index.js.map +1 -1
  67. package/dist/cache/singleflight.d.ts +18 -1
  68. package/dist/cache/singleflight.d.ts.map +1 -1
  69. package/dist/cache/sizeof.d.ts +22 -0
  70. package/dist/cache/sizeof.d.ts.map +1 -0
  71. package/dist/cache/timber-cache.d.ts +1 -1
  72. package/dist/cache/timber-cache.d.ts.map +1 -1
  73. package/dist/cli.d.ts +6 -1
  74. package/dist/cli.d.ts.map +1 -1
  75. package/dist/cli.js +8 -3
  76. package/dist/cli.js.map +1 -1
  77. package/dist/client/browser-dev.d.ts +27 -1
  78. package/dist/client/browser-dev.d.ts.map +1 -1
  79. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  80. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  81. package/dist/client/browser-entry/hmr.d.ts +21 -0
  82. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  83. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  84. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  85. package/dist/client/browser-entry/index.d.ts +30 -0
  86. package/dist/client/browser-entry/index.d.ts.map +1 -0
  87. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  88. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  89. package/dist/client/browser-entry/router-init.d.ts +23 -0
  90. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  91. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  92. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  93. package/dist/client/browser-entry/scroll.d.ts +19 -0
  94. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  95. package/dist/client/error-boundary.d.ts +12 -5
  96. package/dist/client/error-boundary.d.ts.map +1 -1
  97. package/dist/client/error-boundary.js +10 -4
  98. package/dist/client/error-boundary.js.map +1 -1
  99. package/dist/client/error-reconstituter.d.ts +54 -0
  100. package/dist/client/error-reconstituter.d.ts.map +1 -0
  101. package/dist/client/form.d.ts +6 -3
  102. package/dist/client/form.d.ts.map +1 -1
  103. package/dist/client/history.d.ts +19 -4
  104. package/dist/client/history.d.ts.map +1 -1
  105. package/dist/client/index.d.ts +9 -21
  106. package/dist/client/index.d.ts.map +1 -1
  107. package/dist/client/index.js +229 -1018
  108. package/dist/client/index.js.map +1 -1
  109. package/dist/client/internal.d.ts +18 -0
  110. package/dist/client/internal.d.ts.map +1 -0
  111. package/dist/client/internal.js +890 -0
  112. package/dist/client/internal.js.map +1 -0
  113. package/dist/client/link-pending-store.d.ts +63 -0
  114. package/dist/client/link-pending-store.d.ts.map +1 -0
  115. package/dist/client/link.d.ts +62 -55
  116. package/dist/client/link.d.ts.map +1 -1
  117. package/dist/client/nav-link-store.d.ts +36 -0
  118. package/dist/client/nav-link-store.d.ts.map +1 -0
  119. package/dist/client/navigation-api-types.d.ts +90 -0
  120. package/dist/client/navigation-api-types.d.ts.map +1 -0
  121. package/dist/client/navigation-api.d.ts +115 -0
  122. package/dist/client/navigation-api.d.ts.map +1 -0
  123. package/dist/client/navigation-context.d.ts +13 -2
  124. package/dist/client/navigation-context.d.ts.map +1 -1
  125. package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
  126. package/dist/client/navigation-root.d.ts.map +1 -0
  127. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  128. package/dist/client/router-ref.d.ts +1 -1
  129. package/dist/client/router.d.ts +70 -4
  130. package/dist/client/router.d.ts.map +1 -1
  131. package/dist/client/rsc-fetch.d.ts +38 -3
  132. package/dist/client/rsc-fetch.d.ts.map +1 -1
  133. package/dist/client/segment-cache.d.ts +1 -1
  134. package/dist/client/segment-cache.d.ts.map +1 -1
  135. package/dist/client/segment-outlet.d.ts +63 -0
  136. package/dist/client/segment-outlet.d.ts.map +1 -0
  137. package/dist/client/ssr-data.d.ts +13 -4
  138. package/dist/client/ssr-data.d.ts.map +1 -1
  139. package/dist/client/stale-reload.d.ts +15 -0
  140. package/dist/client/stale-reload.d.ts.map +1 -1
  141. package/dist/client/top-loader.d.ts +5 -5
  142. package/dist/client/top-loader.d.ts.map +1 -1
  143. package/dist/client/use-link-status.d.ts +5 -5
  144. package/dist/client/use-link-status.d.ts.map +1 -1
  145. package/dist/client/use-params.d.ts +6 -4
  146. package/dist/client/use-params.d.ts.map +1 -1
  147. package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
  148. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  149. package/dist/client/use-query-states.d.ts +1 -1
  150. package/dist/client/use-query-states.d.ts.map +1 -1
  151. package/dist/client/use-router.d.ts +1 -1
  152. package/dist/codec.d.ts +33 -0
  153. package/dist/codec.d.ts.map +1 -0
  154. package/dist/codec.js +2 -0
  155. package/dist/config-types.d.ts +266 -0
  156. package/dist/config-types.d.ts.map +1 -0
  157. package/dist/config-validation.d.ts +51 -0
  158. package/dist/config-validation.d.ts.map +1 -0
  159. package/dist/content/index.d.ts +1 -10
  160. package/dist/content/index.d.ts.map +1 -1
  161. package/dist/content/index.js +0 -2
  162. package/dist/cookies/define-cookie.d.ts +35 -14
  163. package/dist/cookies/define-cookie.d.ts.map +1 -1
  164. package/dist/cookies/index.js +1 -83
  165. package/dist/fonts/bundle.d.ts +48 -0
  166. package/dist/fonts/bundle.d.ts.map +1 -0
  167. package/dist/fonts/css.d.ts +1 -0
  168. package/dist/fonts/css.d.ts.map +1 -1
  169. package/dist/fonts/dev-middleware.d.ts +22 -0
  170. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  171. package/dist/fonts/pipeline.d.ts +138 -0
  172. package/dist/fonts/pipeline.d.ts.map +1 -0
  173. package/dist/fonts/transform.d.ts +72 -0
  174. package/dist/fonts/transform.d.ts.map +1 -0
  175. package/dist/fonts/types.d.ts +45 -1
  176. package/dist/fonts/types.d.ts.map +1 -1
  177. package/dist/fonts/virtual-modules.d.ts +59 -0
  178. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  179. package/dist/index.d.ts +45 -190
  180. package/dist/index.d.ts.map +1 -1
  181. package/dist/index.js +4294 -2453
  182. package/dist/index.js.map +1 -1
  183. package/dist/plugin-context.d.ts +107 -0
  184. package/dist/plugin-context.d.ts.map +1 -0
  185. package/dist/plugins/adapter-build.d.ts +1 -1
  186. package/dist/plugins/adapter-build.d.ts.map +1 -1
  187. package/dist/plugins/build-manifest.d.ts +2 -2
  188. package/dist/plugins/build-manifest.d.ts.map +1 -1
  189. package/dist/plugins/build-report.d.ts +3 -3
  190. package/dist/plugins/build-report.d.ts.map +1 -1
  191. package/dist/plugins/client-chunks.d.ts +32 -0
  192. package/dist/plugins/client-chunks.d.ts.map +1 -0
  193. package/dist/plugins/content.d.ts +1 -1
  194. package/dist/plugins/content.d.ts.map +1 -1
  195. package/dist/plugins/dev-404-page.d.ts +56 -0
  196. package/dist/plugins/dev-404-page.d.ts.map +1 -0
  197. package/dist/plugins/dev-browser-logs.d.ts +84 -0
  198. package/dist/plugins/dev-browser-logs.d.ts.map +1 -0
  199. package/dist/plugins/dev-error-overlay.d.ts +49 -9
  200. package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
  201. package/dist/plugins/dev-error-page.d.ts +58 -0
  202. package/dist/plugins/dev-error-page.d.ts.map +1 -0
  203. package/dist/plugins/dev-logs.d.ts +1 -1
  204. package/dist/plugins/dev-logs.d.ts.map +1 -1
  205. package/dist/plugins/dev-server.d.ts +1 -1
  206. package/dist/plugins/dev-server.d.ts.map +1 -1
  207. package/dist/plugins/dev-terminal-error.d.ts +28 -0
  208. package/dist/plugins/dev-terminal-error.d.ts.map +1 -0
  209. package/dist/plugins/entries.d.ts +1 -1
  210. package/dist/plugins/entries.d.ts.map +1 -1
  211. package/dist/plugins/fonts.d.ts +17 -73
  212. package/dist/plugins/fonts.d.ts.map +1 -1
  213. package/dist/plugins/mdx.d.ts +1 -1
  214. package/dist/plugins/mdx.d.ts.map +1 -1
  215. package/dist/plugins/routing.d.ts +1 -1
  216. package/dist/plugins/routing.d.ts.map +1 -1
  217. package/dist/plugins/server-bundle.d.ts.map +1 -1
  218. package/dist/plugins/shims.d.ts +6 -5
  219. package/dist/plugins/shims.d.ts.map +1 -1
  220. package/dist/plugins/static-build.d.ts +4 -4
  221. package/dist/plugins/static-build.d.ts.map +1 -1
  222. package/dist/routing/codegen.d.ts +2 -2
  223. package/dist/routing/codegen.d.ts.map +1 -1
  224. package/dist/routing/convention-lint.d.ts +41 -0
  225. package/dist/routing/convention-lint.d.ts.map +1 -0
  226. package/dist/routing/index.d.ts +2 -0
  227. package/dist/routing/index.d.ts.map +1 -1
  228. package/dist/routing/index.js +3 -2
  229. package/dist/routing/scanner.d.ts.map +1 -1
  230. package/dist/routing/segment-classify.d.ts +46 -0
  231. package/dist/routing/segment-classify.d.ts.map +1 -0
  232. package/dist/routing/status-file-lint.d.ts +2 -1
  233. package/dist/routing/status-file-lint.d.ts.map +1 -1
  234. package/dist/routing/types.d.ts +16 -4
  235. package/dist/routing/types.d.ts.map +1 -1
  236. package/dist/rsc-runtime/rsc.d.ts +1 -1
  237. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  238. package/dist/rsc-runtime/ssr.d.ts +12 -0
  239. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  240. package/dist/schema-bridge.d.ts +76 -0
  241. package/dist/schema-bridge.d.ts.map +1 -0
  242. package/dist/search-params/define.d.ts +139 -0
  243. package/dist/search-params/define.d.ts.map +1 -0
  244. package/dist/search-params/index.d.ts +4 -7
  245. package/dist/search-params/index.d.ts.map +1 -1
  246. package/dist/search-params/index.js +32 -441
  247. package/dist/search-params/index.js.map +1 -1
  248. package/dist/search-params/registry.d.ts +2 -2
  249. package/dist/search-params/registry.d.ts.map +1 -1
  250. package/dist/search-params/wrappers.d.ts +53 -0
  251. package/dist/search-params/wrappers.d.ts.map +1 -0
  252. package/dist/segment-params/define.d.ts +78 -0
  253. package/dist/segment-params/define.d.ts.map +1 -0
  254. package/dist/segment-params/index.d.ts +3 -0
  255. package/dist/segment-params/index.d.ts.map +1 -0
  256. package/dist/segment-params/index.js +2 -0
  257. package/dist/server/access-gate.d.ts +4 -0
  258. package/dist/server/access-gate.d.ts.map +1 -1
  259. package/dist/server/action-client.d.ts +41 -6
  260. package/dist/server/action-client.d.ts.map +1 -1
  261. package/dist/server/action-encryption.d.ts +76 -0
  262. package/dist/server/action-encryption.d.ts.map +1 -0
  263. package/dist/server/action-handler.d.ts +7 -0
  264. package/dist/server/action-handler.d.ts.map +1 -1
  265. package/dist/server/actions.d.ts +3 -6
  266. package/dist/server/actions.d.ts.map +1 -1
  267. package/dist/server/als-registry.d.ts +32 -4
  268. package/dist/server/als-registry.d.ts.map +1 -1
  269. package/dist/server/build-manifest.d.ts +2 -2
  270. package/dist/server/build-manifest.d.ts.map +1 -1
  271. package/dist/server/debug.d.ts +1 -1
  272. package/dist/server/default-logger.d.ts +22 -0
  273. package/dist/server/default-logger.d.ts.map +1 -0
  274. package/dist/server/deny-page-resolver.d.ts +52 -0
  275. package/dist/server/deny-page-resolver.d.ts.map +1 -0
  276. package/dist/server/deny-renderer.d.ts.map +1 -1
  277. package/dist/server/dev-holding-server.d.ts +52 -0
  278. package/dist/server/dev-holding-server.d.ts.map +1 -0
  279. package/dist/server/dev-source-map.d.ts +22 -0
  280. package/dist/server/dev-source-map.d.ts.map +1 -0
  281. package/dist/server/dev-warnings.d.ts +1 -21
  282. package/dist/server/dev-warnings.d.ts.map +1 -1
  283. package/dist/server/early-hints.d.ts +13 -5
  284. package/dist/server/early-hints.d.ts.map +1 -1
  285. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  286. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  287. package/dist/server/fallback-error.d.ts +12 -7
  288. package/dist/server/fallback-error.d.ts.map +1 -1
  289. package/dist/server/flight-injection-state.d.ts +66 -0
  290. package/dist/server/flight-injection-state.d.ts.map +1 -0
  291. package/dist/server/flight-scripts.d.ts +42 -0
  292. package/dist/server/flight-scripts.d.ts.map +1 -0
  293. package/dist/server/flush.d.ts.map +1 -1
  294. package/dist/server/form-data.d.ts +29 -0
  295. package/dist/server/form-data.d.ts.map +1 -1
  296. package/dist/server/html-injectors.d.ts +51 -11
  297. package/dist/server/html-injectors.d.ts.map +1 -1
  298. package/dist/server/index.d.ts +5 -43
  299. package/dist/server/index.d.ts.map +1 -1
  300. package/dist/server/index.js +195 -2800
  301. package/dist/server/index.js.map +1 -1
  302. package/dist/server/internal.d.ts +46 -0
  303. package/dist/server/internal.d.ts.map +1 -0
  304. package/dist/server/internal.js +2900 -0
  305. package/dist/server/internal.js.map +1 -0
  306. package/dist/server/logger.d.ts +25 -7
  307. package/dist/server/logger.d.ts.map +1 -1
  308. package/dist/server/middleware-runner.d.ts +19 -4
  309. package/dist/server/middleware-runner.d.ts.map +1 -1
  310. package/dist/server/node-stream-transforms.d.ts +113 -0
  311. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  312. package/dist/server/page-deny-boundary.d.ts +31 -0
  313. package/dist/server/page-deny-boundary.d.ts.map +1 -0
  314. package/dist/server/pipeline-interception.d.ts +1 -1
  315. package/dist/server/pipeline-interception.d.ts.map +1 -1
  316. package/dist/server/pipeline-metadata.d.ts +6 -0
  317. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  318. package/dist/server/pipeline.d.ts +52 -10
  319. package/dist/server/pipeline.d.ts.map +1 -1
  320. package/dist/server/primitives.d.ts +69 -18
  321. package/dist/server/primitives.d.ts.map +1 -1
  322. package/dist/server/render-timeout.d.ts +51 -0
  323. package/dist/server/render-timeout.d.ts.map +1 -0
  324. package/dist/server/request-context.d.ts +112 -43
  325. package/dist/server/request-context.d.ts.map +1 -1
  326. package/dist/server/route-element-builder.d.ts +27 -1
  327. package/dist/server/route-element-builder.d.ts.map +1 -1
  328. package/dist/server/route-handler.d.ts.map +1 -1
  329. package/dist/server/route-matcher.d.ts +16 -2
  330. package/dist/server/route-matcher.d.ts.map +1 -1
  331. package/dist/server/rsc-entry/api-handler.d.ts +2 -2
  332. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  333. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  334. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  335. package/dist/server/rsc-entry/helpers.d.ts +48 -5
  336. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  337. package/dist/server/rsc-entry/index.d.ts +20 -3
  338. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  339. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
  340. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  341. package/dist/server/rsc-entry/rsc-stream.d.ts +14 -1
  342. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  343. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  344. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  345. package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
  346. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  347. package/dist/server/safe-load.d.ts +46 -0
  348. package/dist/server/safe-load.d.ts.map +1 -0
  349. package/dist/server/sensitive-fields.d.ts +74 -0
  350. package/dist/server/sensitive-fields.d.ts.map +1 -0
  351. package/dist/server/sitemap-generator.d.ts +129 -0
  352. package/dist/server/sitemap-generator.d.ts.map +1 -0
  353. package/dist/server/sitemap-handler.d.ts +22 -0
  354. package/dist/server/sitemap-handler.d.ts.map +1 -0
  355. package/dist/server/slot-resolver.d.ts +1 -1
  356. package/dist/server/slot-resolver.d.ts.map +1 -1
  357. package/dist/server/ssr-entry.d.ts +23 -0
  358. package/dist/server/ssr-entry.d.ts.map +1 -1
  359. package/dist/server/ssr-render.d.ts +39 -21
  360. package/dist/server/ssr-render.d.ts.map +1 -1
  361. package/dist/server/ssr-wrappers.d.ts +50 -0
  362. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  363. package/dist/server/status-code-resolver.d.ts +1 -1
  364. package/dist/server/status-code-resolver.d.ts.map +1 -1
  365. package/dist/server/stream-utils.d.ts +36 -0
  366. package/dist/server/stream-utils.d.ts.map +1 -0
  367. package/dist/server/tracing.d.ts +4 -4
  368. package/dist/server/tracing.d.ts.map +1 -1
  369. package/dist/server/tree-builder.d.ts +22 -19
  370. package/dist/server/tree-builder.d.ts.map +1 -1
  371. package/dist/server/types.d.ts +1 -4
  372. package/dist/server/types.d.ts.map +1 -1
  373. package/dist/server/version-skew.d.ts +61 -0
  374. package/dist/server/version-skew.d.ts.map +1 -0
  375. package/dist/shared/merge-search-params.d.ts +22 -0
  376. package/dist/shared/merge-search-params.d.ts.map +1 -0
  377. package/dist/shims/font-google.d.ts +1 -1
  378. package/dist/shims/font-google.d.ts.map +1 -1
  379. package/dist/shims/font-google.js +42 -0
  380. package/dist/shims/font-google.js.map +1 -0
  381. package/dist/shims/font-local.d.ts +26 -0
  382. package/dist/shims/font-local.d.ts.map +1 -0
  383. package/dist/shims/font-local.js +20 -0
  384. package/dist/shims/font-local.js.map +1 -0
  385. package/dist/shims/headers.d.ts +2 -1
  386. package/dist/shims/headers.d.ts.map +1 -1
  387. package/dist/shims/navigation-client.d.ts +1 -1
  388. package/dist/shims/navigation-client.d.ts.map +1 -1
  389. package/dist/shims/navigation.d.ts +3 -2
  390. package/dist/shims/navigation.d.ts.map +1 -1
  391. package/dist/utils/directive-parser.d.ts +5 -2
  392. package/dist/utils/directive-parser.d.ts.map +1 -1
  393. package/dist/utils/state-machine.d.ts +80 -0
  394. package/dist/utils/state-machine.d.ts.map +1 -0
  395. package/package.json +51 -16
  396. package/src/adapters/cloudflare-dev.ts +177 -0
  397. package/src/adapters/cloudflare-kv-cache.ts +142 -0
  398. package/src/adapters/cloudflare.ts +342 -28
  399. package/src/adapters/compress-module.ts +24 -4
  400. package/src/adapters/nitro.ts +52 -8
  401. package/src/adapters/wrangler.d.ts +7 -0
  402. package/src/cache/cache-api.ts +38 -0
  403. package/src/cache/handler-store.ts +68 -0
  404. package/src/cache/index.ts +81 -18
  405. package/src/cache/singleflight.ts +62 -4
  406. package/src/cache/sizeof.ts +31 -0
  407. package/src/cache/timber-cache.ts +24 -20
  408. package/src/cli.ts +16 -6
  409. package/src/client/browser-dev.ts +128 -1
  410. package/src/client/browser-entry/action-dispatch.ts +116 -0
  411. package/src/client/browser-entry/hmr.ts +81 -0
  412. package/src/client/browser-entry/hydrate.ts +145 -0
  413. package/src/client/browser-entry/index.ts +143 -0
  414. package/src/client/browser-entry/post-hydration.ts +119 -0
  415. package/src/client/browser-entry/router-init.ts +193 -0
  416. package/src/client/browser-entry/rsc-stream.ts +157 -0
  417. package/src/client/browser-entry/scroll.ts +27 -0
  418. package/src/client/error-boundary.tsx +48 -16
  419. package/src/client/error-reconstituter.tsx +65 -0
  420. package/src/client/form.tsx +14 -7
  421. package/src/client/history.ts +26 -4
  422. package/src/client/index.ts +65 -38
  423. package/src/client/internal.ts +57 -0
  424. package/src/client/link-pending-store.ts +111 -0
  425. package/src/client/link.tsx +342 -113
  426. package/src/client/nav-link-store.ts +47 -0
  427. package/src/client/navigation-api-types.ts +112 -0
  428. package/src/client/navigation-api.ts +332 -0
  429. package/src/client/navigation-context.ts +31 -6
  430. package/src/client/navigation-root.tsx +342 -0
  431. package/src/client/nuqs-adapter.tsx +16 -3
  432. package/src/client/router-ref.ts +1 -1
  433. package/src/client/router.ts +299 -72
  434. package/src/client/rsc-fetch.ts +97 -8
  435. package/src/client/segment-cache.ts +1 -1
  436. package/src/client/segment-outlet.tsx +86 -0
  437. package/src/client/ssr-data.ts +13 -5
  438. package/src/client/stale-reload.ts +72 -3
  439. package/src/client/top-loader.tsx +18 -6
  440. package/src/client/use-link-status.ts +7 -7
  441. package/src/client/use-params.ts +7 -5
  442. package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
  443. package/src/client/use-query-states.ts +9 -3
  444. package/src/client/use-router.ts +1 -1
  445. package/src/codec.ts +49 -0
  446. package/src/config-types.ts +264 -0
  447. package/src/config-validation.ts +303 -0
  448. package/src/content/index.ts +5 -13
  449. package/src/cookies/define-cookie.ts +78 -25
  450. package/src/cookies/index.ts +8 -0
  451. package/src/fonts/bundle.ts +142 -0
  452. package/src/fonts/css.ts +2 -1
  453. package/src/fonts/dev-middleware.ts +74 -0
  454. package/src/fonts/pipeline.ts +275 -0
  455. package/src/fonts/transform.ts +353 -0
  456. package/src/fonts/types.ts +50 -1
  457. package/src/fonts/virtual-modules.ts +159 -0
  458. package/src/index.ts +314 -355
  459. package/src/plugin-context.ts +240 -0
  460. package/src/plugins/adapter-build.ts +9 -3
  461. package/src/plugins/build-manifest.ts +13 -2
  462. package/src/plugins/build-report.ts +3 -3
  463. package/src/plugins/client-chunks.ts +65 -0
  464. package/src/plugins/content.ts +1 -1
  465. package/src/plugins/dev-404-page.ts +418 -0
  466. package/src/plugins/dev-browser-logs.ts +288 -0
  467. package/src/plugins/dev-error-overlay.ts +286 -42
  468. package/src/plugins/dev-error-page.ts +536 -0
  469. package/src/plugins/dev-logs.ts +1 -1
  470. package/src/plugins/dev-server.ts +146 -19
  471. package/src/plugins/dev-terminal-error.ts +217 -0
  472. package/src/plugins/entries.ts +111 -10
  473. package/src/plugins/fonts.ts +133 -638
  474. package/src/plugins/mdx.ts +1 -1
  475. package/src/plugins/routing.ts +213 -31
  476. package/src/plugins/server-action-exports.ts +1 -1
  477. package/src/plugins/server-bundle.ts +32 -1
  478. package/src/plugins/shims.ts +136 -35
  479. package/src/plugins/static-build.ts +17 -11
  480. package/src/routing/codegen.ts +273 -105
  481. package/src/routing/convention-lint.ts +356 -0
  482. package/src/routing/index.ts +2 -0
  483. package/src/routing/scanner.ts +93 -23
  484. package/src/routing/segment-classify.ts +89 -0
  485. package/src/routing/status-file-lint.ts +3 -2
  486. package/src/routing/types.ts +17 -4
  487. package/src/rsc-runtime/rsc.ts +2 -0
  488. package/src/rsc-runtime/ssr.ts +50 -0
  489. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  490. package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
  491. package/src/search-params/define.ts +482 -0
  492. package/src/search-params/index.ts +14 -20
  493. package/src/search-params/registry.ts +2 -2
  494. package/src/search-params/wrappers.ts +85 -0
  495. package/src/segment-params/define.ts +279 -0
  496. package/src/segment-params/index.ts +9 -0
  497. package/src/server/access-gate.tsx +70 -29
  498. package/src/server/action-client.ts +88 -15
  499. package/src/server/action-encryption.ts +144 -0
  500. package/src/server/action-handler.ts +53 -6
  501. package/src/server/actions.ts +10 -9
  502. package/src/server/als-registry.ts +34 -6
  503. package/src/server/build-manifest.ts +10 -4
  504. package/src/server/compress.ts +25 -7
  505. package/src/server/debug.ts +1 -1
  506. package/src/server/default-logger.ts +99 -0
  507. package/src/server/deny-page-resolver.ts +154 -0
  508. package/src/server/deny-renderer.ts +24 -38
  509. package/src/server/dev-holding-server.ts +185 -0
  510. package/src/server/dev-source-map.ts +31 -0
  511. package/src/server/dev-warnings.ts +4 -49
  512. package/src/server/early-hints.ts +36 -15
  513. package/src/server/error-boundary-wrapper.ts +74 -22
  514. package/src/server/fallback-error.ts +74 -102
  515. package/src/server/flight-injection-state.ts +113 -0
  516. package/src/server/flight-scripts.ts +62 -0
  517. package/src/server/flush.ts +2 -1
  518. package/src/server/form-data.ts +76 -0
  519. package/src/server/html-injectors.ts +280 -120
  520. package/src/server/index.ts +25 -177
  521. package/src/server/internal.ts +169 -0
  522. package/src/server/logger.ts +44 -36
  523. package/src/server/middleware-runner.ts +31 -4
  524. package/src/server/node-stream-transforms.ts +509 -0
  525. package/src/server/page-deny-boundary.tsx +56 -0
  526. package/src/server/pipeline-interception.ts +17 -16
  527. package/src/server/pipeline-metadata.ts +13 -0
  528. package/src/server/pipeline.ts +261 -66
  529. package/src/server/primitives.ts +111 -28
  530. package/src/server/render-timeout.ts +108 -0
  531. package/src/server/request-context.ts +293 -132
  532. package/src/server/route-element-builder.ts +283 -191
  533. package/src/server/route-handler.ts +24 -4
  534. package/src/server/route-matcher.ts +31 -20
  535. package/src/server/rsc-entry/api-handler.ts +15 -16
  536. package/src/server/rsc-entry/error-renderer.ts +305 -89
  537. package/src/server/rsc-entry/helpers.ts +134 -5
  538. package/src/server/rsc-entry/index.ts +304 -111
  539. package/src/server/rsc-entry/rsc-payload.ts +65 -18
  540. package/src/server/rsc-entry/rsc-stream.ts +81 -13
  541. package/src/server/rsc-entry/ssr-bridge.ts +14 -5
  542. package/src/server/rsc-entry/ssr-renderer.ts +171 -38
  543. package/src/server/safe-load.ts +60 -0
  544. package/src/server/sensitive-fields.ts +230 -0
  545. package/src/server/sitemap-generator.ts +338 -0
  546. package/src/server/sitemap-handler.ts +126 -0
  547. package/src/server/slot-resolver.ts +244 -229
  548. package/src/server/ssr-entry.ts +215 -32
  549. package/src/server/ssr-render.ts +289 -67
  550. package/src/server/ssr-wrappers.tsx +139 -0
  551. package/src/server/status-code-resolver.ts +1 -1
  552. package/src/server/stream-utils.ts +213 -0
  553. package/src/server/tracing.ts +20 -9
  554. package/src/server/tree-builder.ts +92 -58
  555. package/src/server/types.ts +3 -6
  556. package/src/server/version-skew.ts +104 -0
  557. package/src/shared/merge-search-params.ts +55 -0
  558. package/src/shims/font-google.ts +1 -1
  559. package/src/shims/font-local.ts +34 -0
  560. package/src/shims/headers.ts +5 -1
  561. package/src/shims/navigation-client.ts +1 -1
  562. package/src/shims/navigation.ts +7 -2
  563. package/src/utils/directive-parser.ts +5 -2
  564. package/src/utils/state-machine.ts +111 -0
  565. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  566. package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
  567. package/dist/_chunks/format-DviM89f0.js.map +0 -1
  568. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  569. package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
  570. package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
  571. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  572. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  573. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  574. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  575. package/dist/cache/register-cached-function.d.ts +0 -17
  576. package/dist/cache/register-cached-function.d.ts.map +0 -1
  577. package/dist/client/browser-entry.d.ts +0 -21
  578. package/dist/client/browser-entry.d.ts.map +0 -1
  579. package/dist/client/link-status-provider.d.ts +0 -11
  580. package/dist/client/link-status-provider.d.ts.map +0 -1
  581. package/dist/client/transition-root.d.ts.map +0 -1
  582. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  583. package/dist/cookies/index.js.map +0 -1
  584. package/dist/plugins/cache-transform.d.ts +0 -36
  585. package/dist/plugins/cache-transform.d.ts.map +0 -1
  586. package/dist/plugins/dynamic-transform.d.ts +0 -72
  587. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  588. package/dist/search-params/analyze.d.ts +0 -54
  589. package/dist/search-params/analyze.d.ts.map +0 -1
  590. package/dist/search-params/builtin-codecs.d.ts +0 -105
  591. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  592. package/dist/search-params/codecs.d.ts +0 -53
  593. package/dist/search-params/codecs.d.ts.map +0 -1
  594. package/dist/search-params/create.d.ts +0 -106
  595. package/dist/search-params/create.d.ts.map +0 -1
  596. package/dist/server/prerender.d.ts +0 -77
  597. package/dist/server/prerender.d.ts.map +0 -1
  598. package/dist/server/response-cache.d.ts +0 -54
  599. package/dist/server/response-cache.d.ts.map +0 -1
  600. package/src/cache/register-cached-function.ts +0 -103
  601. package/src/client/browser-entry.ts +0 -678
  602. package/src/client/link-status-provider.tsx +0 -30
  603. package/src/client/transition-root.tsx +0 -166
  604. package/src/plugins/cache-transform.ts +0 -199
  605. package/src/plugins/dynamic-transform.ts +0 -161
  606. package/src/search-params/analyze.ts +0 -192
  607. package/src/search-params/builtin-codecs.ts +0 -228
  608. package/src/search-params/create.ts +0 -321
  609. package/src/server/prerender.ts +0 -139
  610. package/src/server/response-cache.ts +0 -410
@@ -0,0 +1,509 @@
1
+ /**
2
+ * Node.js native stream transforms for SSR HTML post-processing.
3
+ *
4
+ * These are Node.js Transform stream equivalents of the Web Stream
5
+ * transforms in html-injectors.ts. Used on Node.js/Bun where native
6
+ * streams (C++ backed) are faster than Web Streams (JS reimplementation).
7
+ *
8
+ * The transforms are pure string operations on HTML chunks — the same
9
+ * logic as the Web Stream versions, just wrapped in Node.js Transform
10
+ * instead of Web TransformStream.
11
+ *
12
+ * Architecture:
13
+ * renderToPipeableStream → pipe(errorHandler) → pipe(headInjector)
14
+ * → pipe(flightInjector) → Readable.toWeb() → Response
15
+ *
16
+ * All chunks stay in C++ Node.js stream buffers until the final
17
+ * Readable.toWeb() conversion for the Response body.
18
+ */
19
+
20
+ import { Transform } from 'node:stream';
21
+ import { createGzip, constants } from 'node:zlib';
22
+
23
+ // ─── Buffered Transform ──────────────────────────────────────────────────────
24
+
25
+ /**
26
+ * Options for the Node.js buffered transform.
27
+ */
28
+ export interface NodeBufferedTransformOptions {
29
+ /**
30
+ * Flush synchronously once the buffer reaches this many bytes.
31
+ * Prevents unbounded memory growth for very large Fizz flushes.
32
+ * Default: Infinity (no byte limit — flush only on tick boundary).
33
+ */
34
+ readonly maxBufferByteLength?: number;
35
+ }
36
+
37
+ /**
38
+ * Node.js Transform that buffers incoming chunks and coalesces them
39
+ * within a single event loop tick.
40
+ *
41
+ * Equivalent to createBufferedTransformStream() in html-injectors.ts.
42
+ * React Fizz may emit multiple micro-chunks within a single flush.
43
+ * Without buffering, downstream transforms (especially flight injection)
44
+ * could see chunk boundaries in the middle of HTML tags or attributes.
45
+ *
46
+ * This transform collects all chunks that arrive in the same tick and
47
+ * emits them as a single concatenated Buffer on the next `setImmediate`.
48
+ *
49
+ * **Not a polling loop.** Uses a single-shot `setImmediate` per flush
50
+ * cycle — no recursive scheduling, no busy-wait. See design/02 §"No Polling".
51
+ *
52
+ * Inspired by Next.js `createBufferedTransformStream`.
53
+ */
54
+ export function createNodeBufferedTransform(options: NodeBufferedTransformOptions = {}): Transform {
55
+ const { maxBufferByteLength = Infinity } = options;
56
+
57
+ let bufferedChunks: Buffer[] = [];
58
+ let bufferByteLength = 0;
59
+ let pendingImmediate: ReturnType<typeof setImmediate> | null = null;
60
+
61
+ const transform = new Transform({
62
+ transform(chunk: Buffer, _encoding, callback) {
63
+ bufferedChunks.push(chunk);
64
+ bufferByteLength += chunk.byteLength;
65
+
66
+ if (bufferByteLength >= maxBufferByteLength) {
67
+ // Synchronous flush — buffer is too large to hold
68
+ flushBuffer();
69
+ } else if (!pendingImmediate) {
70
+ // Schedule a deferred flush for end of this tick.
71
+ // Single-shot setImmediate — NOT a recursive loop.
72
+ // See design/02 §"No Polling".
73
+ pendingImmediate = setImmediate(() => {
74
+ pendingImmediate = null;
75
+ flushBuffer();
76
+ });
77
+ }
78
+
79
+ callback();
80
+ },
81
+ flush(callback) {
82
+ // Cancel any pending deferred flush and flush synchronously
83
+ if (pendingImmediate) {
84
+ clearImmediate(pendingImmediate);
85
+ pendingImmediate = null;
86
+ }
87
+ flushBuffer();
88
+ callback();
89
+ },
90
+ });
91
+
92
+ function flushBuffer() {
93
+ if (bufferedChunks.length === 0) return;
94
+
95
+ const merged = Buffer.concat(bufferedChunks, bufferByteLength);
96
+ bufferedChunks = [];
97
+ bufferByteLength = 0;
98
+ transform.push(merged);
99
+ }
100
+
101
+ return transform;
102
+ }
103
+
104
+ // ─── Injection Transforms ────────────────────────────────────────────────────
105
+
106
+ import { createMachine } from '../utils/state-machine.js';
107
+ import { flightChunkScript } from './flight-scripts.js';
108
+ import {
109
+ flightInjectionTransitions,
110
+ isHtmlDone,
111
+ isPullDone,
112
+ type FlightInjectionState,
113
+ type FlightInjectionEvent,
114
+ } from './flight-injection-state.js';
115
+ import { withTimeout, RenderTimeoutError } from './render-timeout.js';
116
+ import { logStreamingError } from './logger.js';
117
+
118
+ // ─── Move Suffix Transform ───────────────────────────────────────────────────
119
+
120
+ const SUFFIX = '</body></html>';
121
+ const SUFFIX_BUF = Buffer.from(SUFFIX, 'utf-8');
122
+
123
+ /**
124
+ * Node.js Transform that moves `</body></html>` to the end of the stream.
125
+ *
126
+ * Equivalent to createMoveSuffixStream() in html-injectors.ts.
127
+ * Strips the suffix when first encountered and re-emits it in flush().
128
+ * If no suffix is found, it's appended anyway for well-formed HTML.
129
+ */
130
+ export function createNodeMoveSuffixTransform(): Transform {
131
+ let foundSuffix = false;
132
+
133
+ return new Transform({
134
+ transform(chunk: Buffer, _encoding, callback) {
135
+ if (foundSuffix) {
136
+ this.push(chunk);
137
+ callback();
138
+ return;
139
+ }
140
+
141
+ const text = chunk.toString('utf-8');
142
+ const idx = text.indexOf(SUFFIX);
143
+ if (idx === -1) {
144
+ this.push(chunk);
145
+ callback();
146
+ return;
147
+ }
148
+
149
+ foundSuffix = true;
150
+
151
+ // If the entire chunk is exactly the suffix, skip it
152
+ if (chunk.byteLength === SUFFIX_BUF.byteLength) {
153
+ callback();
154
+ return;
155
+ }
156
+
157
+ // Emit content before the suffix
158
+ const before = text.slice(0, idx);
159
+ const after = text.slice(idx + SUFFIX.length);
160
+ if (before) this.push(Buffer.from(before, 'utf-8'));
161
+ if (after) this.push(Buffer.from(after, 'utf-8'));
162
+ callback();
163
+ },
164
+ flush(callback) {
165
+ // Always emit the suffix at the very end
166
+ this.push(SUFFIX_BUF);
167
+ callback();
168
+ },
169
+ });
170
+ }
171
+
172
+ // ─── Head Injection ──────────────────────────────────────────────────────────
173
+
174
+ /**
175
+ * Node.js Transform that injects HTML content before </head>.
176
+ *
177
+ * Equivalent to injectHead() in html-injectors.ts. Streams chunks
178
+ * through immediately, keeping only a small trailing buffer to handle
179
+ * </head> split across chunk boundaries.
180
+ */
181
+ export function createNodeHeadInjector(headHtml: string): Transform {
182
+ if (!headHtml) {
183
+ return new Transform({
184
+ transform(chunk, _enc, cb) {
185
+ cb(null, chunk);
186
+ },
187
+ });
188
+ }
189
+
190
+ const target = '</head>';
191
+ const tailLen = target.length - 1;
192
+ let injected = false;
193
+ let tail = '';
194
+
195
+ return new Transform({
196
+ transform(chunk: Buffer, _encoding, callback) {
197
+ if (injected) {
198
+ callback(null, chunk);
199
+ return;
200
+ }
201
+
202
+ const text = tail + chunk.toString('utf-8');
203
+ const tagIndex = text.indexOf(target);
204
+
205
+ if (tagIndex !== -1) {
206
+ const before = text.slice(0, tagIndex);
207
+ const after = text.slice(tagIndex);
208
+ this.push(Buffer.from(before + headHtml + after, 'utf-8'));
209
+ injected = true;
210
+ tail = '';
211
+ callback();
212
+ } else {
213
+ const safeEnd = Math.max(0, text.length - tailLen);
214
+ if (safeEnd > 0) {
215
+ this.push(Buffer.from(text.slice(0, safeEnd), 'utf-8'));
216
+ }
217
+ tail = text.slice(safeEnd);
218
+ callback();
219
+ }
220
+ },
221
+ flush(callback) {
222
+ if (!injected && tail) {
223
+ this.push(Buffer.from(tail, 'utf-8'));
224
+ }
225
+ callback();
226
+ },
227
+ });
228
+ }
229
+
230
+ // ─── RSC Flight Injection ────────────────────────────────────────────────────
231
+
232
+ /**
233
+ * Node.js Transform that merges RSC script tags into the HTML stream.
234
+ *
235
+ * Reads RSC chunks from the provided ReadableStream and injects them
236
+ * as `<script>` tags between HTML chunks. Scripts are buffered in
237
+ * pending[] and only drained from transform() (after a complete HTML
238
+ * chunk) or flush() — never pushed directly from the pull loop.
239
+ *
240
+ * Suffix stripping (</body></html>) is handled upstream by
241
+ * createNodeMoveSuffixTransform. This transform only interleaves
242
+ * RSC scripts at safe chunk boundaries.
243
+ *
244
+ * The RSC stream is a Web ReadableStream (from the tee'd RSC Flight
245
+ * stream). We read from it using the Web API — this is the one bridge
246
+ * point between Web Streams and Node.js streams in the pipeline.
247
+ */
248
+ /**
249
+ * Options for the Node.js flight injector.
250
+ */
251
+ export interface NodeFlightInjectorOptions {
252
+ /**
253
+ * Timeout in milliseconds for individual RSC stream reads.
254
+ * If a single `rscReader.read()` call does not resolve within
255
+ * this duration, the read is aborted and the stream errors with
256
+ * a RenderTimeoutError. Default: 30000 (30s).
257
+ */
258
+ renderTimeoutMs?: number;
259
+ }
260
+
261
+ export function createNodeFlightInjector(
262
+ rscStream: ReadableStream<Uint8Array> | undefined,
263
+ options?: NodeFlightInjectorOptions
264
+ ): Transform {
265
+ if (!rscStream) {
266
+ return new Transform({
267
+ transform(chunk, _enc, cb) {
268
+ cb(null, chunk);
269
+ },
270
+ });
271
+ }
272
+
273
+ const timeoutMs = options?.renderTimeoutMs ?? 30_000;
274
+ const rscReader = rscStream.getReader();
275
+ const decoder = new TextDecoder('utf-8', { fatal: true });
276
+
277
+ const machine = createMachine<FlightInjectionState, FlightInjectionEvent>({
278
+ initial: { phase: 'init' },
279
+ transitions: flightInjectionTransitions,
280
+ });
281
+
282
+ // Stored promise from pullLoop — awaited in flush() via .then()
283
+ // instead of polling. See design/02 §"No Polling".
284
+ let pullPromise: Promise<void> | null = null;
285
+
286
+ // RSC script chunks waiting to be drained at a safe boundary.
287
+ // pullLoop buffers here; transform() and flush() drain.
288
+ // RSC script chunks waiting to be drained at a safe boundary.
289
+ // pullLoop buffers here; transform(), flush(), and pullLoop's
290
+ // post-yield drain all consume from this buffer.
291
+ const pending: Buffer[] = [];
292
+ async function pullLoop(): Promise<void> {
293
+ // Yield once so the first transform() call can process the shell
294
+ // HTML chunk before we start reading RSC data.
295
+ await new Promise<void>((r) => setImmediate(r));
296
+ try {
297
+ for (;;) {
298
+ // Guard each RSC read with a timeout so a permanently hung
299
+ // RSC stream eventually aborts instead of blocking forever.
300
+ // See design/02-rendering-pipeline.md §"Streaming Constraints".
301
+ const readPromise = rscReader.read();
302
+ const { done, value } =
303
+ timeoutMs > 0
304
+ ? await withTimeout(readPromise, timeoutMs, 'RSC stream read timed out')
305
+ : await readPromise;
306
+ if (done) {
307
+ machine.send({ type: 'PULL_DONE' });
308
+ return;
309
+ }
310
+ const decoded = decoder.decode(value, { stream: true });
311
+ const scriptBuf = Buffer.from(flightChunkScript(decoded), 'utf-8');
312
+ // Buffer the script — drained by the next transform() call,
313
+ // flush(), or by the scheduled drain below.
314
+ pending.push(scriptBuf);
315
+ // Yield between reads so HTML chunks get priority in the event
316
+ // loop — but only while HTML is still streaming. Once flush()
317
+ // fires, read without yielding to drain remaining RSC data.
318
+ if (!isHtmlDone(machine.state)) {
319
+ await new Promise<void>((r) => setImmediate(r));
320
+ // After yielding, if no transform() call drained the buffer
321
+ // (i.e., no new HTML chunk arrived), drain now. This ensures
322
+ // RSC flight data reaches the client at shell-flush time —
323
+ // without this, hydration blocks on createFromReadableStream
324
+ // waiting for data that's stuck in pending[].
325
+ // This is safe: we're between event loop ticks, so no
326
+ // transform() call is mid-execution (no mid-tag risk).
327
+ if (pending.length > 0) {
328
+ drainPending();
329
+ }
330
+ }
331
+ }
332
+ } catch (err) {
333
+ // On timeout, cancel the RSC reader to release resources.
334
+ if (err instanceof RenderTimeoutError) {
335
+ rscReader.cancel(err).catch(() => {});
336
+ }
337
+ machine.send({ type: 'PULL_ERROR', error: err });
338
+ }
339
+ }
340
+
341
+ /** Drain all buffered RSC script chunks to the transform output. */
342
+ function drainPending(): void {
343
+ while (pending.length > 0) {
344
+ transform.push(pending.shift()!);
345
+ }
346
+ }
347
+
348
+ // No bootstrap script here — the init script is in <head> via
349
+ // flightInitScript() (see flight-scripts.ts). This ensures __timber_f
350
+ // exists before any chunk scripts execute.
351
+
352
+ const transform = new Transform({
353
+ transform(chunk: Buffer, _encoding, callback) {
354
+ const isFirst = machine.state.phase === 'init';
355
+ if (isFirst) {
356
+ machine.send({ type: 'FIRST_CHUNK' });
357
+ }
358
+
359
+ // Emit the HTML chunk, then drain any buffered RSC scripts.
360
+ // Scripts always come AFTER a complete HTML chunk — never mid-tag.
361
+ // The buffered transform upstream (TIM-528) ensures each chunk is
362
+ // a coherent HTML fragment. Suffix stripping is handled upstream
363
+ // by createNodeMoveSuffixTransform (TIM-530).
364
+ transform.push(chunk);
365
+ drainPending();
366
+
367
+ // Start the pull loop on the first HTML chunk.
368
+ if (isFirst) {
369
+ pullPromise = pullLoop();
370
+ }
371
+ callback();
372
+ },
373
+ flush(callback) {
374
+ // All HTML chunks have been emitted. Transition to flushing —
375
+ // the pull loop will stop yielding between RSC reads since
376
+ // isHtmlDone() now returns true.
377
+ machine.send({ type: 'HTML_DONE' });
378
+
379
+ const finish = () => {
380
+ // Drain any remaining buffered RSC scripts
381
+ drainPending();
382
+ if (machine.state.phase === 'error') {
383
+ const err = machine.state.error;
384
+ transform.destroy(err instanceof Error ? err : new Error(String(err)));
385
+ return;
386
+ }
387
+ callback();
388
+ };
389
+
390
+ if (isPullDone(machine.state)) {
391
+ finish();
392
+ return;
393
+ }
394
+ // Wait for the RSC pull loop promise to resolve instead of
395
+ // polling with setImmediate. No CPU spin, no busy-poll —
396
+ // just a Promise chain. See design/02 §"No Polling".
397
+ if (!pullPromise) {
398
+ pullPromise = pullLoop();
399
+ }
400
+ pullPromise.then(finish, (err) => {
401
+ machine.send({ type: 'PULL_ERROR', error: err });
402
+ finish();
403
+ });
404
+ },
405
+ });
406
+
407
+ return transform;
408
+ }
409
+
410
+ // ─── Error Handling ──────────────────────────────────────────────────────────
411
+
412
+ const NOINDEX_SCRIPT =
413
+ '<script>document.head.appendChild(Object.assign(document.createElement("meta"),{name:"robots",content:"noindex"}))</script>';
414
+
415
+ /**
416
+ * Node.js Transform that catches post-shell streaming errors.
417
+ *
418
+ * Equivalent to wrapStreamWithErrorHandling() in ssr-render.ts.
419
+ * Catches errors from React's streaming phase (deny/throw inside Suspense
420
+ * after the shell has flushed) and closes the stream cleanly.
421
+ */
422
+ export function createNodeErrorHandler(signal?: AbortSignal): Transform {
423
+ const transform = new Transform({
424
+ transform(chunk, _encoding, callback) {
425
+ callback(null, chunk);
426
+ },
427
+ });
428
+
429
+ transform.on('error', (error) => {
430
+ const isAbort =
431
+ (error instanceof DOMException && error.name === 'AbortError') ||
432
+ (error instanceof Error && error.name === 'AbortError') ||
433
+ signal?.aborted;
434
+
435
+ if (isAbort) {
436
+ transform.end();
437
+ return;
438
+ }
439
+
440
+ logStreamingError({ error });
441
+ transform.push(Buffer.from(NOINDEX_SCRIPT, 'utf-8'));
442
+ transform.end();
443
+ });
444
+
445
+ return transform;
446
+ }
447
+
448
+ // ─── Compression ─────────────────────────────────────────────────────────────
449
+
450
+ const COMPRESSIBLE_TYPES = new Set([
451
+ 'text/html',
452
+ 'text/css',
453
+ 'text/plain',
454
+ 'text/xml',
455
+ 'text/javascript',
456
+ 'text/x-component',
457
+ 'application/json',
458
+ 'application/javascript',
459
+ 'application/xml',
460
+ 'application/xhtml+xml',
461
+ 'application/rss+xml',
462
+ 'application/atom+xml',
463
+ 'image/svg+xml',
464
+ ]);
465
+
466
+ /**
467
+ * Create a Node.js gzip Transform using native node:zlib.
468
+ *
469
+ * Uses `createGzip()` which is backed by C++ zlib — significantly faster
470
+ * than the Web Streams `CompressionStream` API (which is a JS wrapper
471
+ * around the same zlib but with per-chunk Promise overhead).
472
+ *
473
+ * Returns null if the response shouldn't be compressed (wrong content type,
474
+ * client doesn't accept gzip, already encoded, etc.).
475
+ */
476
+ export function createNodeGzipCompressor(
477
+ requestHeaders: Headers,
478
+ responseHeaders: Headers
479
+ ): Transform | null {
480
+ // Check Accept-Encoding
481
+ const acceptEncoding = requestHeaders.get('accept-encoding') || '';
482
+ if (!acceptEncoding.includes('gzip')) return null;
483
+
484
+ // Check content type is compressible
485
+ const contentType = responseHeaders.get('content-type') || '';
486
+ const mimeType = contentType.split(';')[0].trim().toLowerCase();
487
+ if (!COMPRESSIBLE_TYPES.has(mimeType)) return null;
488
+
489
+ // Don't double-compress
490
+ if (responseHeaders.has('content-encoding')) return null;
491
+
492
+ // Set response headers for gzip
493
+ responseHeaders.set('content-encoding', 'gzip');
494
+ responseHeaders.delete('content-length');
495
+ const existingVary = responseHeaders.get('vary');
496
+ if (existingVary) {
497
+ if (!existingVary.toLowerCase().includes('accept-encoding')) {
498
+ responseHeaders.set('vary', existingVary + ', Accept-Encoding');
499
+ }
500
+ } else {
501
+ responseHeaders.set('vary', 'Accept-Encoding');
502
+ }
503
+
504
+ // Z_SYNC_FLUSH ensures each chunk is flushed to the output immediately.
505
+ // Without it, gzip buffers internally and the browser doesn't receive
506
+ // the HTML shell until the gzip stream closes — breaking streaming.
507
+ // ~2–5% size overhead vs Z_NO_FLUSH but preserves correct streaming.
508
+ return createGzip({ flush: constants.Z_SYNC_FLUSH });
509
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * PageDenyBoundary — catches DenySignal from page components server-side.
3
+ *
4
+ * Wraps a server component page by calling it as an async function (the same
5
+ * thing React Flight does internally). If the page throws DenySignal, the
6
+ * boundary catches it and renders the matching deny page as a normal element.
7
+ * No error reaches React Flight — the Flight stream is clean, SSR succeeds,
8
+ * and the entire request uses a single renderToReadableStream call.
9
+ *
10
+ * Client component pages ('use client') are NOT wrapped — they can't call
11
+ * deny() (server-only API) and must go through createElement normally.
12
+ *
13
+ * See design/04-authorization.md, design/10-error-handling.md, TIM-666.
14
+ */
15
+
16
+ import { DenySignal } from './primitives.js';
17
+ import type { DenyPageEntry } from './deny-page-resolver.js';
18
+ import { renderMatchingDenyPage, setDenyStatus } from './deny-page-resolver.js';
19
+ import { withSpan } from './tracing.js';
20
+
21
+ /**
22
+ * Async server component that wraps a page call with DenySignal catching.
23
+ *
24
+ * Calls the page component as an async function, awaits it, and catches
25
+ * DenySignal. On catch, renders the deny page in-tree. On success, returns
26
+ * the page's rendered output normally.
27
+ */
28
+ export async function PageDenyBoundary({
29
+ Page,
30
+ route,
31
+ denyPages,
32
+ }: {
33
+ /** The page server component function. */
34
+ Page: (...args: unknown[]) => unknown;
35
+ /** Route path for OTEL tracing. */
36
+ route: string;
37
+ /** Deny page fallback chain from the segment chain. */
38
+ denyPages: DenyPageEntry[];
39
+ }): Promise<React.ReactElement> {
40
+ try {
41
+ // Call the page as an async function — same as React Flight does.
42
+ // Wrap in OTEL span for tracing (replaces the TracedPage wrapper).
43
+ const result = await withSpan('timber.page', { 'timber.route': route }, () => Page({}));
44
+ return result as React.ReactElement;
45
+ } catch (error: unknown) {
46
+ if (error instanceof DenySignal) {
47
+ const denyElement = renderMatchingDenyPage(denyPages, error.status, error.data);
48
+ if (denyElement) {
49
+ setDenyStatus(error.status);
50
+ return denyElement;
51
+ }
52
+ }
53
+ // Non-deny errors (RedirectSignal, runtime errors) propagate normally.
54
+ throw error;
55
+ }
56
+ }
@@ -9,6 +9,8 @@
9
9
  * See design/07-routing.md §"Intercepting Routes"
10
10
  */
11
11
 
12
+ import { classifyUrlSegment } from '../routing/segment-classify.js';
13
+
12
14
  /** Result of a successful interception match. */
13
15
  export interface InterceptionMatchResult {
14
16
  /** The pathname to re-match (the source/intercepting route's parent). */
@@ -26,7 +28,7 @@ export interface InterceptionMatchResult {
26
28
  export function findInterceptionMatch(
27
29
  targetPathname: string,
28
30
  sourceUrl: string,
29
- rewrites: import('#/routing/interception.js').InterceptionRewrite[]
31
+ rewrites: import('../routing/interception.js').InterceptionRewrite[]
30
32
  ): InterceptionMatchResult | null {
31
33
  for (const rewrite of rewrites) {
32
34
  // Check if the source URL starts with the intercepting prefix
@@ -53,23 +55,22 @@ export function pathnameMatchesPattern(pathname: string, pattern: string): boole
53
55
 
54
56
  let pi = 0;
55
57
  for (let i = 0; i < patternParts.length; i++) {
56
- const segment = patternParts[i];
57
-
58
- // Catch-all: [...param] or [[...param]] — matches rest of URL
59
- if (segment.startsWith('[...') || segment.startsWith('[[...')) {
60
- return pi < pathParts.length || segment.startsWith('[[...');
61
- }
58
+ const seg = classifyUrlSegment(patternParts[i]);
62
59
 
63
- // Dynamic: [param] — matches any single segment
64
- if (segment.startsWith('[') && segment.endsWith(']')) {
65
- if (pi >= pathParts.length) return false;
66
- pi++;
67
- continue;
60
+ switch (seg.kind) {
61
+ case 'catch-all':
62
+ return pi < pathParts.length;
63
+ case 'optional-catch-all':
64
+ return true;
65
+ case 'dynamic':
66
+ if (pi >= pathParts.length) return false;
67
+ pi++;
68
+ continue;
69
+ case 'static':
70
+ if (pi >= pathParts.length || pathParts[pi] !== seg.value) return false;
71
+ pi++;
72
+ continue;
68
73
  }
69
-
70
- // Static — must match exactly
71
- if (pi >= pathParts.length || pathParts[pi] !== segment) return false;
72
- pi++;
73
74
  }
74
75
 
75
76
  return pi === pathParts.length;
@@ -79,6 +79,19 @@ export function serializeSitemap(
79
79
  return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>`;
80
80
  }
81
81
 
82
+ /**
83
+ * Serialize a sitemap index (list of sub-sitemap URLs) to XML.
84
+ * Used for pagination when the total URL count exceeds 50,000.
85
+ * Follows the sitemap.org protocol: https://www.sitemaps.org/protocol.html
86
+ */
87
+ export function serializeSitemapIndex(sitemapUrls: string[]): string {
88
+ const sitemaps = sitemapUrls
89
+ .map((url) => ` <sitemap>\n <loc>${escapeXml(url)}</loc>\n </sitemap>`)
90
+ .join('\n');
91
+
92
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${sitemaps}\n</sitemapindex>`;
93
+ }
94
+
82
95
  /** Escape special XML characters. */
83
96
  export function escapeXml(str: string): string {
84
97
  return str