@timber-js/app 0.2.0-alpha.207 → 0.2.0-alpha.209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (526) hide show
  1. package/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
  2. package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
  3. package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
  4. package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
  5. package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
  6. package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
  7. package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
  8. package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
  9. package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
  10. package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
  11. package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
  12. package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
  13. package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
  14. package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
  15. package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
  16. package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
  17. package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
  18. package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
  19. package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
  20. package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
  21. package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
  22. package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
  23. package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
  24. package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
  25. package/dist/_chunks/{error-boundary-BndF-3Td.js → error-boundary-tA7kVfs4.js} +84 -104
  26. package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
  27. package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
  28. package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
  29. package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
  30. package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
  31. package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
  32. package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
  33. package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
  34. package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
  35. package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
  36. package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
  37. package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
  38. package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
  39. package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
  40. package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
  41. package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
  42. package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
  43. package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
  44. package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
  45. package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
  46. package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
  47. package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
  48. package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
  49. package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
  50. package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
  51. package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
  52. package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
  53. package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
  54. package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
  55. package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
  56. package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
  57. package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
  58. package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
  59. package/dist/_chunks/{status-page-marker-DwQBrLBz.js → status-page-marker-gaihi0KZ.js} +140 -28
  60. package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
  61. package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
  62. package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
  63. package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
  64. package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
  65. package/dist/adapters/build-output-helper.d.ts +7 -7
  66. package/dist/adapters/build-output-helper.d.ts.map +1 -1
  67. package/dist/adapters/canonicalize-module.d.ts +8 -0
  68. package/dist/adapters/canonicalize-module.d.ts.map +1 -0
  69. package/dist/adapters/cloudflare-dev.js +1 -1
  70. package/dist/adapters/cloudflare-kv-cache.js +2 -2
  71. package/dist/adapters/cloudflare.d.ts +30 -8
  72. package/dist/adapters/cloudflare.d.ts.map +1 -1
  73. package/dist/adapters/cloudflare.js +2 -2
  74. package/dist/adapters/compress-module.d.ts +8 -0
  75. package/dist/adapters/compress-module.d.ts.map +1 -1
  76. package/dist/adapters/fs-identity.d.ts +2 -3
  77. package/dist/adapters/fs-identity.d.ts.map +1 -1
  78. package/dist/adapters/nitro-presets.d.ts +0 -6
  79. package/dist/adapters/nitro-presets.d.ts.map +1 -1
  80. package/dist/adapters/nitro-preview.d.ts +43 -11
  81. package/dist/adapters/nitro-preview.d.ts.map +1 -1
  82. package/dist/adapters/nitro.d.ts +1 -13
  83. package/dist/adapters/nitro.d.ts.map +1 -1
  84. package/dist/adapters/nitro.js +291 -176
  85. package/dist/adapters/nitro.js.map +1 -1
  86. package/dist/adapters/shared.d.ts +7 -2
  87. package/dist/adapters/shared.d.ts.map +1 -1
  88. package/dist/adapters/types.d.ts +105 -21
  89. package/dist/adapters/types.d.ts.map +1 -1
  90. package/dist/adapters/types.js +0 -0
  91. package/dist/analyze/crawl-entry.js +3 -3
  92. package/dist/analyze/graph-cache.d.ts.map +1 -1
  93. package/dist/analyze/graph-command.js +4 -4
  94. package/dist/cache/index.js +2 -2
  95. package/dist/cache/json-lossy-check.d.ts.map +1 -1
  96. package/dist/cache/singleflight.d.ts.map +1 -1
  97. package/dist/cache/sizeof.d.ts.map +1 -1
  98. package/dist/cache/stores/memory.js +1 -1
  99. package/dist/cache/tag-aware-handler.d.ts.map +1 -1
  100. package/dist/cdn/workers-cache-purge.js +1 -1
  101. package/dist/cli-check.d.ts +7 -37
  102. package/dist/cli-check.d.ts.map +1 -1
  103. package/dist/cli-context.d.ts +54 -0
  104. package/dist/cli-context.d.ts.map +1 -0
  105. package/dist/cli.d.ts +9 -9
  106. package/dist/cli.d.ts.map +1 -1
  107. package/dist/cli.js +20 -24
  108. package/dist/cli.js.map +1 -1
  109. package/dist/client/browser-dev.d.ts +1 -1
  110. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
  111. package/dist/client/browser-entry/hydrate.d.ts +19 -29
  112. package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
  113. package/dist/client/browser-entry/index.d.ts +7 -7
  114. package/dist/client/browser-entry/post-hydration.d.ts +6 -9
  115. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
  116. package/dist/client/browser-entry/router-init.d.ts +6 -11
  117. package/dist/client/browser-entry/router-init.d.ts.map +1 -1
  118. package/dist/client/error-boundary.d.ts +4 -3
  119. package/dist/client/error-boundary.d.ts.map +1 -1
  120. package/dist/client/error-boundary.js +1 -1
  121. package/dist/client/error-reconstituter.d.ts +3 -9
  122. package/dist/client/error-reconstituter.d.ts.map +1 -1
  123. package/dist/client/history.d.ts +20 -11
  124. package/dist/client/history.d.ts.map +1 -1
  125. package/dist/client/index.d.ts +0 -1
  126. package/dist/client/index.d.ts.map +1 -1
  127. package/dist/client/index.js +5 -6
  128. package/dist/client/index.js.map +1 -1
  129. package/dist/client/internal.d.ts +3 -3
  130. package/dist/client/internal.d.ts.map +1 -1
  131. package/dist/client/internal.js +95 -108
  132. package/dist/client/internal.js.map +1 -1
  133. package/dist/client/navigation-commit.d.ts +20 -7
  134. package/dist/client/navigation-commit.d.ts.map +1 -1
  135. package/dist/client/navigation-context.d.ts +3 -5
  136. package/dist/client/navigation-context.d.ts.map +1 -1
  137. package/dist/client/react-root.d.ts +3 -2
  138. package/dist/client/react-root.d.ts.map +1 -1
  139. package/dist/client/router-pipeline.d.ts +3 -8
  140. package/dist/client/router-pipeline.d.ts.map +1 -1
  141. package/dist/client/router-types.d.ts +45 -39
  142. package/dist/client/router-types.d.ts.map +1 -1
  143. package/dist/client/router-url.d.ts +24 -0
  144. package/dist/client/router-url.d.ts.map +1 -0
  145. package/dist/client/router.d.ts.map +1 -1
  146. package/dist/client/rsc-fetch.d.ts +8 -4
  147. package/dist/client/rsc-fetch.d.ts.map +1 -1
  148. package/dist/client/segment-cache.d.ts +44 -4
  149. package/dist/client/segment-cache.d.ts.map +1 -1
  150. package/dist/client/ssr-data.d.ts +18 -64
  151. package/dist/client/ssr-data.d.ts.map +1 -1
  152. package/dist/client/state.d.ts +2 -5
  153. package/dist/client/state.d.ts.map +1 -1
  154. package/dist/client/use-pathname.d.ts +1 -1
  155. package/dist/config-types.d.ts +2 -1
  156. package/dist/config-types.d.ts.map +1 -1
  157. package/dist/config-validation.d.ts.map +1 -1
  158. package/dist/cookies/index.js +1 -1
  159. package/dist/dev-tools/dev-page-shell.d.ts +17 -0
  160. package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
  161. package/dist/dev-tools/index.d.ts +1 -1
  162. package/dist/dev-tools/index.d.ts.map +1 -1
  163. package/dist/dev-tools/instrumentation.d.ts +17 -2
  164. package/dist/dev-tools/instrumentation.d.ts.map +1 -1
  165. package/dist/dev-tools/overlay.d.ts +6 -27
  166. package/dist/dev-tools/overlay.d.ts.map +1 -1
  167. package/dist/index.d.ts.map +1 -1
  168. package/dist/index.js +632 -373
  169. package/dist/index.js.map +1 -1
  170. package/dist/plugin-context.d.ts +26 -40
  171. package/dist/plugin-context.d.ts.map +1 -1
  172. package/dist/plugins/build-manifest.d.ts.map +1 -1
  173. package/dist/plugins/build-report.d.ts +15 -2
  174. package/dist/plugins/build-report.d.ts.map +1 -1
  175. package/dist/plugins/dev-server.d.ts.map +1 -1
  176. package/dist/plugins/entries.d.ts.map +1 -1
  177. package/dist/plugins/fonts.d.ts +19 -1
  178. package/dist/plugins/fonts.d.ts.map +1 -1
  179. package/dist/plugins/post-build.d.ts +110 -0
  180. package/dist/plugins/post-build.d.ts.map +1 -0
  181. package/dist/plugins/prebuilt-capture.d.ts +11 -4
  182. package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
  183. package/dist/plugins/prebuilt.d.ts +17 -1
  184. package/dist/plugins/prebuilt.d.ts.map +1 -1
  185. package/dist/plugins/prerender-sugar.d.ts.map +1 -1
  186. package/dist/plugins/react-resolve.d.ts +49 -0
  187. package/dist/plugins/react-resolve.d.ts.map +1 -0
  188. package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
  189. package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
  190. package/dist/plugins/shims.d.ts.map +1 -1
  191. package/dist/plugins/static-build.d.ts +32 -9
  192. package/dist/plugins/static-build.d.ts.map +1 -1
  193. package/dist/routing/codegen-write.d.ts +0 -9
  194. package/dist/routing/codegen-write.d.ts.map +1 -1
  195. package/dist/routing/index.js +2 -2
  196. package/dist/routing/segment-codegen.d.ts.map +1 -1
  197. package/dist/server/access-gate.d.ts.map +1 -1
  198. package/dist/server/action-handler.d.ts +5 -4
  199. package/dist/server/action-handler.d.ts.map +1 -1
  200. package/dist/server/actions.d.ts +46 -7
  201. package/dist/server/actions.d.ts.map +1 -1
  202. package/dist/server/als-registry.d.ts +58 -5
  203. package/dist/server/als-registry.d.ts.map +1 -1
  204. package/dist/server/children-interception.d.ts.map +1 -1
  205. package/dist/server/cookie-context.d.ts +2 -23
  206. package/dist/server/cookie-context.d.ts.map +1 -1
  207. package/dist/server/csp-nonce.d.ts +0 -9
  208. package/dist/server/csp-nonce.d.ts.map +1 -1
  209. package/dist/server/csrf.d.ts +27 -4
  210. package/dist/server/csrf.d.ts.map +1 -1
  211. package/dist/server/debug.d.ts +0 -1
  212. package/dist/server/debug.d.ts.map +1 -1
  213. package/dist/server/default-logger.d.ts +2 -1
  214. package/dist/server/default-logger.d.ts.map +1 -1
  215. package/dist/server/deny-boundary.d.ts +12 -6
  216. package/dist/server/deny-boundary.d.ts.map +1 -1
  217. package/dist/server/deny-renderer.d.ts +2 -2
  218. package/dist/server/deny-renderer.d.ts.map +1 -1
  219. package/dist/server/error-boundary-wrapper.d.ts +7 -3
  220. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  221. package/dist/server/fallback-error.d.ts +9 -2
  222. package/dist/server/fallback-error.d.ts.map +1 -1
  223. package/dist/server/head-response.d.ts +4 -4
  224. package/dist/server/html-injectors.d.ts.map +1 -1
  225. package/dist/server/index.d.ts +0 -1
  226. package/dist/server/index.d.ts.map +1 -1
  227. package/dist/server/index.js +3 -4
  228. package/dist/server/index.js.map +1 -1
  229. package/dist/server/instrumentation.d.ts +10 -3
  230. package/dist/server/instrumentation.d.ts.map +1 -1
  231. package/dist/server/internal.d.ts +1 -4
  232. package/dist/server/internal.d.ts.map +1 -1
  233. package/dist/server/internal.js +961 -581
  234. package/dist/server/internal.js.map +1 -1
  235. package/dist/server/json-status-response.d.ts +34 -0
  236. package/dist/server/json-status-response.d.ts.map +1 -0
  237. package/dist/server/logger.d.ts +26 -0
  238. package/dist/server/logger.d.ts.map +1 -1
  239. package/dist/server/param-coercion.d.ts +11 -6
  240. package/dist/server/param-coercion.d.ts.map +1 -1
  241. package/dist/server/pipeline-helpers.d.ts +95 -7
  242. package/dist/server/pipeline-helpers.d.ts.map +1 -1
  243. package/dist/server/pipeline-interception.d.ts +11 -0
  244. package/dist/server/pipeline-interception.d.ts.map +1 -1
  245. package/dist/server/pipeline-outcome.d.ts +11 -1
  246. package/dist/server/pipeline-outcome.d.ts.map +1 -1
  247. package/dist/server/pipeline-phases.d.ts +2 -2
  248. package/dist/server/pipeline-phases.d.ts.map +1 -1
  249. package/dist/server/pipeline.d.ts +23 -35
  250. package/dist/server/pipeline.d.ts.map +1 -1
  251. package/dist/server/prebuilt/capture-render.d.ts +25 -0
  252. package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
  253. package/dist/server/prebuilt/capture-routes.d.ts +37 -0
  254. package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
  255. package/dist/server/prebuilt/capture-state.d.ts +79 -35
  256. package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
  257. package/dist/server/prebuilt/lifetime.d.ts +38 -0
  258. package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
  259. package/dist/server/prebuilt/slots.d.ts +7 -0
  260. package/dist/server/prebuilt/slots.d.ts.map +1 -1
  261. package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
  262. package/dist/server/prebuilt-builder.d.ts.map +1 -1
  263. package/dist/server/prebuilt-runtime.d.ts.map +1 -1
  264. package/dist/server/primitives.d.ts +6 -81
  265. package/dist/server/primitives.d.ts.map +1 -1
  266. package/dist/server/react-cache-bridge.d.ts +59 -0
  267. package/dist/server/react-cache-bridge.d.ts.map +1 -0
  268. package/dist/server/react-cache-scope.d.ts +49 -0
  269. package/dist/server/react-cache-scope.d.ts.map +1 -0
  270. package/dist/server/render-timeout.d.ts +15 -0
  271. package/dist/server/render-timeout.d.ts.map +1 -1
  272. package/dist/server/render-utils.d.ts +9 -0
  273. package/dist/server/render-utils.d.ts.map +1 -1
  274. package/dist/server/request-context.d.ts +26 -5
  275. package/dist/server/request-context.d.ts.map +1 -1
  276. package/dist/server/route-element-builder.d.ts.map +1 -1
  277. package/dist/server/route-handler.d.ts.map +1 -1
  278. package/dist/server/route-matcher.d.ts +7 -0
  279. package/dist/server/route-matcher.d.ts.map +1 -1
  280. package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
  281. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
  282. package/dist/server/rsc-entry/api-handler.d.ts +7 -0
  283. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  284. package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
  285. package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
  286. package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
  287. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  288. package/dist/server/rsc-entry/helpers.d.ts +0 -1
  289. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  290. package/dist/server/rsc-entry/index.d.ts +5 -15
  291. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  292. package/dist/server/rsc-entry/render-route.d.ts +5 -6
  293. package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
  294. package/dist/server/rsc-entry/render-signals.d.ts +65 -0
  295. package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
  296. package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
  297. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
  298. package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
  299. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  300. package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
  301. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  302. package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
  303. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  304. package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
  305. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  306. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
  307. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
  308. package/dist/server/signal-identity.d.ts +43 -0
  309. package/dist/server/signal-identity.d.ts.map +1 -0
  310. package/dist/server/slot-resolver.d.ts +4 -3
  311. package/dist/server/slot-resolver.d.ts.map +1 -1
  312. package/dist/server/slot-subtree-contain.d.ts.map +1 -1
  313. package/dist/server/ssr-bridge-types.d.ts +91 -53
  314. package/dist/server/ssr-bridge-types.d.ts.map +1 -1
  315. package/dist/server/ssr-entry.d.ts +8 -5
  316. package/dist/server/ssr-entry.d.ts.map +1 -1
  317. package/dist/server/ssr-render.d.ts +26 -40
  318. package/dist/server/ssr-render.d.ts.map +1 -1
  319. package/dist/server/ssr-wrappers.d.ts +1 -1
  320. package/dist/server/static-generator.d.ts.map +1 -1
  321. package/dist/server/stream-utils.d.ts +12 -0
  322. package/dist/server/stream-utils.d.ts.map +1 -1
  323. package/dist/server/tracing.d.ts +12 -16
  324. package/dist/server/tracing.d.ts.map +1 -1
  325. package/dist/server/types.d.ts +1 -1
  326. package/dist/server/version-skew.d.ts +3 -3
  327. package/dist/shared/csrf-reject.d.ts +16 -0
  328. package/dist/shared/csrf-reject.d.ts.map +1 -0
  329. package/dist/shared/error-digest.d.ts +28 -0
  330. package/dist/shared/error-digest.d.ts.map +1 -0
  331. package/dist/shared/payload-root.d.ts +11 -10
  332. package/dist/shared/payload-root.d.ts.map +1 -1
  333. package/dist/shared/rsc-payload-path.d.ts +6 -0
  334. package/dist/shared/rsc-payload-path.d.ts.map +1 -1
  335. package/dist/utils/write-file-atomic.d.ts +17 -0
  336. package/dist/utils/write-file-atomic.d.ts.map +1 -0
  337. package/docs/api/30-api-server.mdx +17 -14
  338. package/docs/api/32-api-cache.mdx +51 -23
  339. package/docs/api/34-api-config.mdx +34 -6
  340. package/docs/api/36-cli.mdx +11 -1
  341. package/docs/learn/03-fetching-data.mdx +17 -1
  342. package/docs/learn/04-access-control.mdx +1 -1
  343. package/docs/learn/10-caching.mdx +29 -11
  344. package/docs/learn/11-middleware.mdx +8 -2
  345. package/docs/learn/12-error-handling.mdx +6 -1
  346. package/package.json +7 -3
  347. package/src/adapters/build-output-helper.ts +55 -53
  348. package/src/adapters/canonicalize-module.ts +29 -0
  349. package/src/adapters/cloudflare.ts +105 -63
  350. package/src/adapters/compress-module.ts +16 -5
  351. package/src/adapters/fs-identity.ts +2 -3
  352. package/src/adapters/nitro-presets.ts +0 -15
  353. package/src/adapters/nitro-preview.ts +272 -136
  354. package/src/adapters/nitro.ts +119 -82
  355. package/src/adapters/shared.ts +23 -14
  356. package/src/adapters/types.ts +110 -21
  357. package/src/analyze/graph-cache.ts +3 -4
  358. package/src/cache/json-lossy-check.ts +3 -9
  359. package/src/cache/singleflight.ts +5 -2
  360. package/src/cache/sizeof.ts +3 -1
  361. package/src/cache/tag-aware-handler.ts +43 -26
  362. package/src/cli-check.ts +8 -98
  363. package/src/cli-context.ts +119 -0
  364. package/src/cli.ts +19 -28
  365. package/src/client/browser-dev.ts +1 -1
  366. package/src/client/browser-entry/action-dispatch.ts +26 -4
  367. package/src/client/browser-entry/hydrate.ts +53 -58
  368. package/src/client/browser-entry/index.ts +16 -27
  369. package/src/client/browser-entry/post-hydration.ts +6 -40
  370. package/src/client/browser-entry/router-init.ts +66 -84
  371. package/src/client/error-boundary.tsx +9 -41
  372. package/src/client/error-reconstituter.tsx +10 -5
  373. package/src/client/history.ts +35 -21
  374. package/src/client/index.ts +0 -1
  375. package/src/client/internal.ts +2 -7
  376. package/src/client/navigation-commit.ts +41 -18
  377. package/src/client/navigation-context.ts +3 -39
  378. package/src/client/react-root.ts +3 -2
  379. package/src/client/router-pipeline.ts +96 -132
  380. package/src/client/router-types.ts +46 -44
  381. package/src/client/router-url.ts +32 -0
  382. package/src/client/router.ts +62 -21
  383. package/src/client/rsc-fetch.ts +117 -155
  384. package/src/client/segment-cache.ts +110 -11
  385. package/src/client/ssr-data.ts +19 -80
  386. package/src/client/state.ts +2 -9
  387. package/src/client/use-pathname.ts +1 -1
  388. package/src/config-types.ts +2 -1
  389. package/src/config-validation.ts +2 -1
  390. package/src/dev-tools/dev-page-shell.ts +18 -0
  391. package/src/dev-tools/index.ts +0 -2
  392. package/src/dev-tools/instrumentation.ts +50 -2
  393. package/src/dev-tools/overlay.ts +8 -238
  394. package/src/index.ts +26 -14
  395. package/src/plugin-context.ts +39 -40
  396. package/src/plugins/build-manifest.ts +4 -11
  397. package/src/plugins/build-report.ts +70 -70
  398. package/src/plugins/dev-server.ts +24 -44
  399. package/src/plugins/entries.ts +2 -1
  400. package/src/plugins/fonts.ts +35 -7
  401. package/src/plugins/post-build.ts +327 -0
  402. package/src/plugins/prebuilt-capture.ts +28 -32
  403. package/src/plugins/prebuilt.ts +54 -39
  404. package/src/plugins/prerender-sugar.ts +0 -4
  405. package/src/plugins/react-resolve.ts +149 -0
  406. package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
  407. package/src/plugins/shims.ts +1 -0
  408. package/src/plugins/static-build.ts +42 -74
  409. package/src/routing/codegen-write.ts +25 -3
  410. package/src/routing/segment-codegen.ts +3 -2
  411. package/src/rsc-runtime/vendor-types.d.ts +8 -0
  412. package/src/server/access-gate.tsx +2 -1
  413. package/src/server/action-client.ts +1 -1
  414. package/src/server/action-handler.ts +253 -110
  415. package/src/server/actions.ts +73 -25
  416. package/src/server/als-registry.ts +73 -5
  417. package/src/server/chain-url-parts.ts +1 -1
  418. package/src/server/children-interception.ts +2 -1
  419. package/src/server/cookie-context.ts +18 -48
  420. package/src/server/csp-nonce.ts +0 -12
  421. package/src/server/csrf.ts +140 -8
  422. package/src/server/debug.ts +0 -1
  423. package/src/server/default-logger.ts +2 -1
  424. package/src/server/deny-boundary.ts +25 -13
  425. package/src/server/deny-renderer.ts +30 -97
  426. package/src/server/error-boundary-wrapper.ts +7 -3
  427. package/src/server/fallback-error.ts +26 -11
  428. package/src/server/flight-scripts.ts +1 -1
  429. package/src/server/head-response.ts +4 -4
  430. package/src/server/html-injector-core.ts +2 -2
  431. package/src/server/html-injectors.ts +2 -4
  432. package/src/server/index.ts +0 -4
  433. package/src/server/instrumentation.ts +10 -3
  434. package/src/server/internal.ts +1 -6
  435. package/src/server/json-status-response.ts +105 -0
  436. package/src/server/logger.ts +39 -3
  437. package/src/server/param-coercion.ts +15 -12
  438. package/src/server/pipeline-helpers.ts +257 -12
  439. package/src/server/pipeline-interception.ts +133 -0
  440. package/src/server/pipeline-outcome.ts +103 -31
  441. package/src/server/pipeline-phases.ts +127 -237
  442. package/src/server/pipeline.ts +204 -207
  443. package/src/server/prebuilt/capture-render.ts +118 -0
  444. package/src/server/prebuilt/capture-routes.ts +104 -0
  445. package/src/server/prebuilt/capture-state.ts +155 -48
  446. package/src/server/prebuilt/lifetime.ts +151 -0
  447. package/src/server/prebuilt/slots.ts +14 -2
  448. package/src/server/prebuilt/synthetic-store.ts +3 -0
  449. package/src/server/prebuilt-builder.ts +30 -320
  450. package/src/server/prebuilt-runtime.ts +125 -129
  451. package/src/server/primitives.ts +8 -168
  452. package/src/server/react-cache-bridge.ts +124 -0
  453. package/src/server/react-cache-scope.ts +104 -0
  454. package/src/server/render-timeout.ts +20 -0
  455. package/src/server/render-utils.ts +11 -1
  456. package/src/server/request-context.ts +36 -9
  457. package/src/server/route-element-builder.ts +11 -6
  458. package/src/server/route-handler.ts +36 -23
  459. package/src/server/route-matcher.ts +15 -1
  460. package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
  461. package/src/server/rsc-entry/api-handler.ts +27 -103
  462. package/src/server/rsc-entry/deny-fallback.ts +93 -26
  463. package/src/server/rsc-entry/error-renderer.ts +39 -91
  464. package/src/server/rsc-entry/helpers.ts +2 -4
  465. package/src/server/rsc-entry/index.ts +64 -58
  466. package/src/server/rsc-entry/render-route.ts +15 -80
  467. package/src/server/rsc-entry/render-signals.ts +108 -0
  468. package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
  469. package/src/server/rsc-entry/rsc-payload.ts +28 -61
  470. package/src/server/rsc-entry/rsc-stream.ts +113 -213
  471. package/src/server/rsc-entry/ssr-bridge.ts +2 -2
  472. package/src/server/rsc-entry/ssr-renderer.ts +182 -263
  473. package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
  474. package/src/server/signal-identity.ts +112 -0
  475. package/src/server/slot-resolver.ts +18 -18
  476. package/src/server/slot-subtree-contain.ts +2 -1
  477. package/src/server/ssr-bridge-types.ts +92 -56
  478. package/src/server/ssr-entry.ts +87 -111
  479. package/src/server/ssr-render.ts +55 -64
  480. package/src/server/ssr-wrappers.tsx +2 -2
  481. package/src/server/static-generator.ts +7 -42
  482. package/src/server/static-not-found.ts +3 -3
  483. package/src/server/stream-utils.ts +51 -0
  484. package/src/server/tracing.ts +58 -75
  485. package/src/server/types.ts +1 -1
  486. package/src/server/version-skew.ts +5 -5
  487. package/src/shared/csrf-reject.ts +15 -0
  488. package/src/shared/error-digest.ts +46 -0
  489. package/src/shared/payload-root.ts +11 -10
  490. package/src/shared/rsc-payload-path.ts +8 -1
  491. package/src/utils/write-file-atomic.ts +32 -0
  492. package/dist/_chunks/actions-jNrXdzgs.js +0 -346
  493. package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
  494. package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
  495. package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
  496. package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
  497. package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
  498. package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
  499. package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
  500. package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
  501. package/dist/_chunks/error-boundary-BndF-3Td.js.map +0 -1
  502. package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
  503. package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
  504. package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
  505. package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
  506. package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
  507. package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
  508. package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
  509. package/dist/_chunks/segment-context-D9_89u34.js +0 -34
  510. package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
  511. package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
  512. package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
  513. package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
  514. package/dist/_chunks/state-FippDgxN.js.map +0 -1
  515. package/dist/_chunks/status-page-marker-DwQBrLBz.js.map +0 -1
  516. package/dist/client/types.d.ts +0 -14
  517. package/dist/client/types.d.ts.map +0 -1
  518. package/dist/plugins/adapter-build.d.ts +0 -38
  519. package/dist/plugins/adapter-build.d.ts.map +0 -1
  520. package/dist/server/asset-headers.d.ts +0 -32
  521. package/dist/server/asset-headers.d.ts.map +0 -1
  522. package/dist/server/dev-source-map.d.ts +0 -22
  523. package/dist/server/dev-source-map.d.ts.map +0 -1
  524. package/src/client/types.ts +0 -21
  525. package/src/server/asset-headers.ts +0 -59
  526. package/src/server/dev-source-map.ts +0 -31
@@ -25,17 +25,22 @@ import {
25
25
  import { withSpan } from './tracing.ts';
26
26
  import { requestCspNonce } from './csp-nonce.ts';
27
27
  import { logRenderError } from './logger.ts';
28
- import { isDenySignal, isRedirectSignal } from './primitives.ts';
28
+ import { isDenySignal, isRedirectSignal } from './signal-identity.ts';
29
29
  import { ParamCoercionError } from './param-coercion.ts';
30
30
  import { checkVersionSkew, applyReloadHeaders } from './version-skew.ts';
31
31
  import { serveStaticMetadataFile, serializeSitemap } from './pipeline-metadata.ts';
32
32
  import { loadModule } from './safe-load.ts';
33
- import { findInterceptionMatch } from './pipeline-interception.ts';
34
- import { computeSegmentTreePaths } from '../routing/segment-keys.ts';
35
- import { parseClientStateTree } from './state-tree-diff.ts';
36
- import { applyCookieJar, cloneWithMutableHeaders, type ProxyResolver } from './pipeline-helpers.ts';
33
+ import { resolveInterceptedRoute } from './pipeline-interception.ts';
34
+ import { isApiRouteChain } from './route-matcher.ts';
35
+ import {
36
+ applyCookieJar,
37
+ cloneWithMutableHeaders,
38
+ dynamicResponseHeaders,
39
+ fireOnRequestError,
40
+ type ProxyResolver,
41
+ } from './pipeline-helpers.ts';
37
42
  import { coerceSegmentParams } from './param-coercion.ts';
38
- import { outcomeToResponse, type PhaseOutcome } from './pipeline-outcome.ts';
43
+ import { outcomeToResponse, thrownOutcome, type PhaseOutcome } from './pipeline-outcome.ts';
39
44
  import type { InterceptionContext, PipelineConfig, RouteMatch } from './pipeline.ts';
40
45
  import type { MetadataHandler, MetadataRoute, MiddlewareContext } from './types.ts';
41
46
  import { swallow } from './logger.ts';
@@ -47,26 +52,6 @@ interface RenderContext {
47
52
  interception?: InterceptionContext;
48
53
  }
49
54
 
50
- /**
51
- * Validate and canonicalize the X-Timber-URL header value.
52
- *
53
- * Returns the canonical pathname if valid, or null if rejected:
54
- * - Must start with '/' (relative pathname, no scheme/authority)
55
- * - Must not contain control characters
56
- * - Must pass canonicalization (no encoded separators, null bytes, etc.)
57
- */
58
- function validateInterceptionHeader(raw: string, stripTrailingSlash: boolean): string | null {
59
- if (!raw.startsWith('/')) return null;
60
- if (raw.startsWith('//')) return null;
61
- for (let i = 0; i < raw.length; i++) {
62
- const code = raw.charCodeAt(i);
63
- if (code <= 0x1f || code === 0x7f) return null;
64
- }
65
- const result = canonicalize(raw, stripTrailingSlash);
66
- if (!result.ok) return null;
67
- return result.pathname;
68
- }
69
-
70
55
  // ─── Phase: Proxy ──────────────────────────────────────────────────────────
71
56
 
72
57
  /**
@@ -96,13 +81,7 @@ export async function runProxyPhase(
96
81
  );
97
82
  return { kind: 'response', phase: 'proxy', response };
98
83
  } catch (error) {
99
- if (isRedirectSignal(error)) {
100
- return { kind: 'redirect', phase: 'proxy', signal: error };
101
- }
102
- if (isDenySignal(error)) {
103
- return { kind: 'deny', phase: 'proxy', signal: error };
104
- }
105
- return { kind: 'error', phase: 'proxy', error };
84
+ return thrownOutcome('proxy', error);
106
85
  }
107
86
  }
108
87
 
@@ -118,10 +97,10 @@ export async function runMiddlewarePhase(
118
97
  req: Request,
119
98
  match: RouteMatch,
120
99
  responseHeaders: Headers,
121
- requestHeaderOverlay: Headers,
122
100
  renderContext: RenderContext
123
101
  ): Promise<PhaseOutcome> {
124
102
  const detailed = config.serverTiming === 'detailed';
103
+ const requestHeaderOverlay = new Headers();
125
104
  const ctx: MiddlewareContext = {
126
105
  req,
127
106
  requestHeaders: requestHeaderOverlay,
@@ -169,15 +148,9 @@ export async function runMiddlewarePhase(
169
148
  // injected request headers so getHeaders() returns them downstream.
170
149
  applyRequestHeaderOverlay(requestHeaderOverlay);
171
150
 
172
- return runRenderPhase(config, req, match, responseHeaders, requestHeaderOverlay, renderContext);
151
+ return runRenderPhase(config, req, match, responseHeaders, renderContext);
173
152
  } catch (error) {
174
- if (isRedirectSignal(error)) {
175
- return { kind: 'redirect', phase: 'middleware', signal: error };
176
- }
177
- if (isDenySignal(error)) {
178
- return { kind: 'deny', phase: 'middleware', signal: error };
179
- }
180
- return { kind: 'error', phase: 'middleware', error };
153
+ return thrownOutcome('middleware', error);
181
154
  }
182
155
  }
183
156
 
@@ -203,26 +176,18 @@ export async function runRenderPhase(
203
176
  req: Request,
204
177
  match: RouteMatch,
205
178
  responseHeaders: Headers,
206
- requestHeaderOverlay: Headers,
207
179
  { canonicalPathname, interception }: RenderContext
208
180
  ): Promise<PhaseOutcome> {
209
181
  const detailed = config.serverTiming === 'detailed';
210
182
  applyCookieJar(responseHeaders);
211
183
  try {
212
- const renderFn = () =>
213
- config.render(req, match, responseHeaders, requestHeaderOverlay, interception);
184
+ const renderFn = () => config.render(req, match, responseHeaders, interception);
214
185
  const response = await withSpan('timber.render', { 'http.route': canonicalPathname }, () =>
215
186
  detailed ? withTiming('render', 'RSC + SSR render', renderFn) : renderFn()
216
187
  );
217
188
  return { kind: 'response', phase: 'render', response };
218
189
  } catch (error) {
219
- if (isDenySignal(error)) {
220
- return { kind: 'deny', phase: 'render', signal: error };
221
- }
222
- if (isRedirectSignal(error)) {
223
- return { kind: 'redirect', phase: 'render', signal: error };
224
- }
225
- return { kind: 'error', phase: 'render', error };
190
+ return thrownOutcome('render', error);
226
191
  }
227
192
  }
228
193
 
@@ -347,6 +312,7 @@ export async function handleRequest(
347
312
  return new Response(null, { status: error.status });
348
313
  }
349
314
  logRenderError({ method, path, error });
315
+ await fireOnRequestError(error, req, 'route');
350
316
  if (config.onPipelineError && error instanceof Error)
351
317
  config.onPipelineError(error, 'metadata-route');
352
318
  return new Response(null, { status: 500 });
@@ -364,6 +330,7 @@ export async function handleRequest(
364
330
  if (sitemapResponse) return cloneWithMutableHeaders(sitemapResponse);
365
331
  } catch (error) {
366
332
  logRenderError({ method, path, error });
333
+ await fireOnRequestError(error, req, 'route');
367
334
  if (config.onPipelineError && error instanceof Error)
368
335
  config.onPipelineError(error, 'auto-sitemap');
369
336
  return new Response(null, { status: 500 });
@@ -385,213 +352,136 @@ export async function handleRequest(
385
352
  }
386
353
  }
387
354
 
388
- // Stage 2: Route matching
389
- let match = config.matchRoute(canonicalPathname);
390
- let interception: InterceptionContext | undefined;
391
-
392
- // Stage 2a: Intercepting route resolution (modal pattern).
393
- // Only honored on RSC client-navigation requests (Accept: text/x-component)
394
- // to prevent spoofing from plain HTML navigations or raw HTTP clients.
395
- // The header value must be a valid relative pathname — reject schemes,
396
- // authority, and control characters. Canonicalize before matching.
397
- if (isRsc && config.interceptionRewrites?.length) {
398
- const rawSourceUrl = req.headers.get('X-Timber-URL');
399
- const validatedSourceUrl = rawSourceUrl
400
- ? validateInterceptionHeader(rawSourceUrl, stripTrailingSlash)
401
- : null;
402
- if (validatedSourceUrl) {
403
- // The scope of an interception is the segment that owns the intercepting
404
- // slot, so the guard asks whether the route the user is LEAVING renders
405
- // that segment. Two independent answers to "what is on screen?", tried in
406
- // order — deferred behind a thunk so neither runs unless a rewrite's
407
- // target pattern matches.
408
- //
409
- // 1. What the client says it has mounted (X-Timber-State-Tree
410
- // `treePaths`). Authoritative about tree shape and nothing else.
411
- // 2. What re-matching X-Timber-URL implies. Correct while the address bar
412
- // still holds the source page, which stops being true the moment a
413
- // modal is open — the address is then the *intercepted* URL and
414
- // re-matching it resolves through whichever group owns the canonical
415
- // page (TIM-1282).
416
- //
417
- // Neither is trusted: both are client-supplied, and satisfying the scope
418
- // only selects which build-time rewrite applies. The rendered pathname is
419
- // always the rewrite's own `interceptingPrefix`, the server re-derives the
420
- // rendered chain from it below, and every access.ts runs regardless.
421
- //
422
- // They are handed over as two sets in that order rather than one union:
423
- // each describes a single rendered chain, and only within one chain does
424
- // "the deepest scope" name the innermost owner (TIM-1318). Unioned, a
425
- // deeper scope from the address-implied canonical branch — which after
426
- // (2) may be a route group the client never mounted — would outrank the
427
- // owner actually on screen.
428
- const resolveSourceScopes = () => {
429
- const mounted = new Set(parseClientStateTree(req)?.treePaths ?? []);
430
- const sourceRoute = config.matchRoute(validatedSourceUrl);
431
- const addressed = new Set(sourceRoute ? computeSegmentTreePaths(sourceRoute.segments) : []);
432
- const scopes = [mounted, addressed].filter((scope) => scope.size > 0);
433
- // Neither channel produced a tree — no scope can contain anything, and
434
- // an origin that matches no route is not a legitimate soft navigation.
435
- return scopes.length > 0 ? scopes : null;
436
- };
437
- const rewrite = findInterceptionMatch(
438
- canonicalPathname,
439
- resolveSourceScopes,
440
- config.interceptionRewrites
441
- );
442
- if (rewrite?.mode === 'children') {
443
- // Sibling layout swap (TIM-1280). Nothing is re-matched: the resolver
444
- // addresses the owner directory by tree path and returns the chain
445
- // `[…owner ancestors, interceptingNode, …descendants]`, which renders
446
- // as an ordinary route. `interception` stays unset — there is no slot
447
- // to intercept into, and setting it would additionally arm the modal
448
- // path for every slot in the tree we are about to render.
449
- //
450
- // A null here means the scope named nothing in this manifest, or no
451
- // intercepting child matched the target. Both fall through to the
452
- // canonical route, which is what a hard navigation renders.
453
- const interceptedMatch = config.matchInterceptedRoute?.(
454
- canonicalPathname,
455
- rewrite.interceptingScope
456
- );
457
- if (interceptedMatch) match = interceptedMatch;
458
- } else if (rewrite) {
459
- const sourceMatch = config.matchRoute(rewrite.interceptingPrefix);
460
- // The scope test above was about the route the user is LEAVING. The
461
- // route we are about to render is a different one —
462
- // `interceptingPrefix` is URL-derived, and route groups are
463
- // URL-invisible, so `/` can resolve into a sibling group that does not
464
- // own the slot. Rendering that would reproduce the TIM-1278 failure on
465
- // a valid tree: the rewrite hijacks the navigation and no slot exists
466
- // to render the intercepting page. Fall through to the canonical
467
- // target route instead.
468
- const rendersTheSlot =
469
- sourceMatch !== null &&
470
- computeSegmentTreePaths(sourceMatch.segments).includes(rewrite.interceptingScope);
471
- if (rendersTheSlot) {
472
- match = sourceMatch;
473
- interception = { targetPathname: canonicalPathname };
474
- }
475
- }
476
- }
477
- }
478
-
479
- if (!match) {
480
- // Dev-time diagnostic: log the unmatched pathname so developers can
481
- // see why a request 404'd without needing to add breakpoints.
482
- if (isDebug()) {
483
- console.warn(
484
- `[timber] No route matched for pathname: ${canonicalPathname}\n` +
485
- ` Input path: ${path}\n` +
486
- ` Method: ${method}`
487
- );
488
- }
489
- // No route matched — render 404.tsx in root layout if available,
490
- // otherwise fall back to a bare 404 Response.
491
- if (config.renderNoMatch) {
492
- const responseHeaders = new Headers();
493
- return cloneWithMutableHeaders(await config.renderNoMatch(req, responseHeaders));
494
- }
495
- return new Response(null, { status: 404 });
496
- }
497
-
498
355
  // Response and request header containers — created before early hints so
499
356
  // the emitter can append Link headers (e.g. for Cloudflare CDN → 103).
500
- const responseHeaders = new Headers();
501
- const requestHeaderOverlay = new Headers();
357
+ // Seeded with the dynamic-page cache policy, which the no-match 404
358
+ // rendered below carries too.
359
+ const responseHeaders = dynamicResponseHeaders();
502
360
 
503
- // Set Cache-Control for dynamic HTML responses. Without this header,
504
- // CDNs (particularly Cloudflare) may attempt to buffer/process the
505
- // response differently, causing intermittent multi-second delays.
506
- // This matches Next.js's default behavior.
507
- responseHeaders.set('Cache-Control', 'private, no-cache, no-store, max-age=0, must-revalidate');
508
-
509
- // Stage 2b: 103 Early Hints (before middleware, after match)
510
- // Fires before middleware so the browser can begin fetching critical
511
- // assets while middleware runs. Non-fatal — a failing emitter never
512
- // blocks the request.
361
+ // Stages 2–2c are route setup. Anything they throw — a matcher bug, a
362
+ // codec returning a value a param cannot hold — is a `'setup'` outcome:
363
+ // logged, reported to onRequestError, and answered with the fallback page,
364
+ // with the match when there is one so a route.ts match keeps its format.
365
+ // Before TIM-1537 it escaped `createPipeline`, or was reported as
366
+ // "proxy.ts threw" when a proxy wrapped it.
513
367
  //
514
- // Skip on RSC requests (client-side navigations) — the browser already
515
- // has CSS, fonts, and JS chunks from the initial full-page load.
516
- // Skip on API routes (route.ts without page.tsx) — they return data
517
- // (JSON, images, etc.), not HTML that needs CSS/JS/font hints.
518
- const leafSegment = match.segments[match.segments.length - 1] as
519
- | { route?: unknown; page?: unknown }
520
- | undefined;
521
- const isApiRoute = leafSegment?.route && !leafSegment?.page;
522
- if (config.earlyHints && !isRsc && !isApiRoute) {
368
+ // Rendering the 404 page is render work, not setup, so its own failure is
369
+ // a `'render'` outcome even when setup decided the request is a 404.
370
+ const renderNotFound = async (headers: Headers): Promise<Response> => {
371
+ if (!config.renderNoMatch) return new Response(null, { status: 404 });
523
372
  try {
524
- await config.earlyHints(match, req, responseHeaders);
525
- } catch (err) {
526
- swallow(err, 'early hints hook threw');
373
+ return cloneWithMutableHeaders(await config.renderNoMatch(req, headers));
374
+ } catch (error) {
375
+ return outcomeToResponse(config, thrownOutcome('render', error), {
376
+ req,
377
+ method,
378
+ path,
379
+ responseHeaders: headers,
380
+ });
527
381
  }
528
- }
529
-
530
- // Stage 2c: Param coercion (before middleware)
531
- // Coerce raw string params through the app/schema.ts codecs.
532
- // Coercion failure → 404
533
- // (middleware never runs). See design/07-routing.md §"Where Coercion Runs"
534
- //
535
- // Snapshot raw params before coercion — slot resolution needs the
536
- // original string values to reconstruct URL parts for tree matching.
537
- // Coerced params may have been transformed by codecs.
538
- // segmentParams is typed CoercedParams but is still raw strings here
539
- // (coercion runs below). The snapshot preserves the pre-coercion shape.
540
- match.rawSegmentParams = { ...match.segmentParams } as Record<string, string | string[]>;
382
+ };
383
+ let match: RouteMatch | null = null;
384
+ let interception: InterceptionContext | undefined;
541
385
  try {
542
- await coerceSegmentParams(match);
543
- } catch (error) {
544
- if (error instanceof ParamCoercionError) {
545
- // Dev-time diagnostic: log param coercion failures so developers can
546
- // see why a matched route 404'd. Silent coercion 404s are brutal to debug.
386
+ // Stage 2: Route matching, then 2a: intercepting route resolution.
387
+ match = config.matchRoute(canonicalPathname);
388
+ ({ match, interception } = resolveInterceptedRoute(config, req, canonicalPathname, match));
389
+
390
+ if (!match) {
391
+ // Dev-time diagnostic: log the unmatched pathname so developers can
392
+ // see why a request 404'd without needing to add breakpoints.
547
393
  if (isDebug()) {
548
- const segmentChain = match.segments.map((s) => s.segmentName || '/').join(' → ');
549
394
  console.warn(
550
- `[timber] Param coercion failed for ${method} ${canonicalPathname} — responding with 404\n` +
551
- ` Matched segments: ${segmentChain}\n` +
552
- ` Error: ${error.message}\n` +
553
- ` This usually means a codec in app/schema.ts rejected the URL value.\n` +
554
- ` Check the codec for the bracket key of the segment named above.`
395
+ `[timber] No route matched for pathname: ${canonicalPathname}\n` +
396
+ ` Input path: ${path}\n` +
397
+ ` Method: ${method}`
555
398
  );
556
399
  }
557
- // For API routes (route.ts), return a bare 404 — not an HTML page.
558
- // API consumers expect JSON/empty responses, not rendered HTML.
559
- const leafSegment = match.segments[match.segments.length - 1];
560
- if ((leafSegment as { route?: unknown }).route && !(leafSegment as { page?: unknown }).page) {
561
- return new Response(null, { status: 404 });
400
+ // No route matched — render 404.tsx in root layout if available,
401
+ // otherwise fall back to a bare 404 Response.
402
+ return await renderNotFound(responseHeaders);
403
+ }
404
+
405
+ // Stage 2b: 103 Early Hints (before middleware, after match)
406
+ // Fires before middleware so the browser can begin fetching critical
407
+ // assets while middleware runs. Non-fatal — a failing emitter never
408
+ // blocks the request.
409
+ //
410
+ // Skip on RSC requests (client-side navigations) — the browser already
411
+ // has CSS, fonts, and JS chunks from the initial full-page load.
412
+ // Skip on API routes (route.ts without page.tsx) — they return data
413
+ // (JSON, images, etc.), not HTML that needs CSS/JS/font hints.
414
+ if (config.earlyHints && !isRsc && !isApiRouteChain(match.segments)) {
415
+ try {
416
+ await config.earlyHints(match, req, responseHeaders);
417
+ } catch (err) {
418
+ swallow(err, 'early hints hook threw');
562
419
  }
563
- // Route through the app's 404 page (404.tsx in root layout) instead of
564
- // returning a bare empty 404 Response. Falls back to bare 404 only if
565
- // no renderNoMatch renderer is configured.
566
- if (config.renderNoMatch) {
567
- return cloneWithMutableHeaders(await config.renderNoMatch(req, responseHeaders));
420
+ }
421
+
422
+ // Stage 2c: Param coercion (before middleware)
423
+ // Coerce raw string params through the app/schema.ts codecs.
424
+ // Coercion failure → 404
425
+ // (middleware never runs). See design/07-routing.md §"Where Coercion Runs"
426
+ try {
427
+ match = { ...match, segmentParams: await coerceSegmentParams(match) };
428
+ } catch (error) {
429
+ if (error instanceof ParamCoercionError) {
430
+ // Dev-time diagnostic: log param coercion failures so developers can
431
+ // see why a matched route 404'd. Silent coercion 404s are brutal to debug.
432
+ if (isDebug()) {
433
+ const segmentChain = match.segments.map((s) => s.segmentName || '/').join(' → ');
434
+ console.warn(
435
+ `[timber] Param coercion failed for ${method} ${canonicalPathname} — responding with 404\n` +
436
+ ` Matched segments: ${segmentChain}\n` +
437
+ ` Error: ${error.message}\n` +
438
+ ` This usually means a codec in app/schema.ts rejected the URL value.\n` +
439
+ ` Check the codec for the bracket key of the segment named above.`
440
+ );
441
+ }
442
+ // For API routes (route.ts), return a bare 404 — not an HTML page.
443
+ // API consumers expect JSON/empty responses, not rendered HTML.
444
+ if (isApiRouteChain(match.segments)) {
445
+ return new Response(null, { status: 404 });
446
+ }
447
+ // Route through the app's 404 page (404.tsx in root layout) instead of
448
+ // returning a bare empty 404 Response. Falls back to bare 404 only if
449
+ // no renderNoMatch renderer is configured.
450
+ return await renderNotFound(responseHeaders);
568
451
  }
569
- return new Response(null, { status: 404 });
452
+ throw error;
570
453
  }
571
- throw error;
572
- }
573
454
 
574
- // Store coerced segment params in ALS so components can access them
575
- // via getSegmentParams() instead of receiving them as a prop.
576
- // See design/07-routing.md §"params.ts — Convention File for Typed Params"
577
- setSegmentParams(match.segmentParams);
455
+ // Store coerced segment params in ALS so components can access them
456
+ // via getSegmentParams() instead of receiving them as a prop.
457
+ // See design/07-routing.md §"params.ts — Convention File for Typed Params"
458
+ setSegmentParams(match.segmentParams);
578
459
 
579
- // Store the matched segment path for dev-mode validation in getSegmentParams().
580
- // Build the tree path from the segment chain (includes groups and slots).
581
- const segmentPath =
582
- match.segments
583
- .map((s) => s.segmentName)
584
- .filter(Boolean)
585
- .join('/') || '/';
586
- setMatchedSegmentPath(segmentPath.startsWith('/') ? segmentPath : `/${segmentPath}`);
460
+ // Store the matched segment path for dev-mode validation in getSegmentParams().
461
+ // Build the tree path from the segment chain (includes groups and slots).
462
+ const segmentPath =
463
+ match.segments
464
+ .map((s) => s.segmentName)
465
+ .filter(Boolean)
466
+ .join('/') || '/';
467
+ setMatchedSegmentPath(segmentPath.startsWith('/') ? segmentPath : `/${segmentPath}`);
468
+ } catch (error) {
469
+ return outcomeToResponse(config, thrownOutcome('setup', error), {
470
+ req,
471
+ method,
472
+ path,
473
+ responseHeaders,
474
+ match: match ?? undefined,
475
+ });
476
+ }
587
477
 
588
478
  const outcome =
589
479
  match.middlewareChain.length > 0
590
- ? await runMiddlewarePhase(config, req, match, responseHeaders, requestHeaderOverlay, {
480
+ ? await runMiddlewarePhase(config, req, match, responseHeaders, {
591
481
  canonicalPathname,
592
482
  interception,
593
483
  })
594
- : await runRenderPhase(config, req, match, responseHeaders, requestHeaderOverlay, {
484
+ : await runRenderPhase(config, req, match, responseHeaders, {
595
485
  canonicalPathname,
596
486
  interception,
597
487
  });