@timber-js/app 0.2.0-alpha.208 → 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.
- package/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
- package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
- package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
- package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
- package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
- package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
- package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
- package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
- package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
- package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
- package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
- package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
- package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
- package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
- package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
- package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
- package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
- package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
- package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
- package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
- package/dist/_chunks/{error-boundary-BrHmG-2X.js → error-boundary-tA7kVfs4.js} +84 -104
- package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
- package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
- package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
- package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
- package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
- package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
- package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
- package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
- package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
- package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
- package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
- package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
- package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
- package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
- package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
- package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
- package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
- package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
- package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
- package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
- package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
- package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
- package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
- package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
- package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
- package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
- package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
- package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
- package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
- package/dist/_chunks/{status-page-marker-CNbpUOPB.js → status-page-marker-gaihi0KZ.js} +53 -20
- package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
- package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
- package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +7 -7
- package/dist/adapters/build-output-helper.d.ts.map +1 -1
- package/dist/adapters/canonicalize-module.d.ts +8 -0
- package/dist/adapters/canonicalize-module.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +2 -2
- package/dist/adapters/cloudflare.d.ts +30 -8
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -2
- package/dist/adapters/compress-module.d.ts +8 -0
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +2 -3
- package/dist/adapters/fs-identity.d.ts.map +1 -1
- package/dist/adapters/nitro-presets.d.ts +0 -6
- package/dist/adapters/nitro-presets.d.ts.map +1 -1
- package/dist/adapters/nitro-preview.d.ts +43 -11
- package/dist/adapters/nitro-preview.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +1 -13
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +291 -176
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +7 -2
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +105 -21
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js +0 -0
- package/dist/analyze/crawl-entry.js +3 -3
- package/dist/analyze/graph-cache.d.ts.map +1 -1
- package/dist/analyze/graph-command.js +4 -4
- package/dist/cache/index.js +2 -2
- package/dist/cache/json-lossy-check.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts.map +1 -1
- package/dist/cache/stores/memory.js +1 -1
- package/dist/cache/tag-aware-handler.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.js +1 -1
- package/dist/cli-check.d.ts +7 -37
- package/dist/cli-check.d.ts.map +1 -1
- package/dist/cli-context.d.ts +54 -0
- package/dist/cli-context.d.ts.map +1 -0
- package/dist/cli.d.ts +9 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -24
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts +19 -29
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/index.d.ts +7 -7
- package/dist/client/browser-entry/post-hydration.d.ts +6 -9
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +6 -11
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +4 -3
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -1
- package/dist/client/error-reconstituter.d.ts +3 -9
- package/dist/client/error-reconstituter.d.ts.map +1 -1
- package/dist/client/history.d.ts +12 -11
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -6
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +3 -3
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +68 -104
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +16 -7
- package/dist/client/navigation-commit.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +3 -5
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/react-root.d.ts +3 -2
- package/dist/client/react-root.d.ts.map +1 -1
- package/dist/client/router-pipeline.d.ts +1 -6
- package/dist/client/router-pipeline.d.ts.map +1 -1
- package/dist/client/router-types.d.ts +45 -39
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router-url.d.ts +24 -0
- package/dist/client/router-url.d.ts.map +1 -0
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +8 -4
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/ssr-data.d.ts +18 -64
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +2 -5
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts +1 -1
- package/dist/config-types.d.ts +2 -1
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -1
- package/dist/dev-tools/dev-page-shell.d.ts +17 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
- package/dist/dev-tools/index.d.ts +1 -1
- package/dist/dev-tools/index.d.ts.map +1 -1
- package/dist/dev-tools/instrumentation.d.ts +17 -2
- package/dist/dev-tools/instrumentation.d.ts.map +1 -1
- package/dist/dev-tools/overlay.d.ts +6 -27
- package/dist/dev-tools/overlay.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +531 -373
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +26 -40
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +15 -2
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +19 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/post-build.d.ts +110 -0
- package/dist/plugins/post-build.d.ts.map +1 -0
- package/dist/plugins/prebuilt-capture.d.ts +11 -4
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
- package/dist/plugins/prebuilt.d.ts +17 -1
- package/dist/plugins/prebuilt.d.ts.map +1 -1
- package/dist/plugins/prerender-sugar.d.ts.map +1 -1
- package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
- package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +32 -9
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-write.d.ts +0 -9
- package/dist/routing/codegen-write.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/routing/segment-codegen.d.ts.map +1 -1
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts +5 -4
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +46 -7
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +58 -5
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/children-interception.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts +2 -23
- package/dist/server/cookie-context.d.ts.map +1 -1
- package/dist/server/csp-nonce.d.ts +0 -9
- package/dist/server/csp-nonce.d.ts.map +1 -1
- package/dist/server/csrf.d.ts +27 -4
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/debug.d.ts +0 -1
- package/dist/server/debug.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +2 -1
- package/dist/server/default-logger.d.ts.map +1 -1
- package/dist/server/deny-boundary.d.ts +12 -6
- package/dist/server/deny-boundary.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts +2 -2
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -3
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +9 -2
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +4 -4
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +10 -3
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/internal.d.ts +1 -4
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +961 -581
- package/dist/server/internal.js.map +1 -1
- package/dist/server/json-status-response.d.ts +34 -0
- package/dist/server/json-status-response.d.ts.map +1 -0
- package/dist/server/logger.d.ts +26 -0
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +11 -6
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-helpers.d.ts +95 -7
- package/dist/server/pipeline-helpers.d.ts.map +1 -1
- package/dist/server/pipeline-interception.d.ts +11 -0
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +11 -1
- package/dist/server/pipeline-outcome.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts +2 -2
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +23 -35
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/prebuilt/capture-render.d.ts +25 -0
- package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-routes.d.ts +37 -0
- package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +79 -35
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
- package/dist/server/prebuilt/lifetime.d.ts +38 -0
- package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +7 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -1
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
- package/dist/server/prebuilt-builder.d.ts.map +1 -1
- package/dist/server/prebuilt-runtime.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +6 -81
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/react-cache-bridge.d.ts +59 -0
- package/dist/server/react-cache-bridge.d.ts.map +1 -0
- package/dist/server/react-cache-scope.d.ts +49 -0
- package/dist/server/react-cache-scope.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +15 -0
- package/dist/server/render-timeout.d.ts.map +1 -1
- package/dist/server/render-utils.d.ts +9 -0
- package/dist/server/render-utils.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +26 -5
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +7 -0
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +7 -0
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +0 -1
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +5 -15
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +5 -6
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-signals.d.ts +65 -0
- package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
- package/dist/server/signal-identity.d.ts +43 -0
- package/dist/server/signal-identity.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +4 -3
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/slot-subtree-contain.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +91 -53
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +8 -5
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +26 -40
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +1 -1
- package/dist/server/static-generator.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +12 -0
- package/dist/server/stream-utils.d.ts.map +1 -1
- package/dist/server/tracing.d.ts +12 -16
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -1
- package/dist/server/version-skew.d.ts +3 -3
- package/dist/shared/csrf-reject.d.ts +16 -0
- package/dist/shared/csrf-reject.d.ts.map +1 -0
- package/dist/shared/error-digest.d.ts +28 -0
- package/dist/shared/error-digest.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +11 -10
- package/dist/shared/payload-root.d.ts.map +1 -1
- package/dist/shared/rsc-payload-path.d.ts +6 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -1
- package/dist/utils/write-file-atomic.d.ts +17 -0
- package/dist/utils/write-file-atomic.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +17 -14
- package/docs/api/32-api-cache.mdx +51 -23
- package/docs/api/34-api-config.mdx +34 -6
- package/docs/api/36-cli.mdx +11 -1
- package/docs/learn/03-fetching-data.mdx +17 -1
- package/docs/learn/04-access-control.mdx +1 -1
- package/docs/learn/10-caching.mdx +29 -11
- package/docs/learn/11-middleware.mdx +8 -2
- package/docs/learn/12-error-handling.mdx +6 -1
- package/package.json +5 -1
- package/src/adapters/build-output-helper.ts +55 -53
- package/src/adapters/canonicalize-module.ts +29 -0
- package/src/adapters/cloudflare.ts +105 -63
- package/src/adapters/compress-module.ts +16 -5
- package/src/adapters/fs-identity.ts +2 -3
- package/src/adapters/nitro-presets.ts +0 -15
- package/src/adapters/nitro-preview.ts +272 -136
- package/src/adapters/nitro.ts +119 -82
- package/src/adapters/shared.ts +23 -14
- package/src/adapters/types.ts +110 -21
- package/src/analyze/graph-cache.ts +3 -4
- package/src/cache/json-lossy-check.ts +3 -9
- package/src/cache/singleflight.ts +5 -2
- package/src/cache/sizeof.ts +3 -1
- package/src/cache/tag-aware-handler.ts +43 -26
- package/src/cli-check.ts +8 -98
- package/src/cli-context.ts +119 -0
- package/src/cli.ts +19 -28
- package/src/client/browser-dev.ts +1 -1
- package/src/client/browser-entry/action-dispatch.ts +26 -4
- package/src/client/browser-entry/hydrate.ts +53 -58
- package/src/client/browser-entry/index.ts +16 -27
- package/src/client/browser-entry/post-hydration.ts +6 -40
- package/src/client/browser-entry/router-init.ts +66 -84
- package/src/client/error-boundary.tsx +9 -41
- package/src/client/error-reconstituter.tsx +10 -5
- package/src/client/history.ts +18 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +35 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +65 -128
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +43 -22
- package/src/client/rsc-fetch.ts +117 -155
- package/src/client/ssr-data.ts +19 -80
- package/src/client/state.ts +2 -9
- package/src/client/use-pathname.ts +1 -1
- package/src/config-types.ts +2 -1
- package/src/config-validation.ts +2 -1
- package/src/dev-tools/dev-page-shell.ts +18 -0
- package/src/dev-tools/index.ts +0 -2
- package/src/dev-tools/instrumentation.ts +50 -2
- package/src/dev-tools/overlay.ts +8 -238
- package/src/index.ts +24 -14
- package/src/plugin-context.ts +39 -40
- package/src/plugins/build-manifest.ts +4 -11
- package/src/plugins/build-report.ts +70 -70
- package/src/plugins/dev-server.ts +24 -44
- package/src/plugins/entries.ts +2 -1
- package/src/plugins/fonts.ts +35 -7
- package/src/plugins/post-build.ts +327 -0
- package/src/plugins/prebuilt-capture.ts +28 -32
- package/src/plugins/prebuilt.ts +54 -39
- package/src/plugins/prerender-sugar.ts +0 -4
- package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
- package/src/plugins/shims.ts +1 -0
- package/src/plugins/static-build.ts +42 -74
- package/src/routing/codegen-write.ts +25 -3
- package/src/routing/segment-codegen.ts +3 -2
- package/src/rsc-runtime/vendor-types.d.ts +8 -0
- package/src/server/access-gate.tsx +2 -1
- package/src/server/action-client.ts +1 -1
- package/src/server/action-handler.ts +253 -110
- package/src/server/actions.ts +73 -25
- package/src/server/als-registry.ts +73 -5
- package/src/server/chain-url-parts.ts +1 -1
- package/src/server/children-interception.ts +2 -1
- package/src/server/cookie-context.ts +18 -48
- package/src/server/csp-nonce.ts +0 -12
- package/src/server/csrf.ts +140 -8
- package/src/server/debug.ts +0 -1
- package/src/server/default-logger.ts +2 -1
- package/src/server/deny-boundary.ts +25 -13
- package/src/server/deny-renderer.ts +30 -97
- package/src/server/error-boundary-wrapper.ts +7 -3
- package/src/server/fallback-error.ts +26 -11
- package/src/server/flight-scripts.ts +1 -1
- package/src/server/head-response.ts +4 -4
- package/src/server/html-injector-core.ts +2 -2
- package/src/server/html-injectors.ts +2 -4
- package/src/server/index.ts +0 -4
- package/src/server/instrumentation.ts +10 -3
- package/src/server/internal.ts +1 -6
- package/src/server/json-status-response.ts +105 -0
- package/src/server/logger.ts +39 -3
- package/src/server/param-coercion.ts +15 -12
- package/src/server/pipeline-helpers.ts +257 -12
- package/src/server/pipeline-interception.ts +133 -0
- package/src/server/pipeline-outcome.ts +103 -31
- package/src/server/pipeline-phases.ts +127 -237
- package/src/server/pipeline.ts +204 -207
- package/src/server/prebuilt/capture-render.ts +118 -0
- package/src/server/prebuilt/capture-routes.ts +104 -0
- package/src/server/prebuilt/capture-state.ts +155 -48
- package/src/server/prebuilt/lifetime.ts +151 -0
- package/src/server/prebuilt/slots.ts +14 -2
- package/src/server/prebuilt/synthetic-store.ts +3 -0
- package/src/server/prebuilt-builder.ts +30 -320
- package/src/server/prebuilt-runtime.ts +125 -129
- package/src/server/primitives.ts +8 -168
- package/src/server/react-cache-bridge.ts +124 -0
- package/src/server/react-cache-scope.ts +104 -0
- package/src/server/render-timeout.ts +20 -0
- package/src/server/render-utils.ts +11 -1
- package/src/server/request-context.ts +36 -9
- package/src/server/route-element-builder.ts +11 -6
- package/src/server/route-handler.ts +36 -23
- package/src/server/route-matcher.ts +15 -1
- package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
- package/src/server/rsc-entry/api-handler.ts +27 -103
- package/src/server/rsc-entry/deny-fallback.ts +93 -26
- package/src/server/rsc-entry/error-renderer.ts +39 -91
- package/src/server/rsc-entry/helpers.ts +2 -4
- package/src/server/rsc-entry/index.ts +64 -58
- package/src/server/rsc-entry/render-route.ts +15 -80
- package/src/server/rsc-entry/render-signals.ts +108 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
- package/src/server/rsc-entry/rsc-payload.ts +28 -61
- package/src/server/rsc-entry/rsc-stream.ts +113 -213
- package/src/server/rsc-entry/ssr-bridge.ts +2 -2
- package/src/server/rsc-entry/ssr-renderer.ts +182 -263
- package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
- package/src/server/signal-identity.ts +112 -0
- package/src/server/slot-resolver.ts +18 -18
- package/src/server/slot-subtree-contain.ts +2 -1
- package/src/server/ssr-bridge-types.ts +92 -56
- package/src/server/ssr-entry.ts +87 -111
- package/src/server/ssr-render.ts +55 -64
- package/src/server/ssr-wrappers.tsx +2 -2
- package/src/server/static-generator.ts +7 -42
- package/src/server/static-not-found.ts +3 -3
- package/src/server/stream-utils.ts +51 -0
- package/src/server/tracing.ts +58 -75
- package/src/server/types.ts +1 -1
- package/src/server/version-skew.ts +5 -5
- package/src/shared/csrf-reject.ts +15 -0
- package/src/shared/error-digest.ts +46 -0
- package/src/shared/payload-root.ts +11 -10
- package/src/shared/rsc-payload-path.ts +8 -1
- package/src/utils/write-file-atomic.ts +32 -0
- package/dist/_chunks/actions-jNrXdzgs.js +0 -346
- package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
- package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
- package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
- package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
- package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
- package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
- package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
- package/dist/_chunks/error-boundary-BrHmG-2X.js.map +0 -1
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
- package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
- package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
- package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
- package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
- package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
- package/dist/_chunks/segment-context-D9_89u34.js +0 -34
- package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
- package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
- package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
- package/dist/_chunks/state-FippDgxN.js.map +0 -1
- package/dist/_chunks/status-page-marker-CNbpUOPB.js.map +0 -1
- package/dist/client/types.d.ts +0 -14
- package/dist/client/types.d.ts.map +0 -1
- package/dist/plugins/adapter-build.d.ts +0 -38
- package/dist/plugins/adapter-build.d.ts.map +0 -1
- package/dist/server/asset-headers.d.ts +0 -32
- package/dist/server/asset-headers.d.ts.map +0 -1
- package/dist/server/dev-source-map.d.ts +0 -22
- package/dist/server/dev-source-map.d.ts.map +0 -1
- package/src/client/types.ts +0 -21
- package/src/server/asset-headers.ts +0 -59
- 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 './
|
|
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 {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
|
|
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
|
-
|
|
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,
|
|
151
|
+
return runRenderPhase(config, req, match, responseHeaders, renderContext);
|
|
173
152
|
} catch (error) {
|
|
174
|
-
|
|
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
|
-
|
|
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
|
-
|
|
501
|
-
|
|
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
|
-
//
|
|
504
|
-
//
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
|
|
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
|
-
//
|
|
515
|
-
//
|
|
516
|
-
|
|
517
|
-
|
|
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.
|
|
525
|
-
} catch (
|
|
526
|
-
|
|
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
|
-
|
|
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
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
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]
|
|
551
|
-
`
|
|
552
|
-
`
|
|
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
|
-
//
|
|
558
|
-
//
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
-
|
|
452
|
+
throw error;
|
|
570
453
|
}
|
|
571
|
-
throw error;
|
|
572
|
-
}
|
|
573
454
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
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
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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,
|
|
480
|
+
? await runMiddlewarePhase(config, req, match, responseHeaders, {
|
|
591
481
|
canonicalPathname,
|
|
592
482
|
interception,
|
|
593
483
|
})
|
|
594
|
-
: await runRenderPhase(config, req, match, responseHeaders,
|
|
484
|
+
: await runRenderPhase(config, req, match, responseHeaders, {
|
|
595
485
|
canonicalPathname,
|
|
596
486
|
interception,
|
|
597
487
|
});
|