@timber-js/app 0.2.0-alpha.19 → 0.2.0-alpha.191

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 (1192) hide show
  1. package/LICENSE +8 -0
  2. package/agent-skill.md +344 -0
  3. package/dist/_chunks/actions-BjbbNRFN.js +318 -0
  4. package/dist/_chunks/actions-BjbbNRFN.js.map +1 -0
  5. package/dist/_chunks/als-registry-C6kcfprT.js +41 -0
  6. package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -0
  7. package/dist/_chunks/als-slots-BEEIPKYm.js +26 -0
  8. package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -0
  9. package/dist/_chunks/base-path-DaQrzbez.js +80 -0
  10. package/dist/_chunks/base-path-DaQrzbez.js.map +1 -0
  11. package/dist/_chunks/build-manifest-DWppEdLB.js +86 -0
  12. package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
  13. package/dist/_chunks/build-output-helper-C3DrfzZR.js +369 -0
  14. package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +1 -0
  15. package/dist/_chunks/cache-api-DllJ-Lyw.js +1196 -0
  16. package/dist/_chunks/cache-api-DllJ-Lyw.js.map +1 -0
  17. package/dist/_chunks/cli-check-DJZDc22E.js +256 -0
  18. package/dist/_chunks/cli-check-DJZDc22E.js.map +1 -0
  19. package/dist/_chunks/cli-schema-sync-D4_AZVUb.js +298 -0
  20. package/dist/_chunks/cli-schema-sync-D4_AZVUb.js.map +1 -0
  21. package/dist/_chunks/cloudflare-CGP6BZKO.js +1284 -0
  22. package/dist/_chunks/cloudflare-CGP6BZKO.js.map +1 -0
  23. package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
  24. package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
  25. package/dist/_chunks/convention-lint-CpteIpTm.js +784 -0
  26. package/dist/_chunks/convention-lint-CpteIpTm.js.map +1 -0
  27. package/dist/_chunks/dist-BA3u1z3W.js +423 -0
  28. package/dist/_chunks/dist-BA3u1z3W.js.map +1 -0
  29. package/dist/_chunks/error-boundary-D-ODYX41.js +353 -0
  30. package/dist/_chunks/error-boundary-D-ODYX41.js.map +1 -0
  31. package/dist/_chunks/fast-hash-C-tVYrLb.js +41 -0
  32. package/dist/_chunks/fast-hash-C-tVYrLb.js.map +1 -0
  33. package/dist/_chunks/file-cache-DmX7OqZP.js +454 -0
  34. package/dist/_chunks/file-cache-DmX7OqZP.js.map +1 -0
  35. package/dist/_chunks/format-CfwjgPz9.js +14 -0
  36. package/dist/_chunks/format-CfwjgPz9.js.map +1 -0
  37. package/dist/_chunks/fs-identity-D7vb6GdI.js +208 -0
  38. package/dist/_chunks/fs-identity-D7vb6GdI.js.map +1 -0
  39. package/dist/_chunks/href-validation-CMc5JRls.js +141 -0
  40. package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -0
  41. package/dist/_chunks/json-lossy-check-ClNvBM_3.js +63 -0
  42. package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +1 -0
  43. package/dist/_chunks/logger-CH7IcMmg.js +1436 -0
  44. package/dist/_chunks/logger-CH7IcMmg.js.map +1 -0
  45. package/dist/_chunks/mdx-file-C005ay-P.js +25 -0
  46. package/dist/_chunks/mdx-file-C005ay-P.js.map +1 -0
  47. package/dist/_chunks/plugin-context-rCinWLiE.js +321 -0
  48. package/dist/_chunks/plugin-context-rCinWLiE.js.map +1 -0
  49. package/dist/_chunks/purge-store-Byr8XOjU.js +14 -0
  50. package/dist/_chunks/purge-store-Byr8XOjU.js.map +1 -0
  51. package/dist/_chunks/resolve-schema-CBR6Lm4i.js +50 -0
  52. package/dist/_chunks/resolve-schema-CBR6Lm4i.js.map +1 -0
  53. package/dist/_chunks/router-ref-DuYuV_0Q.js +28 -0
  54. package/dist/_chunks/router-ref-DuYuV_0Q.js.map +1 -0
  55. package/dist/_chunks/rsc-cache-key-DD0fl_-s.js +243 -0
  56. package/dist/_chunks/rsc-cache-key-DD0fl_-s.js.map +1 -0
  57. package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js +40 -0
  58. package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js.map +1 -0
  59. package/dist/_chunks/rsc-media-type-DRqE_lD_.js +46 -0
  60. package/dist/_chunks/rsc-media-type-DRqE_lD_.js.map +1 -0
  61. package/dist/_chunks/rsc-payload-path-B_LBodc2.js +48 -0
  62. package/dist/_chunks/rsc-payload-path-B_LBodc2.js.map +1 -0
  63. package/dist/_chunks/scanner-CAietmj4.js +1564 -0
  64. package/dist/_chunks/scanner-CAietmj4.js.map +1 -0
  65. package/dist/_chunks/schema-bridge-C83xa9lT.js +199 -0
  66. package/dist/_chunks/schema-bridge-C83xa9lT.js.map +1 -0
  67. package/dist/_chunks/segment-classify-C539Pa2O.js +197 -0
  68. package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -0
  69. package/dist/_chunks/segment-context-CjOlyB8Y.js +97 -0
  70. package/dist/_chunks/segment-context-CjOlyB8Y.js.map +1 -0
  71. package/dist/_chunks/segment-keys-BawYuNFO.js +307 -0
  72. package/dist/_chunks/segment-keys-BawYuNFO.js.map +1 -0
  73. package/dist/_chunks/sizeof-lXffQ1Vr.js +35 -0
  74. package/dist/_chunks/sizeof-lXffQ1Vr.js.map +1 -0
  75. package/dist/_chunks/slot-params-BCTmZkQB.js +76 -0
  76. package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -0
  77. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-14MXm7Pj.js} +17 -2
  78. package/dist/_chunks/ssr-data-14MXm7Pj.js.map +1 -0
  79. package/dist/_chunks/use-query-states-I3JMng6J.js +226 -0
  80. package/dist/_chunks/use-query-states-I3JMng6J.js.map +1 -0
  81. package/dist/_chunks/use-segment-params-C4r4BD9T.js +398 -0
  82. package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +1 -0
  83. package/dist/_chunks/walkers-BsVLmD1S.js +141 -0
  84. package/dist/_chunks/walkers-BsVLmD1S.js.map +1 -0
  85. package/dist/adapters/build-output-helper.d.ts +72 -0
  86. package/dist/adapters/build-output-helper.d.ts.map +1 -0
  87. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  88. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  89. package/dist/adapters/cloudflare-dev.js +73 -0
  90. package/dist/adapters/cloudflare-dev.js.map +1 -0
  91. package/dist/adapters/cloudflare-kv-cache.d.ts +65 -0
  92. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  93. package/dist/adapters/cloudflare-kv-cache.js +124 -0
  94. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  95. package/dist/adapters/cloudflare.d.ts +199 -21
  96. package/dist/adapters/cloudflare.d.ts.map +1 -1
  97. package/dist/adapters/cloudflare.js +2 -188
  98. package/dist/adapters/compress-module.d.ts +17 -4
  99. package/dist/adapters/compress-module.d.ts.map +1 -1
  100. package/dist/adapters/fs-identity.d.ts +64 -0
  101. package/dist/adapters/fs-identity.d.ts.map +1 -0
  102. package/dist/adapters/nitro.d.ts +55 -3
  103. package/dist/adapters/nitro.d.ts.map +1 -1
  104. package/dist/adapters/nitro.js +287 -171
  105. package/dist/adapters/nitro.js.map +1 -1
  106. package/dist/adapters/shared.d.ts +62 -0
  107. package/dist/adapters/shared.d.ts.map +1 -0
  108. package/dist/adapters/types.d.ts +28 -6
  109. package/dist/adapters/types.d.ts.map +1 -1
  110. package/dist/cache/cache-api.d.ts +48 -0
  111. package/dist/cache/cache-api.d.ts.map +1 -0
  112. package/dist/cache/fast-hash.d.ts +5 -0
  113. package/dist/cache/fast-hash.d.ts.map +1 -1
  114. package/dist/cache/handler-store.d.ts +33 -0
  115. package/dist/cache/handler-store.d.ts.map +1 -0
  116. package/dist/cache/index.d.ts +31 -8
  117. package/dist/cache/index.d.ts.map +1 -1
  118. package/dist/cache/index.js +3 -326
  119. package/dist/cache/invalidation-epoch.d.ts +43 -0
  120. package/dist/cache/invalidation-epoch.d.ts.map +1 -0
  121. package/dist/cache/json-lossy-check.d.ts +11 -0
  122. package/dist/cache/json-lossy-check.d.ts.map +1 -0
  123. package/dist/cache/redis-handler.d.ts +140 -8
  124. package/dist/cache/redis-handler.d.ts.map +1 -1
  125. package/dist/cache/singleflight.d.ts +19 -2
  126. package/dist/cache/singleflight.d.ts.map +1 -1
  127. package/dist/cache/sizeof.d.ts +22 -0
  128. package/dist/cache/sizeof.d.ts.map +1 -0
  129. package/dist/cache/stable-stringify.d.ts +9 -0
  130. package/dist/cache/stable-stringify.d.ts.map +1 -1
  131. package/dist/cache/store.d.ts +53 -0
  132. package/dist/cache/store.d.ts.map +1 -0
  133. package/dist/cache/stores/cloudflare-kv.d.ts +38 -0
  134. package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -0
  135. package/dist/cache/stores/cloudflare-kv.js +29 -0
  136. package/dist/cache/stores/cloudflare-kv.js.map +1 -0
  137. package/dist/cache/stores/memory.d.ts +42 -0
  138. package/dist/cache/stores/memory.d.ts.map +1 -0
  139. package/dist/cache/stores/memory.js +90 -0
  140. package/dist/cache/stores/memory.js.map +1 -0
  141. package/dist/cache/stores/redis.d.ts +69 -0
  142. package/dist/cache/stores/redis.d.ts.map +1 -0
  143. package/dist/cache/stores/redis.js +35 -0
  144. package/dist/cache/stores/redis.js.map +1 -0
  145. package/dist/cache/stores/vercel.d.ts +36 -0
  146. package/dist/cache/stores/vercel.d.ts.map +1 -0
  147. package/dist/cache/stores/vercel.js +33 -0
  148. package/dist/cache/stores/vercel.js.map +1 -0
  149. package/dist/cache/tag-aware-handler.d.ts +52 -0
  150. package/dist/cache/tag-aware-handler.d.ts.map +1 -0
  151. package/dist/cache/timber-cache.d.ts +20 -10
  152. package/dist/cache/timber-cache.d.ts.map +1 -1
  153. package/dist/cdn/cloudflare-purge.d.ts +23 -0
  154. package/dist/cdn/cloudflare-purge.d.ts.map +1 -0
  155. package/dist/cdn/cloudflare-purge.js +30 -0
  156. package/dist/cdn/cloudflare-purge.js.map +1 -0
  157. package/dist/cdn/fastly-purge.d.ts +25 -0
  158. package/dist/cdn/fastly-purge.d.ts.map +1 -0
  159. package/dist/cdn/fastly-purge.js +33 -0
  160. package/dist/cdn/fastly-purge.js.map +1 -0
  161. package/dist/cdn/headers.d.ts +97 -0
  162. package/dist/cdn/headers.d.ts.map +1 -0
  163. package/dist/cdn/index.d.ts +5 -0
  164. package/dist/cdn/index.d.ts.map +1 -0
  165. package/dist/cdn/index.js +94 -0
  166. package/dist/cdn/index.js.map +1 -0
  167. package/dist/cdn/purge-store.d.ts +23 -0
  168. package/dist/cdn/purge-store.d.ts.map +1 -0
  169. package/dist/cdn/workers-cache-purge.d.ts +16 -0
  170. package/dist/cdn/workers-cache-purge.d.ts.map +1 -0
  171. package/dist/cdn/workers-cache-purge.js +35 -0
  172. package/dist/cdn/workers-cache-purge.js.map +1 -0
  173. package/dist/cli-check.d.ts +153 -0
  174. package/dist/cli-check.d.ts.map +1 -0
  175. package/dist/cli-schema-sync.d.ts +59 -0
  176. package/dist/cli-schema-sync.d.ts.map +1 -0
  177. package/dist/cli.d.ts +66 -7
  178. package/dist/cli.d.ts.map +1 -1
  179. package/dist/cli.js +151 -47
  180. package/dist/cli.js.map +1 -1
  181. package/dist/client/browser-dev.d.ts +37 -1
  182. package/dist/client/browser-dev.d.ts.map +1 -1
  183. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  184. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  185. package/dist/client/browser-entry/hmr.d.ts +21 -0
  186. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  187. package/dist/client/browser-entry/hydrate.d.ts +57 -0
  188. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  189. package/dist/client/browser-entry/index.d.ts +29 -0
  190. package/dist/client/browser-entry/index.d.ts.map +1 -0
  191. package/dist/client/browser-entry/post-hydration.d.ts +29 -0
  192. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  193. package/dist/client/browser-entry/router-init.d.ts +30 -0
  194. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  195. package/dist/client/browser-entry/rsc-stream.d.ts +32 -0
  196. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  197. package/dist/client/browser-entry/scroll.d.ts +28 -0
  198. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  199. package/dist/client/error-boundary.d.ts +19 -5
  200. package/dist/client/error-boundary.d.ts.map +1 -1
  201. package/dist/client/error-boundary.js +1 -125
  202. package/dist/client/error-reconstituter.d.ts +61 -0
  203. package/dist/client/error-reconstituter.d.ts.map +1 -0
  204. package/dist/client/form.d.ts +16 -27
  205. package/dist/client/form.d.ts.map +1 -1
  206. package/dist/client/history.d.ts +29 -7
  207. package/dist/client/history.d.ts.map +1 -1
  208. package/dist/client/index.d.ts +11 -24
  209. package/dist/client/index.d.ts.map +1 -1
  210. package/dist/client/index.js +186 -1134
  211. package/dist/client/index.js.map +1 -1
  212. package/dist/client/internal.d.ts +20 -0
  213. package/dist/client/internal.d.ts.map +1 -0
  214. package/dist/client/internal.js +1624 -0
  215. package/dist/client/internal.js.map +1 -0
  216. package/dist/client/link.d.ts +63 -60
  217. package/dist/client/link.d.ts.map +1 -1
  218. package/dist/client/navigation-api.d.ts +121 -0
  219. package/dist/client/navigation-api.d.ts.map +1 -0
  220. package/dist/client/navigation-commit.d.ts +87 -0
  221. package/dist/client/navigation-commit.d.ts.map +1 -0
  222. package/dist/client/navigation-context.d.ts +38 -20
  223. package/dist/client/navigation-context.d.ts.map +1 -1
  224. package/dist/client/navigation-root.d.ts +159 -0
  225. package/dist/client/navigation-root.d.ts.map +1 -0
  226. package/dist/client/nuqs-adapter.d.ts +1 -1
  227. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  228. package/dist/client/params-context.d.ts +82 -0
  229. package/dist/client/params-context.d.ts.map +1 -0
  230. package/dist/client/router-effects.d.ts +129 -0
  231. package/dist/client/router-effects.d.ts.map +1 -0
  232. package/dist/client/router-lifecycle.d.ts +55 -0
  233. package/dist/client/router-lifecycle.d.ts.map +1 -0
  234. package/dist/client/router-pipeline.d.ts +84 -0
  235. package/dist/client/router-pipeline.d.ts.map +1 -0
  236. package/dist/client/router-ref.d.ts +2 -2
  237. package/dist/client/router-ref.d.ts.map +1 -1
  238. package/dist/client/router-skew.d.ts +21 -0
  239. package/dist/client/router-skew.d.ts.map +1 -0
  240. package/dist/client/router-types.d.ts +207 -0
  241. package/dist/client/router-types.d.ts.map +1 -0
  242. package/dist/client/router.d.ts +1 -97
  243. package/dist/client/router.d.ts.map +1 -1
  244. package/dist/client/rsc-fetch.d.ts +113 -26
  245. package/dist/client/rsc-fetch.d.ts.map +1 -1
  246. package/dist/client/segment-cache.d.ts +107 -25
  247. package/dist/client/segment-cache.d.ts.map +1 -1
  248. package/dist/client/segment-outlet.d.ts +57 -0
  249. package/dist/client/segment-outlet.d.ts.map +1 -0
  250. package/dist/client/segment-update-context.d.ts +21 -0
  251. package/dist/client/segment-update-context.d.ts.map +1 -0
  252. package/dist/client/shallow-url.d.ts +10 -0
  253. package/dist/client/shallow-url.d.ts.map +1 -0
  254. package/dist/client/slot-context.d.ts +31 -0
  255. package/dist/client/slot-context.d.ts.map +1 -0
  256. package/dist/client/slot-outlet.d.ts +16 -0
  257. package/dist/client/slot-outlet.d.ts.map +1 -0
  258. package/dist/client/slot-provider.d.ts +25 -0
  259. package/dist/client/slot-provider.d.ts.map +1 -0
  260. package/dist/client/ssr-data.d.ts +21 -5
  261. package/dist/client/ssr-data.d.ts.map +1 -1
  262. package/dist/client/stale-client.d.ts +69 -0
  263. package/dist/client/stale-client.d.ts.map +1 -0
  264. package/dist/client/state.d.ts +14 -4
  265. package/dist/client/state.d.ts.map +1 -1
  266. package/dist/client/top-loader.d.ts +7 -6
  267. package/dist/client/top-loader.d.ts.map +1 -1
  268. package/dist/client/unload-guard.d.ts +5 -0
  269. package/dist/client/unload-guard.d.ts.map +1 -1
  270. package/dist/client/use-cookie.d.ts +12 -0
  271. package/dist/client/use-cookie.d.ts.map +1 -1
  272. package/dist/client/use-link-status.d.ts +5 -5
  273. package/dist/client/use-link-status.d.ts.map +1 -1
  274. package/dist/client/use-pathname.d.ts.map +1 -1
  275. package/dist/client/use-pending-navigation.d.ts +23 -0
  276. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  277. package/dist/client/use-query-states.d.ts +10 -4
  278. package/dist/client/use-query-states.d.ts.map +1 -1
  279. package/dist/client/use-router.d.ts +2 -2
  280. package/dist/client/use-router.d.ts.map +1 -1
  281. package/dist/client/use-search-params.d.ts +12 -5
  282. package/dist/client/use-search-params.d.ts.map +1 -1
  283. package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +29 -16
  284. package/dist/client/use-segment-params.d.ts.map +1 -0
  285. package/dist/codec.d.ts +69 -0
  286. package/dist/codec.d.ts.map +1 -0
  287. package/dist/codec.js +76 -0
  288. package/dist/codec.js.map +1 -0
  289. package/dist/config-types.d.ts +284 -0
  290. package/dist/config-types.d.ts.map +1 -0
  291. package/dist/config-validation.d.ts +51 -0
  292. package/dist/config-validation.d.ts.map +1 -0
  293. package/dist/content/index.d.ts +1 -10
  294. package/dist/content/index.d.ts.map +1 -1
  295. package/dist/content/index.js +0 -2
  296. package/dist/cookies/define-cookie.d.ts +58 -25
  297. package/dist/cookies/define-cookie.d.ts.map +1 -1
  298. package/dist/cookies/index.d.ts +2 -1
  299. package/dist/cookies/index.d.ts.map +1 -1
  300. package/dist/cookies/index.js +257 -36
  301. package/dist/cookies/index.js.map +1 -1
  302. package/dist/cookies/json-cookie.d.ts +64 -0
  303. package/dist/cookies/json-cookie.d.ts.map +1 -0
  304. package/dist/cookies/validation.d.ts +34 -0
  305. package/dist/cookies/validation.d.ts.map +1 -0
  306. package/dist/dev-tools/404-page.d.ts +50 -0
  307. package/dist/dev-tools/404-page.d.ts.map +1 -0
  308. package/dist/dev-tools/browser-logs.d.ts +40 -0
  309. package/dist/dev-tools/browser-logs.d.ts.map +1 -0
  310. package/dist/dev-tools/dev-page-shell.d.ts +78 -0
  311. package/dist/dev-tools/dev-page-shell.d.ts.map +1 -0
  312. package/dist/dev-tools/error-page.d.ts +32 -0
  313. package/dist/dev-tools/error-page.d.ts.map +1 -0
  314. package/dist/dev-tools/holding-server.d.ts +54 -0
  315. package/dist/dev-tools/holding-server.d.ts.map +1 -0
  316. package/dist/dev-tools/hydration-overlay.d.ts +11 -0
  317. package/dist/dev-tools/hydration-overlay.d.ts.map +1 -0
  318. package/dist/dev-tools/index.d.ts +31 -0
  319. package/dist/dev-tools/index.d.ts.map +1 -0
  320. package/dist/dev-tools/instrumentation.d.ts +59 -0
  321. package/dist/dev-tools/instrumentation.d.ts.map +1 -0
  322. package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
  323. package/dist/dev-tools/logger.d.ts.map +1 -0
  324. package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +17 -3
  325. package/dist/dev-tools/logs.d.ts.map +1 -0
  326. package/dist/dev-tools/overlay.d.ts +91 -0
  327. package/dist/dev-tools/overlay.d.ts.map +1 -0
  328. package/dist/dev-tools/stack-classifier.d.ts +34 -0
  329. package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
  330. package/dist/dev-tools/terminal.d.ts +28 -0
  331. package/dist/dev-tools/terminal.d.ts.map +1 -0
  332. package/dist/fonts/ast-walk.d.ts +68 -0
  333. package/dist/fonts/ast-walk.d.ts.map +1 -0
  334. package/dist/fonts/ast.d.ts +110 -6
  335. package/dist/fonts/ast.d.ts.map +1 -1
  336. package/dist/fonts/bundle.d.ts +50 -0
  337. package/dist/fonts/bundle.d.ts.map +1 -0
  338. package/dist/fonts/dev-middleware.d.ts +22 -0
  339. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  340. package/dist/fonts/fallbacks.d.ts +0 -7
  341. package/dist/fonts/fallbacks.d.ts.map +1 -1
  342. package/dist/fonts/google.d.ts +4 -2
  343. package/dist/fonts/google.d.ts.map +1 -1
  344. package/dist/fonts/local.d.ts +4 -4
  345. package/dist/fonts/local.d.ts.map +1 -1
  346. package/dist/fonts/paths.d.ts +43 -0
  347. package/dist/fonts/paths.d.ts.map +1 -0
  348. package/dist/fonts/pipeline.d.ts +177 -0
  349. package/dist/fonts/pipeline.d.ts.map +1 -0
  350. package/dist/fonts/transform.d.ts +82 -0
  351. package/dist/fonts/transform.d.ts.map +1 -0
  352. package/dist/fonts/types.d.ts +47 -1
  353. package/dist/fonts/types.d.ts.map +1 -1
  354. package/dist/fonts/virtual-modules.d.ts +77 -0
  355. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  356. package/dist/index.d.ts +50 -181
  357. package/dist/index.d.ts.map +1 -1
  358. package/dist/index.js +9805 -14134
  359. package/dist/index.js.map +1 -1
  360. package/dist/params/codec-registry.d.ts +26 -0
  361. package/dist/params/codec-registry.d.ts.map +1 -0
  362. package/dist/params/define-schema.d.ts +81 -0
  363. package/dist/params/define-schema.d.ts.map +1 -0
  364. package/dist/params/index.d.ts +5 -0
  365. package/dist/params/index.d.ts.map +1 -0
  366. package/dist/params/index.js +34 -0
  367. package/dist/params/index.js.map +1 -0
  368. package/dist/params/resolve-schema.d.ts +34 -0
  369. package/dist/params/resolve-schema.d.ts.map +1 -0
  370. package/dist/plugin-context.d.ts +276 -0
  371. package/dist/plugin-context.d.ts.map +1 -0
  372. package/dist/plugins/adapter-build.d.ts +21 -1
  373. package/dist/plugins/adapter-build.d.ts.map +1 -1
  374. package/dist/plugins/build-manifest.d.ts +7 -3
  375. package/dist/plugins/build-manifest.d.ts.map +1 -1
  376. package/dist/plugins/build-report.d.ts +47 -10
  377. package/dist/plugins/build-report.d.ts.map +1 -1
  378. package/dist/plugins/cache.d.ts +64 -0
  379. package/dist/plugins/cache.d.ts.map +1 -0
  380. package/dist/plugins/callsite-ast.d.ts +117 -0
  381. package/dist/plugins/callsite-ast.d.ts.map +1 -0
  382. package/dist/plugins/callsite-jsx.d.ts +35 -0
  383. package/dist/plugins/callsite-jsx.d.ts.map +1 -0
  384. package/dist/plugins/chunks.d.ts +11 -4
  385. package/dist/plugins/chunks.d.ts.map +1 -1
  386. package/dist/plugins/client-chunks.d.ts +40 -0
  387. package/dist/plugins/client-chunks.d.ts.map +1 -0
  388. package/dist/plugins/cloudflare-wasm.d.ts +21 -0
  389. package/dist/plugins/cloudflare-wasm.d.ts.map +1 -0
  390. package/dist/plugins/content.d.ts +1 -1
  391. package/dist/plugins/content.d.ts.map +1 -1
  392. package/dist/plugins/dev-server.d.ts +17 -1
  393. package/dist/plugins/dev-server.d.ts.map +1 -1
  394. package/dist/plugins/entries.d.ts +28 -4
  395. package/dist/plugins/entries.d.ts.map +1 -1
  396. package/dist/plugins/fonts.d.ts +16 -73
  397. package/dist/plugins/fonts.d.ts.map +1 -1
  398. package/dist/plugins/mdx.d.ts +1 -1
  399. package/dist/plugins/mdx.d.ts.map +1 -1
  400. package/dist/plugins/prebuilt-capture.d.ts +60 -0
  401. package/dist/plugins/prebuilt-capture.d.ts.map +1 -0
  402. package/dist/plugins/prebuilt-options-analysis.d.ts +40 -0
  403. package/dist/plugins/prebuilt-options-analysis.d.ts.map +1 -0
  404. package/dist/plugins/prebuilt.d.ts +82 -0
  405. package/dist/plugins/prebuilt.d.ts.map +1 -0
  406. package/dist/plugins/prerender-sugar.d.ts +42 -0
  407. package/dist/plugins/prerender-sugar.d.ts.map +1 -0
  408. package/dist/plugins/request-dep/analysis.d.ts +106 -0
  409. package/dist/plugins/request-dep/analysis.d.ts.map +1 -0
  410. package/dist/plugins/request-dep/index.d.ts +75 -0
  411. package/dist/plugins/request-dep/index.d.ts.map +1 -0
  412. package/dist/plugins/request-dep/origin.d.ts +61 -0
  413. package/dist/plugins/request-dep/origin.d.ts.map +1 -0
  414. package/dist/plugins/routing.d.ts +1 -1
  415. package/dist/plugins/routing.d.ts.map +1 -1
  416. package/dist/plugins/server-bundle.d.ts.map +1 -1
  417. package/dist/plugins/shims.d.ts +29 -5
  418. package/dist/plugins/shims.d.ts.map +1 -1
  419. package/dist/plugins/static-build.d.ts +218 -21
  420. package/dist/plugins/static-build.d.ts.map +1 -1
  421. package/dist/routing/codegen-shared.d.ts +26 -0
  422. package/dist/routing/codegen-shared.d.ts.map +1 -0
  423. package/dist/routing/codegen-types.d.ts +61 -0
  424. package/dist/routing/codegen-types.d.ts.map +1 -0
  425. package/dist/routing/codegen-write.d.ts +51 -0
  426. package/dist/routing/codegen-write.d.ts.map +1 -0
  427. package/dist/routing/codegen.d.ts +7 -2
  428. package/dist/routing/codegen.d.ts.map +1 -1
  429. package/dist/routing/collision-probe.d.ts +104 -0
  430. package/dist/routing/collision-probe.d.ts.map +1 -0
  431. package/dist/routing/collision-spaces.d.ts +26 -0
  432. package/dist/routing/collision-spaces.d.ts.map +1 -0
  433. package/dist/routing/convention-lint.d.ts +55 -0
  434. package/dist/routing/convention-lint.d.ts.map +1 -0
  435. package/dist/routing/export-detect.d.ts +72 -0
  436. package/dist/routing/export-detect.d.ts.map +1 -0
  437. package/dist/routing/file-cache.d.ts +8 -0
  438. package/dist/routing/file-cache.d.ts.map +1 -0
  439. package/dist/routing/index.d.ts +7 -1
  440. package/dist/routing/index.d.ts.map +1 -1
  441. package/dist/routing/index.js +5 -2
  442. package/dist/routing/interception.d.ts +234 -10
  443. package/dist/routing/interception.d.ts.map +1 -1
  444. package/dist/routing/link-codegen.d.ts +105 -0
  445. package/dist/routing/link-codegen.d.ts.map +1 -0
  446. package/dist/routing/manifest-codegen.d.ts +26 -0
  447. package/dist/routing/manifest-codegen.d.ts.map +1 -0
  448. package/dist/routing/scanner.d.ts +1 -10
  449. package/dist/routing/scanner.d.ts.map +1 -1
  450. package/dist/routing/schema-validation.d.ts +35 -0
  451. package/dist/routing/schema-validation.d.ts.map +1 -0
  452. package/dist/routing/segment-classify.d.ts +114 -0
  453. package/dist/routing/segment-classify.d.ts.map +1 -0
  454. package/dist/routing/segment-codegen.d.ts +38 -0
  455. package/dist/routing/segment-codegen.d.ts.map +1 -0
  456. package/dist/routing/segment-keys.d.ts +118 -0
  457. package/dist/routing/segment-keys.d.ts.map +1 -0
  458. package/dist/routing/slot-placement.d.ts +48 -0
  459. package/dist/routing/slot-placement.d.ts.map +1 -0
  460. package/dist/routing/types.d.ts +74 -26
  461. package/dist/routing/types.d.ts.map +1 -1
  462. package/dist/routing/walkers.d.ts +57 -0
  463. package/dist/routing/walkers.d.ts.map +1 -0
  464. package/dist/rsc-runtime/rsc.d.ts +1 -1
  465. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  466. package/dist/rsc-runtime/ssr.d.ts +12 -0
  467. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  468. package/dist/schema-bridge.d.ts +145 -0
  469. package/dist/schema-bridge.d.ts.map +1 -0
  470. package/dist/search-params/define.d.ts +262 -0
  471. package/dist/search-params/define.d.ts.map +1 -0
  472. package/dist/search-params/index.d.ts +3 -7
  473. package/dist/search-params/index.d.ts.map +1 -1
  474. package/dist/search-params/index.js +179 -360
  475. package/dist/search-params/index.js.map +1 -1
  476. package/dist/search-params/parse-total.d.ts +81 -0
  477. package/dist/search-params/parse-total.d.ts.map +1 -0
  478. package/dist/search-params/serialize-equal.d.ts +9 -0
  479. package/dist/search-params/serialize-equal.d.ts.map +1 -0
  480. package/dist/search-params/wrappers.d.ts +76 -0
  481. package/dist/search-params/wrappers.d.ts.map +1 -0
  482. package/dist/server/access-gate.d.ts +26 -10
  483. package/dist/server/access-gate.d.ts.map +1 -1
  484. package/dist/server/action-client.d.ts +42 -7
  485. package/dist/server/action-client.d.ts.map +1 -1
  486. package/dist/server/action-encryption.d.ts +76 -0
  487. package/dist/server/action-encryption.d.ts.map +1 -0
  488. package/dist/server/action-handler.d.ts +35 -1
  489. package/dist/server/action-handler.d.ts.map +1 -1
  490. package/dist/server/actions.d.ts +12 -33
  491. package/dist/server/actions.d.ts.map +1 -1
  492. package/dist/server/als-registry.d.ts +115 -11
  493. package/dist/server/als-registry.d.ts.map +1 -1
  494. package/dist/server/asset-headers.d.ts +8 -18
  495. package/dist/server/asset-headers.d.ts.map +1 -1
  496. package/dist/server/body-limits.d.ts.map +1 -1
  497. package/dist/server/build-manifest.d.ts +25 -30
  498. package/dist/server/build-manifest.d.ts.map +1 -1
  499. package/dist/server/canonicalize.d.ts +10 -0
  500. package/dist/server/canonicalize.d.ts.map +1 -1
  501. package/dist/server/chain-url-parts.d.ts +82 -0
  502. package/dist/server/chain-url-parts.d.ts.map +1 -0
  503. package/dist/server/children-interception.d.ts +49 -0
  504. package/dist/server/children-interception.d.ts.map +1 -0
  505. package/dist/server/coalesce-tick.d.ts +40 -0
  506. package/dist/server/coalesce-tick.d.ts.map +1 -0
  507. package/dist/server/compress.d.ts.map +1 -1
  508. package/dist/server/cookie-context.d.ts +170 -0
  509. package/dist/server/cookie-context.d.ts.map +1 -0
  510. package/dist/server/cookie-parsing.d.ts +65 -0
  511. package/dist/server/cookie-parsing.d.ts.map +1 -0
  512. package/dist/server/csrf.d.ts +3 -2
  513. package/dist/server/csrf.d.ts.map +1 -1
  514. package/dist/server/default-logger.d.ts +22 -0
  515. package/dist/server/default-logger.d.ts.map +1 -0
  516. package/dist/server/default-status-page.d.ts +45 -0
  517. package/dist/server/default-status-page.d.ts.map +1 -0
  518. package/dist/server/deny-boundary.d.ts +247 -0
  519. package/dist/server/deny-boundary.d.ts.map +1 -0
  520. package/dist/server/deny-renderer.d.ts +16 -5
  521. package/dist/server/deny-renderer.d.ts.map +1 -1
  522. package/dist/server/dev-source-map.d.ts +22 -0
  523. package/dist/server/dev-source-map.d.ts.map +1 -0
  524. package/dist/server/early-hints-sender.d.ts.map +1 -1
  525. package/dist/server/early-hints.d.ts +13 -11
  526. package/dist/server/early-hints.d.ts.map +1 -1
  527. package/dist/server/error-boundary-wrapper.d.ts +86 -10
  528. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  529. package/dist/server/fallback-error.d.ts +12 -7
  530. package/dist/server/fallback-error.d.ts.map +1 -1
  531. package/dist/server/flight-injection-state.d.ts +66 -0
  532. package/dist/server/flight-injection-state.d.ts.map +1 -0
  533. package/dist/server/flight-scripts.d.ts +42 -0
  534. package/dist/server/flight-scripts.d.ts.map +1 -0
  535. package/dist/server/form-data.d.ts +41 -0
  536. package/dist/server/form-data.d.ts.map +1 -1
  537. package/dist/server/head-response.d.ts +35 -0
  538. package/dist/server/head-response.d.ts.map +1 -0
  539. package/dist/server/html-injector-core.d.ts +242 -0
  540. package/dist/server/html-injector-core.d.ts.map +1 -0
  541. package/dist/server/html-injectors.d.ts +82 -41
  542. package/dist/server/html-injectors.d.ts.map +1 -1
  543. package/dist/server/index.d.ts +11 -47
  544. package/dist/server/index.d.ts.map +1 -1
  545. package/dist/server/index.js +183 -2906
  546. package/dist/server/index.js.map +1 -1
  547. package/dist/server/internal.d.ts +51 -0
  548. package/dist/server/internal.d.ts.map +1 -0
  549. package/dist/server/internal.js +4154 -0
  550. package/dist/server/internal.js.map +1 -0
  551. package/dist/server/logger.d.ts +39 -7
  552. package/dist/server/logger.d.ts.map +1 -1
  553. package/dist/server/metadata-collector.d.ts +74 -0
  554. package/dist/server/metadata-collector.d.ts.map +1 -0
  555. package/dist/server/metadata-routes.d.ts +60 -11
  556. package/dist/server/metadata-routes.d.ts.map +1 -1
  557. package/dist/server/metadata.d.ts +8 -0
  558. package/dist/server/metadata.d.ts.map +1 -1
  559. package/dist/server/middleware-runner.d.ts +19 -4
  560. package/dist/server/middleware-runner.d.ts.map +1 -1
  561. package/dist/server/node-stream-transforms.d.ts +119 -0
  562. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  563. package/dist/server/param-coercion.d.ts +71 -0
  564. package/dist/server/param-coercion.d.ts.map +1 -0
  565. package/dist/server/pipeline-helpers.d.ts +77 -0
  566. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  567. package/dist/server/pipeline-interception.d.ts +59 -9
  568. package/dist/server/pipeline-interception.d.ts.map +1 -1
  569. package/dist/server/pipeline-metadata.d.ts +6 -0
  570. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  571. package/dist/server/pipeline-outcome.d.ts +49 -0
  572. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  573. package/dist/server/pipeline-phases.d.ts +59 -0
  574. package/dist/server/pipeline-phases.d.ts.map +1 -0
  575. package/dist/server/pipeline.d.ts +152 -19
  576. package/dist/server/pipeline.d.ts.map +1 -1
  577. package/dist/server/port-resolution.d.ts +117 -0
  578. package/dist/server/port-resolution.d.ts.map +1 -0
  579. package/dist/server/prebuilt/cache-key.d.ts +63 -0
  580. package/dist/server/prebuilt/cache-key.d.ts.map +1 -0
  581. package/dist/server/prebuilt/capture-state.d.ts +57 -0
  582. package/dist/server/prebuilt/capture-state.d.ts.map +1 -0
  583. package/dist/server/prebuilt/key-discipline.d.ts +23 -0
  584. package/dist/server/prebuilt/key-discipline.d.ts.map +1 -0
  585. package/dist/server/prebuilt/manifest-tag-index.d.ts +27 -0
  586. package/dist/server/prebuilt/manifest-tag-index.d.ts.map +1 -0
  587. package/dist/server/prebuilt/overlay.d.ts +100 -0
  588. package/dist/server/prebuilt/overlay.d.ts.map +1 -0
  589. package/dist/server/prebuilt/payload-source.d.ts +79 -0
  590. package/dist/server/prebuilt/payload-source.d.ts.map +1 -0
  591. package/dist/server/prebuilt/slots.d.ts +99 -0
  592. package/dist/server/prebuilt/slots.d.ts.map +1 -0
  593. package/dist/server/prebuilt/synthetic-store.d.ts +67 -0
  594. package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -0
  595. package/dist/server/prebuilt-builder.d.ts +121 -0
  596. package/dist/server/prebuilt-builder.d.ts.map +1 -0
  597. package/dist/server/prebuilt-runtime.d.ts +111 -0
  598. package/dist/server/prebuilt-runtime.d.ts.map +1 -0
  599. package/dist/server/primitives.d.ts +100 -44
  600. package/dist/server/primitives.d.ts.map +1 -1
  601. package/dist/server/publish-params.d.ts +33 -0
  602. package/dist/server/publish-params.d.ts.map +1 -0
  603. package/dist/server/render-timeout.d.ts +51 -0
  604. package/dist/server/render-timeout.d.ts.map +1 -0
  605. package/dist/server/render-utils.d.ts +25 -0
  606. package/dist/server/render-utils.d.ts.map +1 -0
  607. package/dist/server/request-context.d.ts +110 -106
  608. package/dist/server/request-context.d.ts.map +1 -1
  609. package/dist/server/request-dep.d.ts +15 -0
  610. package/dist/server/request-dep.d.ts.map +1 -0
  611. package/dist/server/route-element-builder.d.ts +74 -27
  612. package/dist/server/route-element-builder.d.ts.map +1 -1
  613. package/dist/server/route-handler.d.ts.map +1 -1
  614. package/dist/server/route-matcher.d.ts +38 -36
  615. package/dist/server/route-matcher.d.ts.map +1 -1
  616. package/dist/server/rsc-cache-key-guard.d.ts +78 -0
  617. package/dist/server/rsc-cache-key-guard.d.ts.map +1 -0
  618. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  619. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  620. package/dist/server/rsc-entry/api-handler.d.ts +12 -3
  621. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  622. package/dist/server/rsc-entry/deny-fallback.d.ts +29 -0
  623. package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -0
  624. package/dist/server/rsc-entry/error-renderer.d.ts +38 -13
  625. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  626. package/dist/server/rsc-entry/helpers.d.ts +59 -42
  627. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  628. package/dist/server/rsc-entry/index.d.ts +39 -6
  629. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  630. package/dist/server/rsc-entry/render-route.d.ts +51 -0
  631. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  632. package/dist/server/rsc-entry/revalidate-renderer.d.ts +108 -0
  633. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -0
  634. package/dist/server/rsc-entry/rsc-payload.d.ts +5 -6
  635. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  636. package/dist/server/rsc-entry/rsc-stream.d.ts +40 -3
  637. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  638. package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
  639. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  640. package/dist/server/rsc-entry/ssr-renderer.d.ts +36 -4
  641. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  642. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +89 -0
  643. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  644. package/dist/server/safe-load.d.ts +46 -0
  645. package/dist/server/safe-load.d.ts.map +1 -0
  646. package/dist/server/sensitive-fields.d.ts +74 -0
  647. package/dist/server/sensitive-fields.d.ts.map +1 -0
  648. package/dist/server/sitemap-generator.d.ts +130 -0
  649. package/dist/server/sitemap-generator.d.ts.map +1 -0
  650. package/dist/server/sitemap-handler.d.ts +22 -0
  651. package/dist/server/sitemap-handler.d.ts.map +1 -0
  652. package/dist/server/skippable-prefix.d.ts +26 -0
  653. package/dist/server/skippable-prefix.d.ts.map +1 -0
  654. package/dist/server/slot-interception.d.ts +80 -0
  655. package/dist/server/slot-interception.d.ts.map +1 -0
  656. package/dist/server/slot-resolver.d.ts +139 -5
  657. package/dist/server/slot-resolver.d.ts.map +1 -1
  658. package/dist/server/ssr-bridge-types.d.ts +140 -0
  659. package/dist/server/ssr-bridge-types.d.ts.map +1 -0
  660. package/dist/server/ssr-entry.d.ts +1 -43
  661. package/dist/server/ssr-entry.d.ts.map +1 -1
  662. package/dist/server/ssr-render.d.ts +64 -21
  663. package/dist/server/ssr-render.d.ts.map +1 -1
  664. package/dist/server/ssr-wrappers.d.ts +61 -0
  665. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  666. package/dist/server/state-tree-diff.d.ts +44 -9
  667. package/dist/server/state-tree-diff.d.ts.map +1 -1
  668. package/dist/server/static-generator.d.ts +112 -0
  669. package/dist/server/static-generator.d.ts.map +1 -0
  670. package/dist/server/static-not-found.d.ts +52 -0
  671. package/dist/server/static-not-found.d.ts.map +1 -0
  672. package/dist/server/status-code-resolver.d.ts +26 -15
  673. package/dist/server/status-code-resolver.d.ts.map +1 -1
  674. package/dist/server/stream-utils.d.ts +47 -0
  675. package/dist/server/stream-utils.d.ts.map +1 -0
  676. package/dist/server/tracing.d.ts +44 -9
  677. package/dist/server/tracing.d.ts.map +1 -1
  678. package/dist/server/tree-builder.d.ts +66 -42
  679. package/dist/server/tree-builder.d.ts.map +1 -1
  680. package/dist/server/tree-match.d.ts +49 -0
  681. package/dist/server/tree-match.d.ts.map +1 -0
  682. package/dist/server/types.d.ts +77 -6
  683. package/dist/server/types.d.ts.map +1 -1
  684. package/dist/server/utils/element-type.d.ts +40 -0
  685. package/dist/server/utils/element-type.d.ts.map +1 -0
  686. package/dist/server/utils/escape-html.d.ts +14 -0
  687. package/dist/server/utils/escape-html.d.ts.map +1 -0
  688. package/dist/server/utils/mdx-file.d.ts +15 -0
  689. package/dist/server/utils/mdx-file.d.ts.map +1 -0
  690. package/dist/server/version-skew.d.ts +61 -0
  691. package/dist/server/version-skew.d.ts.map +1 -0
  692. package/dist/server/workers-cache-bridge.d.ts +26 -0
  693. package/dist/server/workers-cache-bridge.d.ts.map +1 -0
  694. package/dist/shared/als-slots.d.ts +42 -0
  695. package/dist/shared/als-slots.d.ts.map +1 -0
  696. package/dist/shared/base-path.d.ts +56 -0
  697. package/dist/shared/base-path.d.ts.map +1 -0
  698. package/dist/shared/href-validation.d.ts +49 -0
  699. package/dist/shared/href-validation.d.ts.map +1 -0
  700. package/dist/shared/merge-search-params.d.ts +22 -0
  701. package/dist/shared/merge-search-params.d.ts.map +1 -0
  702. package/dist/shared/param-value.d.ts +104 -0
  703. package/dist/shared/param-value.d.ts.map +1 -0
  704. package/dist/shared/payload-root.d.ts +109 -0
  705. package/dist/shared/payload-root.d.ts.map +1 -0
  706. package/dist/shared/redirect-type.d.ts +17 -0
  707. package/dist/shared/redirect-type.d.ts.map +1 -0
  708. package/dist/shared/rsc-cache-key.d.ts +163 -0
  709. package/dist/shared/rsc-cache-key.d.ts.map +1 -0
  710. package/dist/shared/rsc-error-envelope.d.ts +25 -0
  711. package/dist/shared/rsc-error-envelope.d.ts.map +1 -0
  712. package/dist/shared/rsc-manifest.d.ts +28 -0
  713. package/dist/shared/rsc-manifest.d.ts.map +1 -0
  714. package/dist/shared/rsc-media-type.d.ts +40 -0
  715. package/dist/shared/rsc-media-type.d.ts.map +1 -0
  716. package/dist/shared/rsc-payload-path.d.ts +42 -0
  717. package/dist/shared/rsc-payload-path.d.ts.map +1 -0
  718. package/dist/shared/segment-info.d.ts +66 -0
  719. package/dist/shared/segment-info.d.ts.map +1 -0
  720. package/dist/shared/slot-params.d.ts +52 -0
  721. package/dist/shared/slot-params.d.ts.map +1 -0
  722. package/dist/shared/static-platform-files.d.ts +71 -0
  723. package/dist/shared/static-platform-files.d.ts.map +1 -0
  724. package/dist/shims/font-google.d.ts +1 -1
  725. package/dist/shims/font-google.d.ts.map +1 -1
  726. package/dist/shims/font-google.js +42 -0
  727. package/dist/shims/font-google.js.map +1 -0
  728. package/dist/shims/font-local.d.ts +26 -0
  729. package/dist/shims/font-local.d.ts.map +1 -0
  730. package/dist/shims/font-local.js +20 -0
  731. package/dist/shims/font-local.js.map +1 -0
  732. package/dist/shims/headers.d.ts +53 -1
  733. package/dist/shims/headers.d.ts.map +1 -1
  734. package/dist/shims/image.d.ts +120 -120
  735. package/dist/shims/image.d.ts.map +1 -1
  736. package/dist/shims/navigation-client.d.ts +25 -12
  737. package/dist/shims/navigation-client.d.ts.map +1 -1
  738. package/dist/shims/navigation.d.ts +10 -5
  739. package/dist/shims/navigation.d.ts.map +1 -1
  740. package/dist/utils/state-machine.d.ts +80 -0
  741. package/dist/utils/state-machine.d.ts.map +1 -0
  742. package/docs/api/30-api-server.mdx +233 -0
  743. package/docs/api/31-api-client.mdx +163 -0
  744. package/docs/api/32-api-cache.mdx +311 -0
  745. package/docs/api/33-api-search-params.mdx +176 -0
  746. package/docs/api/34-api-config.mdx +325 -0
  747. package/docs/api/35-api-typescript.mdx +170 -0
  748. package/docs/api/36-cli.mdx +170 -0
  749. package/docs/learn/00-introduction.mdx +109 -0
  750. package/docs/learn/01-quick-start.mdx +94 -0
  751. package/docs/learn/02-pages-and-layouts.mdx +147 -0
  752. package/docs/learn/03-fetching-data.mdx +211 -0
  753. package/docs/learn/03b-access-control.mdx +130 -0
  754. package/docs/learn/04-loading-states.mdx +67 -0
  755. package/docs/learn/04b-the-flush-point.mdx +115 -0
  756. package/docs/learn/05-typed-params.mdx +275 -0
  757. package/docs/learn/06-forms-and-actions.mdx +146 -0
  758. package/docs/learn/07-typed-routes.mdx +132 -0
  759. package/docs/learn/08-streaming.mdx +146 -0
  760. package/docs/learn/09-caching.mdx +252 -0
  761. package/docs/learn/10-middleware.mdx +157 -0
  762. package/docs/learn/11-error-handling.mdx +173 -0
  763. package/docs/learn/12-client-navigation.mdx +176 -0
  764. package/docs/learn/13-configuration.mdx +166 -0
  765. package/docs/learn/14-deploying.mdx +287 -0
  766. package/docs/more/01-advanced-routing.mdx +343 -0
  767. package/docs/more/02-advanced-forms.mdx +137 -0
  768. package/docs/more/03-coming-from-nextjs.mdx +186 -0
  769. package/docs/more/04-metadata-and-fonts.mdx +193 -0
  770. package/docs/more/04b-mdx.mdx +209 -0
  771. package/docs/more/05-content-collections.mdx +90 -0
  772. package/docs/more/06-instrumentation.mdx +214 -0
  773. package/docs/more/07-security.mdx +129 -0
  774. package/docs/more/08-developer-experience.mdx +134 -0
  775. package/docs/more/40-why-timber.mdx +50 -0
  776. package/docs/more/41-timber-vs-nextjs.mdx +81 -0
  777. package/docs/more/42-timber-vs-others.mdx +68 -0
  778. package/docs/more/50-ai-agent-instructions.mdx +171 -0
  779. package/llms.txt +55 -0
  780. package/package.json +108 -26
  781. package/src/adapters/build-output-helper.ts +351 -0
  782. package/src/adapters/cloudflare-dev.ts +177 -0
  783. package/src/adapters/cloudflare-kv-cache.ts +204 -0
  784. package/src/adapters/cloudflare.ts +740 -129
  785. package/src/adapters/compress-module.ts +101 -88
  786. package/src/adapters/fs-identity.ts +156 -0
  787. package/src/adapters/nitro.ts +320 -120
  788. package/src/adapters/raw-imports.d.ts +5 -0
  789. package/src/adapters/shared.ts +274 -0
  790. package/src/adapters/types.ts +28 -7
  791. package/src/adapters/wrangler.d.ts +7 -0
  792. package/src/cache/cache-api.ts +107 -0
  793. package/src/cache/fast-hash.ts +5 -0
  794. package/src/cache/handler-store.ts +76 -0
  795. package/src/cache/index.ts +114 -21
  796. package/src/cache/invalidation-epoch.ts +93 -0
  797. package/src/cache/json-lossy-check.ts +75 -0
  798. package/src/cache/redis-handler.ts +197 -19
  799. package/src/cache/singleflight.ts +64 -6
  800. package/src/cache/sizeof.ts +33 -0
  801. package/src/cache/stable-stringify.ts +65 -2
  802. package/src/cache/store.ts +71 -0
  803. package/src/cache/stores/cloudflare-kv.ts +52 -0
  804. package/src/cache/stores/memory.ts +125 -0
  805. package/src/cache/stores/redis.ts +97 -0
  806. package/src/cache/stores/vercel.ts +59 -0
  807. package/src/cache/tag-aware-handler.ts +237 -0
  808. package/src/cache/timber-cache.ts +161 -36
  809. package/src/cdn/cloudflare-purge.ts +50 -0
  810. package/src/cdn/fastly-purge.ts +63 -0
  811. package/src/cdn/headers.ts +153 -0
  812. package/src/cdn/index.ts +17 -0
  813. package/src/cdn/purge-store.ts +34 -0
  814. package/src/cdn/workers-cache-purge.ts +30 -0
  815. package/src/cli-check.ts +458 -0
  816. package/src/cli-schema-sync.ts +401 -0
  817. package/src/cli.ts +221 -53
  818. package/src/client/browser-dev.ts +156 -1
  819. package/src/client/browser-entry/action-dispatch.ts +130 -0
  820. package/src/client/browser-entry/hmr.ts +70 -0
  821. package/src/client/browser-entry/hydrate.ts +198 -0
  822. package/src/client/browser-entry/index.ts +121 -0
  823. package/src/client/browser-entry/post-hydration.ts +122 -0
  824. package/src/client/browser-entry/router-init.ts +342 -0
  825. package/src/client/browser-entry/rsc-stream.ts +166 -0
  826. package/src/client/browser-entry/scroll.ts +50 -0
  827. package/src/client/error-boundary.tsx +210 -36
  828. package/src/client/error-reconstituter.tsx +79 -0
  829. package/src/client/form.tsx +31 -32
  830. package/src/client/history.ts +29 -7
  831. package/src/client/index.ts +78 -45
  832. package/src/client/internal.ts +59 -0
  833. package/src/client/link.tsx +397 -150
  834. package/src/client/navigation-api.ts +345 -0
  835. package/src/client/navigation-commit.ts +197 -0
  836. package/src/client/navigation-context.ts +43 -62
  837. package/src/client/navigation-root.tsx +580 -0
  838. package/src/client/nuqs-adapter.tsx +16 -3
  839. package/src/client/params-context.ts +192 -0
  840. package/src/client/router-effects.ts +231 -0
  841. package/src/client/router-lifecycle.ts +288 -0
  842. package/src/client/router-pipeline.ts +393 -0
  843. package/src/client/router-ref.ts +2 -2
  844. package/src/client/router-skew.ts +30 -0
  845. package/src/client/router-types.ts +230 -0
  846. package/src/client/router.ts +339 -410
  847. package/src/client/rsc-fetch.ts +530 -73
  848. package/src/client/segment-cache.ts +224 -38
  849. package/src/client/segment-outlet.tsx +141 -0
  850. package/src/client/segment-update-context.ts +42 -0
  851. package/src/client/shallow-url.ts +22 -0
  852. package/src/client/slot-context.ts +50 -0
  853. package/src/client/slot-outlet.tsx +22 -0
  854. package/src/client/slot-provider.tsx +32 -0
  855. package/src/client/ssr-data.ts +21 -6
  856. package/src/client/stale-client.ts +191 -0
  857. package/src/client/state.ts +19 -5
  858. package/src/client/top-loader.tsx +13 -10
  859. package/src/client/unload-guard.ts +34 -2
  860. package/src/client/use-cookie.ts +69 -17
  861. package/src/client/use-link-status.ts +7 -7
  862. package/src/client/use-pathname.ts +1 -0
  863. package/src/client/use-pending-navigation.ts +40 -0
  864. package/src/client/use-query-states.ts +206 -36
  865. package/src/client/use-router.ts +5 -2
  866. package/src/client/use-search-params.ts +31 -44
  867. package/src/client/{use-params.ts → use-segment-params.ts} +52 -25
  868. package/src/codec.ts +149 -0
  869. package/src/config-types.ts +282 -0
  870. package/src/config-validation.ts +330 -0
  871. package/src/content/index.ts +5 -13
  872. package/src/cookies/define-cookie.ts +222 -53
  873. package/src/cookies/index.ts +12 -1
  874. package/src/cookies/json-cookie.ts +105 -0
  875. package/src/cookies/validation.ts +192 -0
  876. package/src/dev-tools/404-page.ts +286 -0
  877. package/src/dev-tools/browser-logs.ts +55 -0
  878. package/src/dev-tools/dev-page-shell.ts +260 -0
  879. package/src/dev-tools/error-page.ts +331 -0
  880. package/src/dev-tools/holding-server.ts +187 -0
  881. package/src/dev-tools/hydration-overlay.ts +158 -0
  882. package/src/dev-tools/index.ts +83 -0
  883. package/src/dev-tools/instrumentation.ts +213 -0
  884. package/src/{server/dev-logger.ts → dev-tools/logger.ts} +33 -51
  885. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +122 -26
  886. package/src/dev-tools/overlay.ts +469 -0
  887. package/src/dev-tools/stack-classifier.ts +75 -0
  888. package/src/dev-tools/terminal.ts +182 -0
  889. package/src/fonts/ast-walk.ts +235 -0
  890. package/src/fonts/ast.ts +477 -126
  891. package/src/fonts/bundle.ts +138 -0
  892. package/src/fonts/dev-middleware.ts +85 -0
  893. package/src/fonts/fallbacks.ts +0 -23
  894. package/src/fonts/google.ts +100 -18
  895. package/src/fonts/local.ts +9 -8
  896. package/src/fonts/paths.ts +58 -0
  897. package/src/fonts/pipeline.ts +348 -0
  898. package/src/fonts/transform.ts +311 -0
  899. package/src/fonts/types.ts +52 -1
  900. package/src/fonts/virtual-modules.ts +179 -0
  901. package/src/index.ts +468 -353
  902. package/src/params/codec-registry.ts +34 -0
  903. package/src/params/define-schema.ts +115 -0
  904. package/src/params/index.ts +17 -0
  905. package/src/params/resolve-schema.ts +84 -0
  906. package/src/plugin-context.ts +503 -0
  907. package/src/plugins/adapter-build.ts +229 -7
  908. package/src/plugins/build-manifest.ts +201 -26
  909. package/src/plugins/build-report.ts +259 -47
  910. package/src/plugins/cache.ts +243 -0
  911. package/src/plugins/callsite-ast.ts +472 -0
  912. package/src/plugins/callsite-jsx.ts +243 -0
  913. package/src/plugins/chunks.ts +74 -5
  914. package/src/plugins/client-chunks.ts +185 -0
  915. package/src/plugins/cloudflare-wasm.ts +141 -0
  916. package/src/plugins/content.ts +1 -1
  917. package/src/plugins/dev-server.ts +284 -94
  918. package/src/plugins/entries.ts +138 -16
  919. package/src/plugins/fonts.ts +228 -660
  920. package/src/plugins/mdx.ts +47 -10
  921. package/src/plugins/prebuilt-capture.ts +217 -0
  922. package/src/plugins/prebuilt-options-analysis.ts +175 -0
  923. package/src/plugins/prebuilt.ts +655 -0
  924. package/src/plugins/prerender-sugar.ts +328 -0
  925. package/src/plugins/request-dep/analysis.ts +447 -0
  926. package/src/plugins/request-dep/index.ts +376 -0
  927. package/src/plugins/request-dep/origin.ts +310 -0
  928. package/src/plugins/routing.ts +268 -277
  929. package/src/plugins/server-bundle.ts +89 -12
  930. package/src/plugins/shims.ts +240 -64
  931. package/src/plugins/static-build.ts +704 -66
  932. package/src/routing/codegen-shared.ts +39 -0
  933. package/src/routing/codegen-types.ts +62 -0
  934. package/src/routing/codegen-write.ts +139 -0
  935. package/src/routing/codegen.ts +339 -231
  936. package/src/routing/collision-probe.ts +438 -0
  937. package/src/routing/collision-spaces.ts +281 -0
  938. package/src/routing/convention-lint.ts +493 -0
  939. package/src/routing/export-detect.ts +448 -0
  940. package/src/routing/file-cache.ts +23 -0
  941. package/src/routing/index.ts +10 -1
  942. package/src/routing/interception.ts +894 -67
  943. package/src/routing/link-codegen.ts +280 -0
  944. package/src/routing/manifest-codegen.ts +226 -0
  945. package/src/routing/scanner.ts +368 -218
  946. package/src/routing/schema-validation.ts +155 -0
  947. package/src/routing/segment-classify.ts +280 -0
  948. package/src/routing/segment-codegen.ts +98 -0
  949. package/src/routing/segment-keys.ts +186 -0
  950. package/src/routing/slot-placement.ts +97 -0
  951. package/src/routing/types.ts +75 -26
  952. package/src/routing/walkers.ts +98 -0
  953. package/src/rsc-runtime/rsc.ts +9 -0
  954. package/src/rsc-runtime/ssr.ts +50 -0
  955. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  956. package/src/schema-bridge.ts +380 -0
  957. package/src/search-params/define.ts +677 -0
  958. package/src/search-params/index.ts +14 -20
  959. package/src/search-params/parse-total.ts +91 -0
  960. package/src/search-params/serialize-equal.ts +14 -0
  961. package/src/search-params/wrappers.ts +150 -0
  962. package/src/server/access-gate.tsx +121 -51
  963. package/src/server/action-client.ts +120 -29
  964. package/src/server/action-encryption.ts +144 -0
  965. package/src/server/action-handler.ts +230 -43
  966. package/src/server/actions.ts +54 -57
  967. package/src/server/als-registry.ts +159 -20
  968. package/src/server/asset-headers.ts +15 -37
  969. package/src/server/body-limits.ts +10 -2
  970. package/src/server/build-manifest.ts +33 -57
  971. package/src/server/canonicalize.ts +6 -3
  972. package/src/server/chain-url-parts.ts +163 -0
  973. package/src/server/children-interception.ts +115 -0
  974. package/src/server/coalesce-tick.ts +75 -0
  975. package/src/server/compress.ts +43 -8
  976. package/src/server/cookie-context.ts +484 -0
  977. package/src/server/cookie-parsing.ts +163 -0
  978. package/src/server/csrf.ts +39 -6
  979. package/src/server/default-logger.ts +99 -0
  980. package/src/server/default-status-page.ts +127 -0
  981. package/src/server/deny-boundary.ts +516 -0
  982. package/src/server/deny-renderer.ts +181 -101
  983. package/src/server/dev-source-map.ts +31 -0
  984. package/src/server/early-hints-sender.ts +3 -2
  985. package/src/server/early-hints.ts +37 -27
  986. package/src/server/error-boundary-wrapper.ts +170 -44
  987. package/src/server/fallback-error.ts +79 -102
  988. package/src/server/flight-injection-state.ts +113 -0
  989. package/src/server/flight-scripts.ts +62 -0
  990. package/src/server/form-data.ts +124 -12
  991. package/src/server/head-response.ts +54 -0
  992. package/src/server/html-injector-core.ts +495 -0
  993. package/src/server/html-injectors.ts +271 -254
  994. package/src/server/index.ts +32 -184
  995. package/src/server/internal.ts +181 -0
  996. package/src/server/logger.ts +72 -36
  997. package/src/server/metadata-collector.ts +189 -0
  998. package/src/server/metadata-routes.ts +205 -24
  999. package/src/server/metadata.ts +21 -0
  1000. package/src/server/middleware-runner.ts +31 -4
  1001. package/src/server/node-stream-transforms.ts +336 -0
  1002. package/src/server/param-coercion.ts +189 -0
  1003. package/src/server/pipeline-helpers.ts +159 -0
  1004. package/src/server/pipeline-interception.ts +109 -33
  1005. package/src/server/pipeline-metadata.ts +14 -0
  1006. package/src/server/pipeline-outcome.ts +196 -0
  1007. package/src/server/pipeline-phases.ts +599 -0
  1008. package/src/server/pipeline.ts +322 -382
  1009. package/src/server/port-resolution.ts +215 -0
  1010. package/src/server/prebuilt/cache-key.ts +299 -0
  1011. package/src/server/prebuilt/capture-state.ts +89 -0
  1012. package/src/server/prebuilt/key-discipline.ts +53 -0
  1013. package/src/server/prebuilt/manifest-tag-index.ts +46 -0
  1014. package/src/server/prebuilt/overlay.ts +256 -0
  1015. package/src/server/prebuilt/payload-source.ts +202 -0
  1016. package/src/server/prebuilt/slots.ts +190 -0
  1017. package/src/server/prebuilt/synthetic-store.ts +122 -0
  1018. package/src/server/prebuilt-builder.ts +804 -0
  1019. package/src/server/prebuilt-runtime.ts +817 -0
  1020. package/src/server/primitives.ts +174 -90
  1021. package/src/server/publish-params.ts +42 -0
  1022. package/src/server/render-timeout.ts +108 -0
  1023. package/src/server/render-utils.ts +31 -0
  1024. package/src/server/request-context.ts +243 -333
  1025. package/src/server/request-dep.ts +37 -0
  1026. package/src/server/route-element-builder.ts +666 -308
  1027. package/src/server/route-handler.ts +39 -12
  1028. package/src/server/route-matcher.ts +162 -269
  1029. package/src/server/rsc-cache-key-guard.ts +164 -0
  1030. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  1031. package/src/server/rsc-entry/api-handler.ts +67 -32
  1032. package/src/server/rsc-entry/deny-fallback.ts +93 -0
  1033. package/src/server/rsc-entry/error-renderer.ts +370 -94
  1034. package/src/server/rsc-entry/helpers.ts +226 -95
  1035. package/src/server/rsc-entry/index.ts +357 -330
  1036. package/src/server/rsc-entry/render-route.ts +308 -0
  1037. package/src/server/rsc-entry/revalidate-renderer.ts +350 -0
  1038. package/src/server/rsc-entry/rsc-payload.ts +188 -55
  1039. package/src/server/rsc-entry/rsc-stream.ts +122 -18
  1040. package/src/server/rsc-entry/ssr-bridge.ts +18 -5
  1041. package/src/server/rsc-entry/ssr-renderer.ts +299 -80
  1042. package/src/server/rsc-entry/wrap-action-dispatch.ts +186 -0
  1043. package/src/server/safe-load.ts +60 -0
  1044. package/src/server/sensitive-fields.ts +230 -0
  1045. package/src/server/server-only-guard-noop.js +3 -0
  1046. package/src/server/sitemap-generator.ts +337 -0
  1047. package/src/server/sitemap-handler.ts +157 -0
  1048. package/src/server/skippable-prefix.ts +74 -0
  1049. package/src/server/slot-interception.ts +168 -0
  1050. package/src/server/slot-resolver.ts +678 -294
  1051. package/src/server/ssr-bridge-types.ts +145 -0
  1052. package/src/server/ssr-entry.ts +216 -78
  1053. package/src/server/ssr-render.ts +345 -82
  1054. package/src/server/ssr-wrappers.tsx +142 -0
  1055. package/src/server/state-tree-diff.ts +85 -30
  1056. package/src/server/static-generator.ts +715 -0
  1057. package/src/server/static-not-found.ts +134 -0
  1058. package/src/server/status-code-resolver.ts +107 -148
  1059. package/src/server/stream-utils.ts +288 -0
  1060. package/src/server/tracing.ts +126 -14
  1061. package/src/server/tree-builder.ts +99 -168
  1062. package/src/server/tree-match.ts +262 -0
  1063. package/src/server/types.ts +84 -9
  1064. package/src/server/utils/element-type.ts +72 -0
  1065. package/src/server/utils/escape-html.ts +20 -0
  1066. package/src/server/utils/mdx-file.ts +22 -0
  1067. package/src/server/version-skew.ts +104 -0
  1068. package/src/server/workers-cache-bridge.ts +33 -0
  1069. package/src/shared/als-slots.ts +74 -0
  1070. package/src/shared/base-path.ts +80 -0
  1071. package/src/shared/href-validation.ts +159 -0
  1072. package/src/shared/merge-search-params.ts +55 -0
  1073. package/src/shared/param-value.ts +281 -0
  1074. package/src/shared/payload-root.ts +152 -0
  1075. package/src/shared/redirect-type.ts +17 -0
  1076. package/src/shared/rsc-cache-key.ts +269 -0
  1077. package/src/shared/rsc-error-envelope.ts +31 -0
  1078. package/src/shared/rsc-manifest.ts +29 -0
  1079. package/src/shared/rsc-media-type.ts +43 -0
  1080. package/src/shared/rsc-payload-path.ts +45 -0
  1081. package/src/shared/segment-info.ts +67 -0
  1082. package/src/shared/slot-params.ts +110 -0
  1083. package/src/shared/static-platform-files.ts +75 -0
  1084. package/src/shims/font-google.ts +1 -1
  1085. package/src/shims/font-local.ts +34 -0
  1086. package/src/shims/headers.ts +122 -1
  1087. package/src/shims/navigation-client.ts +36 -32
  1088. package/src/shims/navigation.ts +10 -7
  1089. package/src/utils/state-machine.ts +111 -0
  1090. package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
  1091. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  1092. package/dist/_chunks/debug-B3Gypr3D.js +0 -108
  1093. package/dist/_chunks/debug-B3Gypr3D.js.map +0 -1
  1094. package/dist/_chunks/format-RyoGQL74.js +0 -164
  1095. package/dist/_chunks/format-RyoGQL74.js.map +0 -1
  1096. package/dist/_chunks/interception-BOoWmLUA.js +0 -676
  1097. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  1098. package/dist/_chunks/metadata-routes-Cjmvi3rQ.js +0 -153
  1099. package/dist/_chunks/metadata-routes-Cjmvi3rQ.js.map +0 -1
  1100. package/dist/_chunks/request-context-BQUC8PHn.js +0 -330
  1101. package/dist/_chunks/request-context-BQUC8PHn.js.map +0 -1
  1102. package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
  1103. package/dist/_chunks/tracing-CemImE6h.js +0 -187
  1104. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  1105. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  1106. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  1107. package/dist/_chunks/use-query-states-D5KaffOK.js +0 -109
  1108. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  1109. package/dist/adapters/cloudflare.js.map +0 -1
  1110. package/dist/cache/index.js.map +0 -1
  1111. package/dist/cache/register-cached-function.d.ts +0 -17
  1112. package/dist/cache/register-cached-function.d.ts.map +0 -1
  1113. package/dist/client/browser-entry.d.ts +0 -21
  1114. package/dist/client/browser-entry.d.ts.map +0 -1
  1115. package/dist/client/error-boundary.js.map +0 -1
  1116. package/dist/client/head.d.ts +0 -16
  1117. package/dist/client/head.d.ts.map +0 -1
  1118. package/dist/client/link-status-provider.d.ts +0 -11
  1119. package/dist/client/link-status-provider.d.ts.map +0 -1
  1120. package/dist/client/segment-merger.d.ts +0 -119
  1121. package/dist/client/segment-merger.d.ts.map +0 -1
  1122. package/dist/client/stale-reload.d.ts +0 -44
  1123. package/dist/client/stale-reload.d.ts.map +0 -1
  1124. package/dist/client/transition-root.d.ts +0 -74
  1125. package/dist/client/transition-root.d.ts.map +0 -1
  1126. package/dist/client/use-navigation-pending.d.ts +0 -26
  1127. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  1128. package/dist/client/use-params.d.ts.map +0 -1
  1129. package/dist/plugins/cache-transform.d.ts +0 -36
  1130. package/dist/plugins/cache-transform.d.ts.map +0 -1
  1131. package/dist/plugins/dev-error-overlay.d.ts +0 -60
  1132. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  1133. package/dist/plugins/dev-logs.d.ts.map +0 -1
  1134. package/dist/plugins/dynamic-transform.d.ts +0 -72
  1135. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  1136. package/dist/plugins/server-action-exports.d.ts +0 -26
  1137. package/dist/plugins/server-action-exports.d.ts.map +0 -1
  1138. package/dist/routing/status-file-lint.d.ts +0 -33
  1139. package/dist/routing/status-file-lint.d.ts.map +0 -1
  1140. package/dist/search-params/analyze.d.ts +0 -54
  1141. package/dist/search-params/analyze.d.ts.map +0 -1
  1142. package/dist/search-params/builtin-codecs.d.ts +0 -105
  1143. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  1144. package/dist/search-params/codecs.d.ts +0 -53
  1145. package/dist/search-params/codecs.d.ts.map +0 -1
  1146. package/dist/search-params/create.d.ts +0 -106
  1147. package/dist/search-params/create.d.ts.map +0 -1
  1148. package/dist/search-params/registry.d.ts +0 -20
  1149. package/dist/search-params/registry.d.ts.map +0 -1
  1150. package/dist/server/client-module-map.d.ts +0 -47
  1151. package/dist/server/client-module-map.d.ts.map +0 -1
  1152. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  1153. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  1154. package/dist/server/dev-logger.d.ts.map +0 -1
  1155. package/dist/server/dev-span-processor.d.ts +0 -29
  1156. package/dist/server/dev-span-processor.d.ts.map +0 -1
  1157. package/dist/server/dev-warnings.d.ts +0 -129
  1158. package/dist/server/dev-warnings.d.ts.map +0 -1
  1159. package/dist/server/flush.d.ts +0 -74
  1160. package/dist/server/flush.d.ts.map +0 -1
  1161. package/dist/server/manifest-status-resolver.d.ts +0 -58
  1162. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  1163. package/dist/server/prerender.d.ts +0 -77
  1164. package/dist/server/prerender.d.ts.map +0 -1
  1165. package/dist/utils/directive-parser.d.ts +0 -70
  1166. package/dist/utils/directive-parser.d.ts.map +0 -1
  1167. package/src/cache/register-cached-function.ts +0 -103
  1168. package/src/client/browser-entry.ts +0 -678
  1169. package/src/client/head.ts +0 -61
  1170. package/src/client/link-status-provider.tsx +0 -30
  1171. package/src/client/segment-merger.ts +0 -339
  1172. package/src/client/stale-reload.ts +0 -87
  1173. package/src/client/transition-root.tsx +0 -166
  1174. package/src/client/use-navigation-pending.ts +0 -38
  1175. package/src/plugins/cache-transform.ts +0 -199
  1176. package/src/plugins/dev-error-overlay.ts +0 -230
  1177. package/src/plugins/dynamic-transform.ts +0 -161
  1178. package/src/plugins/server-action-exports.ts +0 -220
  1179. package/src/routing/status-file-lint.ts +0 -112
  1180. package/src/search-params/analyze.ts +0 -192
  1181. package/src/search-params/builtin-codecs.ts +0 -228
  1182. package/src/search-params/codecs.ts +0 -153
  1183. package/src/search-params/create.ts +0 -321
  1184. package/src/search-params/registry.ts +0 -31
  1185. package/src/server/client-module-map.ts +0 -58
  1186. package/src/server/dev-fetch-instrumentation.ts +0 -96
  1187. package/src/server/dev-span-processor.ts +0 -78
  1188. package/src/server/dev-warnings.ts +0 -283
  1189. package/src/server/flush.ts +0 -182
  1190. package/src/server/manifest-status-resolver.ts +0 -215
  1191. package/src/server/prerender.ts +0 -139
  1192. package/src/utils/directive-parser.ts +0 -529
@@ -6,43 +6,157 @@
6
6
  * rsc-entry.ts under the 500-line limit.
7
7
  *
8
8
  * This module handles:
9
- * 1. Loading page/layout components from the segment chain
10
- * 2. Running access.ts checks (DenySignal/RedirectSignal propagate to caller)
11
- * 3. Resolving metadata (static object or async function, both exported as `metadata`)
9
+ * 1. Running access.ts checks eagerly to gate metadata resolution (TIM-1027)
10
+ * 2. Loading page/layout components from the segment chain
11
+ * 3. Resolving metadata (skipped for denied segments to prevent side effects)
12
12
  * 4. Building the React element tree (page → error boundaries → access gates → layouts)
13
13
  * 5. Resolving parallel slots
14
14
  *
15
15
  * See design/02-rendering-pipeline.md, design/04-authorization.md
16
16
  */
17
17
 
18
- import { createElement } from 'react';
18
+ import { createElement, Fragment } from 'react';
19
19
 
20
- import { withSpan, setSpanAttribute } from './tracing.js';
20
+ import { withSpan } from './tracing.js';
21
21
  import type { RouteMatch } from './pipeline.js';
22
22
  import type { ManifestSegmentNode } from './route-matcher.js';
23
- import { resolveMetadata, renderMetadataToElements } from './metadata.js';
24
- import type { HeadElement as MetadataHeadElement } from './metadata.js';
25
23
  import type { Metadata } from './types.js';
26
- import { METADATA_ROUTE_CONVENTIONS, getMetadataRouteAutoLink } from './metadata-routes.js';
27
24
  import { DenySignal, RedirectSignal } from './primitives.js';
25
+ import { MetadataCollector, MetadataHead } from './metadata-collector.js';
28
26
  import { AccessGate } from './access-gate.js';
29
- import { resolveSlotElement } from './slot-resolver.js';
30
- import { SegmentProvider } from '#/client/segment-context.js';
31
- import { setParsedSearchParams } from './request-context.js';
32
- import type { SearchParamsDefinition } from '#/search-params/create.js';
27
+ import { requestContextAls } from './als-registry.js';
28
+ import { PageDenyBoundary, buildDenyPageChain, handleCaughtDeny } from './deny-boundary.js';
29
+ import type { DenyPageEntry } from './deny-boundary.js';
30
+ import { LAYOUT_CHILDREN_SLOT } from './prebuilt/slots.js';
31
+ import {
32
+ resolveSlotProps,
33
+ publishSlotSegmentParams,
34
+ emitSlotInfoForSkippedLayout,
35
+ type SlotSkipEntry,
36
+ } from './slot-resolver.js';
37
+ import { consumedUrlParts } from './chain-url-parts.js';
38
+ import { withPublishedParams } from './publish-params.js';
39
+ import type { RscPayloadRoot } from '../shared/payload-root.js';
40
+ import { SegmentProvider } from '../client/segment-context.js';
41
+ import { SegmentOutlet } from '../client/segment-outlet.js';
42
+ import { SlotOutlet } from '../client/slot-outlet.js';
43
+ import { SlotsProvider } from '../client/slot-provider.js';
44
+
45
+ import { TimberErrorBoundary } from '../client/error-boundary.js';
33
46
  import { wrapSegmentWithErrorBoundaries } from './error-boundary-wrapper.js';
34
47
  import type { InterceptionContext } from './pipeline.js';
35
- import { shouldSkipSegment } from './state-tree-diff.js';
48
+ import { shouldSkipSegment, type ClientStateTree } from './state-tree-diff.js';
49
+ import { truncateSkippableForChangedSlots } from './skippable-prefix.js';
50
+ import {
51
+ computeSegmentKeys,
52
+ computeSegmentTreePaths,
53
+ computeSlotKey,
54
+ } from '../routing/segment-keys.js';
55
+ import { setFirstDeniedSegmentIndex } from './deny-boundary.js';
56
+ import { loadModule } from './safe-load.js';
36
57
 
37
- // ─── Types ────────────────────────────────────────────────────────────────
58
+ /**
59
+ * Replace the outermost SegmentOutlet in a partial payload with its
60
+ * SegmentProvider child. Walks through AccessGate wrappers (which sit
61
+ * outside SegmentOutlet) to find the outlet.
62
+ */
63
+ function replaceOutermostSegmentOutlet(
64
+ element: React.ReactElement,
65
+ replacement: React.ReactElement
66
+ ): React.ReactElement {
67
+ if (element.type === SegmentOutlet) {
68
+ return replacement;
69
+ }
70
+ // AccessGate and MetadataCollector wrap outside SegmentOutlet — recurse through them.
71
+ const props = element.props as Record<string, unknown>;
72
+ if ((element.type === AccessGate || element.type === MetadataCollector) && props.children) {
73
+ const inner = replaceOutermostSegmentOutlet(props.children as React.ReactElement, replacement);
74
+ /* eslint-disable react/no-children-prop -- createElement API */
75
+ return createElement(element.type as React.FunctionComponent<Record<string, unknown>>, {
76
+ ...props,
77
+ children: inner,
78
+ });
79
+ /* eslint-enable react/no-children-prop */
80
+ }
81
+ return element;
82
+ }
83
+
84
+ // ─── Client Reference Detection ──────────────────────────────────────────
85
+
86
+ /**
87
+ * Symbol used by React Flight to mark client references.
88
+ * Client references are proxy objects created by @vitejs/plugin-rsc for
89
+ * 'use client' modules in the RSC environment. They must be passed to
90
+ * createElement() — calling them as functions throws:
91
+ * "Unexpectedly client reference export 'default' is called on server"
92
+ */
93
+ const CLIENT_REFERENCE_TAG = Symbol.for('react.client.reference');
38
94
 
39
- /** Head element for client-side metadata updates. */
40
- export interface HeadElement {
41
- tag: string;
42
- content?: string;
43
- attrs?: Record<string, string | null>;
95
+ /**
96
+ * Detect whether a component is a React client reference.
97
+ * Client references have $$typeof set to Symbol.for('react.client.reference')
98
+ * by registerClientReference() in the React Flight server runtime.
99
+ *
100
+ * Used to skip OTEL tracing wrappers that would call the component as a
101
+ * function. Client components must go through createElement only — they are
102
+ * serialized as references in the RSC Flight stream, not executed on the server.
103
+ */
104
+ /**
105
+ * The `segments` array handed to a layout's `SegmentProvider` — the value
106
+ * `useSelectedLayoutSegment(s)` reads.
107
+ *
108
+ * Only its **length** matters: both hooks take `segments.length` as a depth and
109
+ * index the live pathname with it. So this is really "how many URL parts had
110
+ * been consumed by the time this layout rendered", which is
111
+ * `consumedUrlParts` — the same derivation slot matching and the slot-skip
112
+ * slicing use, so a layout and the slots beside it cannot disagree about how
113
+ * deep they are. The root consumes nothing → `['']`, length 1.
114
+ *
115
+ * @internal — exported for tests; production has exactly one caller.
116
+ */
117
+ export function computeLayoutSegmentPath(
118
+ segments: ManifestSegmentNode[],
119
+ index: number,
120
+ match: RouteMatch
121
+ ): string[] {
122
+ const parts = consumedUrlParts(segments, index, match);
123
+ return parts.length === 0 ? [''] : ['', ...parts];
124
+ }
125
+
126
+ export function isClientReference(component: unknown): boolean {
127
+ return (
128
+ component != null &&
129
+ typeof component === 'function' &&
130
+ (component as unknown as Record<string, unknown>).$$typeof === CLIENT_REFERENCE_TAG
131
+ );
44
132
  }
45
133
 
134
+ // ─── Typed Errors ────────────────────────────────────────────────────────
135
+
136
+ /**
137
+ * Thrown when an app/schema.ts segment-param codec's parse() fails.
138
+ * The pipeline catches this and responds with 404.
139
+ */
140
+ export class ParamCoercionError extends Error {
141
+ constructor(message: string) {
142
+ super(message);
143
+ this.name = 'ParamCoercionError';
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Thrown when a matched route has no page component in its leaf segment.
149
+ * The pipeline catches this and renders the custom 404 page.
150
+ */
151
+ export class NoPageComponentError extends Error {
152
+ constructor(message: string) {
153
+ super(message);
154
+ this.name = 'NoPageComponentError';
155
+ }
156
+ }
157
+
158
+ // ─── Types ────────────────────────────────────────────────────────────────
159
+
46
160
  /** Layout entry with component and segment. */
47
161
  export interface LayoutComponentEntry {
48
162
  component: (...args: unknown[]) => unknown;
@@ -51,10 +165,12 @@ export interface LayoutComponentEntry {
51
165
 
52
166
  /** Result of building a route element tree. */
53
167
  export interface RouteElementResult {
54
- /** The React element tree (page wrapped in layouts, access gates, error boundaries). */
55
- element: React.ReactElement;
56
- /** Resolved head elements for metadata. */
57
- headElements: HeadElement[];
168
+ /**
169
+ * The payload root: the React element tree (page wrapped in layouts, access
170
+ * gates, error boundaries) plus the params it rendered with, as siblings.
171
+ * See shared/payload-root.ts for why params are not a wrapper around it.
172
+ */
173
+ payload: RscPayloadRoot;
58
174
  /** Layout components loaded along the segment chain. */
59
175
  layoutComponents: LayoutComponentEntry[];
60
176
  /** Segments from the route match. */
@@ -68,20 +184,51 @@ export interface RouteElementResult {
68
184
  * See design/19-client-navigation.md §"X-Timber-State-Tree Header"
69
185
  */
70
186
  skippedSegments: string[];
187
+ /**
188
+ * Resolves when every deny-capable shell component (PageDenyBoundary and
189
+ * each TracedLayout with a deny page chain) has finished executing, OR
190
+ * immediately when any of them catches a DenySignal in-tree (the HTTP
191
+ * status is known at that point; inner components may never run).
192
+ * Undefined when the route has no deny-capable server components.
193
+ * See TIM-1045 (pages), TIM-1208 (layouts).
194
+ */
195
+ shellSettled?: Promise<void>;
196
+ /**
197
+ * Slot metadata for the X-Timber-Segments header. Contains info about
198
+ * all parallel route slots encountered during element tree construction,
199
+ * enabling the client to populate its segment cache with slot entries.
200
+ */
201
+ slotSkipInfo: SlotSkipEntry[];
202
+ }
203
+
204
+ // ─── Module Processing Helpers ─────────────────────────────────────────────
205
+
206
+ /**
207
+ * Reject the legacy `generateMetadata` export with a helpful migration message.
208
+ * Throws if the module exports `generateMetadata` instead of `metadata`.
209
+ */
210
+ function rejectLegacyGenerateMetadata(mod: Record<string, unknown>, filePath: string): void {
211
+ if ('generateMetadata' in mod) {
212
+ throw new Error(
213
+ `${filePath}: "generateMetadata" is not a valid export. ` +
214
+ `Export an async function named "metadata" instead.\n\n` +
215
+ ` // Before\n` +
216
+ ` export async function generateMetadata({ params }) { ... }\n\n` +
217
+ ` // After\n` +
218
+ ` export async function metadata() { ... }`
219
+ );
220
+ }
71
221
  }
72
222
 
73
223
  /**
74
- * Wraps a DenySignal or RedirectSignal with the layout components loaded
75
- * so far, enabling the caller to render deny pages inside the layout shell.
224
+ * Extract `deferSuspenseFor` from a module and return the maximum
225
+ * of the current value and the module's value.
76
226
  */
77
- export class RouteSignalWithContext extends Error {
78
- constructor(
79
- public readonly signal: DenySignal | RedirectSignal,
80
- public readonly layoutComponents: LayoutComponentEntry[],
81
- public readonly segments: ManifestSegmentNode[]
82
- ) {
83
- super(signal.message);
227
+ function extractDeferSuspenseFor(mod: Record<string, unknown>, current: number): number {
228
+ if (typeof mod.deferSuspenseFor === 'number' && mod.deferSuspenseFor > current) {
229
+ return mod.deferSuspenseFor;
84
230
  }
231
+ return current;
85
232
  }
86
233
 
87
234
  // ─── Builder ──────────────────────────────────────────────────────────────
@@ -89,26 +236,41 @@ export class RouteSignalWithContext extends Error {
89
236
  /**
90
237
  * Build a React element tree from a matched route.
91
238
  *
92
- * Loads modules, runs access checks, resolves metadata, and constructs
93
- * the element tree. DenySignal and RedirectSignal propagate to the caller
94
- * for HTTP-level handling.
239
+ * Runs access checks eagerly to gate metadata resolution, then loads
240
+ * modules, resolves metadata (skipping denied segments), and constructs
241
+ * the element tree. DenySignal and RedirectSignal from access are stored
242
+ * as AccessGate verdicts for synchronous replay during render.
95
243
  *
96
244
  * Does NOT serialize to RSC Flight — the caller decides whether to render
97
245
  * to a stream or use the element directly (e.g., for action revalidation).
246
+ *
247
+ * For passing segments, AccessGate re-runs access during render so that
248
+ * React.cache is populated for layout dedup (TIM-662). For denied
249
+ * segments, the pre-computed verdict is replayed — no re-execution,
250
+ * no metadata side effects, no head leak (TIM-1027).
98
251
  */
99
252
  export async function buildRouteElement(
100
253
  req: Request,
101
254
  match: RouteMatch,
102
255
  interception?: InterceptionContext,
103
- clientStateTree?: Set<string> | null
256
+ clientStateTree?: ClientStateTree | null,
257
+ metadataRouteHashes?: Record<string, string>
104
258
  ): Promise<RouteElementResult> {
105
- const segments = match.segments as unknown as ManifestSegmentNode[];
106
-
107
- // Params are passed as a Promise to match Next.js 15+ convention.
108
- const paramsPromise = Promise.resolve(match.params);
109
-
110
- // Load all modules along the segment chain
111
- const metadataEntries: Array<{ metadata: Metadata; isPage: boolean }> = [];
259
+ const segments = match.segments;
260
+
261
+ // ── Module loading ──────────────────────────────────────────────────
262
+ // Load layout/page modules and collect metadata sources. Metadata
263
+ // resolution is deferred to render time via MetadataCollector components
264
+ // placed below each AccessGate — denied segments' metadata() never
265
+ // executes because AccessGate prevents MetadataCollector from rendering.
266
+ // No pre-render access pass needed. See TIM-1363.
267
+ interface MetadataSource {
268
+ metadataExport: Metadata | (() => Promise<Metadata>);
269
+ segmentName: string;
270
+ isPage: boolean;
271
+ segmentIndex: number;
272
+ }
273
+ const metadataSources: MetadataSource[] = [];
112
274
  const layoutComponents: LayoutComponentEntry[] = [];
113
275
  let PageComponent: ((...args: unknown[]) => unknown) | null = null;
114
276
  let deferSuspenseFor = 0;
@@ -119,193 +281,161 @@ export async function buildRouteElement(
119
281
 
120
282
  // Load layout
121
283
  if (segment.layout) {
122
- const mod = (await segment.layout.load()) as Record<string, unknown>;
284
+ const mod = await loadModule(segment.layout);
123
285
  if (mod.default) {
124
286
  layoutComponents.push({
125
287
  component: mod.default as (...args: unknown[]) => unknown,
126
288
  segment,
127
289
  });
128
290
  }
129
- // Reject legacy generateMetadata export — use `export async function metadata()` instead
130
- if ('generateMetadata' in mod) {
131
- const filePath = segment.layout.filePath ?? segment.urlPath;
132
- throw new Error(
133
- `${filePath}: "generateMetadata" is not a valid export. ` +
134
- `Export an async function named "metadata" instead.\n\n` +
135
- ` // Before\n` +
136
- ` export async function generateMetadata({ params }) { ... }\n\n` +
137
- ` // After\n` +
138
- ` export async function metadata({ params }) { ... }`
139
- );
140
- }
141
- // Unified metadata export: static object or async function
142
- if (typeof mod.metadata === 'function') {
143
- type MetadataFn = (props: Record<string, unknown>) => Promise<Metadata>;
144
- const generated = await withSpan(
145
- 'timber.metadata',
146
- { 'timber.segment': segment.segmentName ?? segment.urlPath },
147
- () => (mod.metadata as MetadataFn)({ params: paramsPromise })
148
- );
149
- if (generated) {
150
- metadataEntries.push({ metadata: generated, isPage: false });
151
- }
152
- } else if (mod.metadata) {
153
- metadataEntries.push({ metadata: mod.metadata as Metadata, isPage: false });
154
- }
155
- // deferSuspenseFor hold window — max across all segments
156
- if (typeof mod.deferSuspenseFor === 'number' && mod.deferSuspenseFor > deferSuspenseFor) {
157
- deferSuspenseFor = mod.deferSuspenseFor;
291
+
292
+ rejectLegacyGenerateMetadata(mod, segment.layout.filePath ?? segment.urlPath);
293
+ if (mod.metadata) {
294
+ metadataSources.push({
295
+ metadataExport: mod.metadata as Metadata | (() => Promise<Metadata>),
296
+ segmentName: segment.segmentName ?? segment.urlPath,
297
+ isPage: false,
298
+ segmentIndex: i,
299
+ });
158
300
  }
301
+ deferSuspenseFor = extractDeferSuspenseFor(mod, deferSuspenseFor);
159
302
  }
160
303
 
161
304
  // Load page (leaf segment only)
162
305
  if (isLeaf && segment.page) {
163
- // Load and apply search-params.ts definition before rendering so
164
- // searchParams() from @timber-js/app/server returns parsed typed values.
165
- if (segment.searchParams) {
166
- const spMod = (await segment.searchParams.load()) as {
167
- default?: SearchParamsDefinition<Record<string, unknown>>;
168
- };
169
- if (spMod.default) {
170
- const rawSearchParams = new URL(req.url).searchParams;
171
- const parsed = spMod.default.parse(rawSearchParams);
172
- setParsedSearchParams(parsed);
173
- }
174
- }
306
+ const mod = await loadModule(segment.page);
175
307
 
176
- const mod = (await segment.page.load()) as Record<string, unknown>;
177
308
  if (mod.default) {
178
309
  PageComponent = mod.default as (...args: unknown[]) => unknown;
179
310
  }
180
- // Reject legacy generateMetadata export — use `export async function metadata()` instead
181
- if ('generateMetadata' in mod) {
182
- const filePath = segment.page.filePath ?? segment.urlPath;
183
- throw new Error(
184
- `${filePath}: "generateMetadata" is not a valid export. ` +
185
- `Export an async function named "metadata" instead.\n\n` +
186
- ` // Before\n` +
187
- ` export async function generateMetadata({ params }) { ... }\n\n` +
188
- ` // After\n` +
189
- ` export async function metadata({ params }) { ... }`
190
- );
191
- }
192
- // Unified metadata export: static object or async function
193
- if (typeof mod.metadata === 'function') {
194
- type MetadataFn = (props: Record<string, unknown>) => Promise<Metadata>;
195
- const generated = await withSpan(
196
- 'timber.metadata',
197
- { 'timber.segment': segment.segmentName ?? segment.urlPath },
198
- () => (mod.metadata as MetadataFn)({ params: paramsPromise })
199
- );
200
- if (generated) {
201
- metadataEntries.push({ metadata: generated, isPage: true });
202
- }
203
- } else if (mod.metadata) {
204
- metadataEntries.push({ metadata: mod.metadata as Metadata, isPage: true });
205
- }
206
- // deferSuspenseFor hold window — max across all segments
207
- if (typeof mod.deferSuspenseFor === 'number' && mod.deferSuspenseFor > deferSuspenseFor) {
208
- deferSuspenseFor = mod.deferSuspenseFor;
311
+ rejectLegacyGenerateMetadata(mod, segment.page.filePath ?? segment.urlPath);
312
+ if (mod.metadata) {
313
+ metadataSources.push({
314
+ metadataExport: mod.metadata as Metadata | (() => Promise<Metadata>),
315
+ segmentName: segment.segmentName ?? segment.urlPath,
316
+ isPage: true,
317
+ segmentIndex: i,
318
+ });
209
319
  }
320
+ deferSuspenseFor = extractDeferSuspenseFor(mod, deferSuspenseFor);
210
321
  }
211
322
  }
212
323
 
213
324
  if (!PageComponent) {
214
- throw new Error(`No page component found for route: ${new URL(req.url).pathname}`);
215
- }
216
-
217
- // Run access.ts checks before rendering — top-down through the segment chain.
218
- // Verdicts are stored so AccessGate can replay them synchronously during
219
- // render, avoiding duplicate execution and Suspense timing issues.
220
- // DenySignal and RedirectSignal are wrapped with layout context so the caller
221
- // can render deny pages inside the layout shell.
222
- // See design/04-authorization.md §"access.ts Runs on Every Navigation".
223
- const accessVerdicts = new Map<number, 'pass' | DenySignal | RedirectSignal>();
224
-
225
- for (let si = 0; si < segments.length; si++) {
226
- const segment = segments[si];
227
- if (segment.access) {
228
- const accessMod = (await segment.access.load()) as Record<string, unknown>;
229
- const accessFn = accessMod.default as
230
- | ((ctx: { params: Record<string, string | string[]>; searchParams: unknown }) => unknown)
231
- | undefined;
232
- if (accessFn) {
233
- try {
234
- await withSpan(
235
- 'timber.access',
236
- { 'timber.segment': segment.segmentName ?? 'unknown' },
237
- async () => {
238
- try {
239
- await accessFn({ params: match.params, searchParams: {} });
240
- await setSpanAttribute('timber.result', 'pass');
241
- accessVerdicts.set(si, 'pass');
242
- } catch (error) {
243
- if (error instanceof DenySignal) {
244
- await setSpanAttribute('timber.result', 'deny');
245
- await setSpanAttribute('timber.deny_status', error.status);
246
- if (error.sourceFile) {
247
- await setSpanAttribute('timber.deny_file', error.sourceFile);
248
- }
249
- accessVerdicts.set(si, error);
250
- } else if (error instanceof RedirectSignal) {
251
- await setSpanAttribute('timber.result', 'redirect');
252
- accessVerdicts.set(si, error);
253
- }
254
- throw error;
255
- }
256
- }
257
- );
258
- } catch (error) {
259
- if (error instanceof DenySignal || error instanceof RedirectSignal) {
260
- throw new RouteSignalWithContext(error, layoutComponents, segments);
261
- }
262
- throw error;
263
- }
264
- }
265
- }
325
+ const segmentInfo = segments
326
+ .map(
327
+ (s, i) =>
328
+ ` [${i}] ${s.segmentName} (page: ${s.page ? 'yes' : 'no'}, layout: ${s.layout ? 'yes' : 'no'}, children: ${s.children?.length ?? 0})${i === segments.length - 1 ? ' ← leaf' : ''}`
329
+ )
330
+ .join('\n');
331
+ throw new NoPageComponentError(
332
+ `No page component found for route: ${new URL(req.url).pathname}\nMatched segments:\n${segmentInfo}`
333
+ );
266
334
  }
267
335
 
268
- // Resolve metadata
269
- const resolvedMetadata = resolveMetadata(metadataEntries);
270
- const headElements = renderMetadataToElements(resolvedMetadata);
271
-
272
- // Auto-link metadata route files (icon, apple-icon, manifest) from segments.
273
- // See design/16-metadata.md §"Auto-Linking"
274
- for (const segment of segments) {
275
- if (!segment.metadataRoutes) continue;
276
- for (const baseName of Object.keys(segment.metadataRoutes)) {
277
- const convention = METADATA_ROUTE_CONVENTIONS[baseName];
278
- if (!convention) continue;
279
- // Non-nestable routes only auto-link from root
280
- if (!convention.nestable && segment.urlPath !== '/') continue;
281
- // Build the href: segment urlPath + serve path
282
- const prefix = segment.urlPath === '/' ? '' : segment.urlPath;
283
- const href = `${prefix}/${convention.servePath}`;
284
- const autoLink = getMetadataRouteAutoLink(convention.type, href);
285
- if (autoLink) {
286
- const attrs: Record<string, string> = { rel: autoLink.rel, href: autoLink.href };
287
- if (autoLink.type) attrs.type = autoLink.type;
288
- headElements.push({ tag: 'link', attrs } as MetadataHeadElement);
289
- }
336
+ // Compute state-tree keys for all segments. Route groups accumulate
337
+ // ancestor group names for globally unique keys (e.g., "/(a)/(shared)"
338
+ // instead of just "/(shared)"). This is the single key computation —
339
+ // the same keys are used for skip decisions, SegmentOutlet props, the
340
+ // X-Timber-Segments header (via buildSegmentInfo), the error boundaries,
341
+ // and deny page ownership.
342
+ //
343
+ // Computed here, before the deny chains below, because each chain entry
344
+ // records the key of the segment that owns it.
345
+ const segmentKeys = computeSegmentKeys(segments);
346
+ // The directory path of each segment — the key `setSlotParams` and codegen
347
+ // both use for a slot beneath it, and the identity interception scoping
348
+ // compares against. One derivation, so a slot cannot be keyed two ways.
349
+ const segmentTreePaths = computeSegmentTreePaths(segments);
350
+
351
+ // Build deny page fallback chains for each segment position.
352
+ // When AccessGate or PageDenyBoundary catches a DenySignal, they render
353
+ // the matching deny page in-tree instead of throwing into React Flight.
354
+ // The chain walks from the current segment outward to root, collecting
355
+ // status-code files (403.tsx → 4xx.tsx → error.tsx) in fallback order,
356
+ // each tagged with the key of the segment it came from so the catch site
357
+ // can tell a file it owns from an ancestor's. See TIM-666, TIM-1356.
358
+ const denyPageChains = new Map<number, DenyPageEntry[]>();
359
+ for (let i = 0; i < segments.length; i++) {
360
+ const chain = await buildDenyPageChain(segments, i, segmentKeys);
361
+ if (chain.length > 0) {
362
+ denyPageChains.set(i, chain);
290
363
  }
291
364
  }
292
365
 
293
366
  // Build element tree: page wrapped in layouts (innermost to outermost)
294
367
  const h = createElement as (...args: unknown[]) => React.ReactElement;
295
368
 
296
- // Wrap the page component in an OTEL span
297
- const TracedPage = async (props: Record<string, unknown>) => {
298
- return withSpan(
299
- 'timber.page',
300
- { 'timber.route': match.segments[match.segments.length - 1]?.urlPath ?? '/' },
301
- () => (PageComponent as (props: Record<string, unknown>) => unknown)(props)
302
- );
369
+ // Shell settlement tracking (TIM-1045 pages, TIM-1208 layouts).
370
+ // SlotsProvider is 'use client', so React Flight eagerly
371
+ // serializes both the layout and child content as independent subtrees —
372
+ // the page can settle before an outer layout. We need all deny-capable
373
+ // components to settle before committing the HTTP status.
374
+ //
375
+ // Each tracked component gets its own deferred. shellSettled resolves
376
+ // when ALL settle (Promise.all) OR when any in-tree deny fires
377
+ // (short-circuit via onDenyStatus — covers AccessGate, TracedLayout,
378
+ // and PageDenyBoundary without threading callbacks into each).
379
+ const shellPromises: Promise<void>[] = [];
380
+ let resolveShortCircuit: (() => void) | undefined;
381
+ const trackShellComponent = (): (() => void) => {
382
+ let resolve!: () => void;
383
+ shellPromises.push(new Promise<void>((r) => (resolve = r)));
384
+ return resolve;
303
385
  };
304
386
 
305
- let element = h(TracedPage, {
306
- params: paramsPromise,
307
- searchParams: {},
308
- });
387
+ // Build the page element.
388
+ // Server component pages are wrapped in PageDenyBoundary which calls
389
+ // them as async functions and catches DenySignal — rendering the deny
390
+ // page in-tree instead of throwing into React Flight. This eliminates
391
+ // the second render pass for deny pages. See TIM-666.
392
+ //
393
+ // Client reference pages ('use client') can't call deny() (server-only),
394
+ // so they go through createElement normally — no wrapper needed.
395
+ const leafIndex = segments.length - 1;
396
+ const leafDenyPages = denyPageChains.get(leafIndex);
397
+ let element: React.ReactElement;
398
+ if (isClientReference(PageComponent)) {
399
+ element = h(PageComponent, {});
400
+ } else if (leafDenyPages && leafDenyPages.length > 0) {
401
+ const onSettled = trackShellComponent();
402
+ element = h(PageDenyBoundary, {
403
+ Page: PageComponent,
404
+ route: match.segments[leafIndex]?.urlPath ?? '/',
405
+ denyPages: leafDenyPages,
406
+ segmentKey: segmentKeys[leafIndex],
407
+ onSettled,
408
+ });
409
+ } else {
410
+ // Server component page WITHOUT deny page chain — trace only
411
+ const TracedPage = async (props: Record<string, unknown>) => {
412
+ return withSpan(
413
+ 'timber.page',
414
+ { 'timber.route': match.segments[leafIndex]?.urlPath ?? '/' },
415
+ () => (PageComponent as (props: Record<string, unknown>) => unknown)(props)
416
+ );
417
+ };
418
+ element = h(TracedPage, {});
419
+ }
420
+
421
+ // Place MetadataHead as a SIBLING of the page, not a wrapper. React
422
+ // renders siblings concurrently — the page starts immediately while
423
+ // MetadataHead awaits metadata promises. Float hoists the head
424
+ // elements to <head> regardless of tree position. Both resolve before
425
+ // onShellReady (outside Suspense), but they overlap.
426
+ // Placed at the page level so metadata is always re-rendered on SPA
427
+ // navigation (never skipped by segment tree diffing).
428
+ // See TIM-1363, TIM-1367, design/16-metadata.md.
429
+ element = h(
430
+ Fragment,
431
+ null,
432
+ h(MetadataHead, {
433
+ segments,
434
+ requestUrl: req.url,
435
+ metadataRouteHashes,
436
+ }),
437
+ element
438
+ );
309
439
 
310
440
  // Build a lookup of layout components by segment for O(1) access.
311
441
  const layoutBySegment = new Map(
@@ -316,147 +446,375 @@ export async function buildRouteElement(
316
446
  // The client uses this to merge the partial payload with its cached segments.
317
447
  const skippedSegments: string[] = [];
318
448
 
319
- // Wrap from innermost (leaf) to outermost (root), processing every
320
- // segment in the chain. Each segment may contribute:
321
- // 1. Error boundaries (status files + error.tsx)
322
- // 2. Layout component — wraps children + parallel slots
323
- // 3. SegmentProvider — records position for useSelectedLayoutSegment
449
+ // Pre-compute the contiguous skippable prefix (top-down).
324
450
  //
325
- // When clientStateTree is provided (from X-Timber-State-Tree header on
326
- // client navigation), sync layouts the client already has are skipped.
327
- // Access.ts already ran for ALL segments in the pre-render loop above.
328
- // See design/19-client-navigation.md §"X-Timber-State-Tree Header"
451
+ // Skipped segments must form a contiguous prefix from root to avoid
452
+ // non-contiguous skips that break the client merge. Walk from root
453
+ // toward leaf, marking segments as skippable. Stop at the first
454
+ // segment that can't be skipped (async, not in client tree, leaf).
455
+ // Layoutless segments are transparent (no outlet, no layout to skip).
329
456
  //
330
- // hasRenderedLayoutBelow tracks whether a non-skipped layout has been
331
- // seen below the current segment. A segment can ONLY be skipped if
332
- // there is a rendered layout below it — the client merger can only
333
- // replace inner SegmentProviders (client component boundaries), not
334
- // page content embedded in a layout's server-rendered output.
335
- // Without this guard, skipping the innermost layout causes the merger
336
- // to drop the layout entirely and replace it with just the page.
337
- let hasRenderedLayoutBelow = false;
457
+ // After finding the prefix, validate: the first non-skipped layout
458
+ // must exist in the client's state tree (the client needs a mounted
459
+ // outlet there to receive the partial payload).
460
+ const skippableSet = new Set<number>();
461
+ if (clientStateTree) {
462
+ for (let i = 0; i < segments.length; i++) {
463
+ const isLeaf = i === segments.length - 1;
464
+ const layoutComponent = layoutBySegment.get(segments[i]);
465
+
466
+ if (shouldSkipSegment(segmentKeys[i], layoutComponent, isLeaf, clientStateTree)) {
467
+ skippableSet.add(i);
468
+ } else if (layoutComponent) {
469
+ break;
470
+ }
471
+ }
472
+
473
+ // Ensure there's a merge point: a non-skipped layout whose key is
474
+ // in the client's state tree (so the client has a mounted outlet).
475
+ // If all layouts are in the prefix, keep the innermost as merge point.
476
+ if (skippableSet.size > 0) {
477
+ let mergePointIndex = -1;
478
+ for (let i = 0; i < segments.length; i++) {
479
+ if (skippableSet.has(i)) continue;
480
+ if (layoutBySegment.has(segments[i])) {
481
+ mergePointIndex = i;
482
+ break;
483
+ }
484
+ }
485
+
486
+ if (mergePointIndex === -1) {
487
+ // All layouts are skippable — keep the innermost as merge point
488
+ for (let i = segments.length - 1; i >= 0; i--) {
489
+ if (skippableSet.has(i) && layoutBySegment.has(segments[i])) {
490
+ skippableSet.delete(i);
491
+ mergePointIndex = i;
492
+ break;
493
+ }
494
+ }
495
+ }
496
+
497
+ // Cross-section guard: at least one rendered layout below the
498
+ // prefix must exist in the client's state tree (the client needs
499
+ // a mounted outlet to receive the partial payload). Check ALL
500
+ // non-skipped layouts, not just the merge point — async layouts
501
+ // are excluded from the client state tree but may sit above a
502
+ // sync layout that IS in the tree.
503
+ let hasClientOutlet = false;
504
+ for (let j = 0; j < segments.length; j++) {
505
+ if (skippableSet.has(j)) continue;
506
+ if (layoutBySegment.has(segments[j]) && clientStateTree.has(segmentKeys[j])) {
507
+ hasClientOutlet = true;
508
+ break;
509
+ }
510
+ }
511
+ if (!hasClientOutlet) {
512
+ skippableSet.clear();
513
+ }
514
+ }
515
+ }
516
+
517
+ // Slot-change guard (TIM-1232): if a skippable layout has parallel
518
+ // slots whose content changed, the layout cannot be skipped — it must
519
+ // render so its slots are included in the payload.
520
+ if (skippableSet.size > 0 && clientStateTree) {
521
+ truncateSkippableForChangedSlots(
522
+ skippableSet,
523
+ segments,
524
+ segmentKeys,
525
+ match,
526
+ clientStateTree,
527
+ req
528
+ );
529
+ }
530
+
531
+ let outermostSegmentProvider: React.ReactElement | null = null;
532
+
533
+ // Slot caching uses key-based diffing (TIM-1370). The server computes a
534
+ // content key per slot and the client advertises keys for cached slots.
535
+ // The skip decision is a set-membership check — no departing URL needed.
536
+ const destinationUrl = req.url;
537
+ const slotSkipInfo: SlotSkipEntry[] = [];
338
538
 
339
539
  for (let i = segments.length - 1; i >= 0; i--) {
340
540
  const segment = segments[i];
341
541
  const isLeaf = i === segments.length - 1;
342
542
  const layoutComponent = layoutBySegment.get(segment);
343
543
 
344
- // Check if this segment's layout can be skipped for partial rendering.
345
- // Skipped segments: no layout wrapping, no error boundaries, no slots,
346
- // no AccessGate in element tree (access already ran pre-render).
347
- //
348
- // Additional constraints beyond shouldSkipSegment:
349
- // - Must have a rendered layout below (so the merger can find an
350
- // inner SegmentProvider to splice the new content into)
351
- // - Route groups are never skipped because sibling groups share the
352
- // same urlPath (e.g., /(marketing) and /(app) both have "/"),
353
- // which would cause the wrong cached layout to be reused
354
- const skip =
355
- shouldSkipSegment(segment.urlPath, layoutComponent, isLeaf, clientStateTree ?? null) &&
356
- hasRenderedLayoutBelow &&
357
- segment.segmentType !== 'group';
358
-
359
- if (skip) {
360
- // Skip this segment entirely — the client uses its cached version.
361
- // Access.ts already ran in the pre-render loop (security guarantee).
362
- // Metadata was already resolved above (head elements are correct).
544
+ // Skip decision was pre-computed in the top-down prefix pass.
545
+ if (skippableSet.has(i)) {
363
546
  // Record for X-Timber-Skipped-Segments header (outermost first, so prepend).
364
- skippedSegments.unshift(segment.urlPath);
547
+ skippedSegments.unshift(segmentKeys[i]);
548
+
549
+ // A skipped layout never reaches resolveSlotProps below, but its slots
550
+ // stay mounted on the client — so their params still have to be
551
+ // published, or useSegmentParams(slotPath) falls back to the main
552
+ // route's record after any navigation that skipped their parent
553
+ // (TIM-1285). Params only: nothing renders and no access chain runs,
554
+ // because an unchanged slot is what made this layout skippable.
555
+ publishSlotSegmentParams(segment, match, destinationUrl, segmentTreePaths[i]);
556
+
557
+ // Emit slot metadata so the client's segment tree retains contentKeys
558
+ // for slots of skipped layouts. Without this, the client rebuilds its
559
+ // tree from the response and loses slot keys it can't advertise next time.
560
+ emitSlotInfoForSkippedLayout(segment, segmentKeys[i], match, destinationUrl, slotSkipInfo);
561
+
562
+ // No error boundaries are wrapped for a skipped segment — the `continue`
563
+ // below returns before that walk. A deny addressed to this segment
564
+ // therefore finds no boundary in the payload, and since TIM-1356 the
565
+ // payload path no longer falls back to a re-render for an addressed
566
+ // deny. What makes that sound is the precondition for skipping at all:
567
+ // `shouldSkipSegment` only returns true when this exact segment key is
568
+ // in the client's state tree, which means the client rendered this
569
+ // segment on an earlier navigation and still has its boundaries mounted,
570
+ // carrying the same key this build would have stamped. The payload
571
+ // splices in below them, so the throw passes through them on its way up.
572
+ //
573
+ // Metadata from skipped segments still needs to be collected (e.g.,
574
+ // root layout title templates). MetadataCollector wraps the element
575
+ // inside AccessGate — if access denies, metadata is excluded.
576
+ const skippedMeta = metadataSources.filter((s) => s.segmentIndex === i).reverse();
577
+ for (const meta of skippedMeta) {
578
+ const isDynamic = typeof meta.metadataExport === 'function';
579
+ element = h(MetadataCollector, {
580
+ metadataExport: meta.metadataExport,
581
+ segmentName: meta.segmentName,
582
+ isPage: meta.isPage,
583
+ ...(isDynamic ? { onSettled: trackShellComponent() } : {}),
584
+ children: element,
585
+ });
586
+ }
587
+
588
+ // SECURITY: Even though the layout is skipped, AccessGate MUST still
589
+ // wrap the element tree. access.ts runs on every navigation regardless
590
+ // of cached layouts or state tree content.
591
+ // See design/13-security.md §"Auth always runs" (test #11).
592
+ //
593
+ // Skipped segments omit denyPages and set skippedSegment=true. If
594
+ // access denies at a skipped segment, AccessGate records the deny in
595
+ // ALS and rethrows — the response path returns rscErrorEnvelope so the
596
+ // client hard-navigates for a clean full render with correct deny page
597
+ // placement. Rendering the deny page in-tree here would appear inside
598
+ // the client's cached layout chrome (TIM-1074). See TIM-1363.
599
+ if (segment.access) {
600
+ const accessMod = await loadModule(segment.access);
601
+ const accessFn = accessMod.default as (() => unknown) | undefined;
602
+ if (accessFn) {
603
+ const onGateSettled = trackShellComponent();
604
+ element = h(AccessGate, {
605
+ accessFn,
606
+ segmentName: segment.segmentName,
607
+ segmentKey: segmentKeys[i],
608
+ segmentIndex: i,
609
+ skippedSegment: true,
610
+ onSettled: onGateSettled,
611
+ children: element,
612
+ });
613
+ }
614
+ }
615
+
365
616
  continue;
366
617
  }
367
618
 
368
- // This segment is rendered — mark that future (outer) segments have
369
- // a rendered layout below them and can safely be skipped.
370
- if (layoutComponent) {
371
- hasRenderedLayoutBelow = true;
619
+ // Wrap with MetadataCollector(s) INSIDE error boundaries so a
620
+ // metadata() throw is caught by this segment's status-file boundaries,
621
+ // not an ancestor's. Still inside AccessGate (placed below) — when
622
+ // access denies, neither MetadataCollector nor error boundaries render.
623
+ //
624
+ // Reversed: the loop wraps innermost-to-outermost, so the last-wrapped
625
+ // collector renders first. Reversing ensures layout metadata is pushed
626
+ // before page metadata, preserving the root→page merge order required
627
+ // by resolveMetadata (page-authoritative). See TIM-1363.
628
+ const segmentMetadata = metadataSources.filter((s) => s.segmentIndex === i).reverse();
629
+ for (const meta of segmentMetadata) {
630
+ const isDynamic = typeof meta.metadataExport === 'function';
631
+ element = h(MetadataCollector, {
632
+ metadataExport: meta.metadataExport,
633
+ segmentName: meta.segmentName,
634
+ isPage: meta.isPage,
635
+ ...(isDynamic ? { onSettled: trackShellComponent() } : {}),
636
+ children: element,
637
+ });
372
638
  }
373
639
 
374
640
  // Wrap with error boundaries from this segment (inside layout).
375
- element = await wrapSegmentWithErrorBoundaries(segment, element, h);
641
+ // Keep ALL error boundaries (including 4xx) — they're the safety net for
642
+ // DenySignal from nested server components that escape AccessGate/PageDenyBoundary
643
+ // try/catch. Status-code files must be 'use client' TSX or MDX to serialize
644
+ // as error boundary fallbacks. See TIM-666.
645
+ // `segmentKey` makes each boundary addressable: a deny hoisted to this
646
+ // segment carries its owner's key, and every other boundary declines it
647
+ // rather than catching it first and rendering at the wrong depth
648
+ // (TIM-1356).
649
+ element = await wrapSegmentWithErrorBoundaries(segment, element, {
650
+ loadModule,
651
+ createElement: h,
652
+ errorBoundaryComponent: TimberErrorBoundary,
653
+ segmentKey: segmentKeys[i],
654
+ });
655
+
656
+ // Wrap with layout BEFORE AccessGate — AccessGate is OUTSIDE the layout.
657
+ // When AccessGate denies, the layout never renders. The deny page appears
658
+ // at the AccessGate level, wrapped by PARENT layouts only.
659
+ // This prevents leaking layout UI (sidebars, nav) on denied pages.
660
+ // See design/04-authorization.md §"Access Failure".
661
+ if (layoutComponent) {
662
+ // Resolve parallel slots for this layout. If a parent AccessGate
663
+ // denies during render, the layout never renders and slot props
664
+ // are never consumed. Slot access functions may still fire eagerly
665
+ // for skip-candidate slots — a follow-up will make that lazy.
666
+ const segmentId = segmentKeys[i];
667
+ const parentTreePath = segmentTreePaths[i];
668
+ const slotProps = await resolveSlotProps({
669
+ segment,
670
+ segmentId,
671
+ match,
672
+ h,
673
+ interception,
674
+ parentTreePath,
675
+ destinationUrl,
676
+ clientStateTree: clientStateTree as ClientStateTree | null,
677
+ slotSkipInfo,
678
+ });
679
+
680
+ const segmentPath = computeLayoutSegmentPath(segments, i, match);
681
+ const parallelRouteKeys = Object.keys(segment.slots ?? {});
682
+
683
+ // Build the layout element.
684
+ // Layouts receive <SlotOutlet slot={LAYOUT_CHILDREN_SLOT} /> as
685
+ // children — a stable client reference — instead of the varying
686
+ // inner content. The actual child content is provided via
687
+ // SlotsProvider above the layout. Uses a reserved slot name to
688
+ // avoid collision with user-declared cache.component slots.
689
+ // See design/45-cache-lifetimes.md §Layout Propagation.
690
+ const childOutlet = h(SlotOutlet, { slot: LAYOUT_CHILDREN_SLOT });
691
+ let layoutElement: React.ReactElement;
692
+ if (isClientReference(layoutComponent)) {
693
+ layoutElement = h(layoutComponent, {
694
+ ...slotProps,
695
+ children: childOutlet,
696
+ });
697
+ } else {
698
+ // Server component layout — wrap with OTEL tracing AND DenySignal
699
+ // catching. If the layout calls deny(), the signal is caught here
700
+ // and the matching deny page renders in-tree (same pattern as
701
+ // AccessGate and PageDenyBoundary). Without this, DenySignal
702
+ // escapes to React Flight onError and triggers the re-render
703
+ // fallback path. See TIM-668, design/04-authorization.md.
704
+ const layoutComponentRef = layoutComponent;
705
+ const layoutDenyPages = denyPageChains.get(i);
706
+ const hasLayoutDenyChain = !!layoutDenyPages && layoutDenyPages.length > 0;
707
+ const onLayoutSettled = hasLayoutDenyChain ? trackShellComponent() : undefined;
708
+ const TracedLayout = async (props: Record<string, unknown>) => {
709
+ try {
710
+ return await withSpan('timber.layout', { 'timber.segment': segmentId }, () =>
711
+ (layoutComponentRef as (props: Record<string, unknown>) => unknown)(props)
712
+ );
713
+ } catch (error: unknown) {
714
+ // A layout that denied never renders its own chrome — it threw
715
+ // instead of returning it — so an entry this segment owns is
716
+ // already correctly placed here. Anything owned further up is
717
+ // hoisted (handleCaughtDeny throws). See TIM-1356.
718
+ if (error instanceof DenySignal) {
719
+ setFirstDeniedSegmentIndex(i);
720
+ if (layoutDenyPages) {
721
+ return handleCaughtDeny(layoutDenyPages, error, segmentId);
722
+ }
723
+ }
724
+ throw error;
725
+ } finally {
726
+ onLayoutSettled?.();
727
+ }
728
+ };
729
+ layoutElement = h(TracedLayout, {
730
+ ...slotProps,
731
+ children: childOutlet,
732
+ });
733
+ }
734
+
735
+ // Wrap the layout in SlotsProvider so the SlotOutlet inside the
736
+ // layout's children can read the actual child content.
737
+ layoutElement = h(SlotsProvider, {
738
+ values: { [LAYOUT_CHILDREN_SLOT]: element },
739
+ children: layoutElement,
740
+ });
741
+
742
+ const segmentProviderElement = h(SegmentProvider, {
743
+ segments: segmentPath,
744
+ segmentId,
745
+ parallelRouteKeys,
746
+ children: layoutElement,
747
+ });
748
+
749
+ element = h(SegmentOutlet, {
750
+ segmentPath: segmentId,
751
+ children: segmentProviderElement,
752
+ });
753
+
754
+ // Track the SegmentProvider for the outermost rendered layout.
755
+ // On partial navigation (segments skipped above), the client already
756
+ // has a SegmentOutlet mounted at this position. Sending another one
757
+ // in the payload causes double-wrapping and infinite context recursion.
758
+ // We'll strip the outermost SegmentOutlet after the loop.
759
+ outermostSegmentProvider = segmentProviderElement;
760
+ }
376
761
 
377
- // Wrap in AccessGate if segment has access.ts.
378
- // Pass the pre-computed verdict so AccessGate replays it synchronously
379
- // instead of re-calling accessFn (dedup + Suspense immunity).
762
+ // Wrap in AccessGate OUTSIDE the layout, error boundaries, and MetadataCollector.
763
+ // If access denies, neither the layout nor MetadataCollector renders.
764
+ // Parent layouts (from outer iterations) form the shell. Access runs
765
+ // exactly once, during render, inside React.cache scope — layouts
766
+ // share the cache. See TIM-1363, design/04-authorization.md.
380
767
  if (segment.access) {
381
- const accessMod = (await segment.access.load()) as Record<string, unknown>;
382
- const accessFn = accessMod.default as
383
- | ((ctx: { params: Record<string, string | string[]>; searchParams: unknown }) => unknown)
384
- | undefined;
768
+ const accessMod = await loadModule(segment.access);
769
+ const accessFn = accessMod.default as (() => unknown) | undefined;
385
770
  if (accessFn) {
771
+ const onGateSettled = trackShellComponent();
386
772
  element = h(AccessGate, {
387
773
  accessFn,
388
- params: match.params,
389
- searchParams: {},
390
774
  segmentName: segment.segmentName,
391
- verdict: accessVerdicts.get(i),
775
+ segmentKey: segmentKeys[i],
776
+ segmentIndex: i,
777
+ denyPages: denyPageChains.get(i),
778
+ onSettled: onGateSettled,
392
779
  children: element,
393
780
  });
394
781
  }
395
782
  }
783
+ }
396
784
 
397
- // Wrap with layout if this segment has one — traced with OTEL span
398
- if (layoutComponent) {
399
- // Resolve parallel slots for this layout
400
- const slotProps: Record<string, unknown> = {};
401
- const slotEntries = Object.entries(segment.slots ?? {});
402
- for (const [slotName, slotNode] of slotEntries) {
403
- slotProps[slotName] = await resolveSlotElement(
404
- slotNode as ManifestSegmentNode,
405
- match,
406
- paramsPromise,
407
- h,
408
- interception
409
- );
410
- }
411
-
412
- const segmentPath = segment.urlPath.split('/');
413
- const parallelRouteKeys = Object.keys(segment.slots ?? {});
785
+ // On partial navigation (some segments skipped), the client already has a
786
+ // SegmentOutlet mounted at the outermost non-skipped segment's position.
787
+ // Sending another SegmentOutlet in the payload causes double-wrapping —
788
+ // the inner outlet reads the same context update and recurses infinitely.
789
+ // Replace the outermost SegmentOutlet with just its SegmentProvider child.
790
+ if (skippedSegments.length > 0 && outermostSegmentProvider) {
791
+ element = replaceOutermostSegmentOutlet(element, outermostSegmentProvider);
792
+ }
414
793
 
415
- // Wrap the layout component in an OTEL span.
416
- // For route groups, urlPath is "/" (groups don't add URL segments), so
417
- // include the directory name to distinguish e.g. "layout /(pre-release)"
418
- // from the root "layout /".
419
- const segmentForSpan = segment;
420
- const layoutComponentForSpan = layoutComponent;
421
- const segmentLabel =
422
- segmentForSpan.segmentType === 'group'
423
- ? `${segmentForSpan.urlPath === '/' ? '' : segmentForSpan.urlPath}/${segmentForSpan.segmentName}`
424
- : segmentForSpan.urlPath;
425
- const TracedLayout = async (props: Record<string, unknown>) => {
426
- return withSpan('timber.layout', { 'timber.segment': segmentLabel }, () =>
427
- (layoutComponentForSpan as (props: Record<string, unknown>) => unknown)(props)
428
- );
429
- };
430
-
431
- // segmentId uniquely identifies this segment for client-side element
432
- // caching. For route groups, urlPath is shared with the parent (both "/"),
433
- // so we include the group name to distinguish them. Without this, the
434
- // segment merger's element cache would conflate root and group elements.
435
- const segmentId =
436
- segment.segmentType === 'group'
437
- ? `${segment.urlPath === '/' ? '' : segment.urlPath}/${segment.segmentName}`
438
- : segment.urlPath;
439
-
440
- element = h(SegmentProvider, {
441
- segments: segmentPath,
442
- segmentId,
443
- parallelRouteKeys,
444
- children: h(TracedLayout, {
445
- ...slotProps,
446
- params: paramsPromise,
447
- searchParams: {},
448
- children: element,
449
- }),
450
- });
451
- }
794
+ // Compose shellSettled: resolves when ALL deny-capable components settle
795
+ // (Promise.all) OR immediately when any component calls setDenyStatus()
796
+ // (short-circuit via onDenyStatus — covers AccessGate, TracedLayout, and
797
+ // PageDenyBoundary). See TIM-1045, TIM-1208.
798
+ let shellSettled: Promise<void> | undefined;
799
+ if (shellPromises.length > 0) {
800
+ const shortCircuit = new Promise<void>((r) => (resolveShortCircuit = r));
801
+ const store = requestContextAls.getStore();
802
+ if (store) store.onDenyStatus = () => resolveShortCircuit?.();
803
+ shellSettled = Promise.race([Promise.all(shellPromises).then(() => {}), shortCircuit]);
452
804
  }
453
805
 
806
+ // Publish the request's params beside the finished tree, as the payload's
807
+ // root row. Last, because the partial-navigation rewrite above rebuilds the
808
+ // tree and this takes it as it finally stands.
809
+ const payload = withPublishedParams(element);
810
+
454
811
  return {
455
- element,
456
- headElements: headElements as HeadElement[],
812
+ payload,
457
813
  layoutComponents,
458
814
  segments,
459
815
  deferSuspenseFor,
460
816
  skippedSegments,
817
+ shellSettled,
818
+ slotSkipInfo,
461
819
  };
462
820
  }