@timber-js/app 0.2.0-alpha.196 → 0.2.0-alpha.198

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 (289) hide show
  1. package/dist/_chunks/{actions-CWYtq6ii.js → actions-BS-m5SLv.js} +3 -3
  2. package/dist/_chunks/{actions-CWYtq6ii.js.map → actions-BS-m5SLv.js.map} +1 -1
  3. package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -1
  4. package/dist/_chunks/{build-manifest-DWppEdLB.js → build-manifest-DTmSGLRz.js} +51 -2
  5. package/dist/_chunks/build-manifest-DTmSGLRz.js.map +1 -0
  6. package/dist/_chunks/{cache-api-CQeYzA5g.js → cache-api-DqzgTEqk.js} +4 -49
  7. package/dist/_chunks/cache-api-DqzgTEqk.js.map +1 -0
  8. package/dist/_chunks/{chains-h7EO-u3n.js → chains-CZG7E5zg.js} +2 -2
  9. package/dist/_chunks/{chains-h7EO-u3n.js.map → chains-CZG7E5zg.js.map} +1 -1
  10. package/dist/_chunks/{cli-check-BVthpfLS.js → cli-check-dVDi1GQz.js} +3 -3
  11. package/dist/_chunks/{cli-check-BVthpfLS.js.map → cli-check-dVDi1GQz.js.map} +1 -1
  12. package/dist/_chunks/{cli-schema-sync-3Wutm8pH.js → cli-schema-sync-DTy_-Msq.js} +2 -2
  13. package/dist/_chunks/{cli-schema-sync-3Wutm8pH.js.map → cli-schema-sync-DTy_-Msq.js.map} +1 -1
  14. package/dist/_chunks/{cloudflare-BKJC3SC_.js → cloudflare-BFb__LYG.js} +2 -2
  15. package/dist/_chunks/{cloudflare-BKJC3SC_.js.map → cloudflare-BFb__LYG.js.map} +1 -1
  16. package/dist/_chunks/{convention-lint-DO10_pVl.js → convention-lint-Ph6luW4c.js} +4 -2
  17. package/dist/_chunks/convention-lint-Ph6luW4c.js.map +1 -0
  18. package/dist/_chunks/{error-boundary-D-lkwyaD.js → error-boundary-BvRCCmbN.js} +3 -3
  19. package/dist/_chunks/{error-boundary-D-lkwyaD.js.map → error-boundary-BvRCCmbN.js.map} +1 -1
  20. package/dist/_chunks/{href-validation-CMc5JRls.js → href-validation-BIrxavIy.js} +74 -2
  21. package/dist/_chunks/href-validation-BIrxavIy.js.map +1 -0
  22. package/dist/_chunks/{live-graph-Bx4HodF1.js → live-graph-BXDsdzBv.js} +3 -3
  23. package/dist/_chunks/{live-graph-Bx4HodF1.js.map → live-graph-BXDsdzBv.js.map} +1 -1
  24. package/dist/_chunks/{logger-pumCm3Il.js → logger-DDirEsn7.js} +3 -4
  25. package/dist/_chunks/{logger-pumCm3Il.js.map → logger-DDirEsn7.js.map} +1 -1
  26. package/dist/_chunks/navigation-root-B00jjGd5.js +233 -0
  27. package/dist/_chunks/navigation-root-B00jjGd5.js.map +1 -0
  28. package/dist/_chunks/{segment-context-CjOlyB8Y.js → param-value-C8TNYchQ.js} +2 -33
  29. package/dist/_chunks/param-value-C8TNYchQ.js.map +1 -0
  30. package/dist/_chunks/{poison-scan-BAxfTT5L.js → poison-scan-BoDLgbix.js} +2 -2
  31. package/dist/_chunks/{poison-scan-BAxfTT5L.js.map → poison-scan-BoDLgbix.js.map} +1 -1
  32. package/dist/_chunks/{router-ref-BzqbPwYC.js → router-ref-8gr8qsxN.js} +2 -2
  33. package/dist/_chunks/{router-ref-BzqbPwYC.js.map → router-ref-8gr8qsxN.js.map} +1 -1
  34. package/dist/_chunks/{rsc-cache-key-DD0fl_-s.js → rsc-cache-key-ClUiXQnK.js} +2 -2
  35. package/dist/_chunks/{rsc-cache-key-DD0fl_-s.js.map → rsc-cache-key-ClUiXQnK.js.map} +1 -1
  36. package/dist/_chunks/{scanner-BRIOmHE2.js → scanner-tdFPvDYi.js} +174 -7
  37. package/dist/_chunks/scanner-tdFPvDYi.js.map +1 -0
  38. package/dist/_chunks/segment-context-D9_89u34.js +34 -0
  39. package/dist/_chunks/segment-context-D9_89u34.js.map +1 -0
  40. package/dist/_chunks/singleflight-2lUWfcAk.js +54 -0
  41. package/dist/_chunks/singleflight-2lUWfcAk.js.map +1 -0
  42. package/dist/_chunks/{ssr-data-Ya2HJPFp.js → ssr-data-BQGhTPAK.js} +2 -17
  43. package/dist/_chunks/ssr-data-BQGhTPAK.js.map +1 -0
  44. package/dist/_chunks/{walkers-BU6z9xRV.js → walkers-DNX05dC0.js} +2 -2
  45. package/dist/_chunks/{walkers-BU6z9xRV.js.map → walkers-DNX05dC0.js.map} +1 -1
  46. package/dist/adapters/cloudflare-dev.js +1 -1
  47. package/dist/adapters/cloudflare-kv-cache.js +1 -1
  48. package/dist/adapters/cloudflare.js +1 -1
  49. package/dist/adapters/nitro.d.ts +1 -1
  50. package/dist/adapters/nitro.d.ts.map +1 -1
  51. package/dist/adapters/nitro.js.map +1 -1
  52. package/dist/analyze/crawl-entry.js +2 -2
  53. package/dist/analyze/graph-command.js +2 -2
  54. package/dist/cache/index.js +1 -1
  55. package/dist/cache/singleflight.d.ts +2 -0
  56. package/dist/cache/singleflight.d.ts.map +1 -1
  57. package/dist/cli.js +2 -2
  58. package/dist/client/browser-entry/hydrate.d.ts +21 -15
  59. package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
  60. package/dist/client/browser-entry/index.d.ts +4 -3
  61. package/dist/client/browser-entry/index.d.ts.map +1 -1
  62. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
  63. package/dist/client/browser-entry/router-init.d.ts +17 -1
  64. package/dist/client/browser-entry/router-init.d.ts.map +1 -1
  65. package/dist/client/error-boundary.js +1 -1
  66. package/dist/client/global-context.d.ts +15 -0
  67. package/dist/client/global-context.d.ts.map +1 -0
  68. package/dist/client/index.js +138 -35
  69. package/dist/client/index.js.map +1 -1
  70. package/dist/client/internal.d.ts +0 -1
  71. package/dist/client/internal.d.ts.map +1 -1
  72. package/dist/client/internal.js +206 -55
  73. package/dist/client/internal.js.map +1 -1
  74. package/dist/client/link.d.ts.map +1 -1
  75. package/dist/client/location-search.d.ts +12 -0
  76. package/dist/client/location-search.d.ts.map +1 -0
  77. package/dist/client/navigation-api.d.ts.map +1 -1
  78. package/dist/client/navigation-commit.d.ts +18 -0
  79. package/dist/client/navigation-commit.d.ts.map +1 -1
  80. package/dist/client/navigation-context.d.ts +13 -11
  81. package/dist/client/navigation-context.d.ts.map +1 -1
  82. package/dist/client/navigation-root.d.ts +47 -108
  83. package/dist/client/navigation-root.d.ts.map +1 -1
  84. package/dist/client/navigation-transition.d.ts +136 -0
  85. package/dist/client/navigation-transition.d.ts.map +1 -0
  86. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  87. package/dist/client/params-context.d.ts +4 -5
  88. package/dist/client/params-context.d.ts.map +1 -1
  89. package/dist/client/react-root.d.ts +44 -0
  90. package/dist/client/react-root.d.ts.map +1 -0
  91. package/dist/client/router-pipeline.d.ts +2 -2
  92. package/dist/client/router-pipeline.d.ts.map +1 -1
  93. package/dist/client/router-types.d.ts +12 -2
  94. package/dist/client/router-types.d.ts.map +1 -1
  95. package/dist/client/router.d.ts.map +1 -1
  96. package/dist/client/segment-cache.d.ts +39 -0
  97. package/dist/client/segment-cache.d.ts.map +1 -1
  98. package/dist/client/segment-context.d.ts.map +1 -1
  99. package/dist/client/segment-outlet.d.ts +25 -14
  100. package/dist/client/segment-outlet.d.ts.map +1 -1
  101. package/dist/client/segment-update-context.d.ts +3 -9
  102. package/dist/client/segment-update-context.d.ts.map +1 -1
  103. package/dist/client/slot-content-cache-context.d.ts +35 -0
  104. package/dist/client/slot-content-cache-context.d.ts.map +1 -0
  105. package/dist/client/ssr-data.d.ts +8 -2
  106. package/dist/client/ssr-data.d.ts.map +1 -1
  107. package/dist/client/state.d.ts +0 -15
  108. package/dist/client/state.d.ts.map +1 -1
  109. package/dist/client/use-pathname.d.ts +13 -11
  110. package/dist/client/use-pathname.d.ts.map +1 -1
  111. package/dist/client/use-search-params.d.ts +13 -13
  112. package/dist/client/use-search-params.d.ts.map +1 -1
  113. package/dist/client/use-segment-params.d.ts +18 -68
  114. package/dist/client/use-segment-params.d.ts.map +1 -1
  115. package/dist/config-types.d.ts +17 -0
  116. package/dist/config-types.d.ts.map +1 -1
  117. package/dist/config-validation.d.ts.map +1 -1
  118. package/dist/cookies/index.js +1 -1
  119. package/dist/dev-tools/holding-server.d.ts +15 -10
  120. package/dist/dev-tools/holding-server.d.ts.map +1 -1
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +44 -43
  123. package/dist/index.js.map +1 -1
  124. package/dist/plugins/dev-server.d.ts.map +1 -1
  125. package/dist/plugins/entries.d.ts.map +1 -1
  126. package/dist/plugins/shims.d.ts.map +1 -1
  127. package/dist/plugins/static-build.d.ts +2 -2
  128. package/dist/plugins/static-build.d.ts.map +1 -1
  129. package/dist/routing/codegen-write.d.ts.map +1 -1
  130. package/dist/routing/index.js +2 -2
  131. package/dist/routing/interception-overlap.d.ts +35 -0
  132. package/dist/routing/interception-overlap.d.ts.map +1 -0
  133. package/dist/routing/interception.d.ts.map +1 -1
  134. package/dist/rsc-runtime/ssr.d.ts +3 -1
  135. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  136. package/dist/server/als-registry.d.ts +6 -0
  137. package/dist/server/als-registry.d.ts.map +1 -1
  138. package/dist/server/csp-nonce.d.ts +45 -0
  139. package/dist/server/csp-nonce.d.ts.map +1 -0
  140. package/dist/server/default-status-page.d.ts.map +1 -1
  141. package/dist/server/deny-renderer.d.ts.map +1 -1
  142. package/dist/server/flight-scripts.d.ts +5 -2
  143. package/dist/server/flight-scripts.d.ts.map +1 -1
  144. package/dist/server/html-injector-core.d.ts +17 -2
  145. package/dist/server/html-injector-core.d.ts.map +1 -1
  146. package/dist/server/html-injectors.d.ts +3 -2
  147. package/dist/server/html-injectors.d.ts.map +1 -1
  148. package/dist/server/index.js +2 -2
  149. package/dist/server/internal.js +86 -37
  150. package/dist/server/internal.js.map +1 -1
  151. package/dist/server/metadata-render.d.ts.map +1 -1
  152. package/dist/server/node-stream-transforms.d.ts +3 -17
  153. package/dist/server/node-stream-transforms.d.ts.map +1 -1
  154. package/dist/server/nuqs-ssr-provider.d.ts +7 -3
  155. package/dist/server/nuqs-ssr-provider.d.ts.map +1 -1
  156. package/dist/server/pipeline-phases.d.ts.map +1 -1
  157. package/dist/server/prebuilt/key-discipline.d.ts +32 -3
  158. package/dist/server/prebuilt/key-discipline.d.ts.map +1 -1
  159. package/dist/server/primitives.d.ts.map +1 -1
  160. package/dist/server/render-utils.d.ts +4 -3
  161. package/dist/server/render-utils.d.ts.map +1 -1
  162. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
  163. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  164. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  165. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  166. package/dist/server/ssr-bridge-types.d.ts +22 -2
  167. package/dist/server/ssr-bridge-types.d.ts.map +1 -1
  168. package/dist/server/ssr-entry.d.ts.map +1 -1
  169. package/dist/server/ssr-render.d.ts +5 -1
  170. package/dist/server/ssr-render.d.ts.map +1 -1
  171. package/dist/server/ssr-wrappers.d.ts +59 -27
  172. package/dist/server/ssr-wrappers.d.ts.map +1 -1
  173. package/dist/server/types.d.ts +10 -0
  174. package/dist/server/types.d.ts.map +1 -1
  175. package/dist/shims/navigation-rsc.d.ts +21 -0
  176. package/dist/shims/navigation-rsc.d.ts.map +1 -0
  177. package/docs/api/30-api-server.mdx +1 -0
  178. package/docs/api/35-api-typescript.mdx +4 -83
  179. package/docs/learn/03-fetching-data.mdx +1 -1
  180. package/docs/learn/{03b-access-control.mdx → 04-access-control.mdx} +2 -17
  181. package/docs/learn/05-the-flush-point.mdx +175 -0
  182. package/docs/learn/{05-typed-params.mdx → 06-typed-params.mdx} +1 -1
  183. package/docs/learn/07-typed-routes.mdx +25 -49
  184. package/docs/learn/{08-streaming.mdx → 09-streaming.mdx} +1 -7
  185. package/docs/learn/{10-middleware.mdx → 11-middleware.mdx} +1 -0
  186. package/package.json +3 -3
  187. package/src/adapters/nitro.ts +7 -7
  188. package/src/cache/singleflight.ts +5 -0
  189. package/src/client/browser-entry/hydrate.ts +54 -104
  190. package/src/client/browser-entry/index.ts +16 -6
  191. package/src/client/browser-entry/post-hydration.ts +3 -2
  192. package/src/client/browser-entry/router-init.ts +84 -33
  193. package/src/client/global-context.ts +31 -0
  194. package/src/client/internal.ts +1 -2
  195. package/src/client/link.tsx +18 -18
  196. package/src/client/location-search.ts +15 -0
  197. package/src/client/navigation-api.ts +4 -2
  198. package/src/client/navigation-commit.ts +48 -2
  199. package/src/client/navigation-context.ts +25 -37
  200. package/src/client/navigation-root.tsx +55 -411
  201. package/src/client/navigation-transition.ts +278 -0
  202. package/src/client/nuqs-adapter.tsx +4 -5
  203. package/src/client/params-context.ts +13 -18
  204. package/src/client/react-root.ts +72 -0
  205. package/src/client/router-lifecycle.ts +1 -1
  206. package/src/client/router-pipeline.ts +96 -22
  207. package/src/client/router-types.ts +12 -2
  208. package/src/client/router.ts +48 -36
  209. package/src/client/segment-cache.ts +70 -2
  210. package/src/client/segment-context.ts +7 -4
  211. package/src/client/segment-outlet.tsx +41 -86
  212. package/src/client/segment-update-context.ts +7 -26
  213. package/src/client/slot-content-cache-context.ts +43 -0
  214. package/src/client/ssr-data.ts +8 -2
  215. package/src/client/state.ts +0 -26
  216. package/src/client/use-pathname.ts +21 -31
  217. package/src/client/use-search-params.ts +31 -29
  218. package/src/client/use-segment-params.ts +27 -126
  219. package/src/config-types.ts +17 -0
  220. package/src/config-validation.ts +17 -0
  221. package/src/dev-tools/holding-server.ts +23 -12
  222. package/src/index.ts +26 -11
  223. package/src/plugins/dev-server.ts +9 -12
  224. package/src/plugins/entries.ts +3 -0
  225. package/src/plugins/shims.ts +8 -7
  226. package/src/plugins/static-build.ts +9 -5
  227. package/src/react-canary.d.ts +2 -0
  228. package/src/routing/codegen-write.ts +2 -0
  229. package/src/routing/interception-overlap.ts +141 -0
  230. package/src/routing/interception.ts +118 -5
  231. package/src/rsc-runtime/ssr.ts +3 -2
  232. package/src/server/als-registry.ts +6 -0
  233. package/src/server/csp-nonce.ts +70 -0
  234. package/src/server/default-status-page.ts +1 -0
  235. package/src/server/deny-renderer.ts +7 -3
  236. package/src/server/flight-scripts.ts +9 -4
  237. package/src/server/html-injector-core.ts +26 -9
  238. package/src/server/html-injectors.ts +8 -8
  239. package/src/server/metadata-render.ts +26 -4
  240. package/src/server/node-stream-transforms.ts +7 -20
  241. package/src/server/nuqs-ssr-provider.tsx +8 -7
  242. package/src/server/pipeline-phases.ts +5 -0
  243. package/src/server/prebuilt/key-discipline.ts +82 -13
  244. package/src/server/prebuilt-runtime.ts +2 -2
  245. package/src/server/primitives.ts +4 -4
  246. package/src/server/render-utils.ts +8 -4
  247. package/src/server/rsc-entry/action-middleware-runner.ts +7 -0
  248. package/src/server/rsc-entry/error-renderer.ts +5 -2
  249. package/src/server/rsc-entry/index.ts +8 -0
  250. package/src/server/rsc-entry/ssr-renderer.ts +11 -4
  251. package/src/server/ssr-bridge-types.ts +22 -2
  252. package/src/server/ssr-entry.ts +35 -28
  253. package/src/server/ssr-render.ts +13 -4
  254. package/src/server/ssr-wrappers.tsx +81 -61
  255. package/src/server/types.ts +10 -0
  256. package/src/shared/slot-params.ts +3 -4
  257. package/src/shims/navigation-rsc.ts +47 -0
  258. package/dist/_chunks/build-manifest-DWppEdLB.js.map +0 -1
  259. package/dist/_chunks/cache-api-CQeYzA5g.js.map +0 -1
  260. package/dist/_chunks/convention-lint-DO10_pVl.js.map +0 -1
  261. package/dist/_chunks/href-validation-CMc5JRls.js.map +0 -1
  262. package/dist/_chunks/scanner-BRIOmHE2.js.map +0 -1
  263. package/dist/_chunks/segment-context-CjOlyB8Y.js.map +0 -1
  264. package/dist/_chunks/slot-params-BCTmZkQB.js +0 -76
  265. package/dist/_chunks/slot-params-BCTmZkQB.js.map +0 -1
  266. package/dist/_chunks/ssr-data-Ya2HJPFp.js.map +0 -1
  267. package/dist/_chunks/use-segment-params-DzTBpkvj.js +0 -398
  268. package/dist/_chunks/use-segment-params-DzTBpkvj.js.map +0 -1
  269. package/docs/learn/04-loading-states.mdx +0 -67
  270. package/docs/learn/04b-the-flush-point.mdx +0 -115
  271. package/docs/learn/12-client-navigation.mdx +0 -176
  272. package/docs/learn/13-configuration.mdx +0 -166
  273. package/docs/more/01-advanced-routing.mdx +0 -344
  274. package/docs/more/02-advanced-forms.mdx +0 -137
  275. package/docs/more/03-coming-from-nextjs.mdx +0 -186
  276. package/docs/more/04-metadata-and-fonts.mdx +0 -193
  277. package/docs/more/04b-mdx.mdx +0 -229
  278. package/docs/more/05-content-collections.mdx +0 -90
  279. package/docs/more/06-instrumentation.mdx +0 -214
  280. package/docs/more/07-security.mdx +0 -129
  281. package/docs/more/08-developer-experience.mdx +0 -134
  282. package/docs/more/40-why-timber.mdx +0 -50
  283. package/docs/more/41-timber-vs-nextjs.mdx +0 -81
  284. package/docs/more/42-timber-vs-others.mdx +0 -68
  285. package/docs/more/50-ai-agent-instructions.mdx +0 -171
  286. /package/docs/learn/{06-forms-and-actions.mdx → 08-forms-and-actions.mdx} +0 -0
  287. /package/docs/learn/{09-caching.mdx → 10-caching.mdx} +0 -0
  288. /package/docs/learn/{11-error-handling.mdx → 12-error-handling.mdx} +0 -0
  289. /package/docs/learn/{14-deploying.mdx → 13-deploying.mdx} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"singleflight.d.ts","sourceRoot":"","sources":["../../src/cache/singleflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACzE;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,YAAY,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAGzC;CACF;AAED,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,YAAY,CAkD3E"}
1
+ {"version":3,"file":"singleflight.d.ts","sourceRoot":"","sources":["../../src/cache/singleflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACxE,oEAAoE;IACpE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;CAChD;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,YAAY,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAGzC;CACF;AAED,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,YAAY,CAqD3E"}
package/dist/cli.js CHANGED
@@ -136,7 +136,7 @@ async function runPreview(options, _deps) {
136
136
  * `--project` names the tsconfig handed to tsgo.
137
137
  */
138
138
  async function runCheck(options, _deps) {
139
- const { checkRoutes, runTypeCheck } = await import("./_chunks/cli-check-BVthpfLS.js");
139
+ const { checkRoutes, runTypeCheck } = await import("./_chunks/cli-check-dVDi1GQz.js");
140
140
  const { root } = await checkRoutes({ viteConfigFile: options.config }, _deps);
141
141
  await runTypeCheck({
142
142
  root,
@@ -152,7 +152,7 @@ async function runCheck(options, _deps) {
152
152
  async function runSchema(args) {
153
153
  const subcommand = args[0];
154
154
  if (subcommand !== "sync") throw new Error(`Unknown schema subcommand: ${subcommand ?? "(none)"}. Usage: timber schema sync`);
155
- const { runSchemaSync, defaultCodecForSegment } = await import("./_chunks/cli-schema-sync-3Wutm8pH.js").then((n) => n.t);
155
+ const { runSchemaSync, defaultCodecForSegment } = await import("./_chunks/cli-schema-sync-DTy_-Msq.js").then((n) => n.t);
156
156
  const result = runSchemaSync(process.cwd());
157
157
  if (result.filesystemSegments.length === 0) {
158
158
  console.log("[timber] No dynamic segments found in app/.");
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Hydration — pre-hydration sequence and React root creation.
2
+ * Hydration — pre-hydration sequence and hydrating the React root.
3
3
  *
4
4
  * Handles two paths:
5
- * 1. RSC payload available: hydrateRoot with NavigationProvider wrapping
6
- * 2. No RSC payload: deferred root creation via installDeferredNavigation
5
+ * 1. RSC payload available: hydrate the router's React root with the payload
6
+ * 2. No RSC payload: nothing — the root is created by the first render
7
+ * (client/react-root.ts)
7
8
  *
8
9
  * Pre-hydration ordering contract (MUST execute in this order):
9
10
  * 1. initRouter() — creates the global router so useRouter()
@@ -20,15 +21,16 @@
20
21
  *
21
22
  * See design/19-client-navigation.md §"NavigationContext"
22
23
  */
23
- import type { TopLoaderConfig } from '../top-loader.tsx';
24
+ import type { ReactRootHost } from '../react-root.ts';
24
25
  import type { RscStreamResult } from './rsc-stream.ts';
26
+ import type { RouterInitResult } from './router-init.ts';
25
27
  interface HydrateOptions {
26
28
  /** RSC stream result (null if no inlined payload) */
27
29
  rscResult: RscStreamResult | null;
28
- /** Runtime config from virtual:timber-config */
29
- config: {
30
- topLoader?: TopLoaderConfig;
31
- };
30
+ /** The router's React root — the one every navigation renders through. */
31
+ reactRoot: ReactRootHost;
32
+ /** The router's wrapper chain — see `RouterInitResult.renderTree`. */
33
+ renderTree: RouterInitResult['renderTree'];
32
34
  }
33
35
  /**
34
36
  * Run the pre-hydration sequence: set navigation state from the address bar.
@@ -43,15 +45,19 @@ interface HydrateOptions {
43
45
  */
44
46
  export declare function runPreHydration(): void;
45
47
  /**
46
- * Hydrate the React tree or set up deferred root creation.
48
+ * Hydrate the React tree when an RSC payload is available.
47
49
  *
48
- * When an RSC payload is available, wraps it with NavigationProvider +
49
- * TimberNuqsAdapter + NavigationRoot and calls hydrateRoot on the
50
- * document.
50
+ * Wraps the payload with the router's chain (NavigationProvider,
51
+ * TimberNuqsAdapter, the slot content cache, ...) and hydrates the router's
52
+ * React root with it, on the document.
51
53
  *
52
- * When no RSC payload is available (JS-only client), sets up deferred
53
- * navigation so the first client navigation creates the React root.
54
+ * When no RSC payload is available (JS-only client) there is nothing to
55
+ * hydrate and nothing to do: the root must not be created at bootstrap —
56
+ * `createRoot(document).render()` would take React ownership of the entire
57
+ * document and blank the SSR HTML — so the router's first render, i.e. the
58
+ * first navigation or revalidation, creates it with the tree it renders
59
+ * (`createReactRoot`, TIM-600 / TIM-580).
54
60
  */
55
- export declare function hydrateApp({ rscResult, config }: HydrateOptions): void;
61
+ export declare function hydrateApp({ rscResult, reactRoot, renderTree }: HydrateOptions): void;
56
62
  export {};
57
63
  //# sourceMappingURL=hydrate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/hydrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAeH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAwCvD,UAAU,cAAc;IACtB,qDAAqD;IACrD,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,gDAAgD;IAChD,MAAM,EAAE;QAAE,SAAS,CAAC,EAAE,eAAe,CAAA;KAAE,CAAC;CACzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,cAAc,GAAG,IAAI,CAoFtE"}
1
+ {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/hydrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAwCzD,UAAU,cAAc;IACtB,qDAAqD;IACrD,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,0EAA0E;IAC1E,SAAS,EAAE,aAAa,CAAC;IACzB,sEAAsE;IACtE,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,cAAc,GAAG,IAAI,CAmCrF"}
@@ -7,7 +7,7 @@
7
7
  * action-dispatch.ts — server action callServer callback
8
8
  * rsc-stream.ts — __timber_f chunk handling + ReadableStream
9
9
  * router-init.ts — createRouter + Navigation API setup
10
- * hydrate.ts — pre-hydration sequence + hydrateRoot/createRoot
10
+ * hydrate.ts — pre-hydration sequence + hydrating the root
11
11
  * post-hydration.ts — history stack, segment cache, popstate, scroll
12
12
  * hmr.ts — dev-only HMR + error forwarding
13
13
  * scroll.ts — getScrollY helper
@@ -16,9 +16,10 @@
16
16
  *
17
17
  * 1. setupServerActions() — register callServer (independent)
18
18
  * 2. createRscPayloadStream() — decode inlined RSC payload
19
- * 3. createTimberRouter() — create router + Navigation API
19
+ * 3. createReactRoot() + — the root host the router renders through,
20
+ * createTimberRouter() then the router + Navigation API
20
21
  * 4. runPreHydration() — set params + navigation state
21
- * 5. hydrateApp() — hydrateRoot or deferred createRoot
22
+ * 5. hydrateApp() — hydrate the root (no-op without a payload)
22
23
  * 6. setupPostHydration() — history stack, popstate, scroll
23
24
  * 7. setupHmr() — dev-only HMR wiring
24
25
  * 8. timber-ready signal — E2E test readiness indicator
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG"}
@@ -1 +1 @@
1
- {"version":3,"file":"post-hydration.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/post-hydration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,UAAU,oBAAoB;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,gBAAgB,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACjD,oEAAoE;IACpE,cAAc,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,aAAa,EAAE,YAAY,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,gBAAgB,EAChB,cAAc,EACd,aAAa,GACd,EAAE,oBAAoB,GAAG,IAAI,CAqF7B"}
1
+ {"version":3,"file":"post-hydration.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/post-hydration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,UAAU,oBAAoB;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,gBAAgB,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACjD,oEAAoE;IACpE,cAAc,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,aAAa,EAAE,YAAY,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,gBAAgB,EAChB,cAAc,EACd,aAAa,GACd,EAAE,oBAAoB,GAAG,IAAI,CAqF7B"}
@@ -8,8 +8,16 @@
8
8
  */
9
9
  import { type ParamsSource } from '../../shared/payload-root.ts';
10
10
  import type { RouterInstance } from '#client-internal';
11
+ import type { NavigationState } from '#client-internal';
12
+ import type { NavigationRender } from '../navigation-root.tsx';
11
13
  import { type NavigationApiController } from '../navigation-api.ts';
12
14
  export interface RouterInitOptions {
15
+ /**
16
+ * The router's React root (`createReactRoot().render`). Every path that puts
17
+ * a page on screen renders through it — it is the synchronous transition
18
+ * around `root.render`, and the `publish` it takes runs on React's commit.
19
+ */
20
+ render: NavigationRender;
13
21
  initialElement?: unknown;
14
22
  /** The params the hydration payload published, beside `initialElement`. */
15
23
  initialParams?: ParamsSource;
@@ -18,6 +26,14 @@ export interface RouterInitOptions {
18
26
  export interface RouterInitResult {
19
27
  router: RouterInstance;
20
28
  navApiController: NavigationApiController | null;
29
+ /**
30
+ * The client's wrapper chain around a tree — the one every navigation
31
+ * renders through. Hydration builds its root with this too, so the
32
+ * hydrated tree and the first navigated tree cannot differ in shape
33
+ * (a type present on one and absent on the other remounts everything
34
+ * below it) and share the router's slot content cache.
35
+ */
36
+ renderTree: (tree: unknown, navState: NavigationState, params: ParamsSource) => React.ReactElement;
21
37
  }
22
38
  /**
23
39
  * Create and register the global timber router.
@@ -26,5 +42,5 @@ export interface RouterInitResult {
26
42
  * the initial render (methods lazily resolve the router at invocation,
27
43
  * not render time, but initRouter must still run first).
28
44
  */
29
- export declare function createTimberRouter(options?: RouterInitOptions): RouterInitResult;
45
+ export declare function createTimberRouter(options: RouterInitOptions): RouterInitResult;
30
46
  //# sourceMappingURL=router-init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"router-init.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/router-init.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEtF,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAUnE,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,gBAAgB,EAAE,uBAAuB,GAAG,IAAI,CAAC;CAClD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAmShF"}
1
+ {"version":3,"file":"router-init.d.ts","sourceRoot":"","sources":["../../../src/client/browser-entry/router-init.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEtF,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAK9B,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,MAAM,EAAE,gBAAgB,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,gBAAgB,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACjD;;;;;;OAMG;IACH,UAAU,EAAE,CACV,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,YAAY,KACjB,KAAK,CAAC,YAAY,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAgU/E"}
@@ -1,4 +1,4 @@
1
1
  "use client";
2
2
  "use client";
3
- import { t as TimberErrorBoundary } from "../_chunks/error-boundary-D-lkwyaD.js";
3
+ import { t as TimberErrorBoundary } from "../_chunks/error-boundary-BvRCCmbN.js";
4
4
  export { TimberErrorBoundary };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * createGlobalContext — a React context with a process-wide singleton identity.
3
+ *
4
+ * SINGLETON GUARANTEE: Uses globalThis + Symbol.for — same pattern as
5
+ * NavigationContext. The RSC client bundler can duplicate a module across
6
+ * chunks (browser-entry graph + client-reference graph). With ESM output,
7
+ * each chunk gets its own module scope — a bare createContext at module
8
+ * level would create separate instances per chunk. globalThis guarantees a
9
+ * single instance regardless of duplication.
10
+ *
11
+ * See design/19-client-navigation.md §"Singleton Guarantee via globalThis"
12
+ */
13
+ import React from 'react';
14
+ export declare function createGlobalContext<T>(key: string, defaultValue: T): React.Context<T>;
15
+ //# sourceMappingURL=global-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-context.d.ts","sourceRoot":"","sources":["../../src/client/global-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAarF"}
@@ -1,13 +1,15 @@
1
1
  "use client";
2
2
  import { n as classifyUrlSegment } from "../_chunks/segment-classify-C539Pa2O.js";
3
- import { a as mergePreservedSearchParams, i as validateNavigationHref, n as isInternalHref } from "../_chunks/href-validation-CMc5JRls.js";
4
- import { n as getSsrData } from "../_chunks/ssr-data-Ya2HJPFp.js";
5
- import { n as getRouterOrNull } from "../_chunks/router-ref-BzqbPwYC.js";
6
- import { n as useSegmentContext } from "../_chunks/segment-context-CjOlyB8Y.js";
3
+ import { c as stripRscCacheKey } from "../_chunks/rsc-cache-key-ClUiXQnK.js";
4
+ import { a as mergePreservedSearchParams, i as validateNavigationHref, n as isInternalHref, o as resolveSegmentParams } from "../_chunks/href-validation-BIrxavIy.js";
5
+ import { n as getSsrData } from "../_chunks/ssr-data-BQGhTPAK.js";
6
+ import { n as getRouterOrNull } from "../_chunks/router-ref-8gr8qsxN.js";
7
+ import "../_chunks/param-value-C8TNYchQ.js";
8
+ import { n as useSegmentContext } from "../_chunks/segment-context-D9_89u34.js";
7
9
  import { t as getLinkCodec } from "../_chunks/codec-registry-oOUxugz3.js";
8
- import { l as useNavigationContext, r as useSegmentParams, u as usePendingNavigation } from "../_chunks/use-segment-params-DzTBpkvj.js";
10
+ import { a as useNavigationContext, o as usePendingNavigation } from "../_chunks/navigation-root-B00jjGd5.js";
9
11
  import { n as useQueryStates } from "../_chunks/use-query-states-I3JMng6J.js";
10
- import { createContext, startTransition, useActionState as useActionState$1, useContext, useRef, useState, useTransition } from "react";
12
+ import React, { createContext, startTransition, useActionState as useActionState$1, useContext, useRef, useState, useTransition } from "react";
11
13
  import { jsx } from "react/jsx-runtime";
12
14
  //#region src/client/use-link-status.ts
13
15
  /**
@@ -44,20 +46,35 @@ function useLinkStatus() {
44
46
  return useContext(LinkStatusContext);
45
47
  }
46
48
  //#endregion
49
+ //#region src/client/location-search.ts
50
+ /**
51
+ * The app-visible search string from the address bar.
52
+ *
53
+ * Mirrors what `appVisibleSearch()` does on the server: strips key-shaped
54
+ * `_rsc` values so the client and server agree on search state regardless
55
+ * of whether the document URL itself carries a payload cache key (a user
56
+ * pasting/sharing an RSC payload URL). Non-key-shaped `_rsc` values — an
57
+ * application legitimately owning that name — survive, using the same
58
+ * `isRscCacheKeyShape` predicate the server uses.
59
+ */
60
+ function locationSearch() {
61
+ return stripRscCacheKey(window.location.search);
62
+ }
63
+ //#endregion
47
64
  //#region src/client/link.tsx
48
65
  var LINK_PENDING = { isPending: true };
49
66
  var LINK_IDLE = { isPending: false };
50
67
  /**
51
68
  * Read the current URL's search string without requiring a React hook.
52
- * On the client, reads window.location.search. During SSR, reads from
53
- * the request context (getSsrData). Returns empty string if unavailable.
69
+ * On the client, reads window.location.search. During SSR, reads the raw
70
+ * query string from the request context (getSsrData) — the same `''` or
71
+ * `?…` shape, preserving repeated keys (`?tag=a&tag=b`) so the
72
+ * server-rendered href matches what the hydrated client rebuilds from the
73
+ * address bar (TIM-1428). Returns empty string if unavailable.
54
74
  */
55
75
  function getCurrentSearch() {
56
- if (typeof window !== "undefined") return window.location.search;
57
- const data = getSsrData();
58
- if (!data) return "";
59
- const str = new URLSearchParams(data.searchParams).toString();
60
- return str ? `?${str}` : "";
76
+ if (typeof window !== "undefined") return locationSearch();
77
+ return getSsrData()?.search ?? "";
61
78
  }
62
79
  /**
63
80
  * Interpolate dynamic segments in a route pattern with actual values.
@@ -253,10 +270,10 @@ var Link = function LinkImpl(props) {
253
270
  if (!router) return;
254
271
  const navHref = preserveSearchParams ? mergePreservedSearchParams(baseHref, getCurrentSearch(), preserveSearchParams) : resolvedHref;
255
272
  const resolved = new URL(navHref, window.location.href);
256
- if (resolved.pathname === window.location.pathname && resolved.search === window.location.search && resolved.hash) return;
273
+ if (resolved.pathname === window.location.pathname && stripRscCacheKey(resolved.search) === locationSearch() && resolved.hash) return;
257
274
  event.preventDefault();
258
275
  const shouldScroll = scroll !== false;
259
- const absoluteHref = resolved.pathname + resolved.search + resolved.hash;
276
+ const absoluteHref = resolved.pathname + stripRscCacheKey(resolved.search) + resolved.hash;
260
277
  const seq = ++clickSeq.current;
261
278
  const settle = () => {
262
279
  if (clickSeq.current === seq) startTransition(() => setIsPending(false));
@@ -273,7 +290,7 @@ var Link = function LinkImpl(props) {
273
290
  if (router) {
274
291
  const prefetchHref = preserveSearchParams ? mergePreservedSearchParams(baseHref, getCurrentSearch(), preserveSearchParams) : resolvedHref;
275
292
  const resolved = new URL(prefetchHref, window.location.href);
276
- router.prefetch(resolved.pathname + resolved.search);
293
+ router.prefetch(resolved.pathname + stripRscCacheKey(resolved.search));
277
294
  }
278
295
  } : userOnMouseEnter;
279
296
  return /* @__PURE__ */ jsx("a", {
@@ -382,34 +399,31 @@ function useRouter() {
382
399
  * Returns the pathname portion of the current URL (e.g. '/dashboard/settings').
383
400
  * Updates when client-side navigation changes the URL.
384
401
  *
385
- * On the client, reads from NavigationContext which is updated atomically
386
- * with the RSC tree render. This replaces the previous useSyncExternalStore
387
- * approach which only subscribed to popstate events — meaning usePathname()
388
- * did NOT re-render on forward navigation (pushState). The context approach
389
- * fixes this: pathname updates in the same render pass as the new tree.
402
+ * One unconditional read of NavigationContext, on every side (TIM-1425):
390
403
  *
391
- * During SSR, reads the request pathname from the SSR ALS context
392
- * (populated by ssr-entry.ts) instead of window.location.
404
+ * - In the browser, the provider wraps the RSC payload in renderRoot(), so
405
+ * the pathname updates in the same render pass as the new tree.
406
+ * - During SSR, the wrapper chain mounts the same provider with the request's
407
+ * pathname (TIM-1424), so this is the identical code path — no ALS read,
408
+ * no fallback tiers.
409
+ * - In the RSC environment, this module is never evaluated — the shims plugin
410
+ * resolves next/navigation to navigation-rsc.ts, which has a throwing stub
411
+ * (TIM-1420).
412
+ * - Called outside a component entirely, React itself throws its
413
+ * invalid-hook-call error — loud, not guessed-at from window.location.
393
414
  *
394
415
  * Compatible with Next.js's `usePathname()` from `next/navigation`.
395
416
  */
396
417
  /**
397
418
  * Read the current URL pathname.
398
419
  *
399
- * On the client, reads from NavigationContext (provided by
400
- * NavigationProvider in renderRoot). During SSR, reads from the
401
- * ALS-backed SSR data context. Falls back to window.location.pathname
402
- * when called outside a React component (e.g., in tests).
420
+ * Throws when no NavigationProvider is above the caller (a component rendered
421
+ * outside the timber app — in tests, render inside the timber providers).
403
422
  */
404
423
  function usePathname() {
405
- try {
406
- const navContext = useNavigationContext();
407
- if (navContext !== null) return navContext.pathname;
408
- } catch {}
409
- const ssrData = getSsrData();
410
- if (ssrData) return ssrData.pathname ?? "/";
411
- if (typeof window !== "undefined") return window.location.pathname;
412
- return "/";
424
+ const nav = useNavigationContext();
425
+ if (nav === null) throw new Error("[timber] usePathname() was called outside the timber app tree (no NavigationProvider found). In tests, render the component inside the timber providers.");
426
+ return nav.pathname;
413
427
  }
414
428
  //#endregion
415
429
  //#region src/client/navigation-api.ts
@@ -641,6 +655,95 @@ function deriveFormErrors(result) {
641
655
  };
642
656
  }
643
657
  //#endregion
658
+ //#region src/client/params-context.ts
659
+ /**
660
+ * Segment params context — the one channel params use to reach the browser.
661
+ *
662
+ * Params ride the RSC payload's root row as a sibling of the tree
663
+ * (`{ tree, params, slotParams }`), rather than in four side channels that
664
+ * raced to seed them: a response header, an inline script, and two build-time
665
+ * manifest fields all previously carried the same record, each with its own
666
+ * `JSON.stringify` (TIM-1294).
667
+ *
668
+ * Riding the payload is what makes them *typed*. `defineSchema` takes any
669
+ * `Codec<T>`, so a coerced param is whatever the codec returned — a `Date`, a
670
+ * `bigint` — and `JSON.stringify` either flattened it to a string or threw
671
+ * mid-response. React Flight carries those values natively, so the client
672
+ * reads the value the server produced instead of a lossy copy of it. See
673
+ * design/41-global-params.md §"Transport".
674
+ *
675
+ * **The client owns the provider.** There is exactly one `ParamsProvider` in
676
+ * the browser's tree, rendered by `PayloadRoot` above the point where a
677
+ * partial navigation splices the new payload into the retained tree. It has to
678
+ * be there and it has to be alone: a provider *inside* the payload lands below
679
+ * the retained region, whose own root is the departing route's provider, so
680
+ * every reader in a skipped layout resolves to the departing record and no
681
+ * amount of wrapping above it helps (TIM-1297).
682
+ *
683
+ * Ordering still holds without a bootstrap contract, for the same reason it
684
+ * did when the provider was in the tree: a provider renders before its own
685
+ * descendants by construction, so `useSegmentParams()` is correct during
686
+ * hydration without anything having to run before `hydrateRoot()`.
687
+ */
688
+ /**
689
+ * SINGLETON GUARANTEE: globalThis + `Symbol.for`, the same pattern as
690
+ * `NavigationContext` and `SegmentUpdateContext`.
691
+ *
692
+ * The RSC client bundler can duplicate a module across chunks, and with ESM
693
+ * output each chunk gets its own module scope — so a bare `createContext` at
694
+ * module level yields one context per chunk. This module is now reached from
695
+ * *both* graphs: `PayloadRoot` is imported by the browser entry, while
696
+ * `useParamsContext()` arrives through the client-reference graph with the
697
+ * app's own components. A duplicate would put the provider on instance A and
698
+ * every reader on instance B, so `useContext` returns `null` and every
699
+ * `useSegmentParams()` call throws the outside-the-timber-app-tree error
700
+ * even though the provider is mounted (the module-snapshot fallback it once
701
+ * silently landed on was deleted in TIM-1425).
702
+ *
703
+ * This module was the one client context without the guard — harmless while
704
+ * the provider travelled inside the payload, in the same graph as its readers,
705
+ * and load-bearing the moment the client started rendering it (TIM-1297).
706
+ *
707
+ * The React APIs are reached through the namespace rather than named imports,
708
+ * for the same reason `segment-update-context.ts` and `navigation-context.ts`
709
+ * do it: React's `react-server` export provides neither `createContext` nor
710
+ * `useContext`, and a *named* ESM import of a missing export fails at module
711
+ * instantiation — before any feature check could run. This module is reachable
712
+ * from every entry a Server Component imports, so the named form crashed
713
+ * those entries outright (codex, PR #992; originally reproduced against
714
+ * `@timber-js/app/segment-params`, an entry point since deleted by TIM-1342 —
715
+ * the hazard is unchanged for the entries that remain).
716
+ *
717
+ * See design/19-client-navigation.md §"Singleton Guarantee via globalThis"
718
+ */
719
+ var PARAMS_CTX_KEY = Symbol.for("__timber_params_ctx");
720
+ function getOrCreateContext() {
721
+ const store = globalThis;
722
+ const existing = store[PARAMS_CTX_KEY];
723
+ if (existing !== void 0) return existing;
724
+ if (typeof React.createContext !== "function") return;
725
+ const ctx = React.createContext(null);
726
+ store[PARAMS_CTX_KEY] = ctx;
727
+ return ctx;
728
+ }
729
+ var ParamsContext = getOrCreateContext();
730
+ /**
731
+ * Read the params provided by the tree. Returns null only when no provider
732
+ * is above the caller — a component rendered outside a timber route. During
733
+ * SSR the wrapper chain mounts `PayloadRoot` too (TIM-1424), so both sides
734
+ * resolve through this context.
735
+ */
736
+ function useParamsContext() {
737
+ return React.useContext(ParamsContext);
738
+ }
739
+ //#endregion
740
+ //#region src/client/use-segment-params.ts
741
+ function useSegmentParams(segmentPath) {
742
+ const paramsContext = useParamsContext();
743
+ if (paramsContext === null) throw new Error("[timber] useSegmentParams() was called outside the timber app tree (no params provider found). In tests, render the component inside the timber providers.");
744
+ return resolveSegmentParams(paramsContext.params, paramsContext.slotParams, segmentPath);
745
+ }
746
+ //#endregion
644
747
  export { Link, LinkStatusContext, buildLinkProps, interpolateParams, mergePreservedSearchParams, replaceUrl, resolveHref, useActionState, useFormAction, useLinkStatus, usePathname, usePendingNavigation, useQueryStates, useRouter, useSegmentParams, useSelectedLayoutSegment, useSelectedLayoutSegments, validateNavigationHref as validateLinkHref };
645
748
 
646
749
  //# sourceMappingURL=index.js.map