@timber-js/app 0.2.0-alpha.185 → 0.2.0-alpha.187

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 (570) hide show
  1. package/dist/_chunks/{actions-O_LsyCE4.js → actions-35jnMdeJ.js} +4 -3
  2. package/dist/_chunks/{actions-O_LsyCE4.js.map → actions-35jnMdeJ.js.map} +1 -1
  3. package/dist/_chunks/als-registry-C6kcfprT.js +41 -0
  4. package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -0
  5. package/dist/_chunks/als-slots-BEEIPKYm.js +26 -0
  6. package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -0
  7. package/dist/_chunks/base-path-DaQrzbez.js +80 -0
  8. package/dist/_chunks/base-path-DaQrzbez.js.map +1 -0
  9. package/dist/_chunks/build-manifest-DWppEdLB.js +86 -0
  10. package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
  11. package/dist/_chunks/build-output-helper-C3DrfzZR.js +369 -0
  12. package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +1 -0
  13. package/dist/_chunks/{cache-api-B-lhk9p4.js → cache-api-DjNrIWRR.js} +8 -14
  14. package/dist/_chunks/cache-api-DjNrIWRR.js.map +1 -0
  15. package/dist/_chunks/cli-check-CpmN7Nh-.js +256 -0
  16. package/dist/_chunks/cli-check-CpmN7Nh-.js.map +1 -0
  17. package/dist/_chunks/cli-schema-sync-CGMp_Psg.js +298 -0
  18. package/dist/_chunks/cli-schema-sync-CGMp_Psg.js.map +1 -0
  19. package/dist/_chunks/{cloudflare-CnT5Lr7U.js → cloudflare-CGP6BZKO.js} +92 -14
  20. package/dist/_chunks/{cloudflare-CnT5Lr7U.js.map → cloudflare-CGP6BZKO.js.map} +1 -1
  21. package/dist/_chunks/convention-lint-kXsgc_-7.js +784 -0
  22. package/dist/_chunks/convention-lint-kXsgc_-7.js.map +1 -0
  23. package/dist/_chunks/error-boundary-D-ODYX41.js +353 -0
  24. package/dist/_chunks/error-boundary-D-ODYX41.js.map +1 -0
  25. package/dist/_chunks/{fast-hash-D6hIVt1Y.js → fast-hash-C-tVYrLb.js} +6 -1
  26. package/dist/_chunks/fast-hash-C-tVYrLb.js.map +1 -0
  27. package/dist/_chunks/file-cache-DmX7OqZP.js +454 -0
  28. package/dist/_chunks/file-cache-DmX7OqZP.js.map +1 -0
  29. package/dist/_chunks/fs-identity-D7vb6GdI.js +208 -0
  30. package/dist/_chunks/fs-identity-D7vb6GdI.js.map +1 -0
  31. package/dist/_chunks/{logger-AWfuX-KJ.js → logger-D8xJZXIN.js} +34 -51
  32. package/dist/_chunks/logger-D8xJZXIN.js.map +1 -0
  33. package/dist/_chunks/mdx-file-C005ay-P.js +25 -0
  34. package/dist/_chunks/mdx-file-C005ay-P.js.map +1 -0
  35. package/dist/_chunks/{plugin-context---kTF5v8.js → plugin-context-rCinWLiE.js} +8 -2
  36. package/dist/_chunks/plugin-context-rCinWLiE.js.map +1 -0
  37. package/dist/_chunks/purge-store-Byr8XOjU.js +14 -0
  38. package/dist/_chunks/purge-store-Byr8XOjU.js.map +1 -0
  39. package/dist/_chunks/{resolve-schema-Dz3fcFUo.js → resolve-schema-5ma5pp1b.js} +2 -2
  40. package/dist/_chunks/{resolve-schema-Dz3fcFUo.js.map → resolve-schema-5ma5pp1b.js.map} +1 -1
  41. package/dist/_chunks/{router-ref-CtmF-aPv.js → router-ref-DuYuV_0Q.js} +2 -2
  42. package/dist/_chunks/router-ref-DuYuV_0Q.js.map +1 -0
  43. package/dist/_chunks/rsc-cache-key-DD0fl_-s.js +243 -0
  44. package/dist/_chunks/rsc-cache-key-DD0fl_-s.js.map +1 -0
  45. package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js +40 -0
  46. package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js.map +1 -0
  47. package/dist/_chunks/rsc-media-type-DRqE_lD_.js +46 -0
  48. package/dist/_chunks/rsc-media-type-DRqE_lD_.js.map +1 -0
  49. package/dist/_chunks/rsc-payload-path-B_LBodc2.js +48 -0
  50. package/dist/_chunks/rsc-payload-path-B_LBodc2.js.map +1 -0
  51. package/dist/_chunks/scanner-C8b0Gcw3.js +1564 -0
  52. package/dist/_chunks/scanner-C8b0Gcw3.js.map +1 -0
  53. package/dist/_chunks/schema-bridge-Cc2Gngu1.js +199 -0
  54. package/dist/_chunks/schema-bridge-Cc2Gngu1.js.map +1 -0
  55. package/dist/_chunks/{segment-classify-Byy425ng.js → segment-classify-C539Pa2O.js} +23 -2
  56. package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -0
  57. package/dist/_chunks/segment-context-CjOlyB8Y.js +97 -0
  58. package/dist/_chunks/segment-context-CjOlyB8Y.js.map +1 -0
  59. package/dist/_chunks/{canonicalize-DQHyFClh.js → segment-keys-BawYuNFO.js} +61 -2
  60. package/dist/_chunks/segment-keys-BawYuNFO.js.map +1 -0
  61. package/dist/_chunks/slot-params-BCTmZkQB.js +76 -0
  62. package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -0
  63. package/dist/_chunks/{ssr-data-BOWsq18U.js → ssr-data-14MXm7Pj.js} +17 -2
  64. package/dist/_chunks/ssr-data-14MXm7Pj.js.map +1 -0
  65. package/dist/_chunks/{use-query-states-DFvWd-EA.js → use-query-states-BbU5Ge1V.js} +74 -26
  66. package/dist/_chunks/use-query-states-BbU5Ge1V.js.map +1 -0
  67. package/dist/_chunks/use-segment-params-C4r4BD9T.js +398 -0
  68. package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +1 -0
  69. package/dist/_chunks/walkers-RzN6AFjr.js +141 -0
  70. package/dist/_chunks/walkers-RzN6AFjr.js.map +1 -0
  71. package/dist/adapters/build-output-helper.d.ts +37 -0
  72. package/dist/adapters/build-output-helper.d.ts.map +1 -1
  73. package/dist/adapters/cloudflare-dev.js +1 -1
  74. package/dist/adapters/cloudflare-kv-cache.js +1 -1
  75. package/dist/adapters/cloudflare.d.ts.map +1 -1
  76. package/dist/adapters/cloudflare.js +1 -1
  77. package/dist/adapters/compress-module.d.ts +12 -0
  78. package/dist/adapters/compress-module.d.ts.map +1 -1
  79. package/dist/adapters/fs-identity.d.ts +64 -0
  80. package/dist/adapters/fs-identity.d.ts.map +1 -0
  81. package/dist/adapters/nitro.d.ts.map +1 -1
  82. package/dist/adapters/nitro.js +56 -5
  83. package/dist/adapters/nitro.js.map +1 -1
  84. package/dist/adapters/shared.d.ts +57 -1
  85. package/dist/adapters/shared.d.ts.map +1 -1
  86. package/dist/adapters/types.d.ts +13 -1
  87. package/dist/adapters/types.d.ts.map +1 -1
  88. package/dist/cache/fast-hash.d.ts +5 -0
  89. package/dist/cache/fast-hash.d.ts.map +1 -1
  90. package/dist/cache/index.js +1 -1
  91. package/dist/cdn/cloudflare-purge.js +30 -0
  92. package/dist/cdn/cloudflare-purge.js.map +1 -0
  93. package/dist/cdn/fastly-purge.js +33 -0
  94. package/dist/cdn/fastly-purge.js.map +1 -0
  95. package/dist/cdn/index.js +94 -0
  96. package/dist/cdn/index.js.map +1 -0
  97. package/dist/cdn/workers-cache-purge.js +35 -0
  98. package/dist/cdn/workers-cache-purge.js.map +1 -0
  99. package/dist/cli-check.d.ts +153 -0
  100. package/dist/cli-check.d.ts.map +1 -0
  101. package/dist/cli.d.ts +34 -8
  102. package/dist/cli.d.ts.map +1 -1
  103. package/dist/cli.js +46 -21
  104. package/dist/cli.js.map +1 -1
  105. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
  106. package/dist/client/browser-entry/hydrate.d.ts +20 -9
  107. package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
  108. package/dist/client/browser-entry/index.d.ts +1 -1
  109. package/dist/client/browser-entry/index.d.ts.map +1 -1
  110. package/dist/client/browser-entry/post-hydration.d.ts +4 -1
  111. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
  112. package/dist/client/browser-entry/router-init.d.ts +3 -0
  113. package/dist/client/browser-entry/router-init.d.ts.map +1 -1
  114. package/dist/client/browser-entry/rsc-stream.d.ts +8 -0
  115. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -1
  116. package/dist/client/error-boundary.d.ts +7 -0
  117. package/dist/client/error-boundary.d.ts.map +1 -1
  118. package/dist/client/error-boundary.js +1 -162
  119. package/dist/client/history.d.ts +13 -6
  120. package/dist/client/history.d.ts.map +1 -1
  121. package/dist/client/index.d.ts +1 -0
  122. package/dist/client/index.d.ts.map +1 -1
  123. package/dist/client/index.js +42 -41
  124. package/dist/client/index.js.map +1 -1
  125. package/dist/client/internal.d.ts +4 -3
  126. package/dist/client/internal.d.ts.map +1 -1
  127. package/dist/client/internal.js +877 -311
  128. package/dist/client/internal.js.map +1 -1
  129. package/dist/client/link.d.ts +1 -7
  130. package/dist/client/link.d.ts.map +1 -1
  131. package/dist/client/navigation-api.d.ts +2 -2
  132. package/dist/client/navigation-commit.d.ts +87 -0
  133. package/dist/client/navigation-commit.d.ts.map +1 -0
  134. package/dist/client/navigation-context.d.ts +37 -20
  135. package/dist/client/navigation-context.d.ts.map +1 -1
  136. package/dist/client/navigation-root.d.ts +63 -23
  137. package/dist/client/navigation-root.d.ts.map +1 -1
  138. package/dist/client/params-context.d.ts +81 -0
  139. package/dist/client/params-context.d.ts.map +1 -0
  140. package/dist/client/router-effects.d.ts +129 -0
  141. package/dist/client/router-effects.d.ts.map +1 -0
  142. package/dist/client/router-lifecycle.d.ts +55 -0
  143. package/dist/client/router-lifecycle.d.ts.map +1 -0
  144. package/dist/client/router-pipeline.d.ts +84 -0
  145. package/dist/client/router-pipeline.d.ts.map +1 -0
  146. package/dist/client/router-ref.d.ts +1 -1
  147. package/dist/client/router-ref.d.ts.map +1 -1
  148. package/dist/client/router-skew.d.ts +21 -0
  149. package/dist/client/router-skew.d.ts.map +1 -0
  150. package/dist/client/router-types.d.ts +207 -0
  151. package/dist/client/router-types.d.ts.map +1 -0
  152. package/dist/client/router.d.ts +1 -182
  153. package/dist/client/router.d.ts.map +1 -1
  154. package/dist/client/rsc-fetch.d.ts +47 -26
  155. package/dist/client/rsc-fetch.d.ts.map +1 -1
  156. package/dist/client/segment-cache.d.ts +87 -34
  157. package/dist/client/segment-cache.d.ts.map +1 -1
  158. package/dist/client/ssr-data.d.ts +6 -0
  159. package/dist/client/ssr-data.d.ts.map +1 -1
  160. package/dist/client/stale-client.d.ts +69 -0
  161. package/dist/client/stale-client.d.ts.map +1 -0
  162. package/dist/client/state.d.ts +10 -1
  163. package/dist/client/state.d.ts.map +1 -1
  164. package/dist/client/top-loader.d.ts +2 -1
  165. package/dist/client/top-loader.d.ts.map +1 -1
  166. package/dist/client/unload-guard.d.ts +5 -0
  167. package/dist/client/unload-guard.d.ts.map +1 -1
  168. package/dist/client/use-cookie.d.ts.map +1 -1
  169. package/dist/client/use-query-states.d.ts +9 -3
  170. package/dist/client/use-query-states.d.ts.map +1 -1
  171. package/dist/client/use-router.d.ts +1 -1
  172. package/dist/client/use-segment-params.d.ts +18 -8
  173. package/dist/client/use-segment-params.d.ts.map +1 -1
  174. package/dist/codec.js +1 -1
  175. package/dist/cookies/define-cookie.d.ts.map +1 -1
  176. package/dist/cookies/index.js +5 -5
  177. package/dist/cookies/index.js.map +1 -1
  178. package/dist/index.d.ts +4 -1
  179. package/dist/index.d.ts.map +1 -1
  180. package/dist/index.js +1009 -759
  181. package/dist/index.js.map +1 -1
  182. package/dist/params/index.js +1 -1
  183. package/dist/plugin-context.d.ts +46 -0
  184. package/dist/plugin-context.d.ts.map +1 -1
  185. package/dist/plugins/adapter-build.d.ts.map +1 -1
  186. package/dist/plugins/build-manifest.d.ts +1 -1
  187. package/dist/plugins/build-manifest.d.ts.map +1 -1
  188. package/dist/plugins/entries.d.ts.map +1 -1
  189. package/dist/plugins/fonts.d.ts.map +1 -1
  190. package/dist/plugins/request-dep/analysis.d.ts +106 -0
  191. package/dist/plugins/request-dep/analysis.d.ts.map +1 -0
  192. package/dist/plugins/request-dep/index.d.ts +75 -0
  193. package/dist/plugins/request-dep/index.d.ts.map +1 -0
  194. package/dist/plugins/request-dep/origin.d.ts +61 -0
  195. package/dist/plugins/request-dep/origin.d.ts.map +1 -0
  196. package/dist/plugins/routing.d.ts.map +1 -1
  197. package/dist/plugins/shims.d.ts.map +1 -1
  198. package/dist/plugins/static-build.d.ts +160 -8
  199. package/dist/plugins/static-build.d.ts.map +1 -1
  200. package/dist/routing/codegen-shared.d.ts +3 -44
  201. package/dist/routing/codegen-shared.d.ts.map +1 -1
  202. package/dist/routing/codegen-types.d.ts +28 -31
  203. package/dist/routing/codegen-types.d.ts.map +1 -1
  204. package/dist/routing/codegen-write.d.ts +51 -0
  205. package/dist/routing/codegen-write.d.ts.map +1 -0
  206. package/dist/routing/codegen.d.ts.map +1 -1
  207. package/dist/routing/collision-probe.d.ts +104 -0
  208. package/dist/routing/collision-probe.d.ts.map +1 -0
  209. package/dist/routing/collision-spaces.d.ts +26 -0
  210. package/dist/routing/collision-spaces.d.ts.map +1 -0
  211. package/dist/routing/convention-lint.d.ts +18 -4
  212. package/dist/routing/convention-lint.d.ts.map +1 -1
  213. package/dist/routing/export-detect.d.ts +16 -0
  214. package/dist/routing/export-detect.d.ts.map +1 -1
  215. package/dist/routing/index.js +4 -3
  216. package/dist/routing/interception.d.ts +235 -6
  217. package/dist/routing/interception.d.ts.map +1 -1
  218. package/dist/routing/link-codegen.d.ts +19 -4
  219. package/dist/routing/link-codegen.d.ts.map +1 -1
  220. package/dist/routing/manifest-codegen.d.ts +1 -7
  221. package/dist/routing/manifest-codegen.d.ts.map +1 -1
  222. package/dist/routing/scanner.d.ts.map +1 -1
  223. package/dist/routing/segment-classify.d.ts +33 -0
  224. package/dist/routing/segment-classify.d.ts.map +1 -1
  225. package/dist/routing/segment-keys.d.ts +95 -0
  226. package/dist/routing/segment-keys.d.ts.map +1 -0
  227. package/dist/routing/slot-placement.d.ts +48 -0
  228. package/dist/routing/slot-placement.d.ts.map +1 -0
  229. package/dist/routing/types.d.ts +0 -6
  230. package/dist/routing/types.d.ts.map +1 -1
  231. package/dist/routing/walkers.d.ts +6 -0
  232. package/dist/routing/walkers.d.ts.map +1 -1
  233. package/dist/schema-bridge.d.ts +60 -9
  234. package/dist/schema-bridge.d.ts.map +1 -1
  235. package/dist/search-params/define.d.ts +62 -14
  236. package/dist/search-params/define.d.ts.map +1 -1
  237. package/dist/search-params/index.d.ts +0 -1
  238. package/dist/search-params/index.d.ts.map +1 -1
  239. package/dist/search-params/index.js +221 -10
  240. package/dist/search-params/index.js.map +1 -1
  241. package/dist/search-params/parse-total.d.ts +70 -0
  242. package/dist/search-params/parse-total.d.ts.map +1 -0
  243. package/dist/search-params/wrappers.d.ts +26 -3
  244. package/dist/search-params/wrappers.d.ts.map +1 -1
  245. package/dist/server/access-gate.d.ts +19 -8
  246. package/dist/server/access-gate.d.ts.map +1 -1
  247. package/dist/server/action-handler.d.ts.map +1 -1
  248. package/dist/server/actions.d.ts +6 -3
  249. package/dist/server/actions.d.ts.map +1 -1
  250. package/dist/server/als-registry.d.ts +18 -1
  251. package/dist/server/als-registry.d.ts.map +1 -1
  252. package/dist/server/build-manifest.d.ts +13 -1
  253. package/dist/server/build-manifest.d.ts.map +1 -1
  254. package/dist/server/chain-url-parts.d.ts +82 -0
  255. package/dist/server/chain-url-parts.d.ts.map +1 -0
  256. package/dist/server/children-interception.d.ts +49 -0
  257. package/dist/server/children-interception.d.ts.map +1 -0
  258. package/dist/server/compress.d.ts.map +1 -1
  259. package/dist/server/default-status-page.d.ts +45 -0
  260. package/dist/server/default-status-page.d.ts.map +1 -0
  261. package/dist/server/deny-boundary.d.ts +148 -15
  262. package/dist/server/deny-boundary.d.ts.map +1 -1
  263. package/dist/server/deny-renderer.d.ts +15 -4
  264. package/dist/server/deny-renderer.d.ts.map +1 -1
  265. package/dist/server/error-boundary-wrapper.d.ts +85 -15
  266. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  267. package/dist/server/head-response.d.ts +35 -0
  268. package/dist/server/head-response.d.ts.map +1 -0
  269. package/dist/server/index.d.ts +0 -1
  270. package/dist/server/index.d.ts.map +1 -1
  271. package/dist/server/index.js +3 -2
  272. package/dist/server/index.js.map +1 -1
  273. package/dist/server/internal.d.ts +3 -1
  274. package/dist/server/internal.d.ts.map +1 -1
  275. package/dist/server/internal.js +712 -418
  276. package/dist/server/internal.js.map +1 -1
  277. package/dist/server/metadata-collector.d.ts +52 -0
  278. package/dist/server/metadata-collector.d.ts.map +1 -0
  279. package/dist/server/param-coercion.d.ts +22 -6
  280. package/dist/server/param-coercion.d.ts.map +1 -1
  281. package/dist/server/pipeline-helpers.d.ts +0 -18
  282. package/dist/server/pipeline-helpers.d.ts.map +1 -1
  283. package/dist/server/pipeline-interception.d.ts +59 -9
  284. package/dist/server/pipeline-interception.d.ts.map +1 -1
  285. package/dist/server/pipeline-outcome.d.ts.map +1 -1
  286. package/dist/server/pipeline-phases.d.ts.map +1 -1
  287. package/dist/server/pipeline.d.ts +11 -0
  288. package/dist/server/pipeline.d.ts.map +1 -1
  289. package/dist/server/primitives.d.ts +23 -0
  290. package/dist/server/primitives.d.ts.map +1 -1
  291. package/dist/server/publish-params.d.ts +33 -0
  292. package/dist/server/publish-params.d.ts.map +1 -0
  293. package/dist/server/request-context.d.ts +48 -0
  294. package/dist/server/request-context.d.ts.map +1 -1
  295. package/dist/server/route-element-builder.d.ts +22 -3
  296. package/dist/server/route-element-builder.d.ts.map +1 -1
  297. package/dist/server/route-handler.d.ts.map +1 -1
  298. package/dist/server/route-matcher.d.ts +13 -0
  299. package/dist/server/route-matcher.d.ts.map +1 -1
  300. package/dist/server/rsc-cache-key-guard.d.ts +78 -0
  301. package/dist/server/rsc-cache-key-guard.d.ts.map +1 -0
  302. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  303. package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
  304. package/dist/server/rsc-entry/error-renderer.d.ts +15 -3
  305. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  306. package/dist/server/rsc-entry/helpers.d.ts +2 -17
  307. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  308. package/dist/server/rsc-entry/index.d.ts +0 -1
  309. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  310. package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
  311. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
  312. package/dist/server/rsc-entry/rsc-payload.d.ts +1 -2
  313. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  314. package/dist/server/rsc-entry/rsc-stream.d.ts +15 -2
  315. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  316. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  317. package/dist/server/skippable-prefix.d.ts +23 -0
  318. package/dist/server/skippable-prefix.d.ts.map +1 -0
  319. package/dist/server/slot-interception.d.ts +80 -0
  320. package/dist/server/slot-interception.d.ts.map +1 -0
  321. package/dist/server/slot-resolver.d.ts +70 -8
  322. package/dist/server/slot-resolver.d.ts.map +1 -1
  323. package/dist/server/ssr-bridge-types.d.ts +17 -0
  324. package/dist/server/ssr-bridge-types.d.ts.map +1 -1
  325. package/dist/server/ssr-entry.d.ts +0 -1
  326. package/dist/server/ssr-entry.d.ts.map +1 -1
  327. package/dist/server/ssr-wrappers.d.ts +24 -13
  328. package/dist/server/ssr-wrappers.d.ts.map +1 -1
  329. package/dist/server/state-tree-diff.d.ts +6 -27
  330. package/dist/server/state-tree-diff.d.ts.map +1 -1
  331. package/dist/server/static-generator.d.ts +6 -0
  332. package/dist/server/static-generator.d.ts.map +1 -1
  333. package/dist/server/static-not-found.d.ts +52 -0
  334. package/dist/server/static-not-found.d.ts.map +1 -0
  335. package/dist/server/status-code-resolver.d.ts +8 -1
  336. package/dist/server/status-code-resolver.d.ts.map +1 -1
  337. package/dist/server/tree-builder.d.ts +28 -36
  338. package/dist/server/tree-builder.d.ts.map +1 -1
  339. package/dist/server/types.d.ts +12 -7
  340. package/dist/server/types.d.ts.map +1 -1
  341. package/dist/server/utils/element-type.d.ts +40 -0
  342. package/dist/server/utils/element-type.d.ts.map +1 -0
  343. package/dist/shared/als-slots.d.ts +41 -0
  344. package/dist/shared/als-slots.d.ts.map +1 -0
  345. package/dist/shared/base-path.d.ts +56 -0
  346. package/dist/shared/base-path.d.ts.map +1 -0
  347. package/dist/shared/param-value.d.ts +80 -0
  348. package/dist/shared/param-value.d.ts.map +1 -0
  349. package/dist/shared/payload-root.d.ts +108 -0
  350. package/dist/shared/payload-root.d.ts.map +1 -0
  351. package/dist/shared/rsc-cache-key.d.ts +163 -0
  352. package/dist/shared/rsc-cache-key.d.ts.map +1 -0
  353. package/dist/shared/rsc-error-envelope.d.ts +25 -0
  354. package/dist/shared/rsc-error-envelope.d.ts.map +1 -0
  355. package/dist/shared/rsc-manifest.d.ts +28 -0
  356. package/dist/shared/rsc-manifest.d.ts.map +1 -0
  357. package/dist/shared/rsc-media-type.d.ts +40 -0
  358. package/dist/shared/rsc-media-type.d.ts.map +1 -0
  359. package/dist/shared/rsc-payload-path.d.ts +42 -0
  360. package/dist/shared/rsc-payload-path.d.ts.map +1 -0
  361. package/dist/shared/segment-info.d.ts +59 -0
  362. package/dist/shared/segment-info.d.ts.map +1 -0
  363. package/dist/shared/slot-params.d.ts +51 -0
  364. package/dist/shared/slot-params.d.ts.map +1 -0
  365. package/dist/shared/static-platform-files.d.ts +71 -0
  366. package/dist/shared/static-platform-files.d.ts.map +1 -0
  367. package/docs/api/30-api-server.mdx +1 -1
  368. package/docs/api/31-api-client.mdx +4 -2
  369. package/docs/api/33-api-search-params.mdx +38 -16
  370. package/docs/api/35-api-typescript.mdx +3 -3
  371. package/docs/api/36-cli.mdx +34 -7
  372. package/docs/learn/00-introduction.mdx +1 -1
  373. package/docs/learn/02-pages-and-layouts.mdx +2 -2
  374. package/docs/learn/05-typed-params.mdx +8 -8
  375. package/docs/learn/07-typed-routes.mdx +12 -7
  376. package/docs/learn/11-error-handling.mdx +18 -0
  377. package/docs/learn/12-client-navigation.mdx +2 -2
  378. package/docs/learn/14-deploying.mdx +23 -0
  379. package/docs/more/01-advanced-routing.mdx +173 -3
  380. package/docs/more/03-coming-from-nextjs.mdx +2 -2
  381. package/docs/more/04-metadata-and-fonts.mdx +1 -1
  382. package/docs/more/50-ai-agent-instructions.mdx +6 -4
  383. package/package.json +9 -6
  384. package/src/adapters/build-output-helper.ts +116 -3
  385. package/src/adapters/cloudflare.ts +90 -12
  386. package/src/adapters/compress-module.ts +79 -1
  387. package/src/adapters/fs-identity.ts +156 -0
  388. package/src/adapters/nitro.ts +6 -6
  389. package/src/adapters/shared.ts +196 -21
  390. package/src/adapters/types.ts +13 -1
  391. package/src/cache/fast-hash.ts +5 -0
  392. package/src/cli-check.ts +458 -0
  393. package/src/cli.ts +59 -24
  394. package/src/client/browser-entry/action-dispatch.ts +11 -5
  395. package/src/client/browser-entry/hydrate.ts +40 -29
  396. package/src/client/browser-entry/index.ts +15 -6
  397. package/src/client/browser-entry/post-hydration.ts +10 -9
  398. package/src/client/browser-entry/router-init.ts +104 -48
  399. package/src/client/browser-entry/rsc-stream.ts +11 -2
  400. package/src/client/error-boundary.tsx +85 -16
  401. package/src/client/history.ts +13 -6
  402. package/src/client/index.ts +14 -3
  403. package/src/client/internal.ts +4 -3
  404. package/src/client/link.tsx +120 -72
  405. package/src/client/navigation-api.ts +3 -3
  406. package/src/client/navigation-commit.ts +197 -0
  407. package/src/client/navigation-context.ts +40 -67
  408. package/src/client/navigation-root.tsx +326 -101
  409. package/src/client/params-context.ts +192 -0
  410. package/src/client/router-effects.ts +231 -0
  411. package/src/client/router-lifecycle.ts +288 -0
  412. package/src/client/router-pipeline.ts +393 -0
  413. package/src/client/router-ref.ts +1 -1
  414. package/src/client/router-skew.ts +30 -0
  415. package/src/client/router-types.ts +230 -0
  416. package/src/client/router.ts +243 -707
  417. package/src/client/rsc-fetch.ts +183 -106
  418. package/src/client/segment-cache.ts +129 -44
  419. package/src/client/ssr-data.ts +6 -0
  420. package/src/client/stale-client.ts +191 -0
  421. package/src/client/state.ts +14 -1
  422. package/src/client/top-loader.tsx +2 -1
  423. package/src/client/unload-guard.ts +34 -2
  424. package/src/client/use-cookie.ts +9 -2
  425. package/src/client/use-query-states.ts +102 -39
  426. package/src/client/use-router.ts +1 -1
  427. package/src/client/use-segment-params.ts +41 -18
  428. package/src/cookies/define-cookie.ts +6 -1
  429. package/src/index.ts +25 -4
  430. package/src/plugin-context.ts +58 -0
  431. package/src/plugins/adapter-build.ts +4 -0
  432. package/src/plugins/build-manifest.ts +34 -13
  433. package/src/plugins/entries.ts +4 -0
  434. package/src/plugins/fonts.ts +11 -8
  435. package/src/plugins/request-dep/analysis.ts +447 -0
  436. package/src/plugins/request-dep/index.ts +376 -0
  437. package/src/plugins/request-dep/origin.ts +310 -0
  438. package/src/plugins/routing.ts +97 -102
  439. package/src/plugins/shims.ts +0 -1
  440. package/src/plugins/static-build.ts +391 -95
  441. package/src/routing/codegen-shared.ts +3 -79
  442. package/src/routing/codegen-types.ts +28 -31
  443. package/src/routing/codegen-write.ts +139 -0
  444. package/src/routing/codegen.ts +86 -172
  445. package/src/routing/collision-probe.ts +438 -0
  446. package/src/routing/collision-spaces.ts +281 -0
  447. package/src/routing/convention-lint.ts +139 -40
  448. package/src/routing/export-detect.ts +151 -7
  449. package/src/routing/interception.ts +896 -50
  450. package/src/routing/link-codegen.ts +32 -65
  451. package/src/routing/manifest-codegen.ts +6 -62
  452. package/src/routing/scanner.ts +117 -92
  453. package/src/routing/segment-classify.ts +57 -0
  454. package/src/routing/segment-keys.ts +146 -0
  455. package/src/routing/slot-placement.ts +97 -0
  456. package/src/routing/types.ts +0 -6
  457. package/src/routing/walkers.ts +8 -0
  458. package/src/schema-bridge.ts +180 -58
  459. package/src/search-params/define.ts +108 -66
  460. package/src/search-params/index.ts +0 -1
  461. package/src/search-params/parse-total.ts +78 -0
  462. package/src/search-params/wrappers.ts +60 -11
  463. package/src/server/access-gate.tsx +60 -40
  464. package/src/server/action-handler.ts +4 -5
  465. package/src/server/actions.ts +6 -3
  466. package/src/server/als-registry.ts +18 -1
  467. package/src/server/build-manifest.ts +14 -1
  468. package/src/server/chain-url-parts.ts +163 -0
  469. package/src/server/children-interception.ts +115 -0
  470. package/src/server/compress.ts +9 -1
  471. package/src/server/default-status-page.ts +127 -0
  472. package/src/server/deny-boundary.ts +269 -41
  473. package/src/server/deny-renderer.ts +111 -39
  474. package/src/server/error-boundary-wrapper.ts +166 -79
  475. package/src/server/head-response.ts +54 -0
  476. package/src/server/index.ts +1 -3
  477. package/src/server/internal.ts +2 -2
  478. package/src/server/metadata-collector.ts +115 -0
  479. package/src/server/param-coercion.ts +51 -69
  480. package/src/server/pipeline-helpers.ts +2 -47
  481. package/src/server/pipeline-interception.ts +81 -32
  482. package/src/server/pipeline-outcome.ts +4 -5
  483. package/src/server/pipeline-phases.ts +77 -25
  484. package/src/server/pipeline.ts +57 -10
  485. package/src/server/prebuilt-runtime.ts +4 -4
  486. package/src/server/primitives.ts +25 -0
  487. package/src/server/publish-params.ts +42 -0
  488. package/src/server/request-context.ts +97 -18
  489. package/src/server/route-element-builder.ts +241 -253
  490. package/src/server/route-handler.ts +8 -8
  491. package/src/server/route-matcher.ts +21 -9
  492. package/src/server/rsc-cache-key-guard.ts +164 -0
  493. package/src/server/rsc-entry/api-handler.ts +6 -8
  494. package/src/server/rsc-entry/deny-fallback.ts +3 -2
  495. package/src/server/rsc-entry/error-renderer.ts +94 -35
  496. package/src/server/rsc-entry/helpers.ts +33 -28
  497. package/src/server/rsc-entry/index.ts +36 -33
  498. package/src/server/rsc-entry/render-route.ts +18 -10
  499. package/src/server/rsc-entry/revalidate-renderer.ts +3 -2
  500. package/src/server/rsc-entry/rsc-payload.ts +113 -40
  501. package/src/server/rsc-entry/rsc-stream.ts +29 -5
  502. package/src/server/rsc-entry/ssr-renderer.ts +38 -22
  503. package/src/server/skippable-prefix.ts +92 -0
  504. package/src/server/slot-interception.ts +168 -0
  505. package/src/server/slot-resolver.ts +263 -158
  506. package/src/server/ssr-bridge-types.ts +18 -0
  507. package/src/server/ssr-entry.ts +20 -10
  508. package/src/server/ssr-wrappers.tsx +33 -32
  509. package/src/server/state-tree-diff.ts +14 -55
  510. package/src/server/static-generator.ts +68 -29
  511. package/src/server/static-not-found.ts +134 -0
  512. package/src/server/status-code-resolver.ts +28 -11
  513. package/src/server/tree-builder.ts +35 -218
  514. package/src/server/types.ts +12 -7
  515. package/src/server/utils/element-type.ts +72 -0
  516. package/src/shared/als-slots.ts +72 -0
  517. package/src/shared/base-path.ts +80 -0
  518. package/src/shared/param-value.ts +244 -0
  519. package/src/shared/payload-root.ts +151 -0
  520. package/src/shared/rsc-cache-key.ts +269 -0
  521. package/src/shared/rsc-error-envelope.ts +31 -0
  522. package/src/shared/rsc-manifest.ts +29 -0
  523. package/src/shared/rsc-media-type.ts +43 -0
  524. package/src/shared/rsc-payload-path.ts +45 -0
  525. package/src/shared/segment-info.ts +60 -0
  526. package/src/shared/slot-params.ts +111 -0
  527. package/src/shared/static-platform-files.ts +75 -0
  528. package/dist/_chunks/build-output-helper-DOGYFb_X.js +0 -196
  529. package/dist/_chunks/build-output-helper-DOGYFb_X.js.map +0 -1
  530. package/dist/_chunks/cache-api-B-lhk9p4.js.map +0 -1
  531. package/dist/_chunks/canonicalize-DQHyFClh.js.map +0 -1
  532. package/dist/_chunks/cli-schema-sync-BTWEKJXo.js +0 -668
  533. package/dist/_chunks/cli-schema-sync-BTWEKJXo.js.map +0 -1
  534. package/dist/_chunks/define-COtkxMRT.js +0 -191
  535. package/dist/_chunks/define-COtkxMRT.js.map +0 -1
  536. package/dist/_chunks/define-c4au4I9R.js +0 -82
  537. package/dist/_chunks/define-c4au4I9R.js.map +0 -1
  538. package/dist/_chunks/fast-hash-D6hIVt1Y.js.map +0 -1
  539. package/dist/_chunks/logger-AWfuX-KJ.js.map +0 -1
  540. package/dist/_chunks/navigation-root-bUDZLw74.js +0 -124
  541. package/dist/_chunks/navigation-root-bUDZLw74.js.map +0 -1
  542. package/dist/_chunks/plugin-context---kTF5v8.js.map +0 -1
  543. package/dist/_chunks/registry-DbJPKoBp.js +0 -20
  544. package/dist/_chunks/registry-DbJPKoBp.js.map +0 -1
  545. package/dist/_chunks/router-ref-CtmF-aPv.js.map +0 -1
  546. package/dist/_chunks/schema-bridge-DT_Tn0Xf.js +0 -119
  547. package/dist/_chunks/schema-bridge-DT_Tn0Xf.js.map +0 -1
  548. package/dist/_chunks/segment-classify-Byy425ng.js.map +0 -1
  549. package/dist/_chunks/segment-context-ZDnXDkbz.js +0 -34
  550. package/dist/_chunks/segment-context-ZDnXDkbz.js.map +0 -1
  551. package/dist/_chunks/ssr-data-BOWsq18U.js.map +0 -1
  552. package/dist/_chunks/use-query-states-DFvWd-EA.js.map +0 -1
  553. package/dist/_chunks/use-segment-params-D1CzlgBo.js +0 -151
  554. package/dist/_chunks/use-segment-params-D1CzlgBo.js.map +0 -1
  555. package/dist/_chunks/walkers-_6zKFlch.js +0 -1002
  556. package/dist/_chunks/walkers-_6zKFlch.js.map +0 -1
  557. package/dist/client/error-boundary.js.map +0 -1
  558. package/dist/plugins/request-dep.d.ts +0 -32
  559. package/dist/plugins/request-dep.d.ts.map +0 -1
  560. package/dist/search-params/registry.d.ts +0 -20
  561. package/dist/search-params/registry.d.ts.map +0 -1
  562. package/dist/segment-params/define.d.ts +0 -89
  563. package/dist/segment-params/define.d.ts.map +0 -1
  564. package/dist/segment-params/index.d.ts +0 -3
  565. package/dist/segment-params/index.d.ts.map +0 -1
  566. package/dist/segment-params/index.js +0 -2
  567. package/src/plugins/request-dep.ts +0 -499
  568. package/src/search-params/registry.ts +0 -31
  569. package/src/segment-params/define.ts +0 -249
  570. package/src/segment-params/index.ts +0 -9
@@ -11,14 +11,41 @@
11
11
  * See design/19-client-navigation.md §"RSC Payload Handling"
12
12
  */
13
13
 
14
- import type { SegmentInfo } from './segment-cache';
15
- import type { RouterDeps } from './router';
14
+ import {
15
+ rscCacheKey,
16
+ recordLookup,
17
+ randomRscCacheKey,
18
+ RSC_KEY_PARAM,
19
+ } from '../shared/rsc-cache-key.js';
20
+ import type { RscManifest, RscManifestEntry } from '../shared/rsc-manifest.js';
21
+ import {
22
+ splitPayloadRoot,
23
+ readPublishedParams,
24
+ type PublishedParams,
25
+ } from '../shared/payload-root.js';
26
+ import { normalizeBasePath, stripBasePath, withBasePath } from '../shared/base-path.js';
27
+ import { rscPayloadPath } from '../shared/rsc-payload-path.js';
28
+ import type { SegmentInfo, StateTree } from '../shared/segment-info.js';
29
+ import { TIMBER_ERROR_HEADER } from '../shared/rsc-error-envelope.js';
30
+ import { RSC_CONTENT_TYPE } from '../shared/rsc-media-type.js';
31
+ import type { RouterDeps } from './router-types.js';
16
32
 
17
33
  // ─── Types ───────────────────────────────────────────────────────
18
34
 
19
35
  /** Result of fetching an RSC payload — includes segment metadata. */
20
36
  export interface FetchResult {
37
+ /** The renderable tree, split off the payload root. */
21
38
  payload: unknown;
39
+ /**
40
+ * The params the same payload published beside that tree.
41
+ *
42
+ * Not a separate channel: both fields come out of one `splitPayloadRoot`
43
+ * call on one decoded root, so a response cannot deliver a tree and another
44
+ * route's params. They used to arrive on their own header, which is how a
45
+ * navigation could render one route and publish another's (TIM-1285,
46
+ * TIM-1294).
47
+ */
48
+ params: PublishedParams | Promise<PublishedParams>;
22
49
  /**
23
50
  * Promise that settles when the RSC decode completes or fails.
24
51
  * The payload thenable is NOT awaited before returning (for streaming),
@@ -29,44 +56,55 @@ export interface FetchResult {
29
56
  decodePromise: Promise<void> | null;
30
57
  /** Segment metadata from X-Timber-Segments header for populating the segment cache. */
31
58
  segmentInfo: SegmentInfo[] | null;
32
- /** Route params from X-Timber-Params header for populating useSegmentParams(). */
33
- params: Record<string, string | string[]> | null;
34
59
  /** Segment paths that were skipped by the server (for client-side merging). */
35
60
  skippedSegments: string[] | null;
61
+ /**
62
+ * HTTP status of the navigation response.
63
+ *
64
+ * Read at the commit site to decide whether the tree this payload produced
65
+ * is one worth caching. A deny page replaced a subtree, so `segmentInfo`
66
+ * describes more than actually mounted — but it cannot simply be emptied,
67
+ * because the merge point is chosen out of it. See TIM-1356.
68
+ */
69
+ status: number;
36
70
  }
37
71
 
38
- // ─── Constants ───────────────────────────────────────────────────
39
-
40
- export const RSC_CONTENT_TYPE = 'text/x-component';
41
-
42
72
  // ─── URL Helpers ─────────────────────────────────────────────────
43
73
 
44
74
  /**
45
- * Generate a short random cache-busting ID (5 chars, a-z0-9).
46
- * Matches the format Next.js uses for _rsc params.
47
- */
48
- function generateCacheBustId(): string {
49
- const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
50
- let id = '';
51
- for (let i = 0; i < 5; i++) {
52
- id += chars[(Math.random() * 36) | 0];
53
- }
54
- return id;
55
- }
56
-
57
- /**
58
- * Append a `_rsc=<id>` query parameter to the URL.
59
- * Follows Next.js's pattern — prevents CDN/browser from serving cached HTML
60
- * for RSC navigation requests and signals that this is an RSC fetch.
75
+ * Append a `_rsc=<key>` query parameter to the URL (TIM-1268).
76
+ *
77
+ * The key is a deterministic hash of the RSC request headers, so identical
78
+ * requests share a URL and the payload becomes cacheable. It also keeps the
79
+ * document and the payload on different URLs, so a shared cache cannot
80
+ * return HTML for an RSC request (or vice versa) even where `Vary` is
81
+ * opt-in configuration rather than default behaviour — Cloudflare and
82
+ * CloudFront both. See GHSA-wfc6-r584-vfw7, design/13-security.md.
83
+ *
84
+ * The origin recomputes this key from the received headers and refuses to
85
+ * let a mismatched response be shared-cached, so a caller cannot claim
86
+ * another client's key while sending its own headers.
87
+ *
88
+ * Falls back to a random value when no key can be derived — `crypto.subtle`
89
+ * is absent in non-secure browsing contexts (plain `http://` on a LAN
90
+ * address). Dropping the parameter instead would put the payload back on
91
+ * the document URL, where a query-keyed cache that ignores `Vary` could
92
+ * store a Flight response under `/about` and serve it to an HTML
93
+ * navigation. The random parameter this feature replaced did separate those
94
+ * representations, and the fallback must not be worse than what it
95
+ * replaced. The origin cannot verify a random key, so it refuses to
96
+ * share-cache the response — which is exactly the old behaviour, where a
97
+ * unique URL was never a cache hit anyway.
61
98
  *
62
99
  * Strips any #fragment before appending — fragments are client-only and
63
100
  * fetch() discards them, so _rsc would land inside the hash and be lost.
64
101
  */
65
- function appendRscParam(url: string): string {
102
+ async function appendRscParam(url: string, headers: Record<string, string>): Promise<string> {
66
103
  const hashIndex = url.indexOf('#');
67
104
  const urlWithoutHash = hashIndex === -1 ? url : url.slice(0, hashIndex);
105
+ const key = (await rscCacheKey(recordLookup(headers))) ?? randomRscCacheKey();
68
106
  const separator = urlWithoutHash.includes('?') ? '&' : '?';
69
- return `${urlWithoutHash}${separator}_rsc=${generateCacheBustId()}`;
107
+ return `${urlWithoutHash}${separator}${RSC_KEY_PARAM}=${key}`;
70
108
  }
71
109
 
72
110
  // ─── Deployment ID ───────────────────────────────────────────────
@@ -88,6 +126,30 @@ export function getClientDeploymentId(): string | null {
88
126
  return clientDeploymentId;
89
127
  }
90
128
 
129
+ // ─── Base Path ───────────────────────────────────────────────────
130
+
131
+ /**
132
+ * The deployment base path (Vite's resolved `base`), normalized.
133
+ * Set at bootstrap from `virtual:timber-config`; `'/'` unless the app is
134
+ * deployed under a sub-path. See design/11-platform.md, TIM-1261.
135
+ *
136
+ * **The base is applied in exactly one place: at fetch time**
137
+ * (`toStaticRscUrl`). The static build writes the RSC manifest with
138
+ * root-relative keys *and* root-relative URLs, so the generated site stays
139
+ * relocatable and there is no second copy of the base to drift from this one.
140
+ */
141
+ let basePath = '/';
142
+
143
+ /** Set the deployment base path. Called once at bootstrap. */
144
+ export function setBasePath(base: string | undefined): void {
145
+ basePath = normalizeBasePath(base);
146
+ }
147
+
148
+ /** Get the normalized deployment base path. @internal Exported for testing. */
149
+ export function getBasePath(): string {
150
+ return basePath;
151
+ }
152
+
91
153
  // ─── Static Mode ────────────────────────────────────────────────
92
154
 
93
155
  /**
@@ -107,20 +169,10 @@ export function isStaticMode(): boolean {
107
169
  }
108
170
 
109
171
  /**
110
- * RSC manifest entry: hashed URL with optional inlined route params.
111
- * Params are embedded at build time (TIM-1255) so no sidecar fetch needed.
112
- */
113
- interface RscManifestEntry {
114
- url: string;
115
- params?: Record<string, string | string[]>;
116
- }
117
-
118
- type RscManifest = Record<string, RscManifestEntry>;
119
-
120
- /**
121
- * RSC manifest mapping unhashed → hashed URLs + params. Populated from
122
- * `window.__TIMBER_RSC_MANIFEST__` (injected into HTML during
123
- * static generation). See TIM-1254, TIM-1255.
172
+ * RSC manifest mapping unhashed → content-hashed `.rsc` URLs. Populated from
173
+ * `window.__TIMBER_RSC_MANIFEST__` (injected into HTML during static
174
+ * generation). Shape shared with the static build that writes it — see
175
+ * `shared/rsc-manifest.ts`. See TIM-1254.
124
176
  */
125
177
  let rscManifest: RscManifest | null = null;
126
178
 
@@ -137,24 +189,45 @@ export function setRscManifest(manifest: RscManifest | null): void {
137
189
  rscManifest = manifest;
138
190
  }
139
191
 
192
+ /** A resolved static payload target: the URL to fetch, and how it was resolved. */
193
+ interface StaticRscTarget {
194
+ /** Fetchable URL — base-prefixed. */
195
+ url: string;
196
+ /**
197
+ * True when the RSC manifest supplied a content-hashed filename. The hash
198
+ * guarantees freshness, so no `_rsc` cache key is appended (TIM-1254).
199
+ */
200
+ hashed: boolean;
201
+ }
202
+
140
203
  /**
141
- * Convert a route URL to the corresponding _rsc/*.rsc file path.
142
- * Mirrors the naming in plugins/static-build.ts staticOutputPath.
204
+ * Resolve a route URL to the `_rsc/*.rsc` file to fetch. The naming rule is
205
+ * `shared/rsc-payload-path.ts`, shared with the build that writes the files.
143
206
  *
144
207
  * When an RSC manifest is available (hashed filenames from TIM-1254),
145
208
  * the manifest is consulted to resolve to the hashed path.
146
209
  *
147
210
  * / → /_rsc/index.rsc (or /_rsc/index-B7YxEKdN.rsc with manifest)
148
- * /about → /_rsc/about.rsc (or /_rsc/about-C8ZzFLfO.rsc with manifest)
149
- * /blog/hello → /_rsc/blog/hello.rsc
211
+ * /about → /_rsc/about/index.rsc (or /_rsc/about/index-C8ZzFLfO.rsc)
212
+ * /blog/hello → /_rsc/blog/hello/index.rsc
213
+ *
214
+ * The manifest is written and read in route space (no base prefix), so the
215
+ * base is applied here — once, on the way out. See client/base-path.ts.
150
216
  */
151
- function toStaticRscUrl(url: string): string {
217
+ function toStaticRscUrl(url: string): StaticRscTarget {
152
218
  const unhashed = toUnhashedRscUrl(url);
153
- return manifestLookup(unhashed) ?? unhashed;
219
+ const hashedUrl = manifestLookup(unhashed);
220
+ return { url: withBasePath(basePath, hashedUrl ?? unhashed), hashed: hashedUrl !== null };
154
221
  }
155
222
 
156
223
  /**
157
- * Compute the unhashed _rsc/*.rsc URL for a route path.
224
+ * Compute the unhashed `_rsc/*.rsc` path for a route URL.
225
+ *
226
+ * Returns a **route-space** path: the deployment base is stripped from the
227
+ * incoming URL and is NOT re-applied, because this value doubles as the RSC
228
+ * manifest key, and the manifest is base-less. `toStaticRscUrl` applies the
229
+ * base to whatever is actually fetched.
230
+ *
158
231
  * @internal Exported for testing.
159
232
  */
160
233
  export function toUnhashedRscUrl(url: string): string {
@@ -163,13 +236,12 @@ export function toUnhashedRscUrl(url: string): string {
163
236
  const hashEnd = hashIndex === -1 ? url.length : hashIndex;
164
237
  const queryEnd = queryIndex === -1 ? url.length : queryIndex;
165
238
  const end = Math.min(hashEnd, queryEnd);
166
- let pathname = url.slice(0, end);
239
+ let pathname = stripBasePath(basePath, url.slice(0, end));
167
240
  // Strip trailing slash (unless root) to match static build output naming
168
241
  if (pathname.length > 1 && pathname.endsWith('/')) {
169
242
  pathname = pathname.slice(0, -1);
170
243
  }
171
- const rscPath = pathname === '/' ? '/index' : pathname;
172
- return `/_rsc${rscPath}.rsc`;
244
+ return rscPayloadPath(pathname);
173
245
  }
174
246
 
175
247
  /**
@@ -196,13 +268,11 @@ function manifestLookup(key: string): string | null {
196
268
  return manifestEntry(key)?.url ?? null;
197
269
  }
198
270
 
199
- /**
200
- * Look up inlined route params for a route from the manifest. TIM-1255.
201
- */
202
- function manifestParams(url: string): Record<string, string | string[]> | null {
203
- const key = toUnhashedRscUrl(url);
204
- return manifestEntry(key)?.params ?? null;
205
- }
271
+ // The manifest used to inline each route's params, because a generated
272
+ // `.rsc` file carries no response headers and the header channel therefore
273
+ // did not exist on the static path (TIM-1255, TIM-1285). The `.rsc` file now
274
+ // carries them itself — they are props inside the payload — so the static
275
+ // path needs no special case at all.
206
276
 
207
277
  // ─── Reload Signal ───────────────────────────────────────────────
208
278
 
@@ -222,8 +292,19 @@ export function checkReloadSignal(response: Response): boolean {
222
292
 
223
293
  // ─── Header Builder ──────────────────────────────────────────────
224
294
 
295
+ /**
296
+ * Build the headers for an RSC payload request.
297
+ *
298
+ * **Every header added here is hashed into the payload URL** as the `_rsc`
299
+ * cache key (see `rscCacheKey`), and URLs are logged by proxies, CDNs, and
300
+ * origin access logs. So: no credentials, no session identifiers, no
301
+ * user-supplied content. `fnv1aHash` is a cache-key hash, not a KDF — a
302
+ * low-entropy secret would be recoverable from the URL by brute force.
303
+ * Authentication already travels on cookies, which are not part of this
304
+ * object and never enter the key.
305
+ */
225
306
  export function buildRscHeaders(
226
- stateTree: { segments: string[] } | undefined,
307
+ stateTree: StateTree | undefined,
227
308
  currentUrl?: string
228
309
  ): Record<string, string> {
229
310
  const headers: Record<string, string> = {
@@ -301,23 +382,6 @@ export function extractSkippedSegments(response: Response): string[] | null {
301
382
  }
302
383
  }
303
384
 
304
- /**
305
- * Extract route params from the X-Timber-Params response header.
306
- * Returns null if the header is missing or malformed.
307
- *
308
- * Used to populate useSegmentParams() after client-side navigation.
309
- */
310
- export function extractParams(response: Response): Record<string, string | string[]> | null {
311
- const header = response.headers.get('X-Timber-Params');
312
- if (!header) return null;
313
- try {
314
- return JSON.parse(header);
315
- } catch {
316
- warnMalformedHeader('X-Timber-Params', header);
317
- return null;
318
- }
319
- }
320
-
321
385
  // ─── Redirect Error ──────────────────────────────────────────────
322
386
 
323
387
  /**
@@ -388,9 +452,10 @@ export class NonRscResponse extends Error {
388
452
  * a `done` promise that resolves when the last chunk is read (or
389
453
  * rejects if the stream errors).
390
454
  *
391
- * Used to keep React transitions open for the full RSC stream
392
- * duration — createFromFetch's thenable resolves on shell arrival,
393
- * but we need stream completion for useOptimistic pending state.
455
+ * createFromFetch's thenable resolves on shell arrival, but callers need to
456
+ * know when the stream is fully decoded: that is what `navigateTransition`'s
457
+ * returned promise means, and what the router's pending store, the Navigation
458
+ * API deferred and `<Link>`'s `isPending` are all timed against.
394
459
  */
395
460
  function trackStreamCompletion(body: ReadableStream<Uint8Array>): {
396
461
  body: ReadableStream<Uint8Array>;
@@ -445,13 +510,23 @@ export async function fetchRscPayload(
445
510
  // In static mode, fetch the pre-generated _rsc/*.rsc file directly
446
511
  // instead of the route URL with Accept headers. Static hosts ignore
447
512
  // Accept headers, so the route URL would return HTML.
448
- const fetchTarget = staticMode ? toStaticRscUrl(url) : url;
449
- // Skip the cache-bust param when the manifest supplies a content-hashed
513
+ const staticTarget = staticMode ? toStaticRscUrl(url) : null;
514
+ const fetchTarget = staticTarget ? staticTarget.url : url;
515
+ // Static hosts resolve neither partial payloads nor intercepting routes,
516
+ // so neither the state tree nor the source URL is sent — and neither may
517
+ // fragment the cache key of a file that does not vary on them.
518
+ const headers = staticMode
519
+ ? buildRscHeaders(undefined, undefined)
520
+ : buildRscHeaders(stateTree, currentUrl);
521
+ // Skip the cache key when the manifest supplies a content-hashed
450
522
  // URL — the hash itself guarantees freshness, and the param would defeat
451
523
  // the immutable cache headers on /_rsc/* (TIM-1254).
452
- const isHashedFromManifest = staticMode && fetchTarget !== toUnhashedRscUrl(url);
453
- const rscUrl = isHashedFromManifest ? fetchTarget : appendRscParam(fetchTarget);
454
- const headers = buildRscHeaders(staticMode ? undefined : stateTree, currentUrl);
524
+ const rscUrl = staticTarget?.hashed ? fetchTarget : await appendRscParam(fetchTarget, headers);
525
+ // Deriving the cache key is async (SubtleCrypto), so the fetch is no
526
+ // longer issued in the same tick as the call. A navigation superseded
527
+ // during that window would otherwise still hit the network with an
528
+ // already-aborted signal.
529
+ signal?.throwIfAborted();
455
530
  if (deps.decodeRsc) {
456
531
  // Production path: use createFromFetch for streaming RSC decoding.
457
532
  // createFromFetch takes a Promise<Response> and progressively parses
@@ -461,8 +536,8 @@ export async function fetchRscPayload(
461
536
  // consumes the body. Reading headers does NOT consume the body stream.
462
537
  const fetchPromise = deps.fetch(rscUrl, { headers, redirect: 'manual', signal });
463
538
  let segmentInfo: SegmentInfo[] | null = null;
464
- let params: Record<string, string | string[]> | null = null;
465
539
  let skippedSegments: string[] | null = null;
540
+ let status = 200;
466
541
  // Track when the full RSC body stream is consumed (not just shell).
467
542
  // Initialized to resolved for bodyless responses; overwritten when
468
543
  // the response has a body.
@@ -489,7 +564,7 @@ export async function fetchRscPayload(
489
564
  // with a JSON body instead of a broken RSC stream for any RenderError
490
565
  // (4xx or 5xx). Hard-navigate so the server renders the error page as HTML.
491
566
  // See design/10-error-handling.md §"Error Page Rendering for Client Navigation"
492
- if (response.headers.get('X-Timber-Error') === '1') {
567
+ if (response.headers.get(TIMBER_ERROR_HEADER) === '1') {
493
568
  throw new ServerErrorResponse(response.status, url);
494
569
  }
495
570
  // Content-Type guard: reject non-RSC responses before createFromFetch
@@ -517,13 +592,13 @@ export async function fetchRscPayload(
517
592
  // Metadata (<title>/<meta>/<link>) now rides the RSC Flight payload
518
593
  // as React elements — React 19 Float handles them. See TIM-1151.
519
594
  segmentInfo = extractSegmentInfo(response);
520
- params = extractParams(response);
521
595
  skippedSegments = extractSkippedSegments(response);
596
+ status = response.status;
522
597
 
523
598
  // Wrap the body to track full stream consumption. createFromFetch's
524
599
  // thenable resolves when the root model (shell) arrives, but we need
525
- // to know when ALL chunks are read so the React transition stays
526
- // open for the full streaming duration (keeps useOptimistic alive).
600
+ // to know when ALL chunks are read — that is what the navigation
601
+ // promise resolving means, and what keeps the pending store set.
527
602
  if (response.body) {
528
603
  const tracked = trackStreamCompletion(response.body);
529
604
  streamDone = tracked.done;
@@ -535,34 +610,39 @@ export async function fetchRscPayload(
535
610
  }
536
611
  return response;
537
612
  });
538
- // Await headers so segmentInfo/params are populated.
613
+ // Await headers so segmentInfo is populated.
539
614
  await wrappedPromise;
540
- // In static mode, params come from the manifest (inlined at build
541
- // time) since .rsc files have no HTTP headers. TIM-1255.
542
- if (staticMode && !params) {
543
- params = manifestParams(url);
544
- }
545
615
  // Start decoding but do NOT await — return the in-progress thenable.
546
616
  // React can render a Flight thenable directly: it suspends on unresolved
547
617
  // parts and progressively renders as chunks arrive, spreading work across
548
618
  // frames instead of blocking the main thread in one burst.
549
- const payload = deps.decodeRsc(wrappedPromise);
619
+ const root = deps.decodeRsc(wrappedPromise);
620
+ // One split, one root: the tree and the params it was rendered with come
621
+ // apart here and nowhere else, so nothing downstream has to keep them
622
+ // paired by hand.
623
+ const { tree: payload, params } = splitPayloadRoot(root);
550
624
  // Combine stream completion with payload error propagation.
551
- // streamDone keeps the transition open for the full RSC stream
552
- // duration (useOptimistic pending state). payloadError propagates
625
+ // streamDone marks the end of the RSC stream, which is what the
626
+ // navigation promise resolves on. payloadError propagates
553
627
  // decode failures (stale client references, Flight parse errors)
554
628
  // so the router's catch block can trigger recovery (stale reload).
555
629
  const payloadError = new Promise<void>((_, reject) => {
556
- Promise.resolve(payload).then(() => {}, reject);
630
+ Promise.resolve(root).then(() => {}, reject);
557
631
  });
558
632
  payloadError.catch(() => {});
559
633
  const decodePromise = Promise.race([streamDone, payloadError]);
634
+ // Mark handled, like payloadError above. The same rejection reaches the
635
+ // router through `payload`, and a navigation that recovers by hard
636
+ // navigating (version skew, non-RSC response) hangs deliberately and never
637
+ // awaits this one — leaving it to surface as an unhandled rejection.
638
+ decodePromise.catch(() => {});
560
639
  return {
561
640
  payload,
641
+ params,
562
642
  decodePromise,
563
643
  segmentInfo,
564
- params,
565
644
  skippedSegments,
645
+ status,
566
646
  };
567
647
  }
568
648
  // Test/fallback path: return raw text
@@ -575,7 +655,7 @@ export async function fetchRscPayload(
575
655
  }
576
656
  }
577
657
  // Server error guard (same as production path above).
578
- if (response.headers.get('X-Timber-Error') === '1') {
658
+ if (response.headers.get(TIMBER_ERROR_HEADER) === '1') {
579
659
  throw new ServerErrorResponse(response.status, url);
580
660
  }
581
661
  // Content-Type guard (same as production path above). See TIM-1231, TIM-1243, TIM-1247.
@@ -599,16 +679,13 @@ export async function fetchRscPayload(
599
679
  throw new NonRscResponse(url);
600
680
  }
601
681
  }
602
- let fallbackParams = extractParams(response);
603
- // In static mode, params come from the manifest. TIM-1255.
604
- if (staticMode && !fallbackParams) {
605
- fallbackParams = manifestParams(url);
606
- }
682
+ // Test/fallback path: raw text carries no payload root, so no params.
607
683
  return {
608
684
  payload: await response.text(),
685
+ params: readPublishedParams(undefined),
609
686
  decodePromise: null,
610
687
  segmentInfo: extractSegmentInfo(response),
611
- params: fallbackParams,
612
688
  skippedSegments: extractSkippedSegments(response),
689
+ status: response.status,
613
690
  };
614
691
  }