@timber-js/app 0.2.0-alpha.15 → 0.2.0-alpha.151

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 (854) hide show
  1. package/LICENSE +8 -0
  2. package/dist/_chunks/actions-a0RczDnB.js +1106 -0
  3. package/dist/_chunks/actions-a0RczDnB.js.map +1 -0
  4. package/dist/_chunks/build-output-helper-B20ZuTSA.js +102 -0
  5. package/dist/_chunks/build-output-helper-B20ZuTSA.js.map +1 -0
  6. package/dist/_chunks/cache-api-Co-yI-gP.js +424 -0
  7. package/dist/_chunks/cache-api-Co-yI-gP.js.map +1 -0
  8. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → canonicalize-P41GR6tY.js} +94 -18
  9. package/dist/_chunks/canonicalize-P41GR6tY.js.map +1 -0
  10. package/dist/_chunks/cli-schema-sync-DJDdyEae.js +629 -0
  11. package/dist/_chunks/cli-schema-sync-DJDdyEae.js.map +1 -0
  12. package/dist/_chunks/cli-schema-sync-D_IhHEUW.js +2 -0
  13. package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
  14. package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
  15. package/dist/_chunks/define-Bssfp6ot.js +82 -0
  16. package/dist/_chunks/define-Bssfp6ot.js.map +1 -0
  17. package/dist/_chunks/define-CFmvb4Bt.js +203 -0
  18. package/dist/_chunks/define-CFmvb4Bt.js.map +1 -0
  19. package/dist/_chunks/fast-hash-D6hIVt1Y.js +36 -0
  20. package/dist/_chunks/fast-hash-D6hIVt1Y.js.map +1 -0
  21. package/dist/_chunks/format-CfwjgPz9.js +14 -0
  22. package/dist/_chunks/format-CfwjgPz9.js.map +1 -0
  23. package/dist/_chunks/href-validation-FiA_rToW.js +141 -0
  24. package/dist/_chunks/href-validation-FiA_rToW.js.map +1 -0
  25. package/dist/_chunks/logger-CM0clugc.js +645 -0
  26. package/dist/_chunks/logger-CM0clugc.js.map +1 -0
  27. package/dist/_chunks/navigation-root-bUDZLw74.js +124 -0
  28. package/dist/_chunks/navigation-root-bUDZLw74.js.map +1 -0
  29. package/dist/_chunks/plugin-context-DurqFBuY.js +2 -0
  30. package/dist/_chunks/plugin-context-GfDWsdd2.js +268 -0
  31. package/dist/_chunks/plugin-context-GfDWsdd2.js.map +1 -0
  32. package/dist/_chunks/registry-DbJPKoBp.js +20 -0
  33. package/dist/_chunks/registry-DbJPKoBp.js.map +1 -0
  34. package/dist/_chunks/resolve-schema-3iUvBV5T.js +50 -0
  35. package/dist/_chunks/resolve-schema-3iUvBV5T.js.map +1 -0
  36. package/dist/_chunks/router-ref-CtmF-aPv.js +28 -0
  37. package/dist/_chunks/router-ref-CtmF-aPv.js.map +1 -0
  38. package/dist/_chunks/schema-bridge-BY3QLBL7.js +119 -0
  39. package/dist/_chunks/schema-bridge-BY3QLBL7.js.map +1 -0
  40. package/dist/_chunks/segment-classify-CDDRVKs7.js +137 -0
  41. package/dist/_chunks/segment-classify-CDDRVKs7.js.map +1 -0
  42. package/dist/_chunks/segment-context-ZDnXDkbz.js +34 -0
  43. package/dist/_chunks/segment-context-ZDnXDkbz.js.map +1 -0
  44. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-BOWsq18U.js} +1 -1
  45. package/dist/_chunks/ssr-data-BOWsq18U.js.map +1 -0
  46. package/dist/_chunks/tree-match-D2l830j2.js +102 -0
  47. package/dist/_chunks/tree-match-D2l830j2.js.map +1 -0
  48. package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-CbeQmext.js} +7 -20
  49. package/dist/_chunks/use-query-states-CbeQmext.js.map +1 -0
  50. package/dist/_chunks/use-segment-params-D1CzlgBo.js +151 -0
  51. package/dist/_chunks/use-segment-params-D1CzlgBo.js.map +1 -0
  52. package/dist/_chunks/validation-taUkvA4Q.js +113 -0
  53. package/dist/_chunks/validation-taUkvA4Q.js.map +1 -0
  54. package/dist/_chunks/walkers-DvWDj453.js +790 -0
  55. package/dist/_chunks/walkers-DvWDj453.js.map +1 -0
  56. package/dist/adapters/build-output-helper.d.ts +28 -0
  57. package/dist/adapters/build-output-helper.d.ts.map +1 -0
  58. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  59. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  60. package/dist/adapters/cloudflare-dev.js +73 -0
  61. package/dist/adapters/cloudflare-dev.js.map +1 -0
  62. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  63. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  64. package/dist/adapters/cloudflare-kv-cache.js +117 -0
  65. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  66. package/dist/adapters/cloudflare.d.ts +142 -20
  67. package/dist/adapters/cloudflare.d.ts.map +1 -1
  68. package/dist/adapters/cloudflare.js +150 -64
  69. package/dist/adapters/cloudflare.js.map +1 -1
  70. package/dist/adapters/compress-module.d.ts +5 -4
  71. package/dist/adapters/compress-module.d.ts.map +1 -1
  72. package/dist/adapters/nitro.d.ts +17 -3
  73. package/dist/adapters/nitro.d.ts.map +1 -1
  74. package/dist/adapters/nitro.js +146 -147
  75. package/dist/adapters/nitro.js.map +1 -1
  76. package/dist/adapters/shared.d.ts +16 -0
  77. package/dist/adapters/shared.d.ts.map +1 -0
  78. package/dist/cache/cache-api.d.ts +24 -0
  79. package/dist/cache/cache-api.d.ts.map +1 -0
  80. package/dist/cache/handler-store.d.ts +31 -0
  81. package/dist/cache/handler-store.d.ts.map +1 -0
  82. package/dist/cache/index.d.ts +25 -7
  83. package/dist/cache/index.d.ts.map +1 -1
  84. package/dist/cache/index.js +100 -240
  85. package/dist/cache/index.js.map +1 -1
  86. package/dist/cache/invalidation-epoch.d.ts +43 -0
  87. package/dist/cache/invalidation-epoch.d.ts.map +1 -0
  88. package/dist/cache/redis-handler.d.ts +85 -8
  89. package/dist/cache/redis-handler.d.ts.map +1 -1
  90. package/dist/cache/singleflight.d.ts +18 -1
  91. package/dist/cache/singleflight.d.ts.map +1 -1
  92. package/dist/cache/sizeof.d.ts +22 -0
  93. package/dist/cache/sizeof.d.ts.map +1 -0
  94. package/dist/cache/stable-stringify.d.ts +9 -0
  95. package/dist/cache/stable-stringify.d.ts.map +1 -1
  96. package/dist/cache/timber-cache.d.ts +20 -10
  97. package/dist/cache/timber-cache.d.ts.map +1 -1
  98. package/dist/cli-schema-sync.d.ts +59 -0
  99. package/dist/cli-schema-sync.d.ts.map +1 -0
  100. package/dist/cli.d.ts +26 -2
  101. package/dist/cli.d.ts.map +1 -1
  102. package/dist/cli.js +70 -33
  103. package/dist/cli.js.map +1 -1
  104. package/dist/client/browser-dev.d.ts +34 -1
  105. package/dist/client/browser-dev.d.ts.map +1 -1
  106. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  107. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  108. package/dist/client/browser-entry/hmr.d.ts +21 -0
  109. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  110. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  111. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  112. package/dist/client/browser-entry/index.d.ts +29 -0
  113. package/dist/client/browser-entry/index.d.ts.map +1 -0
  114. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  115. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  116. package/dist/client/browser-entry/router-init.d.ts +26 -0
  117. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  118. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  119. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  120. package/dist/client/browser-entry/scroll.d.ts +28 -0
  121. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  122. package/dist/client/error-boundary.d.ts +12 -5
  123. package/dist/client/error-boundary.d.ts.map +1 -1
  124. package/dist/client/error-boundary.js +47 -10
  125. package/dist/client/error-boundary.js.map +1 -1
  126. package/dist/client/error-reconstituter.d.ts +61 -0
  127. package/dist/client/error-reconstituter.d.ts.map +1 -0
  128. package/dist/client/form.d.ts +16 -27
  129. package/dist/client/form.d.ts.map +1 -1
  130. package/dist/client/history.d.ts +11 -3
  131. package/dist/client/history.d.ts.map +1 -1
  132. package/dist/client/index.d.ts +10 -24
  133. package/dist/client/index.d.ts.map +1 -1
  134. package/dist/client/index.js +183 -1134
  135. package/dist/client/index.js.map +1 -1
  136. package/dist/client/internal.d.ts +19 -0
  137. package/dist/client/internal.d.ts.map +1 -0
  138. package/dist/client/internal.js +900 -0
  139. package/dist/client/internal.js.map +1 -0
  140. package/dist/client/link.d.ts +69 -60
  141. package/dist/client/link.d.ts.map +1 -1
  142. package/dist/client/navigation-api-types.d.ts +90 -0
  143. package/dist/client/navigation-api-types.d.ts.map +1 -0
  144. package/dist/client/navigation-api.d.ts +122 -0
  145. package/dist/client/navigation-api.d.ts.map +1 -0
  146. package/dist/client/navigation-context.d.ts +3 -2
  147. package/dist/client/navigation-context.d.ts.map +1 -1
  148. package/dist/client/navigation-root.d.ts +119 -0
  149. package/dist/client/navigation-root.d.ts.map +1 -0
  150. package/dist/client/nuqs-adapter.d.ts +1 -1
  151. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  152. package/dist/client/router-ref.d.ts +1 -1
  153. package/dist/client/router.d.ts +86 -10
  154. package/dist/client/router.d.ts.map +1 -1
  155. package/dist/client/rsc-fetch.d.ts +46 -3
  156. package/dist/client/rsc-fetch.d.ts.map +1 -1
  157. package/dist/client/segment-cache.d.ts +3 -1
  158. package/dist/client/segment-cache.d.ts.map +1 -1
  159. package/dist/client/segment-outlet.d.ts +49 -0
  160. package/dist/client/segment-outlet.d.ts.map +1 -0
  161. package/dist/client/segment-update-context.d.ts +21 -0
  162. package/dist/client/segment-update-context.d.ts.map +1 -0
  163. package/dist/client/shallow-url.d.ts +10 -0
  164. package/dist/client/shallow-url.d.ts.map +1 -0
  165. package/dist/client/ssr-data.d.ts +13 -4
  166. package/dist/client/ssr-data.d.ts.map +1 -1
  167. package/dist/client/state.d.ts +1 -1
  168. package/dist/client/top-loader.d.ts +5 -5
  169. package/dist/client/top-loader.d.ts.map +1 -1
  170. package/dist/client/use-cookie.d.ts +12 -0
  171. package/dist/client/use-cookie.d.ts.map +1 -1
  172. package/dist/client/use-link-status.d.ts +5 -5
  173. package/dist/client/use-link-status.d.ts.map +1 -1
  174. package/dist/client/use-pathname.d.ts.map +1 -1
  175. package/dist/client/use-pending-navigation.d.ts +23 -0
  176. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  177. package/dist/client/use-query-states.d.ts +1 -1
  178. package/dist/client/use-query-states.d.ts.map +1 -1
  179. package/dist/client/use-router.d.ts +1 -1
  180. package/dist/client/use-router.d.ts.map +1 -1
  181. package/dist/client/use-search-params.d.ts +12 -5
  182. package/dist/client/use-search-params.d.ts.map +1 -1
  183. package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +8 -6
  184. package/dist/client/use-segment-params.d.ts.map +1 -0
  185. package/dist/codec.d.ts +69 -0
  186. package/dist/codec.d.ts.map +1 -0
  187. package/dist/codec.js +75 -0
  188. package/dist/codec.js.map +1 -0
  189. package/dist/config-types.d.ts +294 -0
  190. package/dist/config-types.d.ts.map +1 -0
  191. package/dist/config-validation.d.ts +51 -0
  192. package/dist/config-validation.d.ts.map +1 -0
  193. package/dist/content/index.d.ts +1 -10
  194. package/dist/content/index.d.ts.map +1 -1
  195. package/dist/content/index.js +0 -2
  196. package/dist/cookies/define-cookie.d.ts +58 -25
  197. package/dist/cookies/define-cookie.d.ts.map +1 -1
  198. package/dist/cookies/index.d.ts +2 -1
  199. package/dist/cookies/index.d.ts.map +1 -1
  200. package/dist/cookies/index.js +249 -36
  201. package/dist/cookies/index.js.map +1 -1
  202. package/dist/cookies/json-cookie.d.ts +64 -0
  203. package/dist/cookies/json-cookie.d.ts.map +1 -0
  204. package/dist/cookies/validation.d.ts +34 -0
  205. package/dist/cookies/validation.d.ts.map +1 -0
  206. package/dist/dev-tools/404-page.d.ts +50 -0
  207. package/dist/dev-tools/404-page.d.ts.map +1 -0
  208. package/dist/dev-tools/browser-logs.d.ts +84 -0
  209. package/dist/dev-tools/browser-logs.d.ts.map +1 -0
  210. package/dist/dev-tools/dev-page-shell.d.ts +78 -0
  211. package/dist/dev-tools/dev-page-shell.d.ts.map +1 -0
  212. package/dist/dev-tools/error-page.d.ts +32 -0
  213. package/dist/dev-tools/error-page.d.ts.map +1 -0
  214. package/dist/dev-tools/holding-server.d.ts +54 -0
  215. package/dist/dev-tools/holding-server.d.ts.map +1 -0
  216. package/dist/dev-tools/hydration-overlay.d.ts +11 -0
  217. package/dist/dev-tools/hydration-overlay.d.ts.map +1 -0
  218. package/dist/dev-tools/index.d.ts +31 -0
  219. package/dist/dev-tools/index.d.ts.map +1 -0
  220. package/dist/dev-tools/instrumentation.d.ts +59 -0
  221. package/dist/dev-tools/instrumentation.d.ts.map +1 -0
  222. package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
  223. package/dist/dev-tools/logger.d.ts.map +1 -0
  224. package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
  225. package/dist/dev-tools/logs.d.ts.map +1 -0
  226. package/dist/dev-tools/overlay.d.ts +91 -0
  227. package/dist/dev-tools/overlay.d.ts.map +1 -0
  228. package/dist/dev-tools/stack-classifier.d.ts +34 -0
  229. package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
  230. package/dist/dev-tools/terminal.d.ts +28 -0
  231. package/dist/dev-tools/terminal.d.ts.map +1 -0
  232. package/dist/fonts/ast-walk.d.ts +68 -0
  233. package/dist/fonts/ast-walk.d.ts.map +1 -0
  234. package/dist/fonts/ast.d.ts +110 -6
  235. package/dist/fonts/ast.d.ts.map +1 -1
  236. package/dist/fonts/bundle.d.ts +50 -0
  237. package/dist/fonts/bundle.d.ts.map +1 -0
  238. package/dist/fonts/dev-middleware.d.ts +22 -0
  239. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  240. package/dist/fonts/fallbacks.d.ts +0 -7
  241. package/dist/fonts/fallbacks.d.ts.map +1 -1
  242. package/dist/fonts/google.d.ts +4 -2
  243. package/dist/fonts/google.d.ts.map +1 -1
  244. package/dist/fonts/local.d.ts +4 -4
  245. package/dist/fonts/local.d.ts.map +1 -1
  246. package/dist/fonts/paths.d.ts +43 -0
  247. package/dist/fonts/paths.d.ts.map +1 -0
  248. package/dist/fonts/pipeline.d.ts +158 -0
  249. package/dist/fonts/pipeline.d.ts.map +1 -0
  250. package/dist/fonts/transform.d.ts +78 -0
  251. package/dist/fonts/transform.d.ts.map +1 -0
  252. package/dist/fonts/types.d.ts +47 -1
  253. package/dist/fonts/types.d.ts.map +1 -1
  254. package/dist/fonts/virtual-modules.d.ts +77 -0
  255. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  256. package/dist/index.d.ts +46 -180
  257. package/dist/index.d.ts.map +1 -1
  258. package/dist/index.js +6452 -13421
  259. package/dist/index.js.map +1 -1
  260. package/dist/params/codec-registry.d.ts +26 -0
  261. package/dist/params/codec-registry.d.ts.map +1 -0
  262. package/dist/params/define-schema.d.ts +81 -0
  263. package/dist/params/define-schema.d.ts.map +1 -0
  264. package/dist/params/index.d.ts +5 -0
  265. package/dist/params/index.d.ts.map +1 -0
  266. package/dist/params/index.js +34 -0
  267. package/dist/params/index.js.map +1 -0
  268. package/dist/params/resolve-schema.d.ts +34 -0
  269. package/dist/params/resolve-schema.d.ts.map +1 -0
  270. package/dist/plugin-context.d.ts +137 -0
  271. package/dist/plugin-context.d.ts.map +1 -0
  272. package/dist/plugins/adapter-build.d.ts +20 -1
  273. package/dist/plugins/adapter-build.d.ts.map +1 -1
  274. package/dist/plugins/build-manifest.d.ts +7 -3
  275. package/dist/plugins/build-manifest.d.ts.map +1 -1
  276. package/dist/plugins/build-report.d.ts +9 -7
  277. package/dist/plugins/build-report.d.ts.map +1 -1
  278. package/dist/plugins/cache.d.ts +73 -0
  279. package/dist/plugins/cache.d.ts.map +1 -0
  280. package/dist/plugins/client-chunks.d.ts +39 -0
  281. package/dist/plugins/client-chunks.d.ts.map +1 -0
  282. package/dist/plugins/cloudflare-wasm.d.ts +21 -0
  283. package/dist/plugins/cloudflare-wasm.d.ts.map +1 -0
  284. package/dist/plugins/content.d.ts +1 -1
  285. package/dist/plugins/content.d.ts.map +1 -1
  286. package/dist/plugins/dev-server.d.ts +17 -1
  287. package/dist/plugins/dev-server.d.ts.map +1 -1
  288. package/dist/plugins/entries.d.ts +1 -1
  289. package/dist/plugins/entries.d.ts.map +1 -1
  290. package/dist/plugins/fonts.d.ts +16 -73
  291. package/dist/plugins/fonts.d.ts.map +1 -1
  292. package/dist/plugins/mdx.d.ts +1 -1
  293. package/dist/plugins/mdx.d.ts.map +1 -1
  294. package/dist/plugins/routing.d.ts +1 -1
  295. package/dist/plugins/routing.d.ts.map +1 -1
  296. package/dist/plugins/server-bundle.d.ts.map +1 -1
  297. package/dist/plugins/shims.d.ts +29 -5
  298. package/dist/plugins/shims.d.ts.map +1 -1
  299. package/dist/plugins/static-build.d.ts +5 -26
  300. package/dist/plugins/static-build.d.ts.map +1 -1
  301. package/dist/routing/codegen-shared.d.ts +67 -0
  302. package/dist/routing/codegen-shared.d.ts.map +1 -0
  303. package/dist/routing/codegen-types.d.ts +64 -0
  304. package/dist/routing/codegen-types.d.ts.map +1 -0
  305. package/dist/routing/codegen.d.ts +7 -2
  306. package/dist/routing/codegen.d.ts.map +1 -1
  307. package/dist/routing/convention-lint.d.ts +41 -0
  308. package/dist/routing/convention-lint.d.ts.map +1 -0
  309. package/dist/routing/file-cache.d.ts +8 -0
  310. package/dist/routing/file-cache.d.ts.map +1 -0
  311. package/dist/routing/index.d.ts +7 -1
  312. package/dist/routing/index.d.ts.map +1 -1
  313. package/dist/routing/index.js +4 -2
  314. package/dist/routing/interception.d.ts +0 -5
  315. package/dist/routing/interception.d.ts.map +1 -1
  316. package/dist/routing/link-codegen.d.ts +90 -0
  317. package/dist/routing/link-codegen.d.ts.map +1 -0
  318. package/dist/routing/manifest-codegen.d.ts +32 -0
  319. package/dist/routing/manifest-codegen.d.ts.map +1 -0
  320. package/dist/routing/scanner.d.ts +1 -10
  321. package/dist/routing/scanner.d.ts.map +1 -1
  322. package/dist/routing/schema-validation.d.ts +35 -0
  323. package/dist/routing/schema-validation.d.ts.map +1 -0
  324. package/dist/routing/segment-classify.d.ts +75 -0
  325. package/dist/routing/segment-classify.d.ts.map +1 -0
  326. package/dist/routing/segment-codegen.d.ts +38 -0
  327. package/dist/routing/segment-codegen.d.ts.map +1 -0
  328. package/dist/routing/types.d.ts +77 -25
  329. package/dist/routing/types.d.ts.map +1 -1
  330. package/dist/routing/walkers.d.ts +51 -0
  331. package/dist/routing/walkers.d.ts.map +1 -0
  332. package/dist/rsc-runtime/rsc.d.ts +1 -1
  333. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  334. package/dist/rsc-runtime/ssr.d.ts +12 -0
  335. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  336. package/dist/schema-bridge.d.ts +91 -0
  337. package/dist/schema-bridge.d.ts.map +1 -0
  338. package/dist/search-params/define.d.ts +157 -0
  339. package/dist/search-params/define.d.ts.map +1 -0
  340. package/dist/search-params/index.d.ts +4 -7
  341. package/dist/search-params/index.d.ts.map +1 -1
  342. package/dist/search-params/index.js +37 -440
  343. package/dist/search-params/index.js.map +1 -1
  344. package/dist/search-params/registry.d.ts +2 -2
  345. package/dist/search-params/registry.d.ts.map +1 -1
  346. package/dist/search-params/wrappers.d.ts +53 -0
  347. package/dist/search-params/wrappers.d.ts.map +1 -0
  348. package/dist/segment-params/define.d.ts +89 -0
  349. package/dist/segment-params/define.d.ts.map +1 -0
  350. package/dist/segment-params/index.d.ts +3 -0
  351. package/dist/segment-params/index.d.ts.map +1 -0
  352. package/dist/segment-params/index.js +2 -0
  353. package/dist/server/access-gate.d.ts +8 -3
  354. package/dist/server/access-gate.d.ts.map +1 -1
  355. package/dist/server/action-client.d.ts +41 -6
  356. package/dist/server/action-client.d.ts.map +1 -1
  357. package/dist/server/action-encryption.d.ts +76 -0
  358. package/dist/server/action-encryption.d.ts.map +1 -0
  359. package/dist/server/action-handler.d.ts +35 -1
  360. package/dist/server/action-handler.d.ts.map +1 -1
  361. package/dist/server/actions.d.ts +9 -30
  362. package/dist/server/actions.d.ts.map +1 -1
  363. package/dist/server/als-registry.d.ts +70 -11
  364. package/dist/server/als-registry.d.ts.map +1 -1
  365. package/dist/server/asset-headers.d.ts +1 -15
  366. package/dist/server/asset-headers.d.ts.map +1 -1
  367. package/dist/server/body-limits.d.ts.map +1 -1
  368. package/dist/server/build-manifest.d.ts +6 -29
  369. package/dist/server/build-manifest.d.ts.map +1 -1
  370. package/dist/server/canonicalize.d.ts +10 -0
  371. package/dist/server/canonicalize.d.ts.map +1 -1
  372. package/dist/server/coalesce-tick.d.ts +40 -0
  373. package/dist/server/coalesce-tick.d.ts.map +1 -0
  374. package/dist/server/cookie-context.d.ts +170 -0
  375. package/dist/server/cookie-context.d.ts.map +1 -0
  376. package/dist/server/cookie-parsing.d.ts +51 -0
  377. package/dist/server/cookie-parsing.d.ts.map +1 -0
  378. package/dist/server/csrf.d.ts +3 -2
  379. package/dist/server/csrf.d.ts.map +1 -1
  380. package/dist/server/default-logger.d.ts +22 -0
  381. package/dist/server/default-logger.d.ts.map +1 -0
  382. package/dist/server/deny-boundary.d.ts +115 -0
  383. package/dist/server/deny-boundary.d.ts.map +1 -0
  384. package/dist/server/deny-renderer.d.ts +2 -2
  385. package/dist/server/deny-renderer.d.ts.map +1 -1
  386. package/dist/server/dev-source-map.d.ts +22 -0
  387. package/dist/server/dev-source-map.d.ts.map +1 -0
  388. package/dist/server/early-hints-sender.d.ts.map +1 -1
  389. package/dist/server/early-hints.d.ts +13 -11
  390. package/dist/server/early-hints.d.ts.map +1 -1
  391. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  392. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  393. package/dist/server/fallback-error.d.ts +12 -7
  394. package/dist/server/fallback-error.d.ts.map +1 -1
  395. package/dist/server/flight-injection-state.d.ts +66 -0
  396. package/dist/server/flight-injection-state.d.ts.map +1 -0
  397. package/dist/server/flight-scripts.d.ts +42 -0
  398. package/dist/server/flight-scripts.d.ts.map +1 -0
  399. package/dist/server/form-data.d.ts +29 -0
  400. package/dist/server/form-data.d.ts.map +1 -1
  401. package/dist/server/html-injector-core.d.ts +221 -0
  402. package/dist/server/html-injector-core.d.ts.map +1 -0
  403. package/dist/server/html-injectors.d.ts +81 -41
  404. package/dist/server/html-injectors.d.ts.map +1 -1
  405. package/dist/server/index.d.ts +10 -46
  406. package/dist/server/index.d.ts.map +1 -1
  407. package/dist/server/index.js +170 -2911
  408. package/dist/server/index.js.map +1 -1
  409. package/dist/server/internal.d.ts +44 -0
  410. package/dist/server/internal.d.ts.map +1 -0
  411. package/dist/server/internal.js +3015 -0
  412. package/dist/server/internal.js.map +1 -0
  413. package/dist/server/logger.d.ts +39 -7
  414. package/dist/server/logger.d.ts.map +1 -1
  415. package/dist/server/metadata-routes.d.ts +23 -7
  416. package/dist/server/metadata-routes.d.ts.map +1 -1
  417. package/dist/server/middleware-runner.d.ts +36 -4
  418. package/dist/server/middleware-runner.d.ts.map +1 -1
  419. package/dist/server/node-stream-transforms.d.ts +119 -0
  420. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  421. package/dist/server/param-coercion.d.ts +54 -0
  422. package/dist/server/param-coercion.d.ts.map +1 -0
  423. package/dist/server/pipeline-helpers.d.ts +95 -0
  424. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  425. package/dist/server/pipeline-interception.d.ts +1 -1
  426. package/dist/server/pipeline-interception.d.ts.map +1 -1
  427. package/dist/server/pipeline-metadata.d.ts +6 -0
  428. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  429. package/dist/server/pipeline-outcome.d.ts +49 -0
  430. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  431. package/dist/server/pipeline-phases.d.ts +56 -0
  432. package/dist/server/pipeline-phases.d.ts.map +1 -0
  433. package/dist/server/pipeline.d.ts +122 -19
  434. package/dist/server/pipeline.d.ts.map +1 -1
  435. package/dist/server/port-resolution.d.ts +117 -0
  436. package/dist/server/port-resolution.d.ts.map +1 -0
  437. package/dist/server/primitives.d.ts +75 -31
  438. package/dist/server/primitives.d.ts.map +1 -1
  439. package/dist/server/render-timeout.d.ts +51 -0
  440. package/dist/server/render-timeout.d.ts.map +1 -0
  441. package/dist/server/render-utils.d.ts +25 -0
  442. package/dist/server/render-utils.d.ts.map +1 -0
  443. package/dist/server/request-context.d.ts +62 -107
  444. package/dist/server/request-context.d.ts.map +1 -1
  445. package/dist/server/route-element-builder.d.ts +30 -18
  446. package/dist/server/route-element-builder.d.ts.map +1 -1
  447. package/dist/server/route-handler.d.ts.map +1 -1
  448. package/dist/server/route-matcher.d.ts +25 -36
  449. package/dist/server/route-matcher.d.ts.map +1 -1
  450. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  451. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  452. package/dist/server/rsc-entry/api-handler.d.ts +12 -3
  453. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  454. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  455. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  456. package/dist/server/rsc-entry/helpers.d.ts +51 -23
  457. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  458. package/dist/server/rsc-entry/index.d.ts +19 -8
  459. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  460. package/dist/server/rsc-entry/render-route.d.ts +50 -0
  461. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  462. package/dist/server/rsc-entry/revalidate-renderer.d.ts +108 -0
  463. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -0
  464. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
  465. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  466. package/dist/server/rsc-entry/rsc-stream.d.ts +17 -1
  467. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  468. package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
  469. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  470. package/dist/server/rsc-entry/ssr-renderer.d.ts +34 -4
  471. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  472. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
  473. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  474. package/dist/server/safe-load.d.ts +46 -0
  475. package/dist/server/safe-load.d.ts.map +1 -0
  476. package/dist/server/sensitive-fields.d.ts +74 -0
  477. package/dist/server/sensitive-fields.d.ts.map +1 -0
  478. package/dist/server/sitemap-generator.d.ts +129 -0
  479. package/dist/server/sitemap-generator.d.ts.map +1 -0
  480. package/dist/server/sitemap-handler.d.ts +22 -0
  481. package/dist/server/sitemap-handler.d.ts.map +1 -0
  482. package/dist/server/slot-resolver.d.ts +7 -5
  483. package/dist/server/slot-resolver.d.ts.map +1 -1
  484. package/dist/server/ssr-bridge-types.d.ts +121 -0
  485. package/dist/server/ssr-bridge-types.d.ts.map +1 -0
  486. package/dist/server/ssr-entry.d.ts +2 -43
  487. package/dist/server/ssr-entry.d.ts.map +1 -1
  488. package/dist/server/ssr-render.d.ts +64 -21
  489. package/dist/server/ssr-render.d.ts.map +1 -1
  490. package/dist/server/ssr-wrappers.d.ts +50 -0
  491. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  492. package/dist/server/state-tree-diff.d.ts +12 -5
  493. package/dist/server/state-tree-diff.d.ts.map +1 -1
  494. package/dist/server/status-code-resolver.d.ts +22 -11
  495. package/dist/server/status-code-resolver.d.ts.map +1 -1
  496. package/dist/server/stream-utils.d.ts +36 -0
  497. package/dist/server/stream-utils.d.ts.map +1 -0
  498. package/dist/server/tracing.d.ts +7 -6
  499. package/dist/server/tracing.d.ts.map +1 -1
  500. package/dist/server/tree-builder.d.ts +62 -30
  501. package/dist/server/tree-builder.d.ts.map +1 -1
  502. package/dist/server/tree-match.d.ts +49 -0
  503. package/dist/server/tree-match.d.ts.map +1 -0
  504. package/dist/server/types.d.ts +71 -6
  505. package/dist/server/types.d.ts.map +1 -1
  506. package/dist/server/utils/escape-html.d.ts +14 -0
  507. package/dist/server/utils/escape-html.d.ts.map +1 -0
  508. package/dist/server/utils/mdx-file.d.ts +15 -0
  509. package/dist/server/utils/mdx-file.d.ts.map +1 -0
  510. package/dist/server/version-skew.d.ts +61 -0
  511. package/dist/server/version-skew.d.ts.map +1 -0
  512. package/dist/shared/head-header.d.ts +54 -0
  513. package/dist/shared/head-header.d.ts.map +1 -0
  514. package/dist/shared/href-validation.d.ts +49 -0
  515. package/dist/shared/href-validation.d.ts.map +1 -0
  516. package/dist/shared/merge-search-params.d.ts +22 -0
  517. package/dist/shared/merge-search-params.d.ts.map +1 -0
  518. package/dist/shared/redirect-type.d.ts +17 -0
  519. package/dist/shared/redirect-type.d.ts.map +1 -0
  520. package/dist/shims/font-google.d.ts +1 -1
  521. package/dist/shims/font-google.d.ts.map +1 -1
  522. package/dist/shims/font-google.js +42 -0
  523. package/dist/shims/font-google.js.map +1 -0
  524. package/dist/shims/font-local.d.ts +26 -0
  525. package/dist/shims/font-local.d.ts.map +1 -0
  526. package/dist/shims/font-local.js +20 -0
  527. package/dist/shims/font-local.js.map +1 -0
  528. package/dist/shims/headers.d.ts +53 -1
  529. package/dist/shims/headers.d.ts.map +1 -1
  530. package/dist/shims/image.d.ts +16 -16
  531. package/dist/shims/navigation-client.d.ts +35 -11
  532. package/dist/shims/navigation-client.d.ts.map +1 -1
  533. package/dist/shims/navigation.d.ts +11 -5
  534. package/dist/shims/navigation.d.ts.map +1 -1
  535. package/dist/utils/state-machine.d.ts +80 -0
  536. package/dist/utils/state-machine.d.ts.map +1 -0
  537. package/package.json +63 -24
  538. package/src/adapters/build-output-helper.ts +139 -0
  539. package/src/adapters/cloudflare-dev.ts +177 -0
  540. package/src/adapters/cloudflare-kv-cache.ts +179 -0
  541. package/src/adapters/cloudflare.ts +356 -116
  542. package/src/adapters/compress-module.ts +27 -92
  543. package/src/adapters/nitro.ts +155 -99
  544. package/src/adapters/raw-imports.d.ts +5 -0
  545. package/src/adapters/shared.ts +40 -0
  546. package/src/adapters/wrangler.d.ts +7 -0
  547. package/src/cache/cache-api.ts +47 -0
  548. package/src/cache/handler-store.ts +68 -0
  549. package/src/cache/index.ts +84 -18
  550. package/src/cache/invalidation-epoch.ts +93 -0
  551. package/src/cache/redis-handler.ts +110 -15
  552. package/src/cache/singleflight.ts +62 -4
  553. package/src/cache/sizeof.ts +33 -0
  554. package/src/cache/stable-stringify.ts +65 -2
  555. package/src/cache/timber-cache.ts +132 -36
  556. package/src/cli-schema-sync.ts +388 -0
  557. package/src/cli.ts +98 -34
  558. package/src/client/browser-dev.ts +153 -1
  559. package/src/client/browser-entry/action-dispatch.ts +119 -0
  560. package/src/client/browser-entry/hmr.ts +70 -0
  561. package/src/client/browser-entry/hydrate.ts +187 -0
  562. package/src/client/browser-entry/index.ts +111 -0
  563. package/src/client/browser-entry/post-hydration.ts +104 -0
  564. package/src/client/browser-entry/router-init.ts +292 -0
  565. package/src/client/browser-entry/rsc-stream.ts +157 -0
  566. package/src/client/browser-entry/scroll.ts +50 -0
  567. package/src/client/error-boundary.tsx +127 -22
  568. package/src/client/error-reconstituter.tsx +79 -0
  569. package/src/client/form.tsx +31 -32
  570. package/src/client/history.ts +11 -3
  571. package/src/client/index.ts +67 -45
  572. package/src/client/internal.ts +58 -0
  573. package/src/client/link.tsx +346 -150
  574. package/src/client/navigation-api-types.ts +112 -0
  575. package/src/client/navigation-api.ts +347 -0
  576. package/src/client/navigation-context.ts +15 -7
  577. package/src/client/navigation-root.tsx +355 -0
  578. package/src/client/nuqs-adapter.tsx +16 -3
  579. package/src/client/router-ref.ts +1 -1
  580. package/src/client/router.ts +490 -140
  581. package/src/client/rsc-fetch.ts +220 -17
  582. package/src/client/segment-cache.ts +6 -3
  583. package/src/client/segment-outlet.tsx +77 -0
  584. package/src/client/segment-update-context.ts +42 -0
  585. package/src/client/shallow-url.ts +22 -0
  586. package/src/client/ssr-data.ts +13 -5
  587. package/src/client/state.ts +2 -2
  588. package/src/client/top-loader.tsx +11 -9
  589. package/src/client/use-cookie.ts +31 -2
  590. package/src/client/use-link-status.ts +7 -7
  591. package/src/client/use-pathname.ts +1 -0
  592. package/src/client/use-pending-navigation.ts +40 -0
  593. package/src/client/use-query-states.ts +9 -3
  594. package/src/client/use-router.ts +4 -1
  595. package/src/client/use-search-params.ts +31 -44
  596. package/src/client/{use-params.ts → use-segment-params.ts} +9 -6
  597. package/src/codec.ts +147 -0
  598. package/src/config-types.ts +292 -0
  599. package/src/config-validation.ts +311 -0
  600. package/src/content/index.ts +5 -13
  601. package/src/cookies/define-cookie.ts +217 -53
  602. package/src/cookies/index.ts +12 -1
  603. package/src/cookies/json-cookie.ts +105 -0
  604. package/src/cookies/validation.ts +192 -0
  605. package/src/dev-tools/404-page.ts +286 -0
  606. package/src/dev-tools/browser-logs.ts +291 -0
  607. package/src/dev-tools/dev-page-shell.ts +260 -0
  608. package/src/dev-tools/error-page.ts +331 -0
  609. package/src/dev-tools/holding-server.ts +187 -0
  610. package/src/dev-tools/hydration-overlay.ts +158 -0
  611. package/src/dev-tools/index.ts +83 -0
  612. package/src/dev-tools/instrumentation.ts +213 -0
  613. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +9 -5
  614. package/src/dev-tools/overlay.ts +469 -0
  615. package/src/dev-tools/stack-classifier.ts +75 -0
  616. package/src/dev-tools/terminal.ts +183 -0
  617. package/src/fonts/ast-walk.ts +235 -0
  618. package/src/fonts/ast.ts +477 -126
  619. package/src/fonts/bundle.ts +138 -0
  620. package/src/fonts/dev-middleware.ts +85 -0
  621. package/src/fonts/fallbacks.ts +0 -23
  622. package/src/fonts/google.ts +7 -3
  623. package/src/fonts/local.ts +9 -8
  624. package/src/fonts/paths.ts +58 -0
  625. package/src/fonts/pipeline.ts +316 -0
  626. package/src/fonts/transform.ts +344 -0
  627. package/src/fonts/types.ts +52 -1
  628. package/src/fonts/virtual-modules.ts +179 -0
  629. package/src/index.ts +417 -346
  630. package/src/params/codec-registry.ts +34 -0
  631. package/src/params/define-schema.ts +115 -0
  632. package/src/params/index.ts +17 -0
  633. package/src/params/resolve-schema.ts +84 -0
  634. package/src/plugin-context.ts +325 -0
  635. package/src/plugins/adapter-build.ts +98 -4
  636. package/src/plugins/build-manifest.ts +168 -23
  637. package/src/plugins/build-report.ts +16 -25
  638. package/src/plugins/cache.ts +285 -0
  639. package/src/plugins/client-chunks.ts +113 -0
  640. package/src/plugins/cloudflare-wasm.ts +141 -0
  641. package/src/plugins/content.ts +1 -1
  642. package/src/plugins/dev-server.ts +293 -46
  643. package/src/plugins/entries.ts +110 -8
  644. package/src/plugins/fonts.ts +170 -663
  645. package/src/plugins/mdx.ts +47 -10
  646. package/src/plugins/routing.ts +237 -241
  647. package/src/plugins/server-bundle.ts +85 -12
  648. package/src/plugins/shims.ts +207 -64
  649. package/src/plugins/static-build.ts +15 -89
  650. package/src/routing/codegen-shared.ts +115 -0
  651. package/src/routing/codegen-types.ts +65 -0
  652. package/src/routing/codegen.ts +380 -178
  653. package/src/routing/convention-lint.ts +358 -0
  654. package/src/routing/file-cache.ts +23 -0
  655. package/src/routing/index.ts +10 -1
  656. package/src/routing/interception.ts +3 -22
  657. package/src/routing/link-codegen.ts +310 -0
  658. package/src/routing/manifest-codegen.ts +290 -0
  659. package/src/routing/scanner.ts +248 -188
  660. package/src/routing/schema-validation.ts +149 -0
  661. package/src/routing/segment-classify.ts +188 -0
  662. package/src/routing/segment-codegen.ts +98 -0
  663. package/src/routing/types.ts +78 -25
  664. package/src/routing/walkers.ts +90 -0
  665. package/src/rsc-runtime/rsc.ts +2 -0
  666. package/src/rsc-runtime/ssr.ts +50 -0
  667. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  668. package/src/schema-bridge.ts +252 -0
  669. package/src/search-params/define.ts +570 -0
  670. package/src/search-params/index.ts +14 -20
  671. package/src/search-params/registry.ts +2 -2
  672. package/src/search-params/wrappers.ts +110 -0
  673. package/src/segment-params/define.ts +249 -0
  674. package/src/segment-params/index.ts +9 -0
  675. package/src/server/access-gate.tsx +84 -34
  676. package/src/server/action-client.ts +119 -28
  677. package/src/server/action-encryption.ts +144 -0
  678. package/src/server/action-handler.ts +122 -16
  679. package/src/server/actions.ts +39 -53
  680. package/src/server/als-registry.ts +108 -20
  681. package/src/server/asset-headers.ts +8 -34
  682. package/src/server/body-limits.ts +10 -2
  683. package/src/server/build-manifest.ts +13 -56
  684. package/src/server/canonicalize.ts +6 -3
  685. package/src/server/coalesce-tick.ts +75 -0
  686. package/src/server/compress.ts +34 -7
  687. package/src/server/cookie-context.ts +484 -0
  688. package/src/server/cookie-parsing.ts +147 -0
  689. package/src/server/csrf.ts +39 -6
  690. package/src/server/default-logger.ts +99 -0
  691. package/src/server/deny-boundary.ts +311 -0
  692. package/src/server/deny-renderer.ts +80 -64
  693. package/src/server/dev-source-map.ts +31 -0
  694. package/src/server/early-hints-sender.ts +3 -2
  695. package/src/server/early-hints.ts +37 -27
  696. package/src/server/error-boundary-wrapper.ts +61 -22
  697. package/src/server/fallback-error.ts +79 -102
  698. package/src/server/flight-injection-state.ts +113 -0
  699. package/src/server/flight-scripts.ts +62 -0
  700. package/src/server/form-data.ts +101 -5
  701. package/src/server/html-injector-core.ts +437 -0
  702. package/src/server/html-injectors.ts +256 -251
  703. package/src/server/index.ts +29 -183
  704. package/src/server/internal.ts +165 -0
  705. package/src/server/logger.ts +67 -36
  706. package/src/server/metadata-routes.ts +44 -19
  707. package/src/server/middleware-runner.ts +75 -4
  708. package/src/server/node-stream-transforms.ts +331 -0
  709. package/src/server/param-coercion.ts +206 -0
  710. package/src/server/pipeline-helpers.ts +204 -0
  711. package/src/server/pipeline-interception.ts +32 -18
  712. package/src/server/pipeline-metadata.ts +13 -0
  713. package/src/server/pipeline-outcome.ts +197 -0
  714. package/src/server/pipeline-phases.ts +527 -0
  715. package/src/server/pipeline.ts +213 -382
  716. package/src/server/port-resolution.ts +215 -0
  717. package/src/server/primitives.ts +126 -63
  718. package/src/server/render-timeout.ts +108 -0
  719. package/src/server/render-utils.ts +31 -0
  720. package/src/server/request-context.ts +168 -337
  721. package/src/server/route-element-builder.ts +481 -222
  722. package/src/server/route-handler.ts +31 -4
  723. package/src/server/route-matcher.ts +144 -277
  724. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  725. package/src/server/rsc-entry/api-handler.ts +69 -32
  726. package/src/server/rsc-entry/error-renderer.ts +306 -89
  727. package/src/server/rsc-entry/helpers.ts +160 -59
  728. package/src/server/rsc-entry/index.ts +299 -329
  729. package/src/server/rsc-entry/render-route.ts +311 -0
  730. package/src/server/rsc-entry/revalidate-renderer.ts +344 -0
  731. package/src/server/rsc-entry/rsc-payload.ts +71 -26
  732. package/src/server/rsc-entry/rsc-stream.ts +85 -13
  733. package/src/server/rsc-entry/ssr-bridge.ts +18 -5
  734. package/src/server/rsc-entry/ssr-renderer.ts +273 -43
  735. package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
  736. package/src/server/safe-load.ts +60 -0
  737. package/src/server/sensitive-fields.ts +230 -0
  738. package/src/server/sitemap-generator.ts +338 -0
  739. package/src/server/sitemap-handler.ts +148 -0
  740. package/src/server/slot-resolver.ts +258 -257
  741. package/src/server/ssr-bridge-types.ts +124 -0
  742. package/src/server/ssr-entry.ts +206 -78
  743. package/src/server/ssr-render.ts +345 -82
  744. package/src/server/ssr-wrappers.tsx +141 -0
  745. package/src/server/state-tree-diff.ts +30 -23
  746. package/src/server/status-code-resolver.ts +115 -130
  747. package/src/server/stream-utils.ts +213 -0
  748. package/src/server/tracing.ts +38 -11
  749. package/src/server/tree-builder.ts +204 -90
  750. package/src/server/tree-match.ts +220 -0
  751. package/src/server/types.ts +78 -9
  752. package/src/server/utils/escape-html.ts +20 -0
  753. package/src/server/utils/mdx-file.ts +22 -0
  754. package/src/server/version-skew.ts +104 -0
  755. package/src/shared/head-header.ts +69 -0
  756. package/src/shared/href-validation.ts +159 -0
  757. package/src/shared/merge-search-params.ts +55 -0
  758. package/src/shared/redirect-type.ts +17 -0
  759. package/src/shims/font-google.ts +1 -1
  760. package/src/shims/font-local.ts +34 -0
  761. package/src/shims/headers.ts +122 -1
  762. package/src/shims/navigation-client.ts +51 -29
  763. package/src/shims/navigation.ts +14 -7
  764. package/src/utils/state-machine.ts +111 -0
  765. package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
  766. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  767. package/dist/_chunks/debug-B3Gypr3D.js +0 -108
  768. package/dist/_chunks/debug-B3Gypr3D.js.map +0 -1
  769. package/dist/_chunks/format-RyoGQL74.js +0 -164
  770. package/dist/_chunks/format-RyoGQL74.js.map +0 -1
  771. package/dist/_chunks/interception-BOoWmLUA.js +0 -676
  772. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  773. package/dist/_chunks/metadata-routes-Cjmvi3rQ.js.map +0 -1
  774. package/dist/_chunks/request-context-BQUC8PHn.js +0 -330
  775. package/dist/_chunks/request-context-BQUC8PHn.js.map +0 -1
  776. package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
  777. package/dist/_chunks/tracing-CemImE6h.js +0 -187
  778. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  779. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  780. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  781. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  782. package/dist/cache/register-cached-function.d.ts +0 -17
  783. package/dist/cache/register-cached-function.d.ts.map +0 -1
  784. package/dist/client/browser-entry.d.ts +0 -21
  785. package/dist/client/browser-entry.d.ts.map +0 -1
  786. package/dist/client/link-status-provider.d.ts +0 -11
  787. package/dist/client/link-status-provider.d.ts.map +0 -1
  788. package/dist/client/segment-merger.d.ts +0 -119
  789. package/dist/client/segment-merger.d.ts.map +0 -1
  790. package/dist/client/stale-reload.d.ts +0 -44
  791. package/dist/client/stale-reload.d.ts.map +0 -1
  792. package/dist/client/transition-root.d.ts +0 -74
  793. package/dist/client/transition-root.d.ts.map +0 -1
  794. package/dist/client/use-navigation-pending.d.ts +0 -26
  795. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  796. package/dist/client/use-params.d.ts.map +0 -1
  797. package/dist/plugins/cache-transform.d.ts +0 -36
  798. package/dist/plugins/cache-transform.d.ts.map +0 -1
  799. package/dist/plugins/dev-error-overlay.d.ts +0 -60
  800. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  801. package/dist/plugins/dev-logs.d.ts.map +0 -1
  802. package/dist/plugins/dynamic-transform.d.ts +0 -72
  803. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  804. package/dist/plugins/server-action-exports.d.ts +0 -26
  805. package/dist/plugins/server-action-exports.d.ts.map +0 -1
  806. package/dist/routing/status-file-lint.d.ts +0 -33
  807. package/dist/routing/status-file-lint.d.ts.map +0 -1
  808. package/dist/search-params/analyze.d.ts +0 -54
  809. package/dist/search-params/analyze.d.ts.map +0 -1
  810. package/dist/search-params/builtin-codecs.d.ts +0 -105
  811. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  812. package/dist/search-params/codecs.d.ts +0 -53
  813. package/dist/search-params/codecs.d.ts.map +0 -1
  814. package/dist/search-params/create.d.ts +0 -106
  815. package/dist/search-params/create.d.ts.map +0 -1
  816. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  817. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  818. package/dist/server/dev-logger.d.ts.map +0 -1
  819. package/dist/server/dev-span-processor.d.ts +0 -29
  820. package/dist/server/dev-span-processor.d.ts.map +0 -1
  821. package/dist/server/dev-warnings.d.ts +0 -129
  822. package/dist/server/dev-warnings.d.ts.map +0 -1
  823. package/dist/server/flush.d.ts +0 -74
  824. package/dist/server/flush.d.ts.map +0 -1
  825. package/dist/server/manifest-status-resolver.d.ts +0 -58
  826. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  827. package/dist/server/prerender.d.ts +0 -77
  828. package/dist/server/prerender.d.ts.map +0 -1
  829. package/dist/utils/directive-parser.d.ts +0 -70
  830. package/dist/utils/directive-parser.d.ts.map +0 -1
  831. package/src/cache/register-cached-function.ts +0 -103
  832. package/src/client/browser-entry.ts +0 -678
  833. package/src/client/link-status-provider.tsx +0 -30
  834. package/src/client/segment-merger.ts +0 -339
  835. package/src/client/stale-reload.ts +0 -87
  836. package/src/client/transition-root.tsx +0 -166
  837. package/src/client/use-navigation-pending.ts +0 -38
  838. package/src/plugins/cache-transform.ts +0 -199
  839. package/src/plugins/dev-error-overlay.ts +0 -230
  840. package/src/plugins/dynamic-transform.ts +0 -161
  841. package/src/plugins/server-action-exports.ts +0 -220
  842. package/src/routing/status-file-lint.ts +0 -112
  843. package/src/search-params/analyze.ts +0 -192
  844. package/src/search-params/builtin-codecs.ts +0 -228
  845. package/src/search-params/codecs.ts +0 -153
  846. package/src/search-params/create.ts +0 -321
  847. package/src/server/dev-fetch-instrumentation.ts +0 -96
  848. package/src/server/dev-span-processor.ts +0 -78
  849. package/src/server/dev-warnings.ts +0 -283
  850. package/src/server/flush.ts +0 -182
  851. package/src/server/manifest-status-resolver.ts +0 -215
  852. package/src/server/prerender.ts +0 -139
  853. package/src/utils/directive-parser.ts +0 -529
  854. /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
@@ -5,10 +5,20 @@ import { SegmentCache, PrefetchCache, buildSegmentTree } from './segment-cache';
5
5
  import type { SegmentInfo } from './segment-cache';
6
6
  import { HistoryStack } from './history';
7
7
  import type { HeadElement } from './head';
8
- import { setCurrentParams } from './use-params.js';
9
- import { setNavigationState } from './navigation-context.js';
10
- import { SegmentElementCache, cacheSegmentElements, mergeSegmentTree } from './segment-merger.js';
11
- import { fetchRscPayload, RedirectError } from './rsc-fetch.js';
8
+ import { setCurrentParams } from './use-segment-params.js';
9
+ import {
10
+ setNavigationState,
11
+ getNavigationState,
12
+ type NavigationState,
13
+ } from './navigation-context.js';
14
+
15
+ import {
16
+ fetchRscPayload,
17
+ RedirectError,
18
+ ServerErrorResponse,
19
+ VersionSkewError,
20
+ } from './rsc-fetch.js';
21
+ import { setHardNavigating, supersedeNavigationTransitions } from './navigation-root.js';
12
22
  import type { FetchResult } from './rsc-fetch.js';
13
23
 
14
24
  // ─── Types ───────────────────────────────────────────────────────
@@ -18,6 +28,19 @@ export interface NavigationOptions {
18
28
  scroll?: boolean;
19
29
  /** Use replaceState instead of pushState (replaces current history entry) */
20
30
  replace?: boolean;
31
+ /**
32
+ * @internal AbortSignal from the Navigation API's NavigateEvent.
33
+ * When provided, the signal is linked to the router's per-navigation
34
+ * AbortController so in-flight RSC fetches are cancelled when a new
35
+ * navigation starts.
36
+ */
37
+ _signal?: AbortSignal;
38
+ /**
39
+ * @internal Skip pushState/replaceState — the Navigation API has already
40
+ * updated the URL via event.intercept(). Used for external navigations
41
+ * intercepted by the navigate event handler.
42
+ */
43
+ _skipHistory?: boolean;
21
44
  }
22
45
 
23
46
  /**
@@ -31,8 +54,12 @@ export type RscDecoder = (fetchPromise: Promise<Response>) => unknown;
31
54
  * Function that renders a decoded RSC element tree into the DOM.
32
55
  * In production: reactRoot.render(element).
33
56
  * In tests: a no-op or mock.
57
+ *
58
+ * Receives the current NavigationState explicitly — no temporal
59
+ * coupling with setNavigationState/getNavigationState. The renderer
60
+ * wraps the element in NavigationProvider with this state.
34
61
  */
35
- export type RootRenderer = (element: unknown) => void;
62
+ export type RootRenderer = (element: unknown, navState: NavigationState) => void;
36
63
 
37
64
  /**
38
65
  * Platform dependencies injected for testability. In production these
@@ -64,14 +91,73 @@ export interface RouterDeps {
64
91
  *
65
92
  * The `perform` callback receives a `wrapPayload` function to wrap the
66
93
  * decoded RSC payload with NavigationProvider + NuqsAdapter before
67
- * TransitionRoot sets it as the new element.
94
+ * NavigationRoot sets it as the new element. The `wrapPayload` function
95
+ * receives the NavigationState explicitly — no temporal coupling with
96
+ * getNavigationState().
68
97
  *
69
98
  * If not provided (tests), the router falls back to renderRoot.
70
99
  */
71
100
  navigateTransition?: (
72
101
  pendingUrl: string,
73
- perform: (wrapPayload: (payload: unknown) => unknown) => Promise<unknown>
102
+ perform: (
103
+ wrapPayload: (
104
+ payload: unknown,
105
+ navState: NavigationState,
106
+ segmentUpdates?: Map<string, unknown>
107
+ ) => unknown
108
+ ) => Promise<{ element: unknown; decodePromise: Promise<void> | null }>
74
109
  ) => Promise<void>;
110
+
111
+ /**
112
+ * Whether the Navigation API is active and handling traversals.
113
+ * When true, the popstate handler is a no-op — the Navigation API's
114
+ * navigate event covers back/forward button presses.
115
+ */
116
+ navigationApiActive?: boolean;
117
+
118
+ /**
119
+ * Called around pushState/replaceState to set a flag that prevents
120
+ * the Navigation API's navigate listener from double-handling
121
+ * router-initiated navigations.
122
+ */
123
+ setRouterNavigating?: (value: boolean) => void;
124
+
125
+ /**
126
+ * Save scroll position via the Navigation API's per-entry state.
127
+ * When provided, used instead of history.replaceState for scroll storage.
128
+ */
129
+ saveNavigationEntryScroll?: (scrollY: number) => void;
130
+
131
+ /**
132
+ * Signal that a router-initiated navigation has completed. Resolves the
133
+ * deferred promise that ties the browser's native loading state to the
134
+ * navigation lifecycle. Called in the finally block of navigate/refresh,
135
+ * aligned with when the TopLoader's pendingUrl clears.
136
+ */
137
+ completeRouterNavigation?: () => void;
138
+
139
+ /**
140
+ * Get the current unwrapped RSC payload element. Used for partial
141
+ * navigation: the router re-wraps the same element with new
142
+ * NavigationProvider context so mounted SegmentOutlets are preserved.
143
+ */
144
+ _getCurrentPayload?: () => unknown;
145
+
146
+ /**
147
+ * Initiate a navigation via the Navigation API (`navigation.navigate()`).
148
+ * Fires the navigate event BEFORE committing the URL, allowing Chrome
149
+ * to show its native loading indicator. Falls back to pushState when
150
+ * unavailable.
151
+ */
152
+ navigationNavigate?: (url: string, replace: boolean) => void;
153
+
154
+ /**
155
+ * Scroll the element matching a URL #fragment into view. Returns true
156
+ * when a matching element was found and scrolled. When absent or false,
157
+ * the router falls back to scroll-to-top on forward navigation — same
158
+ * as a full page load with an unknown fragment landing at the top.
159
+ */
160
+ scrollToHash?: (hash: string) => boolean;
75
161
  }
76
162
 
77
163
  export interface RouterInstance {
@@ -80,7 +166,7 @@ export interface RouterInstance {
80
166
  /** Full re-render of the current URL — no state tree sent */
81
167
  refresh(): Promise<void>;
82
168
  /** Handle a popstate event (back/forward button). scrollY is read from history.state. */
83
- handlePopState(url: string, scrollY?: number): Promise<void>;
169
+ handlePopState(url: string, scrollY?: number, externalSignal?: AbortSignal): Promise<void>;
84
170
  /** Whether a navigation is currently in flight */
85
171
  isPending(): boolean;
86
172
  /** The URL currently being navigated to, or null if idle */
@@ -100,12 +186,7 @@ export interface RouterInstance {
100
186
  * Called on initial hydration with segment info embedded in the HTML.
101
187
  */
102
188
  initSegmentCache(segments: SegmentInfo[]): void;
103
- /**
104
- * Cache segment elements from a decoded RSC element tree.
105
- * Called on initial hydration to populate the element cache so the
106
- * first client navigation can use partial payloads.
107
- */
108
- cacheElementTree(element: unknown): void;
189
+
109
190
  /** The segment cache (exposed for tests and <Link> prefetch) */
110
191
  segmentCache: SegmentCache;
111
192
  /** The prefetch cache (exposed for tests and <Link> prefetch) */
@@ -130,24 +211,83 @@ function isAbortError(error: unknown): boolean {
130
211
  * Create a router instance. In production, called once at app hydration
131
212
  * with real browser APIs. In tests, called with mock dependencies.
132
213
  */
214
+ /**
215
+ * Router navigation phase — discriminated union replacing scattered
216
+ * `pending` + `pendingUrl` boolean flags.
217
+ *
218
+ * - `idle`: No navigation in flight. The committed params/pathname
219
+ * are current.
220
+ * - `navigating`: A fetch or render is in progress. `targetUrl` is
221
+ * the destination being navigated to.
222
+ */
223
+ export type RouterPhase = { phase: 'idle' } | { phase: 'navigating'; targetUrl: string };
224
+
133
225
  export function createRouter(deps: RouterDeps): RouterInstance {
134
226
  const segmentCache = new SegmentCache();
135
227
  const prefetchCache = new PrefetchCache();
136
228
  const historyStack = new HistoryStack();
137
- const segmentElementCache = new SegmentElementCache();
138
-
139
- let pending = false;
140
- let pendingUrl: string | null = null;
229
+ let routerPhase: RouterPhase = { phase: 'idle' };
141
230
  const pendingListeners = new Set<(pending: boolean) => void>();
142
231
 
232
+ // AbortController for the current in-flight navigation.
233
+ // When a new navigation starts, the previous controller is aborted,
234
+ // cancelling any in-progress RSC fetch. This provides automatic
235
+ // cancellation of stale fetches regardless of Navigation API support.
236
+ let currentNavAbort: AbortController | null = null;
237
+
238
+ /**
239
+ * Create a new AbortController for a navigation, superseding any
240
+ * previous in-flight navigation. Optionally links to an external
241
+ * signal (e.g., from the Navigation API's NavigateEvent.signal).
242
+ *
243
+ * Superseding is one operation with three parts:
244
+ * 1. Abort the previous navigation's fetch.
245
+ * 2. Invalidate its render transition so a response that already
246
+ * arrived can't commit a stale tree (NavigationRoot's transId guard).
247
+ * 3. Resolve its Navigation API deferred — the superseded navigation's
248
+ * finally block is staleness-guarded (see TIM-1034) and no longer
249
+ * cleans up after itself, so the browser's native loading state for
250
+ * the dead navigation is cleared here.
251
+ */
252
+ function createNavAbort(externalSignal?: AbortSignal): AbortController {
253
+ if (currentNavAbort) {
254
+ currentNavAbort.abort();
255
+ supersedeNavigationTransitions();
256
+ deps.completeRouterNavigation?.();
257
+ }
258
+ const controller = new AbortController();
259
+ currentNavAbort = controller;
260
+
261
+ // If an external signal is provided (e.g., Navigation API),
262
+ // forward its abort to our controller.
263
+ if (externalSignal) {
264
+ if (externalSignal.aborted) {
265
+ controller.abort();
266
+ } else {
267
+ externalSignal.addEventListener('abort', () => controller.abort(), { once: true });
268
+ }
269
+ }
270
+
271
+ return controller;
272
+ }
273
+
143
274
  function setPending(value: boolean, url?: string): void {
144
- const newPendingUrl = value && url ? url : null;
145
- if (pending === value && pendingUrl === newPendingUrl) return;
146
- pending = value;
147
- pendingUrl = newPendingUrl;
275
+ const next: RouterPhase =
276
+ value && url ? { phase: 'navigating', targetUrl: url } : { phase: 'idle' };
277
+ // Skip no-op updates
278
+ if (
279
+ routerPhase.phase === next.phase &&
280
+ (routerPhase.phase === 'idle' ||
281
+ (routerPhase.phase === 'navigating' &&
282
+ next.phase === 'navigating' &&
283
+ routerPhase.targetUrl === next.targetUrl))
284
+ ) {
285
+ return;
286
+ }
287
+ routerPhase = next;
148
288
  // Notify external store listeners (non-React consumers).
149
289
  // React-facing pending state is handled by useOptimistic in
150
- // TransitionRoot via navigateTransition — not this function.
290
+ // NavigationRoot via navigateTransition — not this function.
151
291
  for (const listener of pendingListeners) {
152
292
  listener(value);
153
293
  }
@@ -163,94 +303,139 @@ export function createRouter(deps: RouterDeps): RouterInstance {
163
303
  }
164
304
 
165
305
  /** Render a decoded RSC payload into the DOM if a renderer is available. */
166
- function renderPayload(payload: unknown): void {
306
+ function renderPayload(payload: unknown, navState: NavigationState): void {
167
307
  if (deps.renderRoot) {
168
- deps.renderRoot(payload);
308
+ deps.renderRoot(payload, navState);
169
309
  }
170
310
  }
171
311
 
312
+ function isPartialNavigation(skippedSegments: string[] | null | undefined): boolean {
313
+ return skippedSegments != null && skippedSegments.length > 0;
314
+ }
315
+
172
316
  /**
173
- * Merge a partial RSC payload with cached segment elements if segments
174
- * were skipped, then cache segments from the (merged) payload.
175
- * Returns the merged payload ready for rendering.
317
+ * Build a segment updates map for partial navigation. Identifies the
318
+ * first non-skipped segment and maps it to the payload content.
176
319
  */
177
- function mergeAndCachePayload(
178
- payload: unknown,
179
- skippedSegments: string[] | null | undefined
180
- ): unknown {
181
- let merged = payload;
182
-
183
- // If segments were skipped, merge the partial payload with cached segments
184
- if (skippedSegments && skippedSegments.length > 0) {
185
- merged = mergeSegmentTree(payload, skippedSegments, segmentElementCache);
320
+ function buildSegmentUpdates(result: FetchResult): Map<string, unknown> {
321
+ const skipped = new Set(result.skippedSegments!);
322
+ const segmentInfo = result.segmentInfo;
323
+ const updates = new Map<string, unknown>();
324
+ if (segmentInfo) {
325
+ for (const info of segmentInfo) {
326
+ if (!skipped.has(info.segmentId ?? info.path)) {
327
+ // Use segmentId (outlet key) when available — route groups
328
+ // use a disambiguated key like "/(marketing)" instead of "/".
329
+ updates.set(info.segmentId ?? info.path, result.payload);
330
+ break;
331
+ }
332
+ }
186
333
  }
187
-
188
- // Cache segment elements from the (merged) payload for future merges
189
- cacheSegmentElements(merged, segmentElementCache);
190
-
191
- return merged;
334
+ return updates;
192
335
  }
193
336
 
194
337
  /**
195
338
  * Update navigation state (params + pathname) for the next render.
196
339
  *
197
- * Sets both the module-level fallback (for tests and SSR) and the
198
- * navigation context state (read by renderRoot to wrap the element
199
- * in NavigationProvider). The context update is atomic with the tree
200
- * render — both are passed to reactRoot.render() in the same call.
340
+ * Sets the module-level fallback (for tests and SSR) and the
341
+ * globalThis bridge, then returns the NavigationState so callers
342
+ * can pass it explicitly to renderRoot/wrapPayload — eliminating
343
+ * temporal coupling with getNavigationState().
201
344
  */
202
345
  function updateNavigationState(
203
346
  params: Record<string, string | string[]> | null | undefined,
204
347
  url: string
205
- ): void {
348
+ ): NavigationState {
206
349
  const resolvedParams = params ?? {};
207
350
  // Module-level fallback for tests (no NavigationProvider) and SSR
208
351
  setCurrentParams(resolvedParams);
209
- // Navigation context — read by renderRoot to wrap the RSC element
210
- const pathname = url.startsWith('http') ? new URL(url).pathname : url.split('?')[0] || '/';
211
- setNavigationState({ params: resolvedParams, pathname });
352
+ // globalThis bridge — kept for backward compat
353
+ const parsed = new URL(url, 'http://localhost');
354
+ const pathname = parsed.pathname || '/';
355
+ const search = parsed.search;
356
+ const navState: NavigationState = { params: resolvedParams, pathname, search };
357
+ setNavigationState(navState);
358
+ return navState;
212
359
  }
213
360
 
214
361
  /**
215
362
  * Render a payload via navigateTransition (production) or renderRoot (tests).
216
- * The perform callback should fetch data, update state, and return the payload.
217
- * In production, the entire callback runs inside a React transition with
218
- * useOptimistic for the pending URL. In tests, the payload is rendered directly.
363
+ * The perform callback should fetch data, update state, and return the
364
+ * FetchResult plus the NavigationState (so it can be passed explicitly
365
+ * to wrapPayload/renderRoot without temporal coupling).
219
366
  */
367
+ interface TransitionResult {
368
+ headElements: HeadElement[] | null;
369
+ decodePromise: Promise<void> | null;
370
+ }
371
+
220
372
  async function renderViaTransition(
221
373
  url: string,
222
- perform: () => Promise<FetchResult>
223
- ): Promise<HeadElement[] | null> {
374
+ perform: () => Promise<FetchResult & { navState: NavigationState }>
375
+ ): Promise<TransitionResult> {
224
376
  if (deps.navigateTransition) {
225
377
  let headElements: HeadElement[] | null = null;
226
378
  await deps.navigateTransition(url, async (wrapPayload) => {
227
379
  const result = await perform();
228
380
  headElements = result.headElements;
229
- // Merge partial payload with cached segments before wrapping
230
- const merged = mergeAndCachePayload(result.payload, result.skippedSegments);
231
- // Store the MERGED payload in history — not the partial pre-merge tree.
232
- // This ensures handlePopState replays the complete tree on back/forward.
381
+
382
+ if (isPartialNavigation(result.skippedSegments)) {
383
+ const segmentUpdates = buildSegmentUpdates(result);
384
+
385
+ historyStack.push(url, {
386
+ payload: null,
387
+ headElements: result.headElements,
388
+ params: result.params,
389
+ });
390
+
391
+ // Re-wrap the CURRENT element with new context values.
392
+ // SegmentOutlets read updates from SegmentUpdateContext;
393
+ // NavigationProvider gets new params/pathname.
394
+ const element = wrapPayload(
395
+ deps._getCurrentPayload?.() ?? result.payload,
396
+ result.navState,
397
+ segmentUpdates
398
+ );
399
+ return { element, decodePromise: result.decodePromise };
400
+ }
401
+
402
+ // Full navigation — empty updates, render the new tree.
233
403
  historyStack.push(url, {
234
- payload: merged,
404
+ payload: result.payload,
235
405
  headElements: result.headElements,
236
406
  params: result.params,
237
407
  });
238
- return wrapPayload(merged);
408
+ const element = wrapPayload(result.payload, result.navState);
409
+ return { element, decodePromise: result.decodePromise };
239
410
  });
240
- return headElements;
411
+ // decodePromise is awaited inside the transition's startTransition
412
+ // callback (NavigationRoot), so we don't need it here.
413
+ return { headElements, decodePromise: null };
241
414
  }
242
415
  // Fallback: no transition (tests, no React tree)
243
416
  const result = await perform();
244
- // Merge partial payload with cached segments before rendering
245
- const merged = mergeAndCachePayload(result.payload, result.skippedSegments);
246
- // Store merged payload in history
247
- historyStack.push(url, {
248
- payload: merged,
249
- headElements: result.headElements,
250
- params: result.params,
251
- });
252
- renderPayload(merged);
253
- return result.headElements;
417
+ if (isPartialNavigation(result.skippedSegments)) {
418
+ historyStack.push(url, {
419
+ payload: null,
420
+ headElements: result.headElements,
421
+ params: result.params,
422
+ });
423
+ } else {
424
+ // Resolve thenables before storing/rendering in the fallback path
425
+ // (tests without navigateTransition). In production, React handles
426
+ // thenables via Suspense; in tests, renderRoot expects resolved values.
427
+ const payload =
428
+ result.payload != null && typeof result.payload === 'object' && 'then' in result.payload
429
+ ? await (result.payload as PromiseLike<unknown>)
430
+ : result.payload;
431
+ historyStack.push(url, {
432
+ payload,
433
+ headElements: result.headElements,
434
+ params: result.params,
435
+ });
436
+ renderPayload(payload, result.navState);
437
+ }
438
+ return { headElements: result.headElements, decodePromise: result.decodePromise };
254
439
  }
255
440
 
256
441
  /** Apply head elements (title, meta tags) to the DOM if available. */
@@ -269,20 +454,47 @@ export function createRouter(deps: RouterDeps): RouterInstance {
269
454
  }
270
455
  }
271
456
 
457
+ /**
458
+ * Schedule scroll restoration after the next paint and fire the
459
+ * scroll-restored event. Used by navigate, popstate, and refresh.
460
+ */
461
+ function restoreScrollAfterPaint(scrollY: number): void {
462
+ afterPaint(() => {
463
+ deps.scrollTo(0, scrollY);
464
+ window.dispatchEvent(new Event('timber:scroll-restored'));
465
+ });
466
+ }
467
+
468
+ /**
469
+ * Scroll to the element matching the URL #fragment after paint, falling
470
+ * back to scroll-to-top when no element matches (matching full-page-load
471
+ * behavior for an unknown fragment). Used by forward navigation to a
472
+ * hash-bearing URL (TIM-1035).
473
+ */
474
+ function scrollToHashAfterPaint(hash: string): void {
475
+ afterPaint(() => {
476
+ if (deps.scrollToHash?.(hash) !== true) {
477
+ deps.scrollTo(0, 0);
478
+ }
479
+ window.dispatchEvent(new Event('timber:scroll-restored'));
480
+ });
481
+ }
482
+
272
483
  /**
273
484
  * Core navigation logic shared between the transition and fallback paths.
274
485
  * Fetches the RSC payload, updates all state, and returns the result.
275
486
  */
276
487
  async function performNavigationFetch(
277
488
  url: string,
278
- options: { replace: boolean }
279
- ): Promise<FetchResult> {
489
+ options: { replace: boolean; commitUrl?: string; signal?: AbortSignal; skipHistory?: boolean }
490
+ ): Promise<FetchResult & { navState: NavigationState }> {
280
491
  // Check prefetch cache first. PrefetchResult has optional segmentInfo/params
281
492
  // fields — normalize to null for FetchResult compatibility.
282
493
  const prefetched = prefetchCache.consume(url);
283
494
  let result: FetchResult | undefined = prefetched
284
495
  ? {
285
496
  payload: prefetched.payload,
497
+ decodePromise: null,
286
498
  headElements: prefetched.headElements,
287
499
  segmentInfo: prefetched.segmentInfo ?? null,
288
500
  params: prefetched.params ?? null,
@@ -293,19 +505,29 @@ export function createRouter(deps: RouterDeps): RouterInstance {
293
505
  if (result === undefined) {
294
506
  // Fetch RSC payload with state tree for partial rendering.
295
507
  // Send current URL for intercepting route resolution (modal pattern).
296
- const stateTree = segmentCache.serializeStateTree(segmentElementCache.getMergeablePaths());
508
+ const stateTree = segmentCache.serializeStateTree();
297
509
  const rawCurrentUrl = deps.getCurrentUrl();
298
510
  const currentUrl = rawCurrentUrl.startsWith('http')
299
511
  ? new URL(rawCurrentUrl).pathname
300
512
  : new URL(rawCurrentUrl, 'http://localhost').pathname;
301
- result = await fetchRscPayload(url, deps, stateTree, currentUrl);
513
+ result = await fetchRscPayload(url, deps, stateTree, currentUrl, options.signal);
302
514
  }
303
515
 
304
- // Update the browser history — replace mode overwrites the current entry
305
- if (options.replace) {
306
- deps.replaceState({ timber: true, scrollY: 0 }, '', url);
307
- } else {
308
- deps.pushState({ timber: true, scrollY: 0 }, '', url);
516
+ // Update the browser history — skip when the Navigation API has already
517
+ // updated the URL via event.intercept() (external navigations).
518
+ // The committed URL keeps the #fragment (commitUrl) even though the
519
+ // fetch/history-stack URL is hash-less (TIM-1035).
520
+ if (!options.skipHistory) {
521
+ const commitUrl = options.commitUrl ?? url;
522
+ // Set the router-navigating flag so the Navigation API's navigate
523
+ // listener doesn't double-intercept this pushState/replaceState.
524
+ deps.setRouterNavigating?.(true);
525
+ if (options.replace) {
526
+ deps.replaceState({ timber: true, scrollY: 0 }, '', commitUrl);
527
+ } else {
528
+ deps.pushState({ timber: true, scrollY: 0 }, '', commitUrl);
529
+ }
530
+ deps.setRouterNavigating?.(false);
309
531
  }
310
532
 
311
533
  // NOTE: History push is deferred — the merged payload (after segment
@@ -316,29 +538,67 @@ export function createRouter(deps: RouterDeps): RouterInstance {
316
538
  // Update the segment cache with the new route's segment tree.
317
539
  updateSegmentCache(result.segmentInfo);
318
540
 
319
- // Update navigation state (params + pathname) before rendering.
320
- updateNavigationState(result.params, url);
541
+ // Update navigation state and capture it for explicit passing.
542
+ const navState = updateNavigationState(result.params, url);
321
543
 
322
- return result;
544
+ return { ...result, navState };
323
545
  }
324
546
 
325
547
  async function navigate(url: string, options: NavigationOptions = {}): Promise<void> {
326
548
  const scroll = options.scroll !== false;
327
549
  const replace = options.replace === true;
550
+ const externalSignal = options._signal as AbortSignal | undefined;
551
+ const skipHistory = options._skipHistory === true;
552
+
553
+ // Split the #fragment off the navigation URL (TIM-1035). The full URL
554
+ // (with hash) is committed to the address bar; the hash-less URL is used
555
+ // for the RSC fetch (fragments are client-only — keeping it would also
556
+ // swallow the ?_rsc cache-bust param into the fragment) and for
557
+ // history-stack/prefetch keys (popstate lookups use pathname + search).
558
+ const hashIndex = url.indexOf('#');
559
+ const hash = hashIndex === -1 ? '' : url.slice(hashIndex);
560
+ const fetchUrl = hashIndex === -1 ? url : url.slice(0, hashIndex);
561
+
562
+ // Create an abort controller for this navigation. Links to the external
563
+ // signal (Navigation API's event.signal) when provided.
564
+ const navAbort = createNavAbort(externalSignal);
328
565
 
329
566
  // Capture the departing page's scroll position for scroll={false} preservation.
330
567
  const currentScrollY = deps.getScrollY();
331
568
 
332
- // Save the departing page's scroll position in history.state before
333
- // pushing a new entry. This ensures back/forward navigation can restore
334
- // the correct scroll position from the browser's per-entry state.
335
- deps.replaceState({ timber: true, scrollY: currentScrollY }, '', deps.getCurrentUrl());
569
+ // Save the departing page's scroll position — use Navigation API entry
570
+ // state when available, otherwise fall back to history.state.
571
+ if (deps.saveNavigationEntryScroll) {
572
+ deps.saveNavigationEntryScroll(currentScrollY);
573
+ } else {
574
+ deps.replaceState({ timber: true, scrollY: currentScrollY }, '', deps.getCurrentUrl());
575
+ }
576
+
577
+ // When Navigation API is active, initiate the navigation via
578
+ // navigation.navigate() BEFORE the fetch. Unlike history.pushState()
579
+ // which commits the URL synchronously (so Chrome sees it as "done"),
580
+ // navigation.navigate() fires the navigate event before committing.
581
+ // Our handler intercepts with a deferred promise, and Chrome shows
582
+ // its native loading indicator until completeRouterNavigation()
583
+ // resolves it in the finally block (same time as TopLoader clears).
584
+ let effectiveSkipHistory = skipHistory;
585
+ if (!skipHistory && deps.navigationNavigate) {
586
+ deps.setRouterNavigating?.(true);
587
+ deps.navigationNavigate(url, replace);
588
+ deps.setRouterNavigating?.(false);
589
+ effectiveSkipHistory = true;
590
+ }
336
591
 
337
592
  setPending(true, url);
338
593
 
339
594
  try {
340
- const headElements = await renderViaTransition(url, () =>
341
- performNavigationFetch(url, { replace })
595
+ const { headElements } = await renderViaTransition(fetchUrl, () =>
596
+ performNavigationFetch(fetchUrl, {
597
+ replace,
598
+ commitUrl: url,
599
+ signal: navAbort.signal,
600
+ skipHistory: effectiveSkipHistory,
601
+ })
342
602
  );
343
603
 
344
604
  // Update document.title and <meta> tags with the new page's metadata
@@ -347,93 +607,168 @@ export function createRouter(deps: RouterDeps): RouterInstance {
347
607
  // Notify nuqs adapter (and any other listeners) that navigation completed.
348
608
  window.dispatchEvent(new Event('timber:navigation-end'));
349
609
 
350
- // Scroll-to-top on forward navigation, or restore captured position
351
- // for scroll={false}. React's render() on the document root can reset
352
- // scroll during DOM reconciliation, so all scroll must be actively managed.
353
- afterPaint(() => {
354
- if (scroll) {
355
- deps.scrollTo(0, 0);
356
- } else {
357
- deps.scrollTo(0, currentScrollY);
358
- }
359
- window.dispatchEvent(new Event('timber:scroll-restored'));
360
- });
610
+ // Scroll-to-top on forward navigation, scroll to the #fragment target
611
+ // when the URL has one, or restore captured position for scroll={false}.
612
+ // React's render() on the document root can reset scroll during DOM
613
+ // reconciliation, so all scroll must be actively managed.
614
+ if (scroll && hash) {
615
+ scrollToHashAfterPaint(hash);
616
+ } else {
617
+ restoreScrollAfterPaint(scroll ? 0 : currentScrollY);
618
+ }
361
619
  } catch (error) {
620
+ // Version skew — server has been redeployed. Full page reload
621
+ // so the browser fetches the new bundle. See TIM-446.
622
+ if (error instanceof VersionSkewError) {
623
+ setHardNavigating(true);
624
+ window.location.reload();
625
+ return new Promise(() => {}) as never;
626
+ }
362
627
  // Server-side redirect during RSC fetch → soft router navigation.
628
+ // The redirect navigate will push/replace its own URL.
363
629
  if (error instanceof RedirectError) {
364
- setPending(false);
630
+ // Drop the redirect if a newer navigation superseded this one
631
+ // while the redirect response was in flight — the newer
632
+ // navigation wins, same as the stale-transition guard.
633
+ if (currentNavAbort !== navAbort) return;
634
+ // The recursive navigate() supersedes this one via createNavAbort,
635
+ // which also resolves this navigation's Navigation API deferred.
365
636
  await navigate(error.redirectUrl, { replace: true });
366
637
  return;
367
638
  }
639
+ // Server 5xx error — hard-navigate so the server renders the
640
+ // error page as HTML. See design/10-error-handling.md
641
+ // §"Error Page Rendering for Client Navigation".
642
+ //
643
+ // Set hard-navigating flag BEFORE setting window.location.href:
644
+ // 1. Prevents Navigation API from intercepting → infinite loop
645
+ // 2. Causes NavigationRoot to throw unresolvedThenable → prevents
646
+ // React from rendering children during page teardown (avoids
647
+ // "Rendered more hooks" crashes). See TIM-626.
648
+ if (error instanceof ServerErrorResponse) {
649
+ setHardNavigating(true);
650
+ window.location.href = error.url;
651
+ return new Promise(() => {}) as never;
652
+ }
368
653
  // Abort errors are not application errors — swallow silently.
369
654
  if (isAbortError(error)) return;
370
655
  throw error;
371
656
  } finally {
372
- setPending(false);
657
+ // Staleness guard (TIM-1034): only clean up when this navigation
658
+ // still owns the abort controller. When a newer navigation
659
+ // superseded this one, createNavAbort() already replaced
660
+ // currentNavAbort — running setPending(false) /
661
+ // completeRouterNavigation() here would clear the NEWER
662
+ // navigation's pending state and resolve its Navigation API
663
+ // deferred. The superseding navigation resolved OUR deferred in
664
+ // createNavAbort().
665
+ if (currentNavAbort === navAbort) {
666
+ // Clear the abort controller so we don't abort a completed
667
+ // navigation when the next one starts. In dev mode, the RSC body
668
+ // stream stays open after data arrives (React's Flight client
669
+ // waits for debug rows). Aborting a "completed" navigation kills
670
+ // the open stream reader → "BodyStreamBuffer was aborted".
671
+ currentNavAbort = null;
672
+ setPending(false);
673
+ // Resolve the Navigation API deferred — clears the browser's
674
+ // native loading state (tab spinner) at the same time as the
675
+ // TopLoader.
676
+ deps.completeRouterNavigation?.();
677
+ }
373
678
  }
374
679
  }
375
680
 
376
681
  async function refresh(): Promise<void> {
377
682
  const currentUrl = deps.getCurrentUrl();
683
+ const navAbort = createNavAbort();
378
684
 
379
685
  setPending(true, currentUrl);
380
686
 
381
687
  try {
382
- const headElements = await renderViaTransition(currentUrl, async () => {
688
+ const { headElements } = await renderViaTransition(currentUrl, async () => {
383
689
  // No state tree sent — server renders the complete RSC payload
384
- const result = await fetchRscPayload(currentUrl, deps);
690
+ const result = await fetchRscPayload(
691
+ currentUrl,
692
+ deps,
693
+ undefined,
694
+ undefined,
695
+ navAbort.signal
696
+ );
385
697
  // History push handled by renderViaTransition (stores merged payload)
386
698
  updateSegmentCache(result.segmentInfo);
387
- updateNavigationState(result.params, currentUrl);
388
- return result;
699
+ const navState = updateNavigationState(result.params, currentUrl);
700
+ return { ...result, navState };
389
701
  });
390
702
 
391
703
  applyHead(headElements);
704
+ } catch (error) {
705
+ if (isAbortError(error)) return;
706
+ throw error;
392
707
  } finally {
393
- setPending(false);
708
+ // Staleness guard (TIM-1034) — see navigate()'s finally block.
709
+ if (currentNavAbort === navAbort) {
710
+ currentNavAbort = null;
711
+ setPending(false);
712
+ deps.completeRouterNavigation?.();
713
+ }
394
714
  }
395
715
  }
396
716
 
397
- async function handlePopState(url: string, scrollY: number = 0): Promise<void> {
717
+ async function handlePopState(
718
+ url: string,
719
+ scrollY: number = 0,
720
+ externalSignal?: AbortSignal
721
+ ): Promise<void> {
398
722
  // Scroll position is read from history.state by the caller (browser-entry.ts)
399
723
  // and passed in. This is more reliable than tracking scroll per-URL in memory
400
724
  // because the browser maintains per-entry state even with duplicate URLs.
401
725
  const entry = historyStack.get(url);
402
726
 
403
727
  if (entry && entry.payload !== null) {
404
- // Replay cached payload — no server roundtrip
405
- updateNavigationState(entry.params, url);
406
- renderPayload(entry.payload);
728
+ // Replay cached payload — no server roundtrip.
729
+ //
730
+ // A forward navigation may still be in flight (back pressed while a
731
+ // slow RSC fetch was pending). createNavAbort() supersedes it: aborts
732
+ // its fetch and invalidates its render transition so the stale
733
+ // forward payload can't commit over this replay (TIM-1022). The
734
+ // replay itself is synchronous — nothing to abort later — so the
735
+ // controller is cleared immediately, and any pending state left by
736
+ // the superseded navigation is reset.
737
+ createNavAbort(externalSignal);
738
+ currentNavAbort = null;
739
+ setPending(false);
740
+ const navState = updateNavigationState(entry.params, url);
741
+ renderPayload(entry.payload, navState);
407
742
  applyHead(entry.headElements);
408
- afterPaint(() => {
409
- deps.scrollTo(0, scrollY);
410
- window.dispatchEvent(new Event('timber:scroll-restored'));
411
- });
743
+ restoreScrollAfterPaint(scrollY);
412
744
  } else {
413
745
  // No cached payload — fetch from server.
414
746
  // This happens when navigating back to the initial SSR'd page
415
747
  // (its payload is null since it was rendered via SSR, not RSC fetch)
416
748
  // or when the entry doesn't exist at all.
749
+ const navAbort = createNavAbort(externalSignal);
417
750
  setPending(true, url);
418
751
  try {
419
- const headElements = await renderViaTransition(url, async () => {
420
- const stateTree = segmentCache.serializeStateTree(
421
- segmentElementCache.getMergeablePaths()
422
- );
423
- const result = await fetchRscPayload(url, deps, stateTree);
752
+ const { headElements } = await renderViaTransition(url, async () => {
753
+ const stateTree = segmentCache.serializeStateTree();
754
+ const result = await fetchRscPayload(url, deps, stateTree, undefined, navAbort.signal);
424
755
  updateSegmentCache(result.segmentInfo);
425
- updateNavigationState(result.params, url);
756
+ const navState = updateNavigationState(result.params, url);
426
757
  // History push handled by renderViaTransition (stores merged payload)
427
- return result;
758
+ return { ...result, navState };
428
759
  });
429
760
 
430
761
  applyHead(headElements);
431
- afterPaint(() => {
432
- deps.scrollTo(0, scrollY);
433
- window.dispatchEvent(new Event('timber:scroll-restored'));
434
- });
762
+ restoreScrollAfterPaint(scrollY);
763
+ } catch (error) {
764
+ if (isAbortError(error)) return;
765
+ throw error;
435
766
  } finally {
436
- setPending(false);
767
+ // Staleness guard (TIM-1034) — see navigate()'s finally block.
768
+ if (currentNavAbort === navAbort) {
769
+ currentNavAbort = null;
770
+ setPending(false);
771
+ }
437
772
  }
438
773
  }
439
774
  }
@@ -443,15 +778,21 @@ export function createRouter(deps: RouterDeps): RouterInstance {
443
778
  * Called on hover of <Link prefetch> elements.
444
779
  */
445
780
  function prefetch(url: string): void {
781
+ // Strip fragment — it's client-only and would swallow the _rsc cache-bust
782
+ // param into the hash. The hash-less key also matches navigate()'s fetchUrl.
783
+ const hashIndex = url.indexOf('#');
784
+ const fetchUrl = hashIndex === -1 ? url : url.slice(0, hashIndex);
785
+
446
786
  // Don't prefetch if already cached
447
- if (prefetchCache.get(url) !== undefined) return;
448
- if (historyStack.has(url)) return;
787
+ if (prefetchCache.get(fetchUrl) !== undefined) return;
788
+ if (historyStack.has(fetchUrl)) return;
449
789
 
450
790
  // Fire-and-forget fetch
451
- const stateTree = segmentCache.serializeStateTree(segmentElementCache.getMergeablePaths());
452
- void fetchRscPayload(url, deps, stateTree).then(
791
+ const stateTree = segmentCache.serializeStateTree();
792
+ void fetchRscPayload(fetchUrl, deps, stateTree).then(
453
793
  (result) => {
454
- prefetchCache.set(url, result);
794
+ result.decodePromise?.catch(() => {});
795
+ prefetchCache.set(fetchUrl, result);
455
796
  },
456
797
  () => {
457
798
  // Prefetch failure is non-fatal — navigation will fetch fresh
@@ -463,8 +804,8 @@ export function createRouter(deps: RouterDeps): RouterInstance {
463
804
  navigate,
464
805
  refresh,
465
806
  handlePopState,
466
- isPending: () => pending,
467
- getPendingUrl: () => pendingUrl,
807
+ isPending: () => routerPhase.phase === 'navigating',
808
+ getPendingUrl: () => (routerPhase.phase === 'navigating' ? routerPhase.targetUrl : null),
468
809
  onPendingChange(listener) {
469
810
  pendingListeners.add(listener);
470
811
  return () => pendingListeners.delete(listener);
@@ -474,18 +815,27 @@ export function createRouter(deps: RouterDeps): RouterInstance {
474
815
  // Render the piggybacked element tree from a server action response.
475
816
  // Updates the current history entry with the fresh payload and applies
476
817
  // head elements — same as refresh() but without a server fetch.
477
- // Cache segment elements for future partial merges.
818
+ // Revalidation payloads are already resolved (no Flight thenable),
819
+ // so no segment merging is needed — just cache and render.
478
820
  const currentUrl = deps.getCurrentUrl();
479
- const merged = mergeAndCachePayload(element, null);
821
+
822
+ // Revalidation doesn't change params/pathname — preserve current state.
823
+ // DO NOT call updateNavigationState(null, ...) here: that normalizes
824
+ // params to {}, clearing dynamic route params on every action response.
825
+ const navState = getNavigationState();
826
+
827
+ // Keep params on the overwritten entry — dropping them would make
828
+ // away-and-back navigation replay this page with params normalized
829
+ // to {} (TIM-1037).
480
830
  historyStack.push(currentUrl, {
481
- payload: merged,
831
+ payload: element,
482
832
  headElements,
833
+ params: navState.params,
483
834
  });
484
- renderPayload(merged);
835
+ renderPayload(element, navState);
485
836
  applyHead(headElements);
486
837
  },
487
838
  initSegmentCache: (segments: SegmentInfo[]) => updateSegmentCache(segments),
488
- cacheElementTree: (element: unknown) => cacheSegmentElements(element, segmentElementCache),
489
839
  segmentCache,
490
840
  prefetchCache,
491
841
  historyStack,