@timber-js/app 0.2.0-alpha.185 → 0.2.0-alpha.187
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/{actions-O_LsyCE4.js → actions-35jnMdeJ.js} +4 -3
- package/dist/_chunks/{actions-O_LsyCE4.js.map → actions-35jnMdeJ.js.map} +1 -1
- package/dist/_chunks/als-registry-C6kcfprT.js +41 -0
- package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js +26 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -0
- package/dist/_chunks/base-path-DaQrzbez.js +80 -0
- package/dist/_chunks/base-path-DaQrzbez.js.map +1 -0
- package/dist/_chunks/build-manifest-DWppEdLB.js +86 -0
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/build-output-helper-C3DrfzZR.js +369 -0
- package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +1 -0
- package/dist/_chunks/{cache-api-B-lhk9p4.js → cache-api-DjNrIWRR.js} +8 -14
- package/dist/_chunks/cache-api-DjNrIWRR.js.map +1 -0
- package/dist/_chunks/cli-check-CpmN7Nh-.js +256 -0
- package/dist/_chunks/cli-check-CpmN7Nh-.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-CGMp_Psg.js +298 -0
- package/dist/_chunks/cli-schema-sync-CGMp_Psg.js.map +1 -0
- package/dist/_chunks/{cloudflare-CnT5Lr7U.js → cloudflare-CGP6BZKO.js} +92 -14
- package/dist/_chunks/{cloudflare-CnT5Lr7U.js.map → cloudflare-CGP6BZKO.js.map} +1 -1
- package/dist/_chunks/convention-lint-kXsgc_-7.js +784 -0
- package/dist/_chunks/convention-lint-kXsgc_-7.js.map +1 -0
- package/dist/_chunks/error-boundary-D-ODYX41.js +353 -0
- package/dist/_chunks/error-boundary-D-ODYX41.js.map +1 -0
- package/dist/_chunks/{fast-hash-D6hIVt1Y.js → fast-hash-C-tVYrLb.js} +6 -1
- package/dist/_chunks/fast-hash-C-tVYrLb.js.map +1 -0
- package/dist/_chunks/file-cache-DmX7OqZP.js +454 -0
- package/dist/_chunks/file-cache-DmX7OqZP.js.map +1 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js +208 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +1 -0
- package/dist/_chunks/{logger-AWfuX-KJ.js → logger-D8xJZXIN.js} +34 -51
- package/dist/_chunks/logger-D8xJZXIN.js.map +1 -0
- package/dist/_chunks/mdx-file-C005ay-P.js +25 -0
- package/dist/_chunks/mdx-file-C005ay-P.js.map +1 -0
- package/dist/_chunks/{plugin-context---kTF5v8.js → plugin-context-rCinWLiE.js} +8 -2
- package/dist/_chunks/plugin-context-rCinWLiE.js.map +1 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js +14 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js.map +1 -0
- package/dist/_chunks/{resolve-schema-Dz3fcFUo.js → resolve-schema-5ma5pp1b.js} +2 -2
- package/dist/_chunks/{resolve-schema-Dz3fcFUo.js.map → resolve-schema-5ma5pp1b.js.map} +1 -1
- package/dist/_chunks/{router-ref-CtmF-aPv.js → router-ref-DuYuV_0Q.js} +2 -2
- package/dist/_chunks/router-ref-DuYuV_0Q.js.map +1 -0
- package/dist/_chunks/rsc-cache-key-DD0fl_-s.js +243 -0
- package/dist/_chunks/rsc-cache-key-DD0fl_-s.js.map +1 -0
- package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js +40 -0
- package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js.map +1 -0
- package/dist/_chunks/rsc-media-type-DRqE_lD_.js +46 -0
- package/dist/_chunks/rsc-media-type-DRqE_lD_.js.map +1 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js +48 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js.map +1 -0
- package/dist/_chunks/scanner-C8b0Gcw3.js +1564 -0
- package/dist/_chunks/scanner-C8b0Gcw3.js.map +1 -0
- package/dist/_chunks/schema-bridge-Cc2Gngu1.js +199 -0
- package/dist/_chunks/schema-bridge-Cc2Gngu1.js.map +1 -0
- package/dist/_chunks/{segment-classify-Byy425ng.js → segment-classify-C539Pa2O.js} +23 -2
- package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -0
- package/dist/_chunks/segment-context-CjOlyB8Y.js +97 -0
- package/dist/_chunks/segment-context-CjOlyB8Y.js.map +1 -0
- package/dist/_chunks/{canonicalize-DQHyFClh.js → segment-keys-BawYuNFO.js} +61 -2
- package/dist/_chunks/segment-keys-BawYuNFO.js.map +1 -0
- package/dist/_chunks/slot-params-BCTmZkQB.js +76 -0
- package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -0
- package/dist/_chunks/{ssr-data-BOWsq18U.js → ssr-data-14MXm7Pj.js} +17 -2
- package/dist/_chunks/ssr-data-14MXm7Pj.js.map +1 -0
- package/dist/_chunks/{use-query-states-DFvWd-EA.js → use-query-states-BbU5Ge1V.js} +74 -26
- package/dist/_chunks/use-query-states-BbU5Ge1V.js.map +1 -0
- package/dist/_chunks/use-segment-params-C4r4BD9T.js +398 -0
- package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +1 -0
- package/dist/_chunks/walkers-RzN6AFjr.js +141 -0
- package/dist/_chunks/walkers-RzN6AFjr.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +37 -0
- package/dist/adapters/build-output-helper.d.ts.map +1 -1
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +1 -1
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +1 -1
- package/dist/adapters/compress-module.d.ts +12 -0
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +64 -0
- package/dist/adapters/fs-identity.d.ts.map +1 -0
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +56 -5
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +57 -1
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +13 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/cache/fast-hash.d.ts +5 -0
- package/dist/cache/fast-hash.d.ts.map +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cdn/cloudflare-purge.js +30 -0
- package/dist/cdn/cloudflare-purge.js.map +1 -0
- package/dist/cdn/fastly-purge.js +33 -0
- package/dist/cdn/fastly-purge.js.map +1 -0
- package/dist/cdn/index.js +94 -0
- package/dist/cdn/index.js.map +1 -0
- package/dist/cdn/workers-cache-purge.js +35 -0
- package/dist/cdn/workers-cache-purge.js.map +1 -0
- package/dist/cli-check.d.ts +153 -0
- package/dist/cli-check.d.ts.map +1 -0
- package/dist/cli.d.ts +34 -8
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +46 -21
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts +20 -9
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/index.d.ts +1 -1
- package/dist/client/browser-entry/index.d.ts.map +1 -1
- package/dist/client/browser-entry/post-hydration.d.ts +4 -1
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +3 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/browser-entry/rsc-stream.d.ts +8 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +7 -0
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -162
- package/dist/client/history.d.ts +13 -6
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +42 -41
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +4 -3
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +877 -311
- package/dist/client/internal.js.map +1 -1
- package/dist/client/link.d.ts +1 -7
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/navigation-api.d.ts +2 -2
- package/dist/client/navigation-commit.d.ts +87 -0
- package/dist/client/navigation-commit.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +37 -20
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/navigation-root.d.ts +63 -23
- package/dist/client/navigation-root.d.ts.map +1 -1
- package/dist/client/params-context.d.ts +81 -0
- package/dist/client/params-context.d.ts.map +1 -0
- package/dist/client/router-effects.d.ts +129 -0
- package/dist/client/router-effects.d.ts.map +1 -0
- package/dist/client/router-lifecycle.d.ts +55 -0
- package/dist/client/router-lifecycle.d.ts.map +1 -0
- package/dist/client/router-pipeline.d.ts +84 -0
- package/dist/client/router-pipeline.d.ts.map +1 -0
- package/dist/client/router-ref.d.ts +1 -1
- package/dist/client/router-ref.d.ts.map +1 -1
- package/dist/client/router-skew.d.ts +21 -0
- package/dist/client/router-skew.d.ts.map +1 -0
- package/dist/client/router-types.d.ts +207 -0
- package/dist/client/router-types.d.ts.map +1 -0
- package/dist/client/router.d.ts +1 -182
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +47 -26
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +87 -34
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/ssr-data.d.ts +6 -0
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-client.d.ts +69 -0
- package/dist/client/stale-client.d.ts.map +1 -0
- package/dist/client/state.d.ts +10 -1
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +2 -1
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/unload-guard.d.ts +5 -0
- package/dist/client/unload-guard.d.ts.map +1 -1
- package/dist/client/use-cookie.d.ts.map +1 -1
- package/dist/client/use-query-states.d.ts +9 -3
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +1 -1
- package/dist/client/use-segment-params.d.ts +18 -8
- package/dist/client/use-segment-params.d.ts.map +1 -1
- package/dist/codec.js +1 -1
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.js +5 -5
- package/dist/cookies/index.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1009 -759
- package/dist/index.js.map +1 -1
- package/dist/params/index.js +1 -1
- package/dist/plugin-context.d.ts +46 -0
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/request-dep/analysis.d.ts +106 -0
- package/dist/plugins/request-dep/analysis.d.ts.map +1 -0
- package/dist/plugins/request-dep/index.d.ts +75 -0
- package/dist/plugins/request-dep/index.d.ts.map +1 -0
- package/dist/plugins/request-dep/origin.d.ts +61 -0
- package/dist/plugins/request-dep/origin.d.ts.map +1 -0
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +160 -8
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +3 -44
- package/dist/routing/codegen-shared.d.ts.map +1 -1
- package/dist/routing/codegen-types.d.ts +28 -31
- package/dist/routing/codegen-types.d.ts.map +1 -1
- package/dist/routing/codegen-write.d.ts +51 -0
- package/dist/routing/codegen-write.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/collision-probe.d.ts +104 -0
- package/dist/routing/collision-probe.d.ts.map +1 -0
- package/dist/routing/collision-spaces.d.ts +26 -0
- package/dist/routing/collision-spaces.d.ts.map +1 -0
- package/dist/routing/convention-lint.d.ts +18 -4
- package/dist/routing/convention-lint.d.ts.map +1 -1
- package/dist/routing/export-detect.d.ts +16 -0
- package/dist/routing/export-detect.d.ts.map +1 -1
- package/dist/routing/index.js +4 -3
- package/dist/routing/interception.d.ts +235 -6
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/routing/link-codegen.d.ts +19 -4
- package/dist/routing/link-codegen.d.ts.map +1 -1
- package/dist/routing/manifest-codegen.d.ts +1 -7
- package/dist/routing/manifest-codegen.d.ts.map +1 -1
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/segment-classify.d.ts +33 -0
- package/dist/routing/segment-classify.d.ts.map +1 -1
- package/dist/routing/segment-keys.d.ts +95 -0
- package/dist/routing/segment-keys.d.ts.map +1 -0
- package/dist/routing/slot-placement.d.ts +48 -0
- package/dist/routing/slot-placement.d.ts.map +1 -0
- package/dist/routing/types.d.ts +0 -6
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +6 -0
- package/dist/routing/walkers.d.ts.map +1 -1
- package/dist/schema-bridge.d.ts +60 -9
- package/dist/schema-bridge.d.ts.map +1 -1
- package/dist/search-params/define.d.ts +62 -14
- package/dist/search-params/define.d.ts.map +1 -1
- package/dist/search-params/index.d.ts +0 -1
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +221 -10
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/parse-total.d.ts +70 -0
- package/dist/search-params/parse-total.d.ts.map +1 -0
- package/dist/search-params/wrappers.d.ts +26 -3
- package/dist/search-params/wrappers.d.ts.map +1 -1
- package/dist/server/access-gate.d.ts +19 -8
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +6 -3
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +18 -1
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +13 -1
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/chain-url-parts.d.ts +82 -0
- package/dist/server/chain-url-parts.d.ts.map +1 -0
- package/dist/server/children-interception.d.ts +49 -0
- package/dist/server/children-interception.d.ts.map +1 -0
- package/dist/server/compress.d.ts.map +1 -1
- package/dist/server/default-status-page.d.ts +45 -0
- package/dist/server/default-status-page.d.ts.map +1 -0
- package/dist/server/deny-boundary.d.ts +148 -15
- package/dist/server/deny-boundary.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts +15 -4
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +85 -15
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +35 -0
- package/dist/server/head-response.d.ts.map +1 -0
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +3 -1
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +712 -418
- package/dist/server/internal.js.map +1 -1
- package/dist/server/metadata-collector.d.ts +52 -0
- package/dist/server/metadata-collector.d.ts.map +1 -0
- package/dist/server/param-coercion.d.ts +22 -6
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-helpers.d.ts +0 -18
- package/dist/server/pipeline-helpers.d.ts.map +1 -1
- package/dist/server/pipeline-interception.d.ts +59 -9
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +11 -0
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +23 -0
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/publish-params.d.ts +33 -0
- package/dist/server/publish-params.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +48 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +22 -3
- 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 +13 -0
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-cache-key-guard.d.ts +78 -0
- package/dist/server/rsc-cache-key-guard.d.ts.map +1 -0
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +15 -3
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +2 -17
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +0 -1
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +1 -2
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +15 -2
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/skippable-prefix.d.ts +23 -0
- package/dist/server/skippable-prefix.d.ts.map +1 -0
- package/dist/server/slot-interception.d.ts +80 -0
- package/dist/server/slot-interception.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +70 -8
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +17 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +0 -1
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +24 -13
- package/dist/server/ssr-wrappers.d.ts.map +1 -1
- package/dist/server/state-tree-diff.d.ts +6 -27
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/dist/server/static-generator.d.ts +6 -0
- package/dist/server/static-generator.d.ts.map +1 -1
- package/dist/server/static-not-found.d.ts +52 -0
- package/dist/server/static-not-found.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +8 -1
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +28 -36
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/types.d.ts +12 -7
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils/element-type.d.ts +40 -0
- package/dist/server/utils/element-type.d.ts.map +1 -0
- package/dist/shared/als-slots.d.ts +41 -0
- package/dist/shared/als-slots.d.ts.map +1 -0
- package/dist/shared/base-path.d.ts +56 -0
- package/dist/shared/base-path.d.ts.map +1 -0
- package/dist/shared/param-value.d.ts +80 -0
- package/dist/shared/param-value.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +108 -0
- package/dist/shared/payload-root.d.ts.map +1 -0
- package/dist/shared/rsc-cache-key.d.ts +163 -0
- package/dist/shared/rsc-cache-key.d.ts.map +1 -0
- package/dist/shared/rsc-error-envelope.d.ts +25 -0
- package/dist/shared/rsc-error-envelope.d.ts.map +1 -0
- package/dist/shared/rsc-manifest.d.ts +28 -0
- package/dist/shared/rsc-manifest.d.ts.map +1 -0
- package/dist/shared/rsc-media-type.d.ts +40 -0
- package/dist/shared/rsc-media-type.d.ts.map +1 -0
- package/dist/shared/rsc-payload-path.d.ts +42 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -0
- package/dist/shared/segment-info.d.ts +59 -0
- package/dist/shared/segment-info.d.ts.map +1 -0
- package/dist/shared/slot-params.d.ts +51 -0
- package/dist/shared/slot-params.d.ts.map +1 -0
- package/dist/shared/static-platform-files.d.ts +71 -0
- package/dist/shared/static-platform-files.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +1 -1
- package/docs/api/31-api-client.mdx +4 -2
- package/docs/api/33-api-search-params.mdx +38 -16
- package/docs/api/35-api-typescript.mdx +3 -3
- package/docs/api/36-cli.mdx +34 -7
- package/docs/learn/00-introduction.mdx +1 -1
- package/docs/learn/02-pages-and-layouts.mdx +2 -2
- package/docs/learn/05-typed-params.mdx +8 -8
- package/docs/learn/07-typed-routes.mdx +12 -7
- package/docs/learn/11-error-handling.mdx +18 -0
- package/docs/learn/12-client-navigation.mdx +2 -2
- package/docs/learn/14-deploying.mdx +23 -0
- package/docs/more/01-advanced-routing.mdx +173 -3
- package/docs/more/03-coming-from-nextjs.mdx +2 -2
- package/docs/more/04-metadata-and-fonts.mdx +1 -1
- package/docs/more/50-ai-agent-instructions.mdx +6 -4
- package/package.json +9 -6
- package/src/adapters/build-output-helper.ts +116 -3
- package/src/adapters/cloudflare.ts +90 -12
- package/src/adapters/compress-module.ts +79 -1
- package/src/adapters/fs-identity.ts +156 -0
- package/src/adapters/nitro.ts +6 -6
- package/src/adapters/shared.ts +196 -21
- package/src/adapters/types.ts +13 -1
- package/src/cache/fast-hash.ts +5 -0
- package/src/cli-check.ts +458 -0
- package/src/cli.ts +59 -24
- package/src/client/browser-entry/action-dispatch.ts +11 -5
- package/src/client/browser-entry/hydrate.ts +40 -29
- package/src/client/browser-entry/index.ts +15 -6
- package/src/client/browser-entry/post-hydration.ts +10 -9
- package/src/client/browser-entry/router-init.ts +104 -48
- package/src/client/browser-entry/rsc-stream.ts +11 -2
- package/src/client/error-boundary.tsx +85 -16
- package/src/client/history.ts +13 -6
- package/src/client/index.ts +14 -3
- package/src/client/internal.ts +4 -3
- package/src/client/link.tsx +120 -72
- package/src/client/navigation-api.ts +3 -3
- package/src/client/navigation-commit.ts +197 -0
- package/src/client/navigation-context.ts +40 -67
- package/src/client/navigation-root.tsx +326 -101
- package/src/client/params-context.ts +192 -0
- package/src/client/router-effects.ts +231 -0
- package/src/client/router-lifecycle.ts +288 -0
- package/src/client/router-pipeline.ts +393 -0
- package/src/client/router-ref.ts +1 -1
- package/src/client/router-skew.ts +30 -0
- package/src/client/router-types.ts +230 -0
- package/src/client/router.ts +243 -707
- package/src/client/rsc-fetch.ts +183 -106
- package/src/client/segment-cache.ts +129 -44
- package/src/client/ssr-data.ts +6 -0
- package/src/client/stale-client.ts +191 -0
- package/src/client/state.ts +14 -1
- package/src/client/top-loader.tsx +2 -1
- package/src/client/unload-guard.ts +34 -2
- package/src/client/use-cookie.ts +9 -2
- package/src/client/use-query-states.ts +102 -39
- package/src/client/use-router.ts +1 -1
- package/src/client/use-segment-params.ts +41 -18
- package/src/cookies/define-cookie.ts +6 -1
- package/src/index.ts +25 -4
- package/src/plugin-context.ts +58 -0
- package/src/plugins/adapter-build.ts +4 -0
- package/src/plugins/build-manifest.ts +34 -13
- package/src/plugins/entries.ts +4 -0
- package/src/plugins/fonts.ts +11 -8
- package/src/plugins/request-dep/analysis.ts +447 -0
- package/src/plugins/request-dep/index.ts +376 -0
- package/src/plugins/request-dep/origin.ts +310 -0
- package/src/plugins/routing.ts +97 -102
- package/src/plugins/shims.ts +0 -1
- package/src/plugins/static-build.ts +391 -95
- package/src/routing/codegen-shared.ts +3 -79
- package/src/routing/codegen-types.ts +28 -31
- package/src/routing/codegen-write.ts +139 -0
- package/src/routing/codegen.ts +86 -172
- package/src/routing/collision-probe.ts +438 -0
- package/src/routing/collision-spaces.ts +281 -0
- package/src/routing/convention-lint.ts +139 -40
- package/src/routing/export-detect.ts +151 -7
- package/src/routing/interception.ts +896 -50
- package/src/routing/link-codegen.ts +32 -65
- package/src/routing/manifest-codegen.ts +6 -62
- package/src/routing/scanner.ts +117 -92
- package/src/routing/segment-classify.ts +57 -0
- package/src/routing/segment-keys.ts +146 -0
- package/src/routing/slot-placement.ts +97 -0
- package/src/routing/types.ts +0 -6
- package/src/routing/walkers.ts +8 -0
- package/src/schema-bridge.ts +180 -58
- package/src/search-params/define.ts +108 -66
- package/src/search-params/index.ts +0 -1
- package/src/search-params/parse-total.ts +78 -0
- package/src/search-params/wrappers.ts +60 -11
- package/src/server/access-gate.tsx +60 -40
- package/src/server/action-handler.ts +4 -5
- package/src/server/actions.ts +6 -3
- package/src/server/als-registry.ts +18 -1
- package/src/server/build-manifest.ts +14 -1
- package/src/server/chain-url-parts.ts +163 -0
- package/src/server/children-interception.ts +115 -0
- package/src/server/compress.ts +9 -1
- package/src/server/default-status-page.ts +127 -0
- package/src/server/deny-boundary.ts +269 -41
- package/src/server/deny-renderer.ts +111 -39
- package/src/server/error-boundary-wrapper.ts +166 -79
- package/src/server/head-response.ts +54 -0
- package/src/server/index.ts +1 -3
- package/src/server/internal.ts +2 -2
- package/src/server/metadata-collector.ts +115 -0
- package/src/server/param-coercion.ts +51 -69
- package/src/server/pipeline-helpers.ts +2 -47
- package/src/server/pipeline-interception.ts +81 -32
- package/src/server/pipeline-outcome.ts +4 -5
- package/src/server/pipeline-phases.ts +77 -25
- package/src/server/pipeline.ts +57 -10
- package/src/server/prebuilt-runtime.ts +4 -4
- package/src/server/primitives.ts +25 -0
- package/src/server/publish-params.ts +42 -0
- package/src/server/request-context.ts +97 -18
- package/src/server/route-element-builder.ts +241 -253
- package/src/server/route-handler.ts +8 -8
- package/src/server/route-matcher.ts +21 -9
- package/src/server/rsc-cache-key-guard.ts +164 -0
- package/src/server/rsc-entry/api-handler.ts +6 -8
- package/src/server/rsc-entry/deny-fallback.ts +3 -2
- package/src/server/rsc-entry/error-renderer.ts +94 -35
- package/src/server/rsc-entry/helpers.ts +33 -28
- package/src/server/rsc-entry/index.ts +36 -33
- package/src/server/rsc-entry/render-route.ts +18 -10
- package/src/server/rsc-entry/revalidate-renderer.ts +3 -2
- package/src/server/rsc-entry/rsc-payload.ts +113 -40
- package/src/server/rsc-entry/rsc-stream.ts +29 -5
- package/src/server/rsc-entry/ssr-renderer.ts +38 -22
- package/src/server/skippable-prefix.ts +92 -0
- package/src/server/slot-interception.ts +168 -0
- package/src/server/slot-resolver.ts +263 -158
- package/src/server/ssr-bridge-types.ts +18 -0
- package/src/server/ssr-entry.ts +20 -10
- package/src/server/ssr-wrappers.tsx +33 -32
- package/src/server/state-tree-diff.ts +14 -55
- package/src/server/static-generator.ts +68 -29
- package/src/server/static-not-found.ts +134 -0
- package/src/server/status-code-resolver.ts +28 -11
- package/src/server/tree-builder.ts +35 -218
- package/src/server/types.ts +12 -7
- package/src/server/utils/element-type.ts +72 -0
- package/src/shared/als-slots.ts +72 -0
- package/src/shared/base-path.ts +80 -0
- package/src/shared/param-value.ts +244 -0
- package/src/shared/payload-root.ts +151 -0
- package/src/shared/rsc-cache-key.ts +269 -0
- package/src/shared/rsc-error-envelope.ts +31 -0
- package/src/shared/rsc-manifest.ts +29 -0
- package/src/shared/rsc-media-type.ts +43 -0
- package/src/shared/rsc-payload-path.ts +45 -0
- package/src/shared/segment-info.ts +60 -0
- package/src/shared/slot-params.ts +111 -0
- package/src/shared/static-platform-files.ts +75 -0
- package/dist/_chunks/build-output-helper-DOGYFb_X.js +0 -196
- package/dist/_chunks/build-output-helper-DOGYFb_X.js.map +0 -1
- package/dist/_chunks/cache-api-B-lhk9p4.js.map +0 -1
- package/dist/_chunks/canonicalize-DQHyFClh.js.map +0 -1
- package/dist/_chunks/cli-schema-sync-BTWEKJXo.js +0 -668
- package/dist/_chunks/cli-schema-sync-BTWEKJXo.js.map +0 -1
- package/dist/_chunks/define-COtkxMRT.js +0 -191
- package/dist/_chunks/define-COtkxMRT.js.map +0 -1
- package/dist/_chunks/define-c4au4I9R.js +0 -82
- package/dist/_chunks/define-c4au4I9R.js.map +0 -1
- package/dist/_chunks/fast-hash-D6hIVt1Y.js.map +0 -1
- package/dist/_chunks/logger-AWfuX-KJ.js.map +0 -1
- package/dist/_chunks/navigation-root-bUDZLw74.js +0 -124
- package/dist/_chunks/navigation-root-bUDZLw74.js.map +0 -1
- package/dist/_chunks/plugin-context---kTF5v8.js.map +0 -1
- package/dist/_chunks/registry-DbJPKoBp.js +0 -20
- package/dist/_chunks/registry-DbJPKoBp.js.map +0 -1
- package/dist/_chunks/router-ref-CtmF-aPv.js.map +0 -1
- package/dist/_chunks/schema-bridge-DT_Tn0Xf.js +0 -119
- package/dist/_chunks/schema-bridge-DT_Tn0Xf.js.map +0 -1
- package/dist/_chunks/segment-classify-Byy425ng.js.map +0 -1
- package/dist/_chunks/segment-context-ZDnXDkbz.js +0 -34
- package/dist/_chunks/segment-context-ZDnXDkbz.js.map +0 -1
- package/dist/_chunks/ssr-data-BOWsq18U.js.map +0 -1
- package/dist/_chunks/use-query-states-DFvWd-EA.js.map +0 -1
- package/dist/_chunks/use-segment-params-D1CzlgBo.js +0 -151
- package/dist/_chunks/use-segment-params-D1CzlgBo.js.map +0 -1
- package/dist/_chunks/walkers-_6zKFlch.js +0 -1002
- package/dist/_chunks/walkers-_6zKFlch.js.map +0 -1
- package/dist/client/error-boundary.js.map +0 -1
- package/dist/plugins/request-dep.d.ts +0 -32
- package/dist/plugins/request-dep.d.ts.map +0 -1
- package/dist/search-params/registry.d.ts +0 -20
- package/dist/search-params/registry.d.ts.map +0 -1
- package/dist/segment-params/define.d.ts +0 -89
- package/dist/segment-params/define.d.ts.map +0 -1
- package/dist/segment-params/index.d.ts +0 -3
- package/dist/segment-params/index.d.ts.map +0 -1
- package/dist/segment-params/index.js +0 -2
- package/src/plugins/request-dep.ts +0 -499
- package/src/search-params/registry.ts +0 -31
- package/src/segment-params/define.ts +0 -249
- package/src/segment-params/index.ts +0 -9
package/src/client/rsc-fetch.ts
CHANGED
|
@@ -11,14 +11,41 @@
|
|
|
11
11
|
* See design/19-client-navigation.md §"RSC Payload Handling"
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import
|
|
15
|
-
|
|
14
|
+
import {
|
|
15
|
+
rscCacheKey,
|
|
16
|
+
recordLookup,
|
|
17
|
+
randomRscCacheKey,
|
|
18
|
+
RSC_KEY_PARAM,
|
|
19
|
+
} from '../shared/rsc-cache-key.js';
|
|
20
|
+
import type { RscManifest, RscManifestEntry } from '../shared/rsc-manifest.js';
|
|
21
|
+
import {
|
|
22
|
+
splitPayloadRoot,
|
|
23
|
+
readPublishedParams,
|
|
24
|
+
type PublishedParams,
|
|
25
|
+
} from '../shared/payload-root.js';
|
|
26
|
+
import { normalizeBasePath, stripBasePath, withBasePath } from '../shared/base-path.js';
|
|
27
|
+
import { rscPayloadPath } from '../shared/rsc-payload-path.js';
|
|
28
|
+
import type { SegmentInfo, StateTree } from '../shared/segment-info.js';
|
|
29
|
+
import { TIMBER_ERROR_HEADER } from '../shared/rsc-error-envelope.js';
|
|
30
|
+
import { RSC_CONTENT_TYPE } from '../shared/rsc-media-type.js';
|
|
31
|
+
import type { RouterDeps } from './router-types.js';
|
|
16
32
|
|
|
17
33
|
// ─── Types ───────────────────────────────────────────────────────
|
|
18
34
|
|
|
19
35
|
/** Result of fetching an RSC payload — includes segment metadata. */
|
|
20
36
|
export interface FetchResult {
|
|
37
|
+
/** The renderable tree, split off the payload root. */
|
|
21
38
|
payload: unknown;
|
|
39
|
+
/**
|
|
40
|
+
* The params the same payload published beside that tree.
|
|
41
|
+
*
|
|
42
|
+
* Not a separate channel: both fields come out of one `splitPayloadRoot`
|
|
43
|
+
* call on one decoded root, so a response cannot deliver a tree and another
|
|
44
|
+
* route's params. They used to arrive on their own header, which is how a
|
|
45
|
+
* navigation could render one route and publish another's (TIM-1285,
|
|
46
|
+
* TIM-1294).
|
|
47
|
+
*/
|
|
48
|
+
params: PublishedParams | Promise<PublishedParams>;
|
|
22
49
|
/**
|
|
23
50
|
* Promise that settles when the RSC decode completes or fails.
|
|
24
51
|
* The payload thenable is NOT awaited before returning (for streaming),
|
|
@@ -29,44 +56,55 @@ export interface FetchResult {
|
|
|
29
56
|
decodePromise: Promise<void> | null;
|
|
30
57
|
/** Segment metadata from X-Timber-Segments header for populating the segment cache. */
|
|
31
58
|
segmentInfo: SegmentInfo[] | null;
|
|
32
|
-
/** Route params from X-Timber-Params header for populating useSegmentParams(). */
|
|
33
|
-
params: Record<string, string | string[]> | null;
|
|
34
59
|
/** Segment paths that were skipped by the server (for client-side merging). */
|
|
35
60
|
skippedSegments: string[] | null;
|
|
61
|
+
/**
|
|
62
|
+
* HTTP status of the navigation response.
|
|
63
|
+
*
|
|
64
|
+
* Read at the commit site to decide whether the tree this payload produced
|
|
65
|
+
* is one worth caching. A deny page replaced a subtree, so `segmentInfo`
|
|
66
|
+
* describes more than actually mounted — but it cannot simply be emptied,
|
|
67
|
+
* because the merge point is chosen out of it. See TIM-1356.
|
|
68
|
+
*/
|
|
69
|
+
status: number;
|
|
36
70
|
}
|
|
37
71
|
|
|
38
|
-
// ─── Constants ───────────────────────────────────────────────────
|
|
39
|
-
|
|
40
|
-
export const RSC_CONTENT_TYPE = 'text/x-component';
|
|
41
|
-
|
|
42
72
|
// ─── URL Helpers ─────────────────────────────────────────────────
|
|
43
73
|
|
|
44
74
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
75
|
+
* Append a `_rsc=<key>` query parameter to the URL (TIM-1268).
|
|
76
|
+
*
|
|
77
|
+
* The key is a deterministic hash of the RSC request headers, so identical
|
|
78
|
+
* requests share a URL and the payload becomes cacheable. It also keeps the
|
|
79
|
+
* document and the payload on different URLs, so a shared cache cannot
|
|
80
|
+
* return HTML for an RSC request (or vice versa) even where `Vary` is
|
|
81
|
+
* opt-in configuration rather than default behaviour — Cloudflare and
|
|
82
|
+
* CloudFront both. See GHSA-wfc6-r584-vfw7, design/13-security.md.
|
|
83
|
+
*
|
|
84
|
+
* The origin recomputes this key from the received headers and refuses to
|
|
85
|
+
* let a mismatched response be shared-cached, so a caller cannot claim
|
|
86
|
+
* another client's key while sending its own headers.
|
|
87
|
+
*
|
|
88
|
+
* Falls back to a random value when no key can be derived — `crypto.subtle`
|
|
89
|
+
* is absent in non-secure browsing contexts (plain `http://` on a LAN
|
|
90
|
+
* address). Dropping the parameter instead would put the payload back on
|
|
91
|
+
* the document URL, where a query-keyed cache that ignores `Vary` could
|
|
92
|
+
* store a Flight response under `/about` and serve it to an HTML
|
|
93
|
+
* navigation. The random parameter this feature replaced did separate those
|
|
94
|
+
* representations, and the fallback must not be worse than what it
|
|
95
|
+
* replaced. The origin cannot verify a random key, so it refuses to
|
|
96
|
+
* share-cache the response — which is exactly the old behaviour, where a
|
|
97
|
+
* unique URL was never a cache hit anyway.
|
|
61
98
|
*
|
|
62
99
|
* Strips any #fragment before appending — fragments are client-only and
|
|
63
100
|
* fetch() discards them, so _rsc would land inside the hash and be lost.
|
|
64
101
|
*/
|
|
65
|
-
function appendRscParam(url: string): string {
|
|
102
|
+
async function appendRscParam(url: string, headers: Record<string, string>): Promise<string> {
|
|
66
103
|
const hashIndex = url.indexOf('#');
|
|
67
104
|
const urlWithoutHash = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
105
|
+
const key = (await rscCacheKey(recordLookup(headers))) ?? randomRscCacheKey();
|
|
68
106
|
const separator = urlWithoutHash.includes('?') ? '&' : '?';
|
|
69
|
-
return `${urlWithoutHash}${separator}
|
|
107
|
+
return `${urlWithoutHash}${separator}${RSC_KEY_PARAM}=${key}`;
|
|
70
108
|
}
|
|
71
109
|
|
|
72
110
|
// ─── Deployment ID ───────────────────────────────────────────────
|
|
@@ -88,6 +126,30 @@ export function getClientDeploymentId(): string | null {
|
|
|
88
126
|
return clientDeploymentId;
|
|
89
127
|
}
|
|
90
128
|
|
|
129
|
+
// ─── Base Path ───────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The deployment base path (Vite's resolved `base`), normalized.
|
|
133
|
+
* Set at bootstrap from `virtual:timber-config`; `'/'` unless the app is
|
|
134
|
+
* deployed under a sub-path. See design/11-platform.md, TIM-1261.
|
|
135
|
+
*
|
|
136
|
+
* **The base is applied in exactly one place: at fetch time**
|
|
137
|
+
* (`toStaticRscUrl`). The static build writes the RSC manifest with
|
|
138
|
+
* root-relative keys *and* root-relative URLs, so the generated site stays
|
|
139
|
+
* relocatable and there is no second copy of the base to drift from this one.
|
|
140
|
+
*/
|
|
141
|
+
let basePath = '/';
|
|
142
|
+
|
|
143
|
+
/** Set the deployment base path. Called once at bootstrap. */
|
|
144
|
+
export function setBasePath(base: string | undefined): void {
|
|
145
|
+
basePath = normalizeBasePath(base);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Get the normalized deployment base path. @internal Exported for testing. */
|
|
149
|
+
export function getBasePath(): string {
|
|
150
|
+
return basePath;
|
|
151
|
+
}
|
|
152
|
+
|
|
91
153
|
// ─── Static Mode ────────────────────────────────────────────────
|
|
92
154
|
|
|
93
155
|
/**
|
|
@@ -107,20 +169,10 @@ export function isStaticMode(): boolean {
|
|
|
107
169
|
}
|
|
108
170
|
|
|
109
171
|
/**
|
|
110
|
-
* RSC manifest
|
|
111
|
-
*
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
url: string;
|
|
115
|
-
params?: Record<string, string | string[]>;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
type RscManifest = Record<string, RscManifestEntry>;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* RSC manifest mapping unhashed → hashed URLs + params. Populated from
|
|
122
|
-
* `window.__TIMBER_RSC_MANIFEST__` (injected into HTML during
|
|
123
|
-
* static generation). See TIM-1254, TIM-1255.
|
|
172
|
+
* RSC manifest mapping unhashed → content-hashed `.rsc` URLs. Populated from
|
|
173
|
+
* `window.__TIMBER_RSC_MANIFEST__` (injected into HTML during static
|
|
174
|
+
* generation). Shape shared with the static build that writes it — see
|
|
175
|
+
* `shared/rsc-manifest.ts`. See TIM-1254.
|
|
124
176
|
*/
|
|
125
177
|
let rscManifest: RscManifest | null = null;
|
|
126
178
|
|
|
@@ -137,24 +189,45 @@ export function setRscManifest(manifest: RscManifest | null): void {
|
|
|
137
189
|
rscManifest = manifest;
|
|
138
190
|
}
|
|
139
191
|
|
|
192
|
+
/** A resolved static payload target: the URL to fetch, and how it was resolved. */
|
|
193
|
+
interface StaticRscTarget {
|
|
194
|
+
/** Fetchable URL — base-prefixed. */
|
|
195
|
+
url: string;
|
|
196
|
+
/**
|
|
197
|
+
* True when the RSC manifest supplied a content-hashed filename. The hash
|
|
198
|
+
* guarantees freshness, so no `_rsc` cache key is appended (TIM-1254).
|
|
199
|
+
*/
|
|
200
|
+
hashed: boolean;
|
|
201
|
+
}
|
|
202
|
+
|
|
140
203
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
204
|
+
* Resolve a route URL to the `_rsc/*.rsc` file to fetch. The naming rule is
|
|
205
|
+
* `shared/rsc-payload-path.ts`, shared with the build that writes the files.
|
|
143
206
|
*
|
|
144
207
|
* When an RSC manifest is available (hashed filenames from TIM-1254),
|
|
145
208
|
* the manifest is consulted to resolve to the hashed path.
|
|
146
209
|
*
|
|
147
210
|
* / → /_rsc/index.rsc (or /_rsc/index-B7YxEKdN.rsc with manifest)
|
|
148
|
-
* /about → /_rsc/about.rsc (or /_rsc/about-C8ZzFLfO.rsc
|
|
149
|
-
* /blog/hello → /_rsc/blog/hello.rsc
|
|
211
|
+
* /about → /_rsc/about/index.rsc (or /_rsc/about/index-C8ZzFLfO.rsc)
|
|
212
|
+
* /blog/hello → /_rsc/blog/hello/index.rsc
|
|
213
|
+
*
|
|
214
|
+
* The manifest is written and read in route space (no base prefix), so the
|
|
215
|
+
* base is applied here — once, on the way out. See client/base-path.ts.
|
|
150
216
|
*/
|
|
151
|
-
function toStaticRscUrl(url: string):
|
|
217
|
+
function toStaticRscUrl(url: string): StaticRscTarget {
|
|
152
218
|
const unhashed = toUnhashedRscUrl(url);
|
|
153
|
-
|
|
219
|
+
const hashedUrl = manifestLookup(unhashed);
|
|
220
|
+
return { url: withBasePath(basePath, hashedUrl ?? unhashed), hashed: hashedUrl !== null };
|
|
154
221
|
}
|
|
155
222
|
|
|
156
223
|
/**
|
|
157
|
-
* Compute the unhashed _rsc/*.rsc
|
|
224
|
+
* Compute the unhashed `_rsc/*.rsc` path for a route URL.
|
|
225
|
+
*
|
|
226
|
+
* Returns a **route-space** path: the deployment base is stripped from the
|
|
227
|
+
* incoming URL and is NOT re-applied, because this value doubles as the RSC
|
|
228
|
+
* manifest key, and the manifest is base-less. `toStaticRscUrl` applies the
|
|
229
|
+
* base to whatever is actually fetched.
|
|
230
|
+
*
|
|
158
231
|
* @internal Exported for testing.
|
|
159
232
|
*/
|
|
160
233
|
export function toUnhashedRscUrl(url: string): string {
|
|
@@ -163,13 +236,12 @@ export function toUnhashedRscUrl(url: string): string {
|
|
|
163
236
|
const hashEnd = hashIndex === -1 ? url.length : hashIndex;
|
|
164
237
|
const queryEnd = queryIndex === -1 ? url.length : queryIndex;
|
|
165
238
|
const end = Math.min(hashEnd, queryEnd);
|
|
166
|
-
let pathname = url.slice(0, end);
|
|
239
|
+
let pathname = stripBasePath(basePath, url.slice(0, end));
|
|
167
240
|
// Strip trailing slash (unless root) to match static build output naming
|
|
168
241
|
if (pathname.length > 1 && pathname.endsWith('/')) {
|
|
169
242
|
pathname = pathname.slice(0, -1);
|
|
170
243
|
}
|
|
171
|
-
|
|
172
|
-
return `/_rsc${rscPath}.rsc`;
|
|
244
|
+
return rscPayloadPath(pathname);
|
|
173
245
|
}
|
|
174
246
|
|
|
175
247
|
/**
|
|
@@ -196,13 +268,11 @@ function manifestLookup(key: string): string | null {
|
|
|
196
268
|
return manifestEntry(key)?.url ?? null;
|
|
197
269
|
}
|
|
198
270
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return manifestEntry(key)?.params ?? null;
|
|
205
|
-
}
|
|
271
|
+
// The manifest used to inline each route's params, because a generated
|
|
272
|
+
// `.rsc` file carries no response headers and the header channel therefore
|
|
273
|
+
// did not exist on the static path (TIM-1255, TIM-1285). The `.rsc` file now
|
|
274
|
+
// carries them itself — they are props inside the payload — so the static
|
|
275
|
+
// path needs no special case at all.
|
|
206
276
|
|
|
207
277
|
// ─── Reload Signal ───────────────────────────────────────────────
|
|
208
278
|
|
|
@@ -222,8 +292,19 @@ export function checkReloadSignal(response: Response): boolean {
|
|
|
222
292
|
|
|
223
293
|
// ─── Header Builder ──────────────────────────────────────────────
|
|
224
294
|
|
|
295
|
+
/**
|
|
296
|
+
* Build the headers for an RSC payload request.
|
|
297
|
+
*
|
|
298
|
+
* **Every header added here is hashed into the payload URL** as the `_rsc`
|
|
299
|
+
* cache key (see `rscCacheKey`), and URLs are logged by proxies, CDNs, and
|
|
300
|
+
* origin access logs. So: no credentials, no session identifiers, no
|
|
301
|
+
* user-supplied content. `fnv1aHash` is a cache-key hash, not a KDF — a
|
|
302
|
+
* low-entropy secret would be recoverable from the URL by brute force.
|
|
303
|
+
* Authentication already travels on cookies, which are not part of this
|
|
304
|
+
* object and never enter the key.
|
|
305
|
+
*/
|
|
225
306
|
export function buildRscHeaders(
|
|
226
|
-
stateTree:
|
|
307
|
+
stateTree: StateTree | undefined,
|
|
227
308
|
currentUrl?: string
|
|
228
309
|
): Record<string, string> {
|
|
229
310
|
const headers: Record<string, string> = {
|
|
@@ -301,23 +382,6 @@ export function extractSkippedSegments(response: Response): string[] | null {
|
|
|
301
382
|
}
|
|
302
383
|
}
|
|
303
384
|
|
|
304
|
-
/**
|
|
305
|
-
* Extract route params from the X-Timber-Params response header.
|
|
306
|
-
* Returns null if the header is missing or malformed.
|
|
307
|
-
*
|
|
308
|
-
* Used to populate useSegmentParams() after client-side navigation.
|
|
309
|
-
*/
|
|
310
|
-
export function extractParams(response: Response): Record<string, string | string[]> | null {
|
|
311
|
-
const header = response.headers.get('X-Timber-Params');
|
|
312
|
-
if (!header) return null;
|
|
313
|
-
try {
|
|
314
|
-
return JSON.parse(header);
|
|
315
|
-
} catch {
|
|
316
|
-
warnMalformedHeader('X-Timber-Params', header);
|
|
317
|
-
return null;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
385
|
// ─── Redirect Error ──────────────────────────────────────────────
|
|
322
386
|
|
|
323
387
|
/**
|
|
@@ -388,9 +452,10 @@ export class NonRscResponse extends Error {
|
|
|
388
452
|
* a `done` promise that resolves when the last chunk is read (or
|
|
389
453
|
* rejects if the stream errors).
|
|
390
454
|
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
455
|
+
* createFromFetch's thenable resolves on shell arrival, but callers need to
|
|
456
|
+
* know when the stream is fully decoded: that is what `navigateTransition`'s
|
|
457
|
+
* returned promise means, and what the router's pending store, the Navigation
|
|
458
|
+
* API deferred and `<Link>`'s `isPending` are all timed against.
|
|
394
459
|
*/
|
|
395
460
|
function trackStreamCompletion(body: ReadableStream<Uint8Array>): {
|
|
396
461
|
body: ReadableStream<Uint8Array>;
|
|
@@ -445,13 +510,23 @@ export async function fetchRscPayload(
|
|
|
445
510
|
// In static mode, fetch the pre-generated _rsc/*.rsc file directly
|
|
446
511
|
// instead of the route URL with Accept headers. Static hosts ignore
|
|
447
512
|
// Accept headers, so the route URL would return HTML.
|
|
448
|
-
const
|
|
449
|
-
|
|
513
|
+
const staticTarget = staticMode ? toStaticRscUrl(url) : null;
|
|
514
|
+
const fetchTarget = staticTarget ? staticTarget.url : url;
|
|
515
|
+
// Static hosts resolve neither partial payloads nor intercepting routes,
|
|
516
|
+
// so neither the state tree nor the source URL is sent — and neither may
|
|
517
|
+
// fragment the cache key of a file that does not vary on them.
|
|
518
|
+
const headers = staticMode
|
|
519
|
+
? buildRscHeaders(undefined, undefined)
|
|
520
|
+
: buildRscHeaders(stateTree, currentUrl);
|
|
521
|
+
// Skip the cache key when the manifest supplies a content-hashed
|
|
450
522
|
// URL — the hash itself guarantees freshness, and the param would defeat
|
|
451
523
|
// the immutable cache headers on /_rsc/* (TIM-1254).
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
524
|
+
const rscUrl = staticTarget?.hashed ? fetchTarget : await appendRscParam(fetchTarget, headers);
|
|
525
|
+
// Deriving the cache key is async (SubtleCrypto), so the fetch is no
|
|
526
|
+
// longer issued in the same tick as the call. A navigation superseded
|
|
527
|
+
// during that window would otherwise still hit the network with an
|
|
528
|
+
// already-aborted signal.
|
|
529
|
+
signal?.throwIfAborted();
|
|
455
530
|
if (deps.decodeRsc) {
|
|
456
531
|
// Production path: use createFromFetch for streaming RSC decoding.
|
|
457
532
|
// createFromFetch takes a Promise<Response> and progressively parses
|
|
@@ -461,8 +536,8 @@ export async function fetchRscPayload(
|
|
|
461
536
|
// consumes the body. Reading headers does NOT consume the body stream.
|
|
462
537
|
const fetchPromise = deps.fetch(rscUrl, { headers, redirect: 'manual', signal });
|
|
463
538
|
let segmentInfo: SegmentInfo[] | null = null;
|
|
464
|
-
let params: Record<string, string | string[]> | null = null;
|
|
465
539
|
let skippedSegments: string[] | null = null;
|
|
540
|
+
let status = 200;
|
|
466
541
|
// Track when the full RSC body stream is consumed (not just shell).
|
|
467
542
|
// Initialized to resolved for bodyless responses; overwritten when
|
|
468
543
|
// the response has a body.
|
|
@@ -489,7 +564,7 @@ export async function fetchRscPayload(
|
|
|
489
564
|
// with a JSON body instead of a broken RSC stream for any RenderError
|
|
490
565
|
// (4xx or 5xx). Hard-navigate so the server renders the error page as HTML.
|
|
491
566
|
// See design/10-error-handling.md §"Error Page Rendering for Client Navigation"
|
|
492
|
-
if (response.headers.get(
|
|
567
|
+
if (response.headers.get(TIMBER_ERROR_HEADER) === '1') {
|
|
493
568
|
throw new ServerErrorResponse(response.status, url);
|
|
494
569
|
}
|
|
495
570
|
// Content-Type guard: reject non-RSC responses before createFromFetch
|
|
@@ -517,13 +592,13 @@ export async function fetchRscPayload(
|
|
|
517
592
|
// Metadata (<title>/<meta>/<link>) now rides the RSC Flight payload
|
|
518
593
|
// as React elements — React 19 Float handles them. See TIM-1151.
|
|
519
594
|
segmentInfo = extractSegmentInfo(response);
|
|
520
|
-
params = extractParams(response);
|
|
521
595
|
skippedSegments = extractSkippedSegments(response);
|
|
596
|
+
status = response.status;
|
|
522
597
|
|
|
523
598
|
// Wrap the body to track full stream consumption. createFromFetch's
|
|
524
599
|
// thenable resolves when the root model (shell) arrives, but we need
|
|
525
|
-
// to know when ALL chunks are read
|
|
526
|
-
//
|
|
600
|
+
// to know when ALL chunks are read — that is what the navigation
|
|
601
|
+
// promise resolving means, and what keeps the pending store set.
|
|
527
602
|
if (response.body) {
|
|
528
603
|
const tracked = trackStreamCompletion(response.body);
|
|
529
604
|
streamDone = tracked.done;
|
|
@@ -535,34 +610,39 @@ export async function fetchRscPayload(
|
|
|
535
610
|
}
|
|
536
611
|
return response;
|
|
537
612
|
});
|
|
538
|
-
// Await headers so segmentInfo
|
|
613
|
+
// Await headers so segmentInfo is populated.
|
|
539
614
|
await wrappedPromise;
|
|
540
|
-
// In static mode, params come from the manifest (inlined at build
|
|
541
|
-
// time) since .rsc files have no HTTP headers. TIM-1255.
|
|
542
|
-
if (staticMode && !params) {
|
|
543
|
-
params = manifestParams(url);
|
|
544
|
-
}
|
|
545
615
|
// Start decoding but do NOT await — return the in-progress thenable.
|
|
546
616
|
// React can render a Flight thenable directly: it suspends on unresolved
|
|
547
617
|
// parts and progressively renders as chunks arrive, spreading work across
|
|
548
618
|
// frames instead of blocking the main thread in one burst.
|
|
549
|
-
const
|
|
619
|
+
const root = deps.decodeRsc(wrappedPromise);
|
|
620
|
+
// One split, one root: the tree and the params it was rendered with come
|
|
621
|
+
// apart here and nowhere else, so nothing downstream has to keep them
|
|
622
|
+
// paired by hand.
|
|
623
|
+
const { tree: payload, params } = splitPayloadRoot(root);
|
|
550
624
|
// Combine stream completion with payload error propagation.
|
|
551
|
-
// streamDone
|
|
552
|
-
//
|
|
625
|
+
// streamDone marks the end of the RSC stream, which is what the
|
|
626
|
+
// navigation promise resolves on. payloadError propagates
|
|
553
627
|
// decode failures (stale client references, Flight parse errors)
|
|
554
628
|
// so the router's catch block can trigger recovery (stale reload).
|
|
555
629
|
const payloadError = new Promise<void>((_, reject) => {
|
|
556
|
-
Promise.resolve(
|
|
630
|
+
Promise.resolve(root).then(() => {}, reject);
|
|
557
631
|
});
|
|
558
632
|
payloadError.catch(() => {});
|
|
559
633
|
const decodePromise = Promise.race([streamDone, payloadError]);
|
|
634
|
+
// Mark handled, like payloadError above. The same rejection reaches the
|
|
635
|
+
// router through `payload`, and a navigation that recovers by hard
|
|
636
|
+
// navigating (version skew, non-RSC response) hangs deliberately and never
|
|
637
|
+
// awaits this one — leaving it to surface as an unhandled rejection.
|
|
638
|
+
decodePromise.catch(() => {});
|
|
560
639
|
return {
|
|
561
640
|
payload,
|
|
641
|
+
params,
|
|
562
642
|
decodePromise,
|
|
563
643
|
segmentInfo,
|
|
564
|
-
params,
|
|
565
644
|
skippedSegments,
|
|
645
|
+
status,
|
|
566
646
|
};
|
|
567
647
|
}
|
|
568
648
|
// Test/fallback path: return raw text
|
|
@@ -575,7 +655,7 @@ export async function fetchRscPayload(
|
|
|
575
655
|
}
|
|
576
656
|
}
|
|
577
657
|
// Server error guard (same as production path above).
|
|
578
|
-
if (response.headers.get(
|
|
658
|
+
if (response.headers.get(TIMBER_ERROR_HEADER) === '1') {
|
|
579
659
|
throw new ServerErrorResponse(response.status, url);
|
|
580
660
|
}
|
|
581
661
|
// Content-Type guard (same as production path above). See TIM-1231, TIM-1243, TIM-1247.
|
|
@@ -599,16 +679,13 @@ export async function fetchRscPayload(
|
|
|
599
679
|
throw new NonRscResponse(url);
|
|
600
680
|
}
|
|
601
681
|
}
|
|
602
|
-
|
|
603
|
-
// In static mode, params come from the manifest. TIM-1255.
|
|
604
|
-
if (staticMode && !fallbackParams) {
|
|
605
|
-
fallbackParams = manifestParams(url);
|
|
606
|
-
}
|
|
682
|
+
// Test/fallback path: raw text carries no payload root, so no params.
|
|
607
683
|
return {
|
|
608
684
|
payload: await response.text(),
|
|
685
|
+
params: readPublishedParams(undefined),
|
|
609
686
|
decodePromise: null,
|
|
610
687
|
segmentInfo: extractSegmentInfo(response),
|
|
611
|
-
params: fallbackParams,
|
|
612
688
|
skippedSegments: extractSkippedSegments(response),
|
|
689
|
+
status: response.status,
|
|
613
690
|
};
|
|
614
691
|
}
|