@timber-js/app 0.2.0-alpha.207 → 0.2.0-alpha.209

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 (526) hide show
  1. package/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
  2. package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
  3. package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
  4. package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
  5. package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
  6. package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
  7. package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
  8. package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
  9. package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
  10. package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
  11. package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
  12. package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
  13. package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
  14. package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
  15. package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
  16. package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
  17. package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
  18. package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
  19. package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
  20. package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
  21. package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
  22. package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
  23. package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
  24. package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
  25. package/dist/_chunks/{error-boundary-BndF-3Td.js → error-boundary-tA7kVfs4.js} +84 -104
  26. package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
  27. package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
  28. package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
  29. package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
  30. package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
  31. package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
  32. package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
  33. package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
  34. package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
  35. package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
  36. package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
  37. package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
  38. package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
  39. package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
  40. package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
  41. package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
  42. package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
  43. package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
  44. package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
  45. package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
  46. package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
  47. package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
  48. package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
  49. package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
  50. package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
  51. package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
  52. package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
  53. package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
  54. package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
  55. package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
  56. package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
  57. package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
  58. package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
  59. package/dist/_chunks/{status-page-marker-DwQBrLBz.js → status-page-marker-gaihi0KZ.js} +140 -28
  60. package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
  61. package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
  62. package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
  63. package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
  64. package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
  65. package/dist/adapters/build-output-helper.d.ts +7 -7
  66. package/dist/adapters/build-output-helper.d.ts.map +1 -1
  67. package/dist/adapters/canonicalize-module.d.ts +8 -0
  68. package/dist/adapters/canonicalize-module.d.ts.map +1 -0
  69. package/dist/adapters/cloudflare-dev.js +1 -1
  70. package/dist/adapters/cloudflare-kv-cache.js +2 -2
  71. package/dist/adapters/cloudflare.d.ts +30 -8
  72. package/dist/adapters/cloudflare.d.ts.map +1 -1
  73. package/dist/adapters/cloudflare.js +2 -2
  74. package/dist/adapters/compress-module.d.ts +8 -0
  75. package/dist/adapters/compress-module.d.ts.map +1 -1
  76. package/dist/adapters/fs-identity.d.ts +2 -3
  77. package/dist/adapters/fs-identity.d.ts.map +1 -1
  78. package/dist/adapters/nitro-presets.d.ts +0 -6
  79. package/dist/adapters/nitro-presets.d.ts.map +1 -1
  80. package/dist/adapters/nitro-preview.d.ts +43 -11
  81. package/dist/adapters/nitro-preview.d.ts.map +1 -1
  82. package/dist/adapters/nitro.d.ts +1 -13
  83. package/dist/adapters/nitro.d.ts.map +1 -1
  84. package/dist/adapters/nitro.js +291 -176
  85. package/dist/adapters/nitro.js.map +1 -1
  86. package/dist/adapters/shared.d.ts +7 -2
  87. package/dist/adapters/shared.d.ts.map +1 -1
  88. package/dist/adapters/types.d.ts +105 -21
  89. package/dist/adapters/types.d.ts.map +1 -1
  90. package/dist/adapters/types.js +0 -0
  91. package/dist/analyze/crawl-entry.js +3 -3
  92. package/dist/analyze/graph-cache.d.ts.map +1 -1
  93. package/dist/analyze/graph-command.js +4 -4
  94. package/dist/cache/index.js +2 -2
  95. package/dist/cache/json-lossy-check.d.ts.map +1 -1
  96. package/dist/cache/singleflight.d.ts.map +1 -1
  97. package/dist/cache/sizeof.d.ts.map +1 -1
  98. package/dist/cache/stores/memory.js +1 -1
  99. package/dist/cache/tag-aware-handler.d.ts.map +1 -1
  100. package/dist/cdn/workers-cache-purge.js +1 -1
  101. package/dist/cli-check.d.ts +7 -37
  102. package/dist/cli-check.d.ts.map +1 -1
  103. package/dist/cli-context.d.ts +54 -0
  104. package/dist/cli-context.d.ts.map +1 -0
  105. package/dist/cli.d.ts +9 -9
  106. package/dist/cli.d.ts.map +1 -1
  107. package/dist/cli.js +20 -24
  108. package/dist/cli.js.map +1 -1
  109. package/dist/client/browser-dev.d.ts +1 -1
  110. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
  111. package/dist/client/browser-entry/hydrate.d.ts +19 -29
  112. package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
  113. package/dist/client/browser-entry/index.d.ts +7 -7
  114. package/dist/client/browser-entry/post-hydration.d.ts +6 -9
  115. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
  116. package/dist/client/browser-entry/router-init.d.ts +6 -11
  117. package/dist/client/browser-entry/router-init.d.ts.map +1 -1
  118. package/dist/client/error-boundary.d.ts +4 -3
  119. package/dist/client/error-boundary.d.ts.map +1 -1
  120. package/dist/client/error-boundary.js +1 -1
  121. package/dist/client/error-reconstituter.d.ts +3 -9
  122. package/dist/client/error-reconstituter.d.ts.map +1 -1
  123. package/dist/client/history.d.ts +20 -11
  124. package/dist/client/history.d.ts.map +1 -1
  125. package/dist/client/index.d.ts +0 -1
  126. package/dist/client/index.d.ts.map +1 -1
  127. package/dist/client/index.js +5 -6
  128. package/dist/client/index.js.map +1 -1
  129. package/dist/client/internal.d.ts +3 -3
  130. package/dist/client/internal.d.ts.map +1 -1
  131. package/dist/client/internal.js +95 -108
  132. package/dist/client/internal.js.map +1 -1
  133. package/dist/client/navigation-commit.d.ts +20 -7
  134. package/dist/client/navigation-commit.d.ts.map +1 -1
  135. package/dist/client/navigation-context.d.ts +3 -5
  136. package/dist/client/navigation-context.d.ts.map +1 -1
  137. package/dist/client/react-root.d.ts +3 -2
  138. package/dist/client/react-root.d.ts.map +1 -1
  139. package/dist/client/router-pipeline.d.ts +3 -8
  140. package/dist/client/router-pipeline.d.ts.map +1 -1
  141. package/dist/client/router-types.d.ts +45 -39
  142. package/dist/client/router-types.d.ts.map +1 -1
  143. package/dist/client/router-url.d.ts +24 -0
  144. package/dist/client/router-url.d.ts.map +1 -0
  145. package/dist/client/router.d.ts.map +1 -1
  146. package/dist/client/rsc-fetch.d.ts +8 -4
  147. package/dist/client/rsc-fetch.d.ts.map +1 -1
  148. package/dist/client/segment-cache.d.ts +44 -4
  149. package/dist/client/segment-cache.d.ts.map +1 -1
  150. package/dist/client/ssr-data.d.ts +18 -64
  151. package/dist/client/ssr-data.d.ts.map +1 -1
  152. package/dist/client/state.d.ts +2 -5
  153. package/dist/client/state.d.ts.map +1 -1
  154. package/dist/client/use-pathname.d.ts +1 -1
  155. package/dist/config-types.d.ts +2 -1
  156. package/dist/config-types.d.ts.map +1 -1
  157. package/dist/config-validation.d.ts.map +1 -1
  158. package/dist/cookies/index.js +1 -1
  159. package/dist/dev-tools/dev-page-shell.d.ts +17 -0
  160. package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
  161. package/dist/dev-tools/index.d.ts +1 -1
  162. package/dist/dev-tools/index.d.ts.map +1 -1
  163. package/dist/dev-tools/instrumentation.d.ts +17 -2
  164. package/dist/dev-tools/instrumentation.d.ts.map +1 -1
  165. package/dist/dev-tools/overlay.d.ts +6 -27
  166. package/dist/dev-tools/overlay.d.ts.map +1 -1
  167. package/dist/index.d.ts.map +1 -1
  168. package/dist/index.js +632 -373
  169. package/dist/index.js.map +1 -1
  170. package/dist/plugin-context.d.ts +26 -40
  171. package/dist/plugin-context.d.ts.map +1 -1
  172. package/dist/plugins/build-manifest.d.ts.map +1 -1
  173. package/dist/plugins/build-report.d.ts +15 -2
  174. package/dist/plugins/build-report.d.ts.map +1 -1
  175. package/dist/plugins/dev-server.d.ts.map +1 -1
  176. package/dist/plugins/entries.d.ts.map +1 -1
  177. package/dist/plugins/fonts.d.ts +19 -1
  178. package/dist/plugins/fonts.d.ts.map +1 -1
  179. package/dist/plugins/post-build.d.ts +110 -0
  180. package/dist/plugins/post-build.d.ts.map +1 -0
  181. package/dist/plugins/prebuilt-capture.d.ts +11 -4
  182. package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
  183. package/dist/plugins/prebuilt.d.ts +17 -1
  184. package/dist/plugins/prebuilt.d.ts.map +1 -1
  185. package/dist/plugins/prerender-sugar.d.ts.map +1 -1
  186. package/dist/plugins/react-resolve.d.ts +49 -0
  187. package/dist/plugins/react-resolve.d.ts.map +1 -0
  188. package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
  189. package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
  190. package/dist/plugins/shims.d.ts.map +1 -1
  191. package/dist/plugins/static-build.d.ts +32 -9
  192. package/dist/plugins/static-build.d.ts.map +1 -1
  193. package/dist/routing/codegen-write.d.ts +0 -9
  194. package/dist/routing/codegen-write.d.ts.map +1 -1
  195. package/dist/routing/index.js +2 -2
  196. package/dist/routing/segment-codegen.d.ts.map +1 -1
  197. package/dist/server/access-gate.d.ts.map +1 -1
  198. package/dist/server/action-handler.d.ts +5 -4
  199. package/dist/server/action-handler.d.ts.map +1 -1
  200. package/dist/server/actions.d.ts +46 -7
  201. package/dist/server/actions.d.ts.map +1 -1
  202. package/dist/server/als-registry.d.ts +58 -5
  203. package/dist/server/als-registry.d.ts.map +1 -1
  204. package/dist/server/children-interception.d.ts.map +1 -1
  205. package/dist/server/cookie-context.d.ts +2 -23
  206. package/dist/server/cookie-context.d.ts.map +1 -1
  207. package/dist/server/csp-nonce.d.ts +0 -9
  208. package/dist/server/csp-nonce.d.ts.map +1 -1
  209. package/dist/server/csrf.d.ts +27 -4
  210. package/dist/server/csrf.d.ts.map +1 -1
  211. package/dist/server/debug.d.ts +0 -1
  212. package/dist/server/debug.d.ts.map +1 -1
  213. package/dist/server/default-logger.d.ts +2 -1
  214. package/dist/server/default-logger.d.ts.map +1 -1
  215. package/dist/server/deny-boundary.d.ts +12 -6
  216. package/dist/server/deny-boundary.d.ts.map +1 -1
  217. package/dist/server/deny-renderer.d.ts +2 -2
  218. package/dist/server/deny-renderer.d.ts.map +1 -1
  219. package/dist/server/error-boundary-wrapper.d.ts +7 -3
  220. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  221. package/dist/server/fallback-error.d.ts +9 -2
  222. package/dist/server/fallback-error.d.ts.map +1 -1
  223. package/dist/server/head-response.d.ts +4 -4
  224. package/dist/server/html-injectors.d.ts.map +1 -1
  225. package/dist/server/index.d.ts +0 -1
  226. package/dist/server/index.d.ts.map +1 -1
  227. package/dist/server/index.js +3 -4
  228. package/dist/server/index.js.map +1 -1
  229. package/dist/server/instrumentation.d.ts +10 -3
  230. package/dist/server/instrumentation.d.ts.map +1 -1
  231. package/dist/server/internal.d.ts +1 -4
  232. package/dist/server/internal.d.ts.map +1 -1
  233. package/dist/server/internal.js +961 -581
  234. package/dist/server/internal.js.map +1 -1
  235. package/dist/server/json-status-response.d.ts +34 -0
  236. package/dist/server/json-status-response.d.ts.map +1 -0
  237. package/dist/server/logger.d.ts +26 -0
  238. package/dist/server/logger.d.ts.map +1 -1
  239. package/dist/server/param-coercion.d.ts +11 -6
  240. package/dist/server/param-coercion.d.ts.map +1 -1
  241. package/dist/server/pipeline-helpers.d.ts +95 -7
  242. package/dist/server/pipeline-helpers.d.ts.map +1 -1
  243. package/dist/server/pipeline-interception.d.ts +11 -0
  244. package/dist/server/pipeline-interception.d.ts.map +1 -1
  245. package/dist/server/pipeline-outcome.d.ts +11 -1
  246. package/dist/server/pipeline-outcome.d.ts.map +1 -1
  247. package/dist/server/pipeline-phases.d.ts +2 -2
  248. package/dist/server/pipeline-phases.d.ts.map +1 -1
  249. package/dist/server/pipeline.d.ts +23 -35
  250. package/dist/server/pipeline.d.ts.map +1 -1
  251. package/dist/server/prebuilt/capture-render.d.ts +25 -0
  252. package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
  253. package/dist/server/prebuilt/capture-routes.d.ts +37 -0
  254. package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
  255. package/dist/server/prebuilt/capture-state.d.ts +79 -35
  256. package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
  257. package/dist/server/prebuilt/lifetime.d.ts +38 -0
  258. package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
  259. package/dist/server/prebuilt/slots.d.ts +7 -0
  260. package/dist/server/prebuilt/slots.d.ts.map +1 -1
  261. package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
  262. package/dist/server/prebuilt-builder.d.ts.map +1 -1
  263. package/dist/server/prebuilt-runtime.d.ts.map +1 -1
  264. package/dist/server/primitives.d.ts +6 -81
  265. package/dist/server/primitives.d.ts.map +1 -1
  266. package/dist/server/react-cache-bridge.d.ts +59 -0
  267. package/dist/server/react-cache-bridge.d.ts.map +1 -0
  268. package/dist/server/react-cache-scope.d.ts +49 -0
  269. package/dist/server/react-cache-scope.d.ts.map +1 -0
  270. package/dist/server/render-timeout.d.ts +15 -0
  271. package/dist/server/render-timeout.d.ts.map +1 -1
  272. package/dist/server/render-utils.d.ts +9 -0
  273. package/dist/server/render-utils.d.ts.map +1 -1
  274. package/dist/server/request-context.d.ts +26 -5
  275. package/dist/server/request-context.d.ts.map +1 -1
  276. package/dist/server/route-element-builder.d.ts.map +1 -1
  277. package/dist/server/route-handler.d.ts.map +1 -1
  278. package/dist/server/route-matcher.d.ts +7 -0
  279. package/dist/server/route-matcher.d.ts.map +1 -1
  280. package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
  281. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
  282. package/dist/server/rsc-entry/api-handler.d.ts +7 -0
  283. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  284. package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
  285. package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
  286. package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
  287. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  288. package/dist/server/rsc-entry/helpers.d.ts +0 -1
  289. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  290. package/dist/server/rsc-entry/index.d.ts +5 -15
  291. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  292. package/dist/server/rsc-entry/render-route.d.ts +5 -6
  293. package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
  294. package/dist/server/rsc-entry/render-signals.d.ts +65 -0
  295. package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
  296. package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
  297. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
  298. package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
  299. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  300. package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
  301. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  302. package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
  303. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  304. package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
  305. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  306. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
  307. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
  308. package/dist/server/signal-identity.d.ts +43 -0
  309. package/dist/server/signal-identity.d.ts.map +1 -0
  310. package/dist/server/slot-resolver.d.ts +4 -3
  311. package/dist/server/slot-resolver.d.ts.map +1 -1
  312. package/dist/server/slot-subtree-contain.d.ts.map +1 -1
  313. package/dist/server/ssr-bridge-types.d.ts +91 -53
  314. package/dist/server/ssr-bridge-types.d.ts.map +1 -1
  315. package/dist/server/ssr-entry.d.ts +8 -5
  316. package/dist/server/ssr-entry.d.ts.map +1 -1
  317. package/dist/server/ssr-render.d.ts +26 -40
  318. package/dist/server/ssr-render.d.ts.map +1 -1
  319. package/dist/server/ssr-wrappers.d.ts +1 -1
  320. package/dist/server/static-generator.d.ts.map +1 -1
  321. package/dist/server/stream-utils.d.ts +12 -0
  322. package/dist/server/stream-utils.d.ts.map +1 -1
  323. package/dist/server/tracing.d.ts +12 -16
  324. package/dist/server/tracing.d.ts.map +1 -1
  325. package/dist/server/types.d.ts +1 -1
  326. package/dist/server/version-skew.d.ts +3 -3
  327. package/dist/shared/csrf-reject.d.ts +16 -0
  328. package/dist/shared/csrf-reject.d.ts.map +1 -0
  329. package/dist/shared/error-digest.d.ts +28 -0
  330. package/dist/shared/error-digest.d.ts.map +1 -0
  331. package/dist/shared/payload-root.d.ts +11 -10
  332. package/dist/shared/payload-root.d.ts.map +1 -1
  333. package/dist/shared/rsc-payload-path.d.ts +6 -0
  334. package/dist/shared/rsc-payload-path.d.ts.map +1 -1
  335. package/dist/utils/write-file-atomic.d.ts +17 -0
  336. package/dist/utils/write-file-atomic.d.ts.map +1 -0
  337. package/docs/api/30-api-server.mdx +17 -14
  338. package/docs/api/32-api-cache.mdx +51 -23
  339. package/docs/api/34-api-config.mdx +34 -6
  340. package/docs/api/36-cli.mdx +11 -1
  341. package/docs/learn/03-fetching-data.mdx +17 -1
  342. package/docs/learn/04-access-control.mdx +1 -1
  343. package/docs/learn/10-caching.mdx +29 -11
  344. package/docs/learn/11-middleware.mdx +8 -2
  345. package/docs/learn/12-error-handling.mdx +6 -1
  346. package/package.json +7 -3
  347. package/src/adapters/build-output-helper.ts +55 -53
  348. package/src/adapters/canonicalize-module.ts +29 -0
  349. package/src/adapters/cloudflare.ts +105 -63
  350. package/src/adapters/compress-module.ts +16 -5
  351. package/src/adapters/fs-identity.ts +2 -3
  352. package/src/adapters/nitro-presets.ts +0 -15
  353. package/src/adapters/nitro-preview.ts +272 -136
  354. package/src/adapters/nitro.ts +119 -82
  355. package/src/adapters/shared.ts +23 -14
  356. package/src/adapters/types.ts +110 -21
  357. package/src/analyze/graph-cache.ts +3 -4
  358. package/src/cache/json-lossy-check.ts +3 -9
  359. package/src/cache/singleflight.ts +5 -2
  360. package/src/cache/sizeof.ts +3 -1
  361. package/src/cache/tag-aware-handler.ts +43 -26
  362. package/src/cli-check.ts +8 -98
  363. package/src/cli-context.ts +119 -0
  364. package/src/cli.ts +19 -28
  365. package/src/client/browser-dev.ts +1 -1
  366. package/src/client/browser-entry/action-dispatch.ts +26 -4
  367. package/src/client/browser-entry/hydrate.ts +53 -58
  368. package/src/client/browser-entry/index.ts +16 -27
  369. package/src/client/browser-entry/post-hydration.ts +6 -40
  370. package/src/client/browser-entry/router-init.ts +66 -84
  371. package/src/client/error-boundary.tsx +9 -41
  372. package/src/client/error-reconstituter.tsx +10 -5
  373. package/src/client/history.ts +35 -21
  374. package/src/client/index.ts +0 -1
  375. package/src/client/internal.ts +2 -7
  376. package/src/client/navigation-commit.ts +41 -18
  377. package/src/client/navigation-context.ts +3 -39
  378. package/src/client/react-root.ts +3 -2
  379. package/src/client/router-pipeline.ts +96 -132
  380. package/src/client/router-types.ts +46 -44
  381. package/src/client/router-url.ts +32 -0
  382. package/src/client/router.ts +62 -21
  383. package/src/client/rsc-fetch.ts +117 -155
  384. package/src/client/segment-cache.ts +110 -11
  385. package/src/client/ssr-data.ts +19 -80
  386. package/src/client/state.ts +2 -9
  387. package/src/client/use-pathname.ts +1 -1
  388. package/src/config-types.ts +2 -1
  389. package/src/config-validation.ts +2 -1
  390. package/src/dev-tools/dev-page-shell.ts +18 -0
  391. package/src/dev-tools/index.ts +0 -2
  392. package/src/dev-tools/instrumentation.ts +50 -2
  393. package/src/dev-tools/overlay.ts +8 -238
  394. package/src/index.ts +26 -14
  395. package/src/plugin-context.ts +39 -40
  396. package/src/plugins/build-manifest.ts +4 -11
  397. package/src/plugins/build-report.ts +70 -70
  398. package/src/plugins/dev-server.ts +24 -44
  399. package/src/plugins/entries.ts +2 -1
  400. package/src/plugins/fonts.ts +35 -7
  401. package/src/plugins/post-build.ts +327 -0
  402. package/src/plugins/prebuilt-capture.ts +28 -32
  403. package/src/plugins/prebuilt.ts +54 -39
  404. package/src/plugins/prerender-sugar.ts +0 -4
  405. package/src/plugins/react-resolve.ts +149 -0
  406. package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
  407. package/src/plugins/shims.ts +1 -0
  408. package/src/plugins/static-build.ts +42 -74
  409. package/src/routing/codegen-write.ts +25 -3
  410. package/src/routing/segment-codegen.ts +3 -2
  411. package/src/rsc-runtime/vendor-types.d.ts +8 -0
  412. package/src/server/access-gate.tsx +2 -1
  413. package/src/server/action-client.ts +1 -1
  414. package/src/server/action-handler.ts +253 -110
  415. package/src/server/actions.ts +73 -25
  416. package/src/server/als-registry.ts +73 -5
  417. package/src/server/chain-url-parts.ts +1 -1
  418. package/src/server/children-interception.ts +2 -1
  419. package/src/server/cookie-context.ts +18 -48
  420. package/src/server/csp-nonce.ts +0 -12
  421. package/src/server/csrf.ts +140 -8
  422. package/src/server/debug.ts +0 -1
  423. package/src/server/default-logger.ts +2 -1
  424. package/src/server/deny-boundary.ts +25 -13
  425. package/src/server/deny-renderer.ts +30 -97
  426. package/src/server/error-boundary-wrapper.ts +7 -3
  427. package/src/server/fallback-error.ts +26 -11
  428. package/src/server/flight-scripts.ts +1 -1
  429. package/src/server/head-response.ts +4 -4
  430. package/src/server/html-injector-core.ts +2 -2
  431. package/src/server/html-injectors.ts +2 -4
  432. package/src/server/index.ts +0 -4
  433. package/src/server/instrumentation.ts +10 -3
  434. package/src/server/internal.ts +1 -6
  435. package/src/server/json-status-response.ts +105 -0
  436. package/src/server/logger.ts +39 -3
  437. package/src/server/param-coercion.ts +15 -12
  438. package/src/server/pipeline-helpers.ts +257 -12
  439. package/src/server/pipeline-interception.ts +133 -0
  440. package/src/server/pipeline-outcome.ts +103 -31
  441. package/src/server/pipeline-phases.ts +127 -237
  442. package/src/server/pipeline.ts +204 -207
  443. package/src/server/prebuilt/capture-render.ts +118 -0
  444. package/src/server/prebuilt/capture-routes.ts +104 -0
  445. package/src/server/prebuilt/capture-state.ts +155 -48
  446. package/src/server/prebuilt/lifetime.ts +151 -0
  447. package/src/server/prebuilt/slots.ts +14 -2
  448. package/src/server/prebuilt/synthetic-store.ts +3 -0
  449. package/src/server/prebuilt-builder.ts +30 -320
  450. package/src/server/prebuilt-runtime.ts +125 -129
  451. package/src/server/primitives.ts +8 -168
  452. package/src/server/react-cache-bridge.ts +124 -0
  453. package/src/server/react-cache-scope.ts +104 -0
  454. package/src/server/render-timeout.ts +20 -0
  455. package/src/server/render-utils.ts +11 -1
  456. package/src/server/request-context.ts +36 -9
  457. package/src/server/route-element-builder.ts +11 -6
  458. package/src/server/route-handler.ts +36 -23
  459. package/src/server/route-matcher.ts +15 -1
  460. package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
  461. package/src/server/rsc-entry/api-handler.ts +27 -103
  462. package/src/server/rsc-entry/deny-fallback.ts +93 -26
  463. package/src/server/rsc-entry/error-renderer.ts +39 -91
  464. package/src/server/rsc-entry/helpers.ts +2 -4
  465. package/src/server/rsc-entry/index.ts +64 -58
  466. package/src/server/rsc-entry/render-route.ts +15 -80
  467. package/src/server/rsc-entry/render-signals.ts +108 -0
  468. package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
  469. package/src/server/rsc-entry/rsc-payload.ts +28 -61
  470. package/src/server/rsc-entry/rsc-stream.ts +113 -213
  471. package/src/server/rsc-entry/ssr-bridge.ts +2 -2
  472. package/src/server/rsc-entry/ssr-renderer.ts +182 -263
  473. package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
  474. package/src/server/signal-identity.ts +112 -0
  475. package/src/server/slot-resolver.ts +18 -18
  476. package/src/server/slot-subtree-contain.ts +2 -1
  477. package/src/server/ssr-bridge-types.ts +92 -56
  478. package/src/server/ssr-entry.ts +87 -111
  479. package/src/server/ssr-render.ts +55 -64
  480. package/src/server/ssr-wrappers.tsx +2 -2
  481. package/src/server/static-generator.ts +7 -42
  482. package/src/server/static-not-found.ts +3 -3
  483. package/src/server/stream-utils.ts +51 -0
  484. package/src/server/tracing.ts +58 -75
  485. package/src/server/types.ts +1 -1
  486. package/src/server/version-skew.ts +5 -5
  487. package/src/shared/csrf-reject.ts +15 -0
  488. package/src/shared/error-digest.ts +46 -0
  489. package/src/shared/payload-root.ts +11 -10
  490. package/src/shared/rsc-payload-path.ts +8 -1
  491. package/src/utils/write-file-atomic.ts +32 -0
  492. package/dist/_chunks/actions-jNrXdzgs.js +0 -346
  493. package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
  494. package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
  495. package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
  496. package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
  497. package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
  498. package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
  499. package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
  500. package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
  501. package/dist/_chunks/error-boundary-BndF-3Td.js.map +0 -1
  502. package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
  503. package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
  504. package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
  505. package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
  506. package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
  507. package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
  508. package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
  509. package/dist/_chunks/segment-context-D9_89u34.js +0 -34
  510. package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
  511. package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
  512. package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
  513. package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
  514. package/dist/_chunks/state-FippDgxN.js.map +0 -1
  515. package/dist/_chunks/status-page-marker-DwQBrLBz.js.map +0 -1
  516. package/dist/client/types.d.ts +0 -14
  517. package/dist/client/types.d.ts.map +0 -1
  518. package/dist/plugins/adapter-build.d.ts +0 -38
  519. package/dist/plugins/adapter-build.d.ts.map +0 -1
  520. package/dist/server/asset-headers.d.ts +0 -32
  521. package/dist/server/asset-headers.d.ts.map +0 -1
  522. package/dist/server/dev-source-map.d.ts +0 -22
  523. package/dist/server/dev-source-map.d.ts.map +0 -1
  524. package/src/client/types.ts +0 -21
  525. package/src/server/asset-headers.ts +0 -59
  526. package/src/server/dev-source-map.ts +0 -31
@@ -1,20 +1,20 @@
1
1
  /**
2
- * Hydration — pre-hydration sequence and hydrating the React root.
2
+ * Hydration — making the server-rendered page current and hydrating the
3
+ * React root with it.
3
4
  *
4
5
  * Handles two paths:
5
6
  * 1. RSC payload available: hydrate the router's React root with the payload
6
- * 2. No RSC payload: nothing — the root is created by the first render
7
- * (client/react-root.ts)
7
+ * 2. No RSC payload: nothing to hydrate — the root is created by the first
8
+ * render (client/react-root.ts) — but the page is still made current
8
9
  *
9
- * Pre-hydration ordering contract (MUST execute in this order):
10
- * 1. initRouter() — creates the global router so useRouter()
11
- * works during render
12
- * 2. setNavigationState() — populates pathname/search so usePathname()
13
- * returns correct values during hydration
14
- * 3. hydrateRoot() — synchronously executes component render
15
- * functions that depend on steps 1-2
10
+ * Either way the page becomes current through `RouterInstance.hydrate`, the
11
+ * same prepare-and-commit every navigation uses, committed before the tree
12
+ * is handed to React. The one ordering left is that the router exists
13
+ * before `hydrateRoot()`, so `useRouter()` works during render. Pathname
14
+ * and search reach the tree as props of its NavigationProvider, from the
15
+ * router's prepared navState — there is no store to seed first (TIM-1541).
16
16
  *
17
- * Params are not part of this sequence. They arrive on the payload root and
17
+ * Params are not part of this sequence either. They arrive on the payload root and
18
18
  * are published by `PayloadRoot` at the top of the tree, so
19
19
  * `useSegmentParams()` is correct during hydration without anything having to
20
20
  * run before it (TIM-1294, TIM-1297).
@@ -22,11 +22,10 @@
22
22
  * See design/19-client-navigation.md §"NavigationContext"
23
23
  */
24
24
 
25
- import { getRouterOrNull } from '#client-internal';
26
- import { getNavigationState, setNavigationState } from '../navigation-context.ts';
27
25
  import { isPageUnloading } from '../unload-guard.ts';
28
- import { locationSearch } from '../location-search.ts';
29
26
  import type { ReactRootHost } from '../react-root.ts';
27
+ import { readPublishedParams } from '../../shared/payload-root.ts';
28
+ import type { SegmentInfo } from '../../shared/segment-info.ts';
30
29
 
31
30
  import type { RscStreamResult } from './rsc-stream.ts';
32
31
  import type { RouterInitResult } from './router-init.ts';
@@ -74,45 +73,39 @@ interface HydrateOptions {
74
73
  rscResult: RscStreamResult | null;
75
74
  /** The router's React root — the one every navigation renders through. */
76
75
  reactRoot: ReactRootHost;
77
- /** The router's wrapper chain — see `RouterInitResult.renderTree`. */
78
- renderTree: RouterInitResult['renderTree'];
76
+ /** Makes the page current and builds its tree — see `RouterInitResult.hydrate`. */
77
+ hydrate: RouterInitResult['hydrate'];
79
78
  }
80
79
 
81
80
  /**
82
- * Run the pre-hydration sequence: set navigation state from the address bar.
83
- * Must be called AFTER initRouter().
84
- *
85
- * Params are no longer seeded here. They used to arrive on two inline scripts
86
- * that had to execute before `hydrateRoot()`, because hydration synchronously
87
- * renders components that read them. They now ride the payload root, and the
88
- * provider that publishes them renders before its own descendants — so the
89
- * ordering the step existed to guarantee is now a property of the tree rather
90
- * than of the bootstrap sequence (TIM-1294, TIM-1297).
81
+ * Take the segment metadata the server embedded in the document
82
+ * (`self.__timber_segments`), and remove it. It describes the chain the
83
+ * server rendered, so the first client navigation can send a state tree.
84
+ * See design/19-client-navigation.md §"X-Timber-State-Tree Header".
91
85
  */
92
- export function runPreHydration(): void {
93
- setNavigationState({
94
- pathname: window.location.pathname,
95
- search: locationSearch(),
96
- });
86
+ function takeEmbeddedSegmentInfo(): SegmentInfo[] | null {
87
+ const embedded: unknown = Reflect.get(self, '__timber_segments');
88
+ Reflect.deleteProperty(self, '__timber_segments');
89
+ return Array.isArray(embedded) ? embedded : null;
97
90
  }
98
91
 
99
92
  /**
100
- * Hydrate the React tree when an RSC payload is available.
93
+ * Make the server-rendered page current, and hydrate the React tree with it
94
+ * when an RSC payload is available.
101
95
  *
102
96
  * Wraps the payload with the router's chain (NavigationProvider,
103
97
  * TimberNuqsAdapter, the slot content cache, ...) and hydrates the router's
104
98
  * React root with it, on the document.
105
99
  *
106
- * When no RSC payload is available (JS-only client) there is nothing to
107
- * hydrate and nothing to do: the root must not be created at bootstrap —
100
+ * When no RSC payload is available (JS-only client) the page is committed
101
+ * at once and there is nothing to hydrate: the root must not be created at
102
+ * bootstrap —
108
103
  * `createRoot(document).render()` would take React ownership of the entire
109
104
  * document and blank the SSR HTML — so the router's first render, i.e. the
110
105
  * first navigation or revalidation, creates it with the tree it renders
111
106
  * (`createReactRoot`, TIM-600 / TIM-580).
112
107
  */
113
- export function hydrateApp({ rscResult, reactRoot, renderTree }: HydrateOptions): void {
114
- if (!rscResult) return;
115
-
108
+ export function hydrateApp({ rscResult, reactRoot, hydrate }: HydrateOptions): void {
116
109
  // The chain is the router's own `renderTree`, not a copy: an element type
117
110
  // that is present here and absent on the first navigation (or the
118
111
  // reverse) changes the type at that position, and React remounts
@@ -123,26 +116,28 @@ export function hydrateApp({ rscResult, reactRoot, renderTree }: HydrateOptions)
123
116
  // record: the inlined Flight stream is still arriving and hydration cannot
124
117
  // wait for it. PayloadRoot suspends on it exactly where React was going to
125
118
  // suspend on `element` (TIM-1297).
126
- const wrapped = renderTree(rscResult.element, getNavigationState(), rscResult.params);
127
-
128
- if (process.env.NODE_ENV !== 'production') {
129
- if (!getRouterOrNull()) {
130
- throw new Error('[timber] hydrateRoot called before initRouter() — bootstrap order violated');
131
- }
132
- }
133
-
134
- reactRoot.hydrate(wrapped, {
135
- // Suppress recoverable hydration errors from deny/error signals
136
- // inside Suspense boundaries. The server already handled these
137
- // (wrapStreamWithErrorHandling closes the stream cleanly after
138
- // the shell is flushed). React replays the error during hydration
139
- // but the server HTML is already correct — no recovery needed.
140
- onRecoverableError(error: unknown) {
141
- if (isPageUnloading()) return;
142
- if (process.env.NODE_ENV === 'development') {
143
- queueOrShowHydrationError(error);
144
- console.debug('[timber] Hydration recoverable error:', error);
145
- }
146
- },
147
- });
119
+ const page = {
120
+ payload: rscResult?.element ?? null,
121
+ params: rscResult?.params ?? readPublishedParams(undefined),
122
+ segmentInfo: takeEmbeddedSegmentInfo(),
123
+ };
124
+ //
125
+ // `hydrate` comes from the router's own init, so the router exists by
126
+ // construction when the tree it builds renders.
127
+ hydrate(page, (element) =>
128
+ reactRoot.hydrate(element, {
129
+ // Suppress recoverable hydration errors from deny/error signals
130
+ // inside Suspense boundaries. The server already handled these
131
+ // (wrapStreamWithErrorHandling closes the stream cleanly after
132
+ // the shell is flushed). React replays the error during hydration
133
+ // but the server HTML is already correct — no recovery needed.
134
+ onRecoverableError(error: unknown) {
135
+ if (isPageUnloading()) return;
136
+ if (process.env.NODE_ENV === 'development') {
137
+ queueOrShowHydrationError(error);
138
+ console.debug('[timber] Hydration recoverable error:', error);
139
+ }
140
+ },
141
+ })
142
+ );
148
143
  }
@@ -7,8 +7,8 @@
7
7
  * action-dispatch.ts — server action callServer callback
8
8
  * rsc-stream.ts — __timber_f chunk handling + ReadableStream
9
9
  * router-init.ts — createRouter + Navigation API setup
10
- * hydrate.ts — pre-hydration sequence + hydrating the root
11
- * post-hydration.ts — history stack, segment cache, popstate, scroll
10
+ * hydrate.ts — makes the server page current + hydrates the root
11
+ * post-hydration.ts — popstate, scroll
12
12
  * hmr.ts — dev-only HMR + error forwarding
13
13
  * scroll.ts — getScrollY helper
14
14
  *
@@ -18,11 +18,11 @@
18
18
  * 2. createRscPayloadStream() — decode inlined RSC payload
19
19
  * 3. createReactRoot() + — the root host the router renders through,
20
20
  * createTimberRouter() then the router + Navigation API
21
- * 4. runPreHydration() — set params + navigation state
22
- * 5. hydrateApp() — hydrate the root (no-op without a payload)
23
- * 6. setupPostHydration() — history stack, popstate, scroll
24
- * 7. setupHmr() — dev-only HMR wiring
25
- * 8. timber-ready signal — E2E test readiness indicator
21
+ * 4. hydrateApp() — make the page current through the router,
22
+ * hydrate the root (no root without a payload)
23
+ * 5. setupPostHydration() — popstate, scroll
24
+ * 6. setupHmr() — dev-only HMR wiring
25
+ * 7. timber-ready signal — E2E test readiness indicator
26
26
  *
27
27
  * Design docs: 18-build-system.md §"Entry Files", 19-client-navigation.md
28
28
  */
@@ -44,8 +44,7 @@ import { createRscPayloadStream } from './rsc-stream.ts';
44
44
  import { createTimberRouter } from './router-init.ts';
45
45
  import { createReactRoot } from '../react-root.ts';
46
46
  import type { TopLoaderConfig } from '../top-loader.tsx';
47
- import { readPublishedParams } from '../../shared/payload-root.ts';
48
- import { runPreHydration, hydrateApp } from './hydrate.ts';
47
+ import { hydrateApp } from './hydrate.ts';
49
48
  import { setupPostHydration } from './post-hydration.ts';
50
49
  import { setupHmr } from './hmr.ts';
51
50
 
@@ -53,7 +52,7 @@ import { setupHmr } from './hmr.ts';
53
52
 
54
53
  setupServerActions();
55
54
 
56
- // ─── 2–7. Bootstrap ─────────────────────────────────────────────
55
+ // ─── 2–6. Bootstrap ─────────────────────────────────────────────
57
56
 
58
57
  function bootstrap(runtimeConfig: typeof config): void {
59
58
  // Initialize deployment ID for version skew detection (TIM-446).
@@ -89,35 +88,25 @@ function bootstrap(runtimeConfig: typeof config): void {
89
88
  container: document,
90
89
  topLoaderConfig: (runtimeConfig as { topLoader?: TopLoaderConfig }).topLoader,
91
90
  });
92
- const { router, navApiController, renderTree } = createTimberRouter({
91
+ const { router, navApiController, hydrate } = createTimberRouter({
93
92
  render: reactRoot.render,
94
- initialElement: rscResult?.element ?? undefined,
95
- initialParams: rscResult?.params,
96
93
  clientSegmentCache:
97
94
  ((runtimeConfig as Record<string, unknown>).clientSegmentCache as boolean) ?? false,
98
95
  });
99
96
 
100
- // Step 4: Pre-hydration — set params + navigation state (MUST run after router init)
101
- runPreHydration();
97
+ // Step 4: Make the page current and hydrate (no root without a payload)
98
+ hydrateApp({ rscResult, reactRoot, hydrate });
102
99
 
103
- // Step 5: Hydrate or set up deferred root creation
104
- hydrateApp({ rscResult, reactRoot, renderTree });
100
+ // Step 5: Post-hydration wiring
101
+ setupPostHydration({ router, navApiController });
105
102
 
106
- // Step 6: Post-hydration wiring
107
- setupPostHydration({
108
- router,
109
- navApiController,
110
- initialElement: rscResult?.element ?? null,
111
- initialParams: rscResult?.params ?? readPublishedParams(undefined),
112
- });
113
-
114
- // Step 7: HMR (dev-only, no-op in production)
103
+ // Step 6: HMR (dev-only, no-op in production)
115
104
  setupHmr(router);
116
105
  }
117
106
 
118
107
  bootstrap(config);
119
108
 
120
- // ─── 8. Ready Signal ────────────────────────────────────────────
109
+ // ─── 7. Ready Signal ────────────────────────────────────────────
121
110
 
122
111
  // Signal that the client runtime has been initialized.
123
112
  // Used by E2E tests to wait for hydration before interacting.
@@ -1,66 +1,32 @@
1
1
  /**
2
- * Post-Hydration Wiring — history stack, segment cache, popstate, scroll.
2
+ * Post-Hydration Wiring — popstate and scroll.
3
3
  *
4
4
  * Sets up everything that needs to happen after the React root exists:
5
- * - Stores initial page in history stack for instant back navigation
6
5
  * - Initializes scroll state for the initial entry
7
- * - Populates segment cache from server-embedded metadata
8
6
  * - Registers popstate handler for back/forward navigation
9
7
  * - Sets up debounced scroll position saving
10
8
  *
9
+ * The initial page's history entry and segment cache are not written here:
10
+ * they are the router's, and hydration makes the page current through
11
+ * `RouterInstance.hydrate` like any other commit (TIM-1541).
12
+ *
11
13
  * See design/19-client-navigation.md §"History Stack"
12
14
  */
13
15
 
14
16
  import type { RouterInstance } from '#client-internal';
15
- import { getNavigationState } from '../navigation-context.ts';
16
17
  import type { NavigationApiController } from '../navigation-api.ts';
17
18
  import { getScrollY } from './scroll.ts';
18
- import type { ParamsSource } from '../../shared/payload-root.ts';
19
19
  import { locationSearch } from '../location-search.ts';
20
20
 
21
21
  interface PostHydrationOptions {
22
22
  router: RouterInstance;
23
23
  navApiController: NavigationApiController | null;
24
- /** Decoded RSC element from initial SSR (null if no RSC payload) */
25
- initialElement: unknown;
26
- /** The params that payload published, from the same decode. */
27
- initialParams: ParamsSource;
28
24
  }
29
25
 
30
26
  /**
31
27
  * Wire up post-hydration event handlers and state.
32
28
  */
33
- export function setupPostHydration({
34
- router,
35
- navApiController,
36
- initialElement,
37
- initialParams,
38
- }: PostHydrationOptions): void {
39
- // Populate the segment cache from server-embedded segment metadata.
40
- // This enables state tree diffing from the very first client navigation.
41
- // See design/19-client-navigation.md §"X-Timber-State-Tree Header"
42
- const timberSegments = (self as unknown as Record<string, unknown>).__timber_segments;
43
- const initialSegmentInfo = Array.isArray(timberSegments)
44
- ? (timberSegments as import('../../shared/segment-info.ts').SegmentInfo[])
45
- : null;
46
- if (initialSegmentInfo) {
47
- router.initSegmentCache(initialSegmentInfo);
48
- delete (self as unknown as Record<string, unknown>).__timber_segments;
49
- }
50
-
51
- // Store the initial page in the history stack so back-button works
52
- // after the first navigation. Include segmentInfo so the segment
53
- // cache is restored correctly on popstate cached replay.
54
- // Replaying this entry on a Back re-renders `initialElement` and republishes
55
- // `initialParams`. Both came out of one split of one decoded payload root
56
- // (rsc-stream.ts), so the entry cannot replay with another route's params —
57
- // which is what a separately-seeded copy used to do (TIM-1037, TIM-1285).
58
- router.historyStack.push(window.location.pathname + locationSearch(), {
59
- payload: initialElement,
60
- params: initialParams,
61
- segmentInfo: initialSegmentInfo,
62
- });
63
-
29
+ export function setupPostHydration({ router, navApiController }: PostHydrationOptions): void {
64
30
  // Leave scrollRestoration = 'auto' so the browser natively restores
65
31
  // scroll on reload, tab restore, and back-from-external-page — cases
66
32
  // JS cannot reliably cover because 'manual' persists on the session
@@ -10,16 +10,13 @@
10
10
  import { createElement } from 'react';
11
11
  import { createFromFetch } from '../../rsc-runtime/browser.ts';
12
12
  import { PayloadRoot } from '../params-context.ts';
13
- import { readPublishedParams, type ParamsSource } from '../../shared/payload-root.ts';
13
+ import type { ParamsSource } from '../../shared/payload-root.ts';
14
14
  import { createRouter, setGlobalRouter } from '#client-internal';
15
15
  import type { RouterDeps, RouterInstance } from '#client-internal';
16
16
  import type { NavigationState } from '#client-internal';
17
+ import type { HydrationPage } from '../router-types.ts';
17
18
  import { TimberNuqsAdapter } from '../nuqs-adapter.tsx';
18
- import {
19
- NavigationProvider,
20
- getNavigationState,
21
- setNavigationState,
22
- } from '../navigation-context.ts';
19
+ import { NavigationProvider } from '../navigation-context.ts';
23
20
  import { navigateTransition, type RenderOwner } from '../navigation-transition.ts';
24
21
  import type { NavigationRender } from '../navigation-root.tsx';
25
22
  import { SegmentUpdateContext, EMPTY_SEGMENT_UPDATES } from '../segment-update-context.ts';
@@ -40,9 +37,6 @@ export interface RouterInitOptions {
40
37
  * around `root.render`, and the `publish` it takes runs on React's commit.
41
38
  */
42
39
  render: NavigationRender;
43
- initialElement?: unknown;
44
- /** The params the hydration payload published, beside `initialElement`. */
45
- initialParams?: ParamsSource;
46
40
  clientSegmentCache?: boolean;
47
41
  }
48
42
 
@@ -50,17 +44,12 @@ export interface RouterInitResult {
50
44
  router: RouterInstance;
51
45
  navApiController: NavigationApiController | null;
52
46
  /**
53
- * The client's wrapper chain around a tree — the one every navigation
54
- * renders through. Hydration builds its root with this too, so the
55
- * hydrated tree and the first navigated tree cannot differ in shape
56
- * (a type present on one and absent on the other remounts everything
57
- * below it) and share the router's slot content cache.
47
+ * Make the server-rendered page current and hand its tree to React
48
+ * hydration. `hydrateRoot` receives the tree, built by the same
49
+ * `renderTree` every navigation renders through. With no payload there is
50
+ * no tree to hydrate and `hydrateRoot` is not called.
58
51
  */
59
- renderTree: (
60
- tree: unknown,
61
- navState: NavigationState,
62
- params: ParamsSource
63
- ) => React.ReactElement;
52
+ hydrate: (page: HydrationPage, hydrateRoot: (element: React.ReactElement) => void) => void;
64
53
  }
65
54
 
66
55
  /**
@@ -78,20 +67,23 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
78
67
  // See design/19-client-navigation.md §"Navigation API Integration"
79
68
  const useNavApi = hasNavigationApi();
80
69
 
81
- // Track the current unwrapped RSC payload. On partial navigation, the
82
- // router re-wraps this same element with new NavigationProvider context
83
- // so mounted SegmentOutlets are preserved (they pick up changes via
84
- // SegmentUpdateContext, not from new children props).
85
- // Initialized from the hydration element so partial nav works on the
86
- // very first client navigation (before any wrapPayload call).
87
- let currentPayload: unknown = options.initialElement ?? null;
88
-
89
- // The params `currentPayload` is displayed with. Tracked beside it because
90
- // the two render paths that do NOT receive a payload — a shallow search
91
- // update and any re-wrap of the current tree — must republish the same
92
- // record rather than dropping it. They are written together, in one place
93
- // (`renderTree`), so they cannot come apart.
94
- let currentParams: ParamsSource = options.initialParams ?? readPublishedParams(undefined);
70
+ /**
71
+ * The tree on screen, with the params published over it and the location
72
+ * it renders — the client's one record of the displayed page. Null until
73
+ * a page with a payload is on screen (a document hydrated without one).
74
+ *
75
+ * The unwrapped tree is kept because a partial navigation re-wraps this
76
+ * same element with new context so mounted SegmentOutlets are preserved
77
+ * (they pick up changes via SegmentUpdateContext, not from new children
78
+ * props). The params and location are kept beside it because the render
79
+ * paths that do NOT receive a payload — a shallow search update, a partial
80
+ * navigation — must republish them rather than drop them.
81
+ *
82
+ * The location used to live in a separate `globalThis` store as well,
83
+ * written by the router's commit, by hydration and by the shallow search
84
+ * path, and read back here. It was a second record of this one (TIM-1541).
85
+ */
86
+ let displayed: { tree: unknown; params: ParamsSource; navState: NavigationState } | null = null;
95
87
 
96
88
  // The slot content the client has committed, by segmentPath. Owned here so
97
89
  // there is exactly one per router (never a module or globalThis singleton —
@@ -114,14 +106,14 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
114
106
  * tests/e2e/segment-merge-navigation.test.ts when the params wrapper was
115
107
  * conditional).
116
108
  *
117
- * `PayloadRoot` is *above* `currentPayload`, which on a partial navigation
109
+ * `PayloadRoot` is *above* the displayed tree, which on a partial navigation
118
110
  * is the retained tree. That position is the whole design: it is the only
119
111
  * provider a reader in a skipped layout can resolve to (TIM-1297).
120
112
  *
121
113
  * Pure — building the element does not make it the displayed one. Every
122
114
  * caller pairs this with `publishTree` at the point the tree is actually
123
115
  * handed to React, because a navigation builds its element before it is
124
- * known to have won and a superseded one must leave `currentPayload`
116
+ * known to have won and a superseded one must leave the displayed record
125
117
  * describing the route still on screen (TIM-1301).
126
118
  */
127
119
  function renderTree(
@@ -146,14 +138,14 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
146
138
  }
147
139
 
148
140
  /**
149
- * Record the tree the client is now displaying, and the params published
150
- * over it. Written together — the two paths that re-wrap without a fresh
151
- * payload (a shallow search update, a partial navigation) read them back as
152
- * a pair and would otherwise restore one route's tree with another's params.
141
+ * Record the tree the client is now displaying, the params published over
142
+ * it and the location it renders. Written together — the paths that re-wrap
143
+ * without a fresh payload (a shallow search update, a partial navigation)
144
+ * read them back as one and would otherwise restore one route's tree with
145
+ * another's params or pathname.
153
146
  */
154
- function publishTree(tree: unknown, params: ParamsSource): void {
155
- currentPayload = tree;
156
- currentParams = params;
147
+ function publishTree(tree: unknown, params: ParamsSource, navState: NavigationState): void {
148
+ displayed = { tree, params, navState };
157
149
  }
158
150
 
159
151
  // Late-bound: syncShallowSearch is defined before createRouter, but only
@@ -187,26 +179,25 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
187
179
  * the patched pushState/replaceState returns).
188
180
  *
189
181
  * Bails when search is unchanged (scroll saves, no-ops, dual-fire).
190
- * Re-wraps currentPayload with updated NavigationProvider and hands it to
182
+ * Re-wraps the displayed tree with updated NavigationProvider and hands it to
191
183
  * React through the root's `render` (startTransition — non-blocking).
192
184
  */
193
185
  function syncShallowSearch(search?: string): void {
186
+ if (!displayed) return;
194
187
  const currentSearch = search != null ? stripRscCacheKey(search) : locationSearch();
195
- const navState = getNavigationState();
196
- if (currentSearch === navState.search) return;
197
- if (!currentPayload) return;
188
+ if (currentSearch === displayed.navState.search) return;
198
189
 
199
190
  // A shallow search update does not re-render the tree from the server, so
200
191
  // the params are unchanged — but they are the client's to publish now, and
201
- // this path rebuilds the whole chain. Republishing `currentParams` is what
192
+ // this path rebuilds the whole chain. Republishing `displayed.params` is what
202
193
  // keeps a `?q=` change from silently clearing the route's params
203
194
  // (TIM-1285's failure mode, on a path that used to be exempt from it
204
195
  // because the record lived inside the payload).
196
+ const { tree, params } = displayed;
205
197
  const newNavState: NavigationState = {
206
- pathname: navState.pathname,
198
+ pathname: displayed.navState.pathname,
207
199
  search: currentSearch,
208
200
  };
209
- setNavigationState(newNavState);
210
201
 
211
202
  // A shallow search update displaces whatever React is rendering. If a
212
203
  // handed-off tree is still suspended (e.g. a cached popstate replay whose
@@ -223,8 +214,8 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
223
214
  // (TIM-1480).
224
215
  queueMicrotask(() => router?.settleHandoffs());
225
216
 
226
- publishTree(currentPayload, currentParams);
227
- render(renderTree(currentPayload, newNavState, currentParams), null);
217
+ publishTree(tree, params, newNavState);
218
+ render(renderTree(tree, newNavState, params), null);
228
219
  }
229
220
 
230
221
  window.history.pushState = function (
@@ -287,33 +278,6 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
287
278
  return createFromFetch(fetchPromise);
288
279
  },
289
280
 
290
- // Render a decoded RSC tree through the router's React root. Used for
291
- // non-navigation renders (popstate cached replay, applyActionResult).
292
- // Wraps with NavigationProvider + TimberNuqsAdapter.
293
- //
294
- // For navigation renders (navigate, refresh, popstate-with-fetch),
295
- // navigateTransition is used instead — it hands the destination tree to
296
- // React in a transition so the departing page stays visible.
297
- //
298
- // navState is passed explicitly by the router — no temporal coupling
299
- // with getNavigationState().
300
- renderRoot: (
301
- element: unknown,
302
- navState: NavigationState,
303
- params: ParamsSource,
304
- commit: () => void
305
- ) => {
306
- // These paths render what is already decided (a replay, a
307
- // revalidation), but "decided" is not "on screen": the tree goes out in
308
- // a transition React may hold. The publish — the router's and this
309
- // module's record of the displayed tree — runs when React commits it,
310
- // the same way a navigation's does (TIM-1301, TIM-1423).
311
- render(renderTree(element, navState, params), () => {
312
- publishTree(element, params);
313
- commit();
314
- });
315
- },
316
-
317
281
  // Hand a navigation's tree to React in a transition
318
282
  // (navigation-transition.ts). The fetch runs outside any transition
319
283
  // scope; only the render that hands the tree over is wrapped, and in a
@@ -323,7 +287,10 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
323
287
  //
324
288
  // The perform callback receives a wrapPayload function that wraps the
325
289
  // decoded RSC payload with NavigationProvider + NuqsAdapter. navState
326
- // is passed explicitly by the router — no getNavigationState() needed.
290
+ // is passed explicitly by the router.
291
+ //
292
+ // Every render the router makes comes through here — navigations,
293
+ // refreshes, traversals (fetched or replayed) and revalidations.
327
294
  //
328
295
  // `_url` names the pending URL the router already published to its own
329
296
  // pending store before calling here; the transition has no use for it.
@@ -335,7 +302,8 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
335
302
  // record of the displayed tree is navigation state like any other, so
336
303
  // it rides the same commit as the segment cache rather than being
337
304
  // written as a side effect of building the element (TIM-1301).
338
- let displayed: { tree: unknown; params: ParamsSource } | null = null;
305
+ let built: { tree: unknown; params: ParamsSource; navState: NavigationState } | null =
306
+ null;
339
307
  const { element, decodePromise, commit } = await perform(
340
308
  (
341
309
  rawPayload: unknown,
@@ -343,7 +311,7 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
343
311
  params: ParamsSource,
344
312
  segmentUpdates?: Map<string, unknown>
345
313
  ) => {
346
- displayed = { tree: rawPayload, params };
314
+ built = { tree: rawPayload, params, navState };
347
315
  return renderTree(
348
316
  rawPayload,
349
317
  navState,
@@ -356,7 +324,7 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
356
324
  element: element as React.ReactNode,
357
325
  decodePromise,
358
326
  commit: () => {
359
- if (displayed) publishTree(displayed.tree, displayed.params);
327
+ if (built) publishTree(built.tree, built.params, built.navState);
360
328
  commit();
361
329
  },
362
330
  };
@@ -366,7 +334,7 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
366
334
  );
367
335
  },
368
336
 
369
- _getCurrentPayload: () => currentPayload,
337
+ _getCurrentPayload: () => displayed?.tree ?? null,
370
338
 
371
339
  // Schedule a callback after the next paint so scroll operations
372
340
  // happen after React commits the new content to the DOM.
@@ -414,5 +382,19 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
414
382
  deps.navigationNavigate = (url, replace) => navApiController!.navigate(url, replace);
415
383
  }
416
384
 
417
- return { router, navApiController, renderTree };
385
+ /**
386
+ * See `RouterInitResult.hydrate`.
387
+ *
388
+ * Everything is recorded at handover, not on hydration's commit: the
389
+ * server's HTML for this tree is already what the user is looking at, and
390
+ * React may never commit the hydration render — see `RouterInstance.hydrate`.
391
+ */
392
+ const hydrate: RouterInitResult['hydrate'] = (page, hydrateRoot) => {
393
+ const navState = router.hydrate(page);
394
+ if (page.payload == null) return;
395
+ publishTree(page.payload, page.params, navState);
396
+ hydrateRoot(renderTree(page.payload, navState, page.params));
397
+ };
398
+
399
+ return { router, navApiController, hydrate };
418
400
  }