@timber-js/app 0.2.0-alpha.208 → 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 (520) 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-BrHmG-2X.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-CNbpUOPB.js → status-page-marker-gaihi0KZ.js} +53 -20
  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 +12 -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 +68 -104
  132. package/dist/client/internal.js.map +1 -1
  133. package/dist/client/navigation-commit.d.ts +16 -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 +1 -6
  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/ssr-data.d.ts +18 -64
  149. package/dist/client/ssr-data.d.ts.map +1 -1
  150. package/dist/client/state.d.ts +2 -5
  151. package/dist/client/state.d.ts.map +1 -1
  152. package/dist/client/use-pathname.d.ts +1 -1
  153. package/dist/config-types.d.ts +2 -1
  154. package/dist/config-types.d.ts.map +1 -1
  155. package/dist/config-validation.d.ts.map +1 -1
  156. package/dist/cookies/index.js +1 -1
  157. package/dist/dev-tools/dev-page-shell.d.ts +17 -0
  158. package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
  159. package/dist/dev-tools/index.d.ts +1 -1
  160. package/dist/dev-tools/index.d.ts.map +1 -1
  161. package/dist/dev-tools/instrumentation.d.ts +17 -2
  162. package/dist/dev-tools/instrumentation.d.ts.map +1 -1
  163. package/dist/dev-tools/overlay.d.ts +6 -27
  164. package/dist/dev-tools/overlay.d.ts.map +1 -1
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +531 -373
  167. package/dist/index.js.map +1 -1
  168. package/dist/plugin-context.d.ts +26 -40
  169. package/dist/plugin-context.d.ts.map +1 -1
  170. package/dist/plugins/build-manifest.d.ts.map +1 -1
  171. package/dist/plugins/build-report.d.ts +15 -2
  172. package/dist/plugins/build-report.d.ts.map +1 -1
  173. package/dist/plugins/dev-server.d.ts.map +1 -1
  174. package/dist/plugins/entries.d.ts.map +1 -1
  175. package/dist/plugins/fonts.d.ts +19 -1
  176. package/dist/plugins/fonts.d.ts.map +1 -1
  177. package/dist/plugins/post-build.d.ts +110 -0
  178. package/dist/plugins/post-build.d.ts.map +1 -0
  179. package/dist/plugins/prebuilt-capture.d.ts +11 -4
  180. package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
  181. package/dist/plugins/prebuilt.d.ts +17 -1
  182. package/dist/plugins/prebuilt.d.ts.map +1 -1
  183. package/dist/plugins/prerender-sugar.d.ts.map +1 -1
  184. package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
  185. package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
  186. package/dist/plugins/shims.d.ts.map +1 -1
  187. package/dist/plugins/static-build.d.ts +32 -9
  188. package/dist/plugins/static-build.d.ts.map +1 -1
  189. package/dist/routing/codegen-write.d.ts +0 -9
  190. package/dist/routing/codegen-write.d.ts.map +1 -1
  191. package/dist/routing/index.js +2 -2
  192. package/dist/routing/segment-codegen.d.ts.map +1 -1
  193. package/dist/server/access-gate.d.ts.map +1 -1
  194. package/dist/server/action-handler.d.ts +5 -4
  195. package/dist/server/action-handler.d.ts.map +1 -1
  196. package/dist/server/actions.d.ts +46 -7
  197. package/dist/server/actions.d.ts.map +1 -1
  198. package/dist/server/als-registry.d.ts +58 -5
  199. package/dist/server/als-registry.d.ts.map +1 -1
  200. package/dist/server/children-interception.d.ts.map +1 -1
  201. package/dist/server/cookie-context.d.ts +2 -23
  202. package/dist/server/cookie-context.d.ts.map +1 -1
  203. package/dist/server/csp-nonce.d.ts +0 -9
  204. package/dist/server/csp-nonce.d.ts.map +1 -1
  205. package/dist/server/csrf.d.ts +27 -4
  206. package/dist/server/csrf.d.ts.map +1 -1
  207. package/dist/server/debug.d.ts +0 -1
  208. package/dist/server/debug.d.ts.map +1 -1
  209. package/dist/server/default-logger.d.ts +2 -1
  210. package/dist/server/default-logger.d.ts.map +1 -1
  211. package/dist/server/deny-boundary.d.ts +12 -6
  212. package/dist/server/deny-boundary.d.ts.map +1 -1
  213. package/dist/server/deny-renderer.d.ts +2 -2
  214. package/dist/server/deny-renderer.d.ts.map +1 -1
  215. package/dist/server/error-boundary-wrapper.d.ts +7 -3
  216. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  217. package/dist/server/fallback-error.d.ts +9 -2
  218. package/dist/server/fallback-error.d.ts.map +1 -1
  219. package/dist/server/head-response.d.ts +4 -4
  220. package/dist/server/html-injectors.d.ts.map +1 -1
  221. package/dist/server/index.d.ts +0 -1
  222. package/dist/server/index.d.ts.map +1 -1
  223. package/dist/server/index.js +3 -4
  224. package/dist/server/index.js.map +1 -1
  225. package/dist/server/instrumentation.d.ts +10 -3
  226. package/dist/server/instrumentation.d.ts.map +1 -1
  227. package/dist/server/internal.d.ts +1 -4
  228. package/dist/server/internal.d.ts.map +1 -1
  229. package/dist/server/internal.js +961 -581
  230. package/dist/server/internal.js.map +1 -1
  231. package/dist/server/json-status-response.d.ts +34 -0
  232. package/dist/server/json-status-response.d.ts.map +1 -0
  233. package/dist/server/logger.d.ts +26 -0
  234. package/dist/server/logger.d.ts.map +1 -1
  235. package/dist/server/param-coercion.d.ts +11 -6
  236. package/dist/server/param-coercion.d.ts.map +1 -1
  237. package/dist/server/pipeline-helpers.d.ts +95 -7
  238. package/dist/server/pipeline-helpers.d.ts.map +1 -1
  239. package/dist/server/pipeline-interception.d.ts +11 -0
  240. package/dist/server/pipeline-interception.d.ts.map +1 -1
  241. package/dist/server/pipeline-outcome.d.ts +11 -1
  242. package/dist/server/pipeline-outcome.d.ts.map +1 -1
  243. package/dist/server/pipeline-phases.d.ts +2 -2
  244. package/dist/server/pipeline-phases.d.ts.map +1 -1
  245. package/dist/server/pipeline.d.ts +23 -35
  246. package/dist/server/pipeline.d.ts.map +1 -1
  247. package/dist/server/prebuilt/capture-render.d.ts +25 -0
  248. package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
  249. package/dist/server/prebuilt/capture-routes.d.ts +37 -0
  250. package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
  251. package/dist/server/prebuilt/capture-state.d.ts +79 -35
  252. package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
  253. package/dist/server/prebuilt/lifetime.d.ts +38 -0
  254. package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
  255. package/dist/server/prebuilt/slots.d.ts +7 -0
  256. package/dist/server/prebuilt/slots.d.ts.map +1 -1
  257. package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
  258. package/dist/server/prebuilt-builder.d.ts.map +1 -1
  259. package/dist/server/prebuilt-runtime.d.ts.map +1 -1
  260. package/dist/server/primitives.d.ts +6 -81
  261. package/dist/server/primitives.d.ts.map +1 -1
  262. package/dist/server/react-cache-bridge.d.ts +59 -0
  263. package/dist/server/react-cache-bridge.d.ts.map +1 -0
  264. package/dist/server/react-cache-scope.d.ts +49 -0
  265. package/dist/server/react-cache-scope.d.ts.map +1 -0
  266. package/dist/server/render-timeout.d.ts +15 -0
  267. package/dist/server/render-timeout.d.ts.map +1 -1
  268. package/dist/server/render-utils.d.ts +9 -0
  269. package/dist/server/render-utils.d.ts.map +1 -1
  270. package/dist/server/request-context.d.ts +26 -5
  271. package/dist/server/request-context.d.ts.map +1 -1
  272. package/dist/server/route-element-builder.d.ts.map +1 -1
  273. package/dist/server/route-handler.d.ts.map +1 -1
  274. package/dist/server/route-matcher.d.ts +7 -0
  275. package/dist/server/route-matcher.d.ts.map +1 -1
  276. package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
  277. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
  278. package/dist/server/rsc-entry/api-handler.d.ts +7 -0
  279. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  280. package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
  281. package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
  282. package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
  283. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  284. package/dist/server/rsc-entry/helpers.d.ts +0 -1
  285. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  286. package/dist/server/rsc-entry/index.d.ts +5 -15
  287. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  288. package/dist/server/rsc-entry/render-route.d.ts +5 -6
  289. package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
  290. package/dist/server/rsc-entry/render-signals.d.ts +65 -0
  291. package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
  292. package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
  293. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
  294. package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
  295. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  296. package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
  297. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  298. package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
  299. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  300. package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
  301. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  302. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
  303. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
  304. package/dist/server/signal-identity.d.ts +43 -0
  305. package/dist/server/signal-identity.d.ts.map +1 -0
  306. package/dist/server/slot-resolver.d.ts +4 -3
  307. package/dist/server/slot-resolver.d.ts.map +1 -1
  308. package/dist/server/slot-subtree-contain.d.ts.map +1 -1
  309. package/dist/server/ssr-bridge-types.d.ts +91 -53
  310. package/dist/server/ssr-bridge-types.d.ts.map +1 -1
  311. package/dist/server/ssr-entry.d.ts +8 -5
  312. package/dist/server/ssr-entry.d.ts.map +1 -1
  313. package/dist/server/ssr-render.d.ts +26 -40
  314. package/dist/server/ssr-render.d.ts.map +1 -1
  315. package/dist/server/ssr-wrappers.d.ts +1 -1
  316. package/dist/server/static-generator.d.ts.map +1 -1
  317. package/dist/server/stream-utils.d.ts +12 -0
  318. package/dist/server/stream-utils.d.ts.map +1 -1
  319. package/dist/server/tracing.d.ts +12 -16
  320. package/dist/server/tracing.d.ts.map +1 -1
  321. package/dist/server/types.d.ts +1 -1
  322. package/dist/server/version-skew.d.ts +3 -3
  323. package/dist/shared/csrf-reject.d.ts +16 -0
  324. package/dist/shared/csrf-reject.d.ts.map +1 -0
  325. package/dist/shared/error-digest.d.ts +28 -0
  326. package/dist/shared/error-digest.d.ts.map +1 -0
  327. package/dist/shared/payload-root.d.ts +11 -10
  328. package/dist/shared/payload-root.d.ts.map +1 -1
  329. package/dist/shared/rsc-payload-path.d.ts +6 -0
  330. package/dist/shared/rsc-payload-path.d.ts.map +1 -1
  331. package/dist/utils/write-file-atomic.d.ts +17 -0
  332. package/dist/utils/write-file-atomic.d.ts.map +1 -0
  333. package/docs/api/30-api-server.mdx +17 -14
  334. package/docs/api/32-api-cache.mdx +51 -23
  335. package/docs/api/34-api-config.mdx +34 -6
  336. package/docs/api/36-cli.mdx +11 -1
  337. package/docs/learn/03-fetching-data.mdx +17 -1
  338. package/docs/learn/04-access-control.mdx +1 -1
  339. package/docs/learn/10-caching.mdx +29 -11
  340. package/docs/learn/11-middleware.mdx +8 -2
  341. package/docs/learn/12-error-handling.mdx +6 -1
  342. package/package.json +5 -1
  343. package/src/adapters/build-output-helper.ts +55 -53
  344. package/src/adapters/canonicalize-module.ts +29 -0
  345. package/src/adapters/cloudflare.ts +105 -63
  346. package/src/adapters/compress-module.ts +16 -5
  347. package/src/adapters/fs-identity.ts +2 -3
  348. package/src/adapters/nitro-presets.ts +0 -15
  349. package/src/adapters/nitro-preview.ts +272 -136
  350. package/src/adapters/nitro.ts +119 -82
  351. package/src/adapters/shared.ts +23 -14
  352. package/src/adapters/types.ts +110 -21
  353. package/src/analyze/graph-cache.ts +3 -4
  354. package/src/cache/json-lossy-check.ts +3 -9
  355. package/src/cache/singleflight.ts +5 -2
  356. package/src/cache/sizeof.ts +3 -1
  357. package/src/cache/tag-aware-handler.ts +43 -26
  358. package/src/cli-check.ts +8 -98
  359. package/src/cli-context.ts +119 -0
  360. package/src/cli.ts +19 -28
  361. package/src/client/browser-dev.ts +1 -1
  362. package/src/client/browser-entry/action-dispatch.ts +26 -4
  363. package/src/client/browser-entry/hydrate.ts +53 -58
  364. package/src/client/browser-entry/index.ts +16 -27
  365. package/src/client/browser-entry/post-hydration.ts +6 -40
  366. package/src/client/browser-entry/router-init.ts +66 -84
  367. package/src/client/error-boundary.tsx +9 -41
  368. package/src/client/error-reconstituter.tsx +10 -5
  369. package/src/client/history.ts +18 -21
  370. package/src/client/index.ts +0 -1
  371. package/src/client/internal.ts +2 -7
  372. package/src/client/navigation-commit.ts +35 -18
  373. package/src/client/navigation-context.ts +3 -39
  374. package/src/client/react-root.ts +3 -2
  375. package/src/client/router-pipeline.ts +65 -128
  376. package/src/client/router-types.ts +46 -44
  377. package/src/client/router-url.ts +32 -0
  378. package/src/client/router.ts +43 -22
  379. package/src/client/rsc-fetch.ts +117 -155
  380. package/src/client/ssr-data.ts +19 -80
  381. package/src/client/state.ts +2 -9
  382. package/src/client/use-pathname.ts +1 -1
  383. package/src/config-types.ts +2 -1
  384. package/src/config-validation.ts +2 -1
  385. package/src/dev-tools/dev-page-shell.ts +18 -0
  386. package/src/dev-tools/index.ts +0 -2
  387. package/src/dev-tools/instrumentation.ts +50 -2
  388. package/src/dev-tools/overlay.ts +8 -238
  389. package/src/index.ts +24 -14
  390. package/src/plugin-context.ts +39 -40
  391. package/src/plugins/build-manifest.ts +4 -11
  392. package/src/plugins/build-report.ts +70 -70
  393. package/src/plugins/dev-server.ts +24 -44
  394. package/src/plugins/entries.ts +2 -1
  395. package/src/plugins/fonts.ts +35 -7
  396. package/src/plugins/post-build.ts +327 -0
  397. package/src/plugins/prebuilt-capture.ts +28 -32
  398. package/src/plugins/prebuilt.ts +54 -39
  399. package/src/plugins/prerender-sugar.ts +0 -4
  400. package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
  401. package/src/plugins/shims.ts +1 -0
  402. package/src/plugins/static-build.ts +42 -74
  403. package/src/routing/codegen-write.ts +25 -3
  404. package/src/routing/segment-codegen.ts +3 -2
  405. package/src/rsc-runtime/vendor-types.d.ts +8 -0
  406. package/src/server/access-gate.tsx +2 -1
  407. package/src/server/action-client.ts +1 -1
  408. package/src/server/action-handler.ts +253 -110
  409. package/src/server/actions.ts +73 -25
  410. package/src/server/als-registry.ts +73 -5
  411. package/src/server/chain-url-parts.ts +1 -1
  412. package/src/server/children-interception.ts +2 -1
  413. package/src/server/cookie-context.ts +18 -48
  414. package/src/server/csp-nonce.ts +0 -12
  415. package/src/server/csrf.ts +140 -8
  416. package/src/server/debug.ts +0 -1
  417. package/src/server/default-logger.ts +2 -1
  418. package/src/server/deny-boundary.ts +25 -13
  419. package/src/server/deny-renderer.ts +30 -97
  420. package/src/server/error-boundary-wrapper.ts +7 -3
  421. package/src/server/fallback-error.ts +26 -11
  422. package/src/server/flight-scripts.ts +1 -1
  423. package/src/server/head-response.ts +4 -4
  424. package/src/server/html-injector-core.ts +2 -2
  425. package/src/server/html-injectors.ts +2 -4
  426. package/src/server/index.ts +0 -4
  427. package/src/server/instrumentation.ts +10 -3
  428. package/src/server/internal.ts +1 -6
  429. package/src/server/json-status-response.ts +105 -0
  430. package/src/server/logger.ts +39 -3
  431. package/src/server/param-coercion.ts +15 -12
  432. package/src/server/pipeline-helpers.ts +257 -12
  433. package/src/server/pipeline-interception.ts +133 -0
  434. package/src/server/pipeline-outcome.ts +103 -31
  435. package/src/server/pipeline-phases.ts +127 -237
  436. package/src/server/pipeline.ts +204 -207
  437. package/src/server/prebuilt/capture-render.ts +118 -0
  438. package/src/server/prebuilt/capture-routes.ts +104 -0
  439. package/src/server/prebuilt/capture-state.ts +155 -48
  440. package/src/server/prebuilt/lifetime.ts +151 -0
  441. package/src/server/prebuilt/slots.ts +14 -2
  442. package/src/server/prebuilt/synthetic-store.ts +3 -0
  443. package/src/server/prebuilt-builder.ts +30 -320
  444. package/src/server/prebuilt-runtime.ts +125 -129
  445. package/src/server/primitives.ts +8 -168
  446. package/src/server/react-cache-bridge.ts +124 -0
  447. package/src/server/react-cache-scope.ts +104 -0
  448. package/src/server/render-timeout.ts +20 -0
  449. package/src/server/render-utils.ts +11 -1
  450. package/src/server/request-context.ts +36 -9
  451. package/src/server/route-element-builder.ts +11 -6
  452. package/src/server/route-handler.ts +36 -23
  453. package/src/server/route-matcher.ts +15 -1
  454. package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
  455. package/src/server/rsc-entry/api-handler.ts +27 -103
  456. package/src/server/rsc-entry/deny-fallback.ts +93 -26
  457. package/src/server/rsc-entry/error-renderer.ts +39 -91
  458. package/src/server/rsc-entry/helpers.ts +2 -4
  459. package/src/server/rsc-entry/index.ts +64 -58
  460. package/src/server/rsc-entry/render-route.ts +15 -80
  461. package/src/server/rsc-entry/render-signals.ts +108 -0
  462. package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
  463. package/src/server/rsc-entry/rsc-payload.ts +28 -61
  464. package/src/server/rsc-entry/rsc-stream.ts +113 -213
  465. package/src/server/rsc-entry/ssr-bridge.ts +2 -2
  466. package/src/server/rsc-entry/ssr-renderer.ts +182 -263
  467. package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
  468. package/src/server/signal-identity.ts +112 -0
  469. package/src/server/slot-resolver.ts +18 -18
  470. package/src/server/slot-subtree-contain.ts +2 -1
  471. package/src/server/ssr-bridge-types.ts +92 -56
  472. package/src/server/ssr-entry.ts +87 -111
  473. package/src/server/ssr-render.ts +55 -64
  474. package/src/server/ssr-wrappers.tsx +2 -2
  475. package/src/server/static-generator.ts +7 -42
  476. package/src/server/static-not-found.ts +3 -3
  477. package/src/server/stream-utils.ts +51 -0
  478. package/src/server/tracing.ts +58 -75
  479. package/src/server/types.ts +1 -1
  480. package/src/server/version-skew.ts +5 -5
  481. package/src/shared/csrf-reject.ts +15 -0
  482. package/src/shared/error-digest.ts +46 -0
  483. package/src/shared/payload-root.ts +11 -10
  484. package/src/shared/rsc-payload-path.ts +8 -1
  485. package/src/utils/write-file-atomic.ts +32 -0
  486. package/dist/_chunks/actions-jNrXdzgs.js +0 -346
  487. package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
  488. package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
  489. package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
  490. package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
  491. package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
  492. package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
  493. package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
  494. package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
  495. package/dist/_chunks/error-boundary-BrHmG-2X.js.map +0 -1
  496. package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
  497. package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
  498. package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
  499. package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
  500. package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
  501. package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
  502. package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
  503. package/dist/_chunks/segment-context-D9_89u34.js +0 -34
  504. package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
  505. package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
  506. package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
  507. package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
  508. package/dist/_chunks/state-FippDgxN.js.map +0 -1
  509. package/dist/_chunks/status-page-marker-CNbpUOPB.js.map +0 -1
  510. package/dist/client/types.d.ts +0 -14
  511. package/dist/client/types.d.ts.map +0 -1
  512. package/dist/plugins/adapter-build.d.ts +0 -38
  513. package/dist/plugins/adapter-build.d.ts.map +0 -1
  514. package/dist/server/asset-headers.d.ts +0 -32
  515. package/dist/server/asset-headers.d.ts.map +0 -1
  516. package/dist/server/dev-source-map.d.ts +0 -22
  517. package/dist/server/dev-source-map.d.ts.map +0 -1
  518. package/src/client/types.ts +0 -21
  519. package/src/server/asset-headers.ts +0 -59
  520. 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
  /**
@@ -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
  }
@@ -180,50 +172,13 @@ export function createNavigationPipeline({
180
172
  forgetOlderHandoffs,
181
173
  }: NavigationPipelineDeps): NavigationPipeline {
182
174
  /**
183
- * Render a decoded RSC payload into the DOM, publishing `commit` when the
184
- * tree is current. The renderer owns that moment (see `RootRenderer`);
185
- * with no renderer there is no tree to wait for, so it publishes now.
186
- */
187
- function renderPayload(
188
- payload: unknown,
189
- navState: NavigationState,
190
- params: ParamsSource,
191
- commit: () => void
192
- ): void {
193
- if (deps.renderRoot) {
194
- deps.renderRoot(payload, navState, params, commit);
195
- } else {
196
- commit();
197
- }
198
- }
199
-
200
- /**
201
- * Resolve thenable payloads in the test/fallback path (no navigateTransition).
202
- * In production, React handles thenables from createFromFetch directly via
203
- * Suspense. In tests, renderRoot is a plain mock that expects resolved values.
204
- */
205
- async function resolveForFallback(payload: unknown): Promise<unknown> {
206
- if (
207
- !deps.navigateTransition &&
208
- payload != null &&
209
- typeof payload === 'object' &&
210
- 'then' in payload
211
- ) {
212
- return await (payload as PromiseLike<unknown>);
213
- }
214
- return payload;
215
- }
216
-
217
- /**
218
- * Render a payload via navigateTransition (production) or renderRoot (tests).
219
- * 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
220
176
  * FetchResult plus the NavigationState and the commit thunk.
221
177
  *
222
178
  * The thunk is handed *through* to NavigationRoot rather than called here:
223
- * state management (segmentCache, navState, historyStack) has to happen on
179
+ * state management (segment cache, history stack, address bar) has to happen on
224
180
  * the far side of the supersession check, which only NavigationRoot can
225
- * make (TIM-1301). The fallback path below has no transition to be
226
- * superseded by, so it commits directly.
181
+ * make (TIM-1301).
227
182
  */
228
183
  async function renderViaTransition(
229
184
  url: string,
@@ -245,84 +200,70 @@ export function createNavigationPipeline({
245
200
  commit();
246
201
  };
247
202
 
248
- if (deps.navigateTransition) {
249
- await deps.navigateTransition(
250
- url,
251
- owner,
252
- async (wrapPayload) => {
253
- const result = await perform();
254
- // Await the payload's *root row* — the same thing React would suspend
255
- // on to render the tree, and the first thing Flight emits. The
256
- // previous UI stays on screen while this resolves: nothing has been
257
- // handed to React yet, and when it is, NavigationRoot hands it over
258
- // inside a transition so a tree that is still streaming does not
259
- // displace the departing page (TIM-1306).
260
- //
261
- // Reading them here rather than with `use()` above the tree is what
262
- // keeps a decode failure contained: `result.params` never rejects, so
263
- // the rejection reaches React only through the tree, inside whatever
264
- // error boundary the app put around it (TIM-1297).
265
- 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;
266
229
 
267
- if (isPartialNavigation(result.skippedSegments)) {
268
- const segmentUpdates = buildSegmentUpdates(result);
230
+ if (isPartialNavigation(result.skippedSegments)) {
231
+ const segmentUpdates = buildSegmentUpdates(result, payload);
269
232
 
270
- // Re-wrap the CURRENT element with new context values.
271
- // SegmentOutlets read updates from SegmentUpdateContext;
272
- // NavigationProvider gets the new pathname; the params published
273
- // above the retained tree are the *incoming* route's.
274
- const element = wrapPayload(
275
- deps._getCurrentPayload?.() ?? result.payload,
276
- result.navState,
277
- params,
278
- segmentUpdates
279
- );
280
- handOff();
281
- return {
282
- element,
283
- decodePromise: observeSkew(result.decodePromise),
284
- commit: commitAndForget(result.commit),
285
- };
286
- }
287
-
288
- // Full navigation — empty updates, render the new tree.
289
- 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
+ );
290
243
  handOff();
291
244
  return {
292
245
  element,
293
246
  decodePromise: observeSkew(result.decodePromise),
294
247
  commit: commitAndForget(result.commit),
295
248
  };
296
- },
297
- onCommit
298
- );
299
- return;
300
- }
301
- // Fallback: no transition (tests, no React tree). The commit is
302
- // synchronous here, so the outcome is always 'committed' or 'failed' —
303
- // no transition counter to supersede. The hook fires on the way out,
304
- // on failure too, so it still fires exactly once.
305
- let fallbackOutcome: CommitOutcome = 'committed';
306
- try {
307
- const result = await perform();
308
- handOff();
309
- const commit = commitAndForget(result.commit);
310
- if (isPartialNavigation(result.skippedSegments)) {
311
- commit();
312
- } else {
313
- renderPayload(result.payload, result.navState, await result.params, commit);
314
- }
315
- } catch (error) {
316
- fallbackOutcome = 'failed';
317
- throw error;
318
- } finally {
319
- onCommit?.(fallbackOutcome);
320
- }
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
+ );
321
262
  }
322
263
 
323
264
  /**
324
- * Core navigation logic shared between the transition and fallback paths.
325
- * 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.
326
267
  */
327
268
  async function performNavigationFetch(
328
269
  url: string,
@@ -468,9 +409,6 @@ export function createNavigationPipeline({
468
409
  deps.setRouterNavigating?.(false);
469
410
  };
470
411
 
471
- // Resolve thenable payloads in the test path so popstate replay
472
- // and renderPayload receive plain values (see resolveForFallback).
473
- const payload = await resolveForFallback(result.payload);
474
412
  const params = await result.params;
475
413
 
476
414
  // Prepare the atomic navigation-state update. It is published by the
@@ -479,7 +417,7 @@ export function createNavigationPipeline({
479
417
  // `prepareNavigation`'s decision, made from `skippedSegments` and
480
418
  // `segmentInfo` (TIM-1432).
481
419
  const { navState, commit } = prepareNavigation(url, {
482
- payload,
420
+ payload: result.payload,
483
421
  params,
484
422
  segmentInfo: result.segmentInfo,
485
423
  skippedSegments: result.skippedSegments,
@@ -496,7 +434,6 @@ export function createNavigationPipeline({
496
434
 
497
435
  return {
498
436
  ...result,
499
- payload,
500
437
  params,
501
438
  navState,
502
439
  commit: () => {
@@ -513,5 +450,5 @@ export function createNavigationPipeline({
513
450
  };
514
451
  }
515
452
 
516
- return { performNavigationFetch, renderViaTransition, renderPayload, resolveForFallback };
453
+ return { performNavigationFetch, renderViaTransition };
517
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
+ }
@@ -12,7 +12,6 @@
12
12
  // See design/19-client-navigation.md for the full architecture.
13
13
 
14
14
  import { SegmentCache, PrefetchCache } from './segment-cache.ts';
15
- import type { SegmentInfo } from '../shared/segment-info.ts';
16
15
  import { HistoryStack } from './history.ts';
17
16
  import { createNavigationCommitter } from './navigation-commit.ts';
18
17
 
@@ -42,7 +41,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
42
41
  const {
43
42
  prepareNavigation,
44
43
  currentStateTree,
45
- updateSegmentCache,
44
+ committedSegmentInfo,
46
45
  isSegmentReuseSuppressed,
47
46
  restoreSegmentReuse,
48
47
  } = createNavigationCommitter({
@@ -66,17 +65,16 @@ export function createRouter(deps: RouterDeps): RouterInstance {
66
65
  } = lifecycle;
67
66
 
68
67
  // Fetch → commit → hand to React. See router-pipeline.ts.
69
- const { performNavigationFetch, renderViaTransition, resolveForFallback } =
70
- createNavigationPipeline({
71
- deps,
72
- prefetchCache,
73
- currentStateTree,
74
- prepareNavigation,
75
- isSegmentReuseSuppressed,
76
- restoreSegmentReuse,
77
- markHandedOff,
78
- forgetOlderHandoffs,
79
- });
68
+ const { performNavigationFetch, renderViaTransition } = createNavigationPipeline({
69
+ deps,
70
+ prefetchCache,
71
+ currentStateTree,
72
+ prepareNavigation,
73
+ isSegmentReuseSuppressed,
74
+ restoreSegmentReuse,
75
+ markHandedOff,
76
+ forgetOlderHandoffs,
77
+ });
80
78
 
81
79
  // Post-paint scroll effects.
82
80
  const { restoreScrollAfterPaint, scrollToHashAfterPaint } = createScrollEffects(deps);
@@ -231,15 +229,14 @@ export function createRouter(deps: RouterDeps): RouterInstance {
231
229
  undefined,
232
230
  owner.fetchAbort.signal
233
231
  );
234
- const payload = await resolveForFallback(result.payload);
235
232
  const params = await result.params;
236
233
  const { navState, commit } = prepareNavigation(url, {
237
- payload,
234
+ payload: result.payload,
238
235
  params,
239
236
  segmentInfo: result.segmentInfo,
240
237
  skippedSegments: result.skippedSegments,
241
238
  });
242
- return { ...result, payload, params, navState, commit };
239
+ return { ...result, params, navState, commit };
243
240
  },
244
241
  opts.onCommit
245
242
  );
@@ -436,6 +433,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
436
433
  onPendingChange,
437
434
  prefetch,
438
435
  epoch: () => lifecycle.epoch(),
436
+ isEpochCurrent: (epoch) => lifecycle.isEpochCurrent(epoch),
439
437
 
440
438
  async applyActionResult(epoch, tree) {
441
439
  if (!lifecycle.isEpochCurrent(epoch)) return false;
@@ -461,7 +459,12 @@ export function createRouter(deps: RouterDeps): RouterInstance {
461
459
  const currentUrl = deps.getCurrentUrl();
462
460
  const payloadTree = readPayloadTree(tree);
463
461
  const params = readPublishedParams(tree);
464
- const existingEntry = historyStack.get(currentUrl);
462
+ // The response carries no segment metadata; the page it re-renders is
463
+ // the one the last commit made current, and the committer kept that
464
+ // page's. Not a history-stack lookup by `currentUrl`: the stack is keyed
465
+ // by the spelling `navigate()` was given, which need not be
466
+ // `window.location`'s (TIM-1541).
467
+ const segmentInfo = committedSegmentInfo();
465
468
 
466
469
  let outcomeResolve!: (o: CommitOutcome) => void;
467
470
  const outcomePromise = new Promise<CommitOutcome>((r) => (outcomeResolve = r));
@@ -479,7 +482,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
479
482
  const { navState, commit } = prepareNavigation(currentUrl, {
480
483
  payload: payloadTree,
481
484
  params,
482
- segmentInfo: existingEntry?.segmentInfo,
485
+ segmentInfo,
483
486
  });
484
487
  return {
485
488
  payload: payloadTree,
@@ -487,7 +490,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
487
490
  navState,
488
491
  commit,
489
492
  decodePromise: null,
490
- segmentInfo: existingEntry?.segmentInfo ?? null,
493
+ segmentInfo,
491
494
  skippedSegments: null,
492
495
  };
493
496
  },
@@ -517,11 +520,29 @@ export function createRouter(deps: RouterDeps): RouterInstance {
517
520
  },
518
521
  evictStaleCaches(): void {
519
522
  prefetchCache.clearReady();
520
- historyStack.clearExcept(deps.getCurrentUrl());
523
+ historyStack.clear();
524
+ },
525
+ hydrate(page) {
526
+ // Where hydration seeds the current page: the same prepare-and-commit
527
+ // every navigation goes through, so the segment cache, the committed
528
+ // segment metadata and the history entry are written by one commit
529
+ // rather than by bootstrap reaching into each (TIM-1541). Committed
530
+ // here, at once — see `RouterInstance.hydrate` for why not on React's
531
+ // hydration commit.
532
+ //
533
+ // Replaying this entry on a Back re-renders `payload` and republishes
534
+ // `params`. Both came out of one split of one decoded payload root
535
+ // (rsc-stream.ts), so the entry cannot replay with another route's
536
+ // params (TIM-1037, TIM-1285).
537
+ const { navState, commit } = prepareNavigation(deps.getCurrentUrl(), {
538
+ payload: page.payload,
539
+ params: page.params,
540
+ segmentInfo: page.segmentInfo,
541
+ });
542
+ commit();
543
+ return navState;
521
544
  },
522
- initSegmentCache: (segments: SegmentInfo[]) => updateSegmentCache(segments),
523
545
  segmentCache,
524
546
  prefetchCache,
525
- historyStack,
526
547
  };
527
548
  }