@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
@@ -15,8 +15,8 @@
15
15
 
16
16
  import { fetchRscPayload, NonRscResponse } from './rsc-fetch.ts';
17
17
  import type { FetchResult } from './rsc-fetch.ts';
18
- import { readPublishedParams, type ParamsSource } from '../shared/payload-root.ts';
19
- import type { PrefetchCache, PrefetchKey, FlightOutcome } from './segment-cache.ts';
18
+ import { readPublishedParams } from '../shared/payload-root.ts';
19
+ import type { PrefetchCache, PrefetchKey } from './segment-cache.ts';
20
20
  import { prefetchScopeOf } from './segment-cache.ts';
21
21
  import type { StateTree } from '../shared/segment-info.ts';
22
22
  import type { NavigationState } from './navigation-context.ts';
@@ -24,6 +24,7 @@ import { isPartialNavigation, type NavigationCommitter } from './navigation-comm
24
24
  import type { RouterDeps } from './router-types.ts';
25
25
  import type { CommitOutcome, RenderOwner } from './navigation-transition.ts';
26
26
  import { recordSkew } from './router-skew.ts';
27
+ import { parseRouterUrl } from './router-url.ts';
27
28
  import { SingleflightTimeoutError } from '../cache/singleflight.ts';
28
29
 
29
30
  /**
@@ -60,7 +61,7 @@ export interface NavigationFetchOptions {
60
61
 
61
62
  export interface NavigationPipelineDeps extends Pick<
62
63
  NavigationCommitter,
63
- 'prepareNavigation' | 'currentStateTree'
64
+ 'prepareNavigation' | 'currentStateTree' | 'isSegmentReuseSuppressed' | 'restoreSegmentReuse'
64
65
  > {
65
66
  deps: RouterDeps;
66
67
  prefetchCache: PrefetchCache;
@@ -76,7 +77,7 @@ export interface NavigationPipeline {
76
77
  url: string,
77
78
  options: NavigationFetchOptions
78
79
  ) => Promise<NavigationPayload>;
79
- /** Hand a payload to React inside a transition, or render it directly in tests. */
80
+ /** Hand a payload to React inside a transition. */
80
81
  renderViaTransition: (
81
82
  url: string,
82
83
  owner: RenderOwner,
@@ -84,15 +85,6 @@ export interface NavigationPipeline {
84
85
  /** See `NavigationOptions.onCommit`. */
85
86
  onCommit?: (outcome: CommitOutcome) => void
86
87
  ) => Promise<void>;
87
- /** Render a decoded payload into the DOM if a renderer is available. */
88
- renderPayload: (
89
- payload: unknown,
90
- navState: NavigationState,
91
- params: ParamsSource,
92
- commit: () => void
93
- ) => void;
94
- /** Resolve thenable payloads on the fallback (test) path. */
95
- resolveForFallback: (payload: unknown) => Promise<unknown>;
96
88
  }
97
89
 
98
90
  /**
@@ -109,7 +101,7 @@ export interface NavigationPipeline {
109
101
  * both `location.href` and a bare pathname.
110
102
  */
111
103
  export function departingPathname(raw: string): string {
112
- return new URL(raw, 'http://localhost').pathname;
104
+ return parseRouterUrl(raw).pathname;
113
105
  }
114
106
 
115
107
  /**
@@ -139,14 +131,14 @@ export function prefetchKeyFor(
139
131
  * Build a segment updates map for partial navigation. Identifies the
140
132
  * first non-skipped segment and maps it to the payload content.
141
133
  */
142
- function buildSegmentUpdates(result: FetchResult): Map<string, unknown> {
134
+ function buildSegmentUpdates(result: FetchResult, payload: unknown): Map<string, unknown> {
143
135
  const skipped = new Set(result.skippedSegments!);
144
136
  const segmentInfo = result.segmentInfo;
145
137
  const updates = new Map<string, unknown>();
146
138
  if (segmentInfo) {
147
139
  for (const info of segmentInfo) {
148
140
  if (!skipped.has(info.segmentId ?? info.path)) {
149
- updates.set(info.segmentId ?? info.path, result.payload);
141
+ updates.set(info.segmentId ?? info.path, payload);
150
142
  break;
151
143
  }
152
144
  }
@@ -174,54 +166,19 @@ export function createNavigationPipeline({
174
166
  prefetchCache,
175
167
  currentStateTree,
176
168
  prepareNavigation,
169
+ isSegmentReuseSuppressed,
170
+ restoreSegmentReuse,
177
171
  markHandedOff,
178
172
  forgetOlderHandoffs,
179
173
  }: NavigationPipelineDeps): NavigationPipeline {
180
174
  /**
181
- * Render a decoded RSC payload into the DOM, publishing `commit` when the
182
- * tree is current. The renderer owns that moment (see `RootRenderer`);
183
- * with no renderer there is no tree to wait for, so it publishes now.
184
- */
185
- function renderPayload(
186
- payload: unknown,
187
- navState: NavigationState,
188
- params: ParamsSource,
189
- commit: () => void
190
- ): void {
191
- if (deps.renderRoot) {
192
- deps.renderRoot(payload, navState, params, commit);
193
- } else {
194
- commit();
195
- }
196
- }
197
-
198
- /**
199
- * Resolve thenable payloads in the test/fallback path (no navigateTransition).
200
- * In production, React handles thenables from createFromFetch directly via
201
- * Suspense. In tests, renderRoot is a plain mock that expects resolved values.
202
- */
203
- async function resolveForFallback(payload: unknown): Promise<unknown> {
204
- if (
205
- !deps.navigateTransition &&
206
- payload != null &&
207
- typeof payload === 'object' &&
208
- 'then' in payload
209
- ) {
210
- return await (payload as PromiseLike<unknown>);
211
- }
212
- return payload;
213
- }
214
-
215
- /**
216
- * Render a payload via navigateTransition (production) or renderRoot (tests).
217
- * The perform callback should fetch data, prepare the commit, and return the
175
+ * Hand a payload to React via navigateTransition. The perform callback should fetch data, prepare the commit, and return the
218
176
  * FetchResult plus the NavigationState and the commit thunk.
219
177
  *
220
178
  * The thunk is handed *through* to NavigationRoot rather than called here:
221
- * state management (segmentCache, navState, historyStack) has to happen on
179
+ * state management (segment cache, history stack, address bar) has to happen on
222
180
  * the far side of the supersession check, which only NavigationRoot can
223
- * make (TIM-1301). The fallback path below has no transition to be
224
- * superseded by, so it commits directly.
181
+ * make (TIM-1301).
225
182
  */
226
183
  async function renderViaTransition(
227
184
  url: string,
@@ -243,84 +200,70 @@ export function createNavigationPipeline({
243
200
  commit();
244
201
  };
245
202
 
246
- if (deps.navigateTransition) {
247
- await deps.navigateTransition(
248
- url,
249
- owner,
250
- async (wrapPayload) => {
251
- const result = await perform();
252
- // Await the payload's *root row* — the same thing React would suspend
253
- // on to render the tree, and the first thing Flight emits. The
254
- // previous UI stays on screen while this resolves: nothing has been
255
- // handed to React yet, and when it is, NavigationRoot hands it over
256
- // inside a transition so a tree that is still streaming does not
257
- // displace the departing page (TIM-1306).
258
- //
259
- // Reading them here rather than with `use()` above the tree is what
260
- // keeps a decode failure contained: `result.params` never rejects, so
261
- // the rejection reaches React only through the tree, inside whatever
262
- // error boundary the app put around it (TIM-1297).
263
- const params = await result.params;
203
+ await deps.navigateTransition(
204
+ url,
205
+ owner,
206
+ async (wrapPayload) => {
207
+ const result = await perform();
208
+ // Await the payload's *root row* — the same thing React would suspend
209
+ // on to render the tree, and the first thing Flight emits. The
210
+ // previous UI stays on screen while this resolves: nothing has been
211
+ // handed to React yet, and when it is, NavigationRoot hands it over
212
+ // inside a transition so a tree that is still streaming does not
213
+ // displace the departing page (TIM-1306).
214
+ //
215
+ // Reading them here rather than with `use()` above the tree is what
216
+ // keeps a decode failure contained: `result.params` never rejects, so
217
+ // it can never take down the provider above every error boundary
218
+ // (TIM-1297). A failure after the root row reaches React through the
219
+ // tree, inside whatever boundary the app put around it.
220
+ const params = await result.params;
221
+ // And the tree itself — settled by the same root row, so this adds no
222
+ // wait, but it is the half that *rejects*: a root row that fails to
223
+ // decode fails this navigation here, before anything is wrapped or
224
+ // handed over, and the router takes its recovery path (TIM-1541).
225
+ // This used to happen by accident — the payload went through an
226
+ // `async` identity helper whose return adopted the thenable — and
227
+ // only on the paths that called it.
228
+ const payload = await result.payload;
264
229
 
265
- if (isPartialNavigation(result.skippedSegments)) {
266
- const segmentUpdates = buildSegmentUpdates(result);
230
+ if (isPartialNavigation(result.skippedSegments)) {
231
+ const segmentUpdates = buildSegmentUpdates(result, payload);
267
232
 
268
- // Re-wrap the CURRENT element with new context values.
269
- // SegmentOutlets read updates from SegmentUpdateContext;
270
- // NavigationProvider gets the new pathname; the params published
271
- // above the retained tree are the *incoming* route's.
272
- const element = wrapPayload(
273
- deps._getCurrentPayload?.() ?? result.payload,
274
- result.navState,
275
- params,
276
- segmentUpdates
277
- );
278
- handOff();
279
- return {
280
- element,
281
- decodePromise: observeSkew(result.decodePromise),
282
- commit: commitAndForget(result.commit),
283
- };
284
- }
285
-
286
- // Full navigation — empty updates, render the new tree.
287
- const element = wrapPayload(result.payload, result.navState, params);
233
+ // Re-wrap the CURRENT element with new context values.
234
+ // SegmentOutlets read updates from SegmentUpdateContext;
235
+ // NavigationProvider gets the new pathname; the params published
236
+ // above the retained tree are the *incoming* route's.
237
+ const element = wrapPayload(
238
+ deps._getCurrentPayload?.() ?? payload,
239
+ result.navState,
240
+ params,
241
+ segmentUpdates
242
+ );
288
243
  handOff();
289
244
  return {
290
245
  element,
291
246
  decodePromise: observeSkew(result.decodePromise),
292
247
  commit: commitAndForget(result.commit),
293
248
  };
294
- },
295
- onCommit
296
- );
297
- return;
298
- }
299
- // Fallback: no transition (tests, no React tree). The commit is
300
- // synchronous here, so the outcome is always 'committed' or 'failed' —
301
- // no transition counter to supersede. The hook fires on the way out,
302
- // on failure too, so it still fires exactly once.
303
- let fallbackOutcome: CommitOutcome = 'committed';
304
- try {
305
- const result = await perform();
306
- handOff();
307
- const commit = commitAndForget(result.commit);
308
- if (isPartialNavigation(result.skippedSegments)) {
309
- commit();
310
- } else {
311
- renderPayload(result.payload, result.navState, await result.params, commit);
312
- }
313
- } catch (error) {
314
- fallbackOutcome = 'failed';
315
- throw error;
316
- } finally {
317
- onCommit?.(fallbackOutcome);
318
- }
249
+ }
250
+
251
+ // Full navigation — empty updates, render the new tree.
252
+ const element = wrapPayload(payload, result.navState, params);
253
+ handOff();
254
+ return {
255
+ element,
256
+ decodePromise: observeSkew(result.decodePromise),
257
+ commit: commitAndForget(result.commit),
258
+ };
259
+ },
260
+ onCommit
261
+ );
319
262
  }
320
263
 
321
264
  /**
322
- * Core navigation logic shared between the transition and fallback paths.
323
- * Fetches the RSC payload, updates all state, and returns the result.
265
+ * Fetch (or take from the prefetch cache) a navigation's payload and
266
+ * prepare — without publishing — the commit that makes it current.
324
267
  */
325
268
  async function performNavigationFetch(
326
269
  url: string,
@@ -339,6 +282,11 @@ export function createNavigationPipeline({
339
282
  // `currentUrl` is read back off the key rather than computed beside it, so
340
283
  // the pathname sent as X-Timber-URL is the one the lookup used.
341
284
  const stateTree = currentStateTree();
285
+ // Capture whether reuse is suppressed at the time we build the state
286
+ // tree. If so, segments/slots are empty and the server will send a
287
+ // full render. We restore reuse after the response is processed so
288
+ // only navigations that fetched with suppression can lift it (TIM-1466).
289
+ let reuseSuppressedAtFetch = isSegmentReuseSuppressed();
342
290
  const cacheKey = prefetchKeyFor(url, options.departingUrl ?? deps.getCurrentUrl(), stateTree);
343
291
  const currentUrl = cacheKey.from;
344
292
 
@@ -381,11 +329,16 @@ export function createNavigationPipeline({
381
329
  // Capture the eviction generation before awaiting the flight.
382
330
  // If an action evicts caches while we wait, the result predates
383
331
  // the mutation and must be discarded (TIM-1476, codex on #1131).
332
+ // Also check the flight's own starting gen: if the flight started
333
+ // before a per-URL invalidation (TIM-1464), a joiner that arrived
334
+ // after the bump would see genBefore === genAfter but the flight
335
+ // still predates the invalidation.
384
336
  const genBefore = prefetchCache.getEvictionGen();
385
337
  try {
386
338
  const outcome = await raceAbort(inflight, options.signal);
387
- if (prefetchCache.getEvictionGen() !== genBefore) {
388
- // Eviction happened while we waited — discard stale result,
339
+ if (prefetchCache.getEvictionGen() !== genBefore || outcome.startGen !== genBefore) {
340
+ // Eviction happened while we waited, or the flight predates
341
+ // an invalidation we arrived after — discard stale result,
389
342
  // fall through to a fresh fetch below.
390
343
  } else if (outcome.kind === 'non-route') {
391
344
  throw new NonRscResponse(url);
@@ -422,7 +375,13 @@ export function createNavigationPipeline({
422
375
  // No in-flight hover prefetch, or the joined flight failed — fetch
423
376
  // directly with the navigation's signal so superseded navigations
424
377
  // abort immediately.
425
- result = await fetchRscPayload(url, deps, stateTree, currentUrl, options.signal);
378
+ // Resample both the state tree and the suppression flag: if we fell
379
+ // through because an invalidation bumped the eviction gen,
380
+ // invalidateReuse() has suppressed segment/slot reuse since our
381
+ // original capture (TIM-1466, codex on #1167).
382
+ reuseSuppressedAtFetch = isSegmentReuseSuppressed();
383
+ const freshStateTree = currentStateTree();
384
+ result = await fetchRscPayload(url, deps, freshStateTree, currentUrl, options.signal);
426
385
  }
427
386
 
428
387
  // Update the browser history — skip when the Navigation API has already
@@ -450,9 +409,6 @@ export function createNavigationPipeline({
450
409
  deps.setRouterNavigating?.(false);
451
410
  };
452
411
 
453
- // Resolve thenable payloads in the test path so popstate replay
454
- // and renderPayload receive plain values (see resolveForFallback).
455
- const payload = await resolveForFallback(result.payload);
456
412
  const params = await result.params;
457
413
 
458
414
  // Prepare the atomic navigation-state update. It is published by the
@@ -461,15 +417,23 @@ export function createNavigationPipeline({
461
417
  // `prepareNavigation`'s decision, made from `skippedSegments` and
462
418
  // `segmentInfo` (TIM-1432).
463
419
  const { navState, commit } = prepareNavigation(url, {
464
- payload,
420
+ payload: result.payload,
465
421
  params,
466
422
  segmentInfo: result.segmentInfo,
467
423
  skippedSegments: result.skippedSegments,
468
424
  });
469
425
 
426
+ // This navigation's fetch used the suppressed state tree (empty
427
+ // segments/slots), so the server sent a full render. The response
428
+ // data is post-invalidation — safe to restore reuse for subsequent
429
+ // navigations. Must happen here (at response time, before the commit
430
+ // thunk), not in set(), because a pre-invalidation navigation's
431
+ // commit thunk also calls set() and would lift suppression too early
432
+ // (codex on #1167).
433
+ if (reuseSuppressedAtFetch) restoreSegmentReuse();
434
+
470
435
  return {
471
436
  ...result,
472
- payload,
473
437
  params,
474
438
  navState,
475
439
  commit: () => {
@@ -486,5 +450,5 @@ export function createNavigationPipeline({
486
450
  };
487
451
  }
488
452
 
489
- return { performNavigationFetch, renderViaTransition, renderPayload, resolveForFallback };
453
+ return { performNavigationFetch, renderViaTransition };
490
454
  }
@@ -13,7 +13,6 @@ import type { NavigationState } from './navigation-context.ts';
13
13
  import type { ParamsSource } from '../shared/payload-root.ts';
14
14
  import type { SegmentInfo } from '../shared/segment-info.ts';
15
15
  import type { SegmentCache, PrefetchCache } from './segment-cache.ts';
16
- import type { HistoryStack } from './history.ts';
17
16
  import type { TransitionResult, CommitOutcome, RenderOwner } from './navigation-transition.ts';
18
17
  import type { NavigationEpoch } from './router-lifecycle.ts';
19
18
 
@@ -53,37 +52,13 @@ export interface NavigationOptions {
53
52
  }
54
53
 
55
54
  /**
56
- * Function that decodes an RSC Flight stream into a React element tree.
57
- * In production: createFromFetch from @vitejs/plugin-rsc/browser.
58
- * In tests: a mock that returns the raw payload.
55
+ * Function that decodes an RSC Flight stream into the payload root.
56
+ * In production: createFromFetch from @vitejs/plugin-rsc/browser. Tests use
57
+ * the same Flight client over Flight bytes (tests/helpers/router-harness.ts),
58
+ * so every response is classified and decoded by the one path production runs.
59
59
  */
60
60
  export type RscDecoder = (fetchPromise: Promise<Response>) => unknown;
61
61
 
62
- /**
63
- * Function that renders a decoded RSC element tree into the DOM.
64
- * In production: reactRoot.render(element).
65
- * In tests: a no-op or mock.
66
- *
67
- * Receives the current NavigationState explicitly — no temporal
68
- * coupling with setNavigationState/getNavigationState. The renderer
69
- * wraps the element in NavigationProvider with this state.
70
- */
71
- export type RootRenderer = (
72
- element: unknown,
73
- navState: NavigationState,
74
- params: ParamsSource,
75
- /**
76
- * Publishes the state that makes this tree the current page (segment
77
- * cache, pathname, history stack, address bar). The renderer runs it when
78
- * the tree is on screen — in production from React's commit of the tree
79
- * (`NavigationRoot`'s layout effect), a test double synchronously. It is not run before
80
- * handing the tree over: a replay or revalidation whose tree suspends is
81
- * given to React without being on screen, and publishing then advertises
82
- * slot content keys the slot content cache has not recorded (TIM-1423).
83
- */
84
- commit: () => void
85
- ) => void;
86
-
87
62
  /**
88
63
  * Platform dependencies injected for testability. In production these
89
64
  * map to browser APIs; in tests they're replaced with mocks.
@@ -95,10 +70,8 @@ export interface RouterDeps {
95
70
  scrollTo: (x: number, y: number) => void;
96
71
  getCurrentUrl: () => string;
97
72
  getScrollY: () => number;
98
- /** Decode RSC Flight stream into React elements. If not provided, raw response text is stored. */
99
- decodeRsc?: RscDecoder;
100
- /** Render decoded RSC tree into the DOM. If not provided, rendering is a no-op. */
101
- renderRoot?: RootRenderer;
73
+ /** Decode an RSC Flight stream into the payload root. */
74
+ decodeRsc: RscDecoder;
102
75
  /**
103
76
  * Schedule a callback after the next paint. In the browser, this is
104
77
  * requestAnimationFrame + setTimeout(0) to run after React commits.
@@ -114,12 +87,14 @@ export interface RouterDeps {
114
87
  * The `perform` callback receives a `wrapPayload` function to wrap the
115
88
  * decoded RSC payload with NavigationProvider + NuqsAdapter before
116
89
  * NavigationRoot sets it as the new element. The `wrapPayload` function
117
- * receives the NavigationState explicitly — no temporal coupling with
118
- * getNavigationState().
90
+ * receives the NavigationState explicitly — there is no store to read it
91
+ * from.
119
92
  *
120
- * If not provided (tests), the router falls back to renderRoot.
93
+ * Every render goes through here — a navigation, a refresh, a traversal
94
+ * (fetched or replayed) and a server action's revalidation — so each one
95
+ * gets the same handover, commit and supersession.
121
96
  */
122
- navigateTransition?: (
97
+ navigateTransition: (
123
98
  pendingUrl: string,
124
99
  owner: RenderOwner,
125
100
  perform: (
@@ -225,6 +200,14 @@ export interface RouterInstance {
225
200
  * Hand the epoch back to `applyActionResult` with the response (TIM-1474).
226
201
  */
227
202
  epoch(): NavigationEpoch;
203
+ /**
204
+ * True when no navigation has started since `epoch` was taken and the
205
+ * router was idle then and is idle now — the same test
206
+ * `applyActionResult` applies. Action branches that never reach
207
+ * `applyActionResult` use it to detect a navigation that ran while the
208
+ * action was in flight and may have rendered pre-mutation data (TIM-1483).
209
+ */
210
+ isEpochCurrent(epoch: NavigationEpoch): boolean;
228
211
  /**
229
212
  * Reconcile the page after a server action. `tree` is the piggybacked
230
213
  * revalidation payload root, or `undefined` when the server sent none.
@@ -264,22 +247,41 @@ export interface RouterInstance {
264
247
  * affect any route's data, not just the paths the server named, so every
265
248
  * cached payload is stale. In-flight prefetch singleflights are fenced
266
249
  * by the eviction generation — their results are discarded if they
267
- * complete after eviction. The current URL's history entry is preserved
268
- * so `applyActionResult` can read its segment metadata.
250
+ * complete after eviction. `applyActionResult` does not need the history
251
+ * stack: the current page's segment metadata is the committer's record.
269
252
  */
270
253
  evictStaleCaches(): void;
271
254
  /**
272
- * Populate the segment cache from server-provided segment metadata.
273
- * Called on initial hydration with segment info embedded in the HTML.
255
+ * Make the server-rendered page the current page — the hydration entry
256
+ * point, and the only one: bootstrap does not reach into the router's
257
+ * caches. Returns the `NavigationState` the page renders with.
258
+ *
259
+ * Goes through the same `prepareNavigation` every navigation uses, and
260
+ * commits at once rather than on React's hydration commit. The server's
261
+ * HTML is already the page on screen, and React does not promise that
262
+ * commit: a render that reaches the root while hydration is suspended (a
263
+ * shallow search update, a navigation the Navigation API intercepted
264
+ * before hydration) switches the root to client rendering, and the
265
+ * hydration tree — with any publish attached to it — never commits. A
266
+ * status document is still kept out of the cache: its `StatusPageMarker`
267
+ * clears the cache when it reports (navigation-commit.ts).
274
268
  */
275
- initSegmentCache(segments: SegmentInfo[]): void;
269
+ hydrate(page: HydrationPage): NavigationState;
276
270
 
277
271
  /** The segment cache (exposed for tests and <Link> prefetch) */
278
272
  segmentCache: SegmentCache;
279
273
  /** The prefetch cache (exposed for tests and <Link> prefetch) */
280
274
  prefetchCache: PrefetchCache;
281
- /** The history stack (exposed for tests) */
282
- historyStack: HistoryStack;
275
+ }
276
+
277
+ /** The page the server rendered, as the browser entry decoded it. */
278
+ export interface HydrationPage {
279
+ /** The inlined payload's tree, or null when the document carried none. */
280
+ payload: unknown;
281
+ /** The params published beside it. */
282
+ params: ParamsSource;
283
+ /** The rendered chain's metadata (`self.__timber_segments`), or null. */
284
+ segmentInfo: SegmentInfo[] | null;
283
285
  }
284
286
 
285
287
  /**
@@ -0,0 +1,32 @@
1
+ /**
2
+ * How the client router reads the URLs it is handed.
3
+ *
4
+ * One parser, so the places that key or compare by URL — the history stack,
5
+ * the navigation state a page renders with, the departing page sent as
6
+ * `X-Timber-URL` — cannot disagree about what a URL says. They did: a
7
+ * history entry stored under `navigate('/café')`'s spelling was looked up
8
+ * under the address bar's `/caf%C3%A9`, and missed (TIM-1541).
9
+ */
10
+
11
+ const BASE = 'http://localhost';
12
+
13
+ /**
14
+ * Parse a router URL. A URL that starts with "/" is a path — including one
15
+ * that starts with "//": that is the pathname a document at
16
+ * `https://host//a/b` reports, and resolved against a base it would parse as
17
+ * a scheme-relative reference to host `a`. Anything else resolves against a
18
+ * placeholder origin, so an absolute URL keeps its own.
19
+ */
20
+ export function parseRouterUrl(url: string): URL {
21
+ return url.startsWith('/') ? new URL(BASE + url) : new URL(url, BASE);
22
+ }
23
+
24
+ /**
25
+ * The spelling a URL is stored and looked up under: the browser's own
26
+ * pathname + search, so `/a?` and `/a`, `/café` and `/caf%C3%A9`, are one
27
+ * key. The fragment is dropped — it is client-only.
28
+ */
29
+ export function routerUrlKey(url: string): string {
30
+ const parsed = parseRouterUrl(url);
31
+ return parsed.pathname + parsed.search;
32
+ }