@timber-js/app 0.2.0-alpha.207 → 0.2.0-alpha.209
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-BndF-3Td.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-DwQBrLBz.js → status-page-marker-gaihi0KZ.js} +140 -28
- 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 +20 -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 +95 -108
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +20 -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 +3 -8
- 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/segment-cache.d.ts +44 -4
- package/dist/client/segment-cache.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 +632 -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/react-resolve.d.ts +49 -0
- package/dist/plugins/react-resolve.d.ts.map +1 -0
- 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 +7 -3
- 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 +35 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +41 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +96 -132
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +62 -21
- package/src/client/rsc-fetch.ts +117 -155
- package/src/client/segment-cache.ts +110 -11
- 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 +26 -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/react-resolve.ts +149 -0
- 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-BndF-3Td.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-DwQBrLBz.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
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
import { fetchRscPayload, NonRscResponse } from './rsc-fetch.ts';
|
|
17
17
|
import type { FetchResult } from './rsc-fetch.ts';
|
|
18
|
-
import { readPublishedParams
|
|
19
|
-
import type { PrefetchCache, PrefetchKey
|
|
18
|
+
import { readPublishedParams } from '../shared/payload-root.ts';
|
|
19
|
+
import type { PrefetchCache, PrefetchKey } from './segment-cache.ts';
|
|
20
20
|
import { prefetchScopeOf } from './segment-cache.ts';
|
|
21
21
|
import type { StateTree } from '../shared/segment-info.ts';
|
|
22
22
|
import type { NavigationState } from './navigation-context.ts';
|
|
@@ -24,6 +24,7 @@ import { isPartialNavigation, type NavigationCommitter } from './navigation-comm
|
|
|
24
24
|
import type { RouterDeps } from './router-types.ts';
|
|
25
25
|
import type { CommitOutcome, RenderOwner } from './navigation-transition.ts';
|
|
26
26
|
import { recordSkew } from './router-skew.ts';
|
|
27
|
+
import { parseRouterUrl } from './router-url.ts';
|
|
27
28
|
import { SingleflightTimeoutError } from '../cache/singleflight.ts';
|
|
28
29
|
|
|
29
30
|
/**
|
|
@@ -60,7 +61,7 @@ export interface NavigationFetchOptions {
|
|
|
60
61
|
|
|
61
62
|
export interface NavigationPipelineDeps extends Pick<
|
|
62
63
|
NavigationCommitter,
|
|
63
|
-
'prepareNavigation' | 'currentStateTree'
|
|
64
|
+
'prepareNavigation' | 'currentStateTree' | 'isSegmentReuseSuppressed' | 'restoreSegmentReuse'
|
|
64
65
|
> {
|
|
65
66
|
deps: RouterDeps;
|
|
66
67
|
prefetchCache: PrefetchCache;
|
|
@@ -76,7 +77,7 @@ export interface NavigationPipeline {
|
|
|
76
77
|
url: string,
|
|
77
78
|
options: NavigationFetchOptions
|
|
78
79
|
) => Promise<NavigationPayload>;
|
|
79
|
-
/** Hand a payload to React inside a transition
|
|
80
|
+
/** Hand a payload to React inside a transition. */
|
|
80
81
|
renderViaTransition: (
|
|
81
82
|
url: string,
|
|
82
83
|
owner: RenderOwner,
|
|
@@ -84,15 +85,6 @@ export interface NavigationPipeline {
|
|
|
84
85
|
/** See `NavigationOptions.onCommit`. */
|
|
85
86
|
onCommit?: (outcome: CommitOutcome) => void
|
|
86
87
|
) => Promise<void>;
|
|
87
|
-
/** Render a decoded payload into the DOM if a renderer is available. */
|
|
88
|
-
renderPayload: (
|
|
89
|
-
payload: unknown,
|
|
90
|
-
navState: NavigationState,
|
|
91
|
-
params: ParamsSource,
|
|
92
|
-
commit: () => void
|
|
93
|
-
) => void;
|
|
94
|
-
/** Resolve thenable payloads on the fallback (test) path. */
|
|
95
|
-
resolveForFallback: (payload: unknown) => Promise<unknown>;
|
|
96
88
|
}
|
|
97
89
|
|
|
98
90
|
/**
|
|
@@ -109,7 +101,7 @@ export interface NavigationPipeline {
|
|
|
109
101
|
* both `location.href` and a bare pathname.
|
|
110
102
|
*/
|
|
111
103
|
export function departingPathname(raw: string): string {
|
|
112
|
-
return
|
|
104
|
+
return parseRouterUrl(raw).pathname;
|
|
113
105
|
}
|
|
114
106
|
|
|
115
107
|
/**
|
|
@@ -139,14 +131,14 @@ export function prefetchKeyFor(
|
|
|
139
131
|
* Build a segment updates map for partial navigation. Identifies the
|
|
140
132
|
* first non-skipped segment and maps it to the payload content.
|
|
141
133
|
*/
|
|
142
|
-
function buildSegmentUpdates(result: FetchResult): Map<string, unknown> {
|
|
134
|
+
function buildSegmentUpdates(result: FetchResult, payload: unknown): Map<string, unknown> {
|
|
143
135
|
const skipped = new Set(result.skippedSegments!);
|
|
144
136
|
const segmentInfo = result.segmentInfo;
|
|
145
137
|
const updates = new Map<string, unknown>();
|
|
146
138
|
if (segmentInfo) {
|
|
147
139
|
for (const info of segmentInfo) {
|
|
148
140
|
if (!skipped.has(info.segmentId ?? info.path)) {
|
|
149
|
-
updates.set(info.segmentId ?? info.path,
|
|
141
|
+
updates.set(info.segmentId ?? info.path, payload);
|
|
150
142
|
break;
|
|
151
143
|
}
|
|
152
144
|
}
|
|
@@ -174,54 +166,19 @@ export function createNavigationPipeline({
|
|
|
174
166
|
prefetchCache,
|
|
175
167
|
currentStateTree,
|
|
176
168
|
prepareNavigation,
|
|
169
|
+
isSegmentReuseSuppressed,
|
|
170
|
+
restoreSegmentReuse,
|
|
177
171
|
markHandedOff,
|
|
178
172
|
forgetOlderHandoffs,
|
|
179
173
|
}: NavigationPipelineDeps): NavigationPipeline {
|
|
180
174
|
/**
|
|
181
|
-
*
|
|
182
|
-
* tree is current. The renderer owns that moment (see `RootRenderer`);
|
|
183
|
-
* with no renderer there is no tree to wait for, so it publishes now.
|
|
184
|
-
*/
|
|
185
|
-
function renderPayload(
|
|
186
|
-
payload: unknown,
|
|
187
|
-
navState: NavigationState,
|
|
188
|
-
params: ParamsSource,
|
|
189
|
-
commit: () => void
|
|
190
|
-
): void {
|
|
191
|
-
if (deps.renderRoot) {
|
|
192
|
-
deps.renderRoot(payload, navState, params, commit);
|
|
193
|
-
} else {
|
|
194
|
-
commit();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Resolve thenable payloads in the test/fallback path (no navigateTransition).
|
|
200
|
-
* In production, React handles thenables from createFromFetch directly via
|
|
201
|
-
* Suspense. In tests, renderRoot is a plain mock that expects resolved values.
|
|
202
|
-
*/
|
|
203
|
-
async function resolveForFallback(payload: unknown): Promise<unknown> {
|
|
204
|
-
if (
|
|
205
|
-
!deps.navigateTransition &&
|
|
206
|
-
payload != null &&
|
|
207
|
-
typeof payload === 'object' &&
|
|
208
|
-
'then' in payload
|
|
209
|
-
) {
|
|
210
|
-
return await (payload as PromiseLike<unknown>);
|
|
211
|
-
}
|
|
212
|
-
return payload;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Render a payload via navigateTransition (production) or renderRoot (tests).
|
|
217
|
-
* The perform callback should fetch data, prepare the commit, and return the
|
|
175
|
+
* Hand a payload to React via navigateTransition. The perform callback should fetch data, prepare the commit, and return the
|
|
218
176
|
* FetchResult plus the NavigationState and the commit thunk.
|
|
219
177
|
*
|
|
220
178
|
* The thunk is handed *through* to NavigationRoot rather than called here:
|
|
221
|
-
* state management (
|
|
179
|
+
* state management (segment cache, history stack, address bar) has to happen on
|
|
222
180
|
* the far side of the supersession check, which only NavigationRoot can
|
|
223
|
-
* make (TIM-1301).
|
|
224
|
-
* superseded by, so it commits directly.
|
|
181
|
+
* make (TIM-1301).
|
|
225
182
|
*/
|
|
226
183
|
async function renderViaTransition(
|
|
227
184
|
url: string,
|
|
@@ -243,84 +200,70 @@ export function createNavigationPipeline({
|
|
|
243
200
|
commit();
|
|
244
201
|
};
|
|
245
202
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
203
|
+
await deps.navigateTransition(
|
|
204
|
+
url,
|
|
205
|
+
owner,
|
|
206
|
+
async (wrapPayload) => {
|
|
207
|
+
const result = await perform();
|
|
208
|
+
// Await the payload's *root row* — the same thing React would suspend
|
|
209
|
+
// on to render the tree, and the first thing Flight emits. The
|
|
210
|
+
// previous UI stays on screen while this resolves: nothing has been
|
|
211
|
+
// handed to React yet, and when it is, NavigationRoot hands it over
|
|
212
|
+
// inside a transition so a tree that is still streaming does not
|
|
213
|
+
// displace the departing page (TIM-1306).
|
|
214
|
+
//
|
|
215
|
+
// Reading them here rather than with `use()` above the tree is what
|
|
216
|
+
// keeps a decode failure contained: `result.params` never rejects, so
|
|
217
|
+
// it can never take down the provider above every error boundary
|
|
218
|
+
// (TIM-1297). A failure after the root row reaches React through the
|
|
219
|
+
// tree, inside whatever boundary the app put around it.
|
|
220
|
+
const params = await result.params;
|
|
221
|
+
// And the tree itself — settled by the same root row, so this adds no
|
|
222
|
+
// wait, but it is the half that *rejects*: a root row that fails to
|
|
223
|
+
// decode fails this navigation here, before anything is wrapped or
|
|
224
|
+
// handed over, and the router takes its recovery path (TIM-1541).
|
|
225
|
+
// This used to happen by accident — the payload went through an
|
|
226
|
+
// `async` identity helper whose return adopted the thenable — and
|
|
227
|
+
// only on the paths that called it.
|
|
228
|
+
const payload = await result.payload;
|
|
264
229
|
|
|
265
|
-
|
|
266
|
-
|
|
230
|
+
if (isPartialNavigation(result.skippedSegments)) {
|
|
231
|
+
const segmentUpdates = buildSegmentUpdates(result, payload);
|
|
267
232
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
handOff();
|
|
279
|
-
return {
|
|
280
|
-
element,
|
|
281
|
-
decodePromise: observeSkew(result.decodePromise),
|
|
282
|
-
commit: commitAndForget(result.commit),
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Full navigation — empty updates, render the new tree.
|
|
287
|
-
const element = wrapPayload(result.payload, result.navState, params);
|
|
233
|
+
// Re-wrap the CURRENT element with new context values.
|
|
234
|
+
// SegmentOutlets read updates from SegmentUpdateContext;
|
|
235
|
+
// NavigationProvider gets the new pathname; the params published
|
|
236
|
+
// above the retained tree are the *incoming* route's.
|
|
237
|
+
const element = wrapPayload(
|
|
238
|
+
deps._getCurrentPayload?.() ?? payload,
|
|
239
|
+
result.navState,
|
|
240
|
+
params,
|
|
241
|
+
segmentUpdates
|
|
242
|
+
);
|
|
288
243
|
handOff();
|
|
289
244
|
return {
|
|
290
245
|
element,
|
|
291
246
|
decodePromise: observeSkew(result.decodePromise),
|
|
292
247
|
commit: commitAndForget(result.commit),
|
|
293
248
|
};
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const commit = commitAndForget(result.commit);
|
|
308
|
-
if (isPartialNavigation(result.skippedSegments)) {
|
|
309
|
-
commit();
|
|
310
|
-
} else {
|
|
311
|
-
renderPayload(result.payload, result.navState, await result.params, commit);
|
|
312
|
-
}
|
|
313
|
-
} catch (error) {
|
|
314
|
-
fallbackOutcome = 'failed';
|
|
315
|
-
throw error;
|
|
316
|
-
} finally {
|
|
317
|
-
onCommit?.(fallbackOutcome);
|
|
318
|
-
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Full navigation — empty updates, render the new tree.
|
|
252
|
+
const element = wrapPayload(payload, result.navState, params);
|
|
253
|
+
handOff();
|
|
254
|
+
return {
|
|
255
|
+
element,
|
|
256
|
+
decodePromise: observeSkew(result.decodePromise),
|
|
257
|
+
commit: commitAndForget(result.commit),
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
onCommit
|
|
261
|
+
);
|
|
319
262
|
}
|
|
320
263
|
|
|
321
264
|
/**
|
|
322
|
-
*
|
|
323
|
-
*
|
|
265
|
+
* Fetch (or take from the prefetch cache) a navigation's payload and
|
|
266
|
+
* prepare — without publishing — the commit that makes it current.
|
|
324
267
|
*/
|
|
325
268
|
async function performNavigationFetch(
|
|
326
269
|
url: string,
|
|
@@ -339,6 +282,11 @@ export function createNavigationPipeline({
|
|
|
339
282
|
// `currentUrl` is read back off the key rather than computed beside it, so
|
|
340
283
|
// the pathname sent as X-Timber-URL is the one the lookup used.
|
|
341
284
|
const stateTree = currentStateTree();
|
|
285
|
+
// Capture whether reuse is suppressed at the time we build the state
|
|
286
|
+
// tree. If so, segments/slots are empty and the server will send a
|
|
287
|
+
// full render. We restore reuse after the response is processed so
|
|
288
|
+
// only navigations that fetched with suppression can lift it (TIM-1466).
|
|
289
|
+
let reuseSuppressedAtFetch = isSegmentReuseSuppressed();
|
|
342
290
|
const cacheKey = prefetchKeyFor(url, options.departingUrl ?? deps.getCurrentUrl(), stateTree);
|
|
343
291
|
const currentUrl = cacheKey.from;
|
|
344
292
|
|
|
@@ -381,11 +329,16 @@ export function createNavigationPipeline({
|
|
|
381
329
|
// Capture the eviction generation before awaiting the flight.
|
|
382
330
|
// If an action evicts caches while we wait, the result predates
|
|
383
331
|
// the mutation and must be discarded (TIM-1476, codex on #1131).
|
|
332
|
+
// Also check the flight's own starting gen: if the flight started
|
|
333
|
+
// before a per-URL invalidation (TIM-1464), a joiner that arrived
|
|
334
|
+
// after the bump would see genBefore === genAfter but the flight
|
|
335
|
+
// still predates the invalidation.
|
|
384
336
|
const genBefore = prefetchCache.getEvictionGen();
|
|
385
337
|
try {
|
|
386
338
|
const outcome = await raceAbort(inflight, options.signal);
|
|
387
|
-
if (prefetchCache.getEvictionGen() !== genBefore) {
|
|
388
|
-
// Eviction happened while we waited
|
|
339
|
+
if (prefetchCache.getEvictionGen() !== genBefore || outcome.startGen !== genBefore) {
|
|
340
|
+
// Eviction happened while we waited, or the flight predates
|
|
341
|
+
// an invalidation we arrived after — discard stale result,
|
|
389
342
|
// fall through to a fresh fetch below.
|
|
390
343
|
} else if (outcome.kind === 'non-route') {
|
|
391
344
|
throw new NonRscResponse(url);
|
|
@@ -422,7 +375,13 @@ export function createNavigationPipeline({
|
|
|
422
375
|
// No in-flight hover prefetch, or the joined flight failed — fetch
|
|
423
376
|
// directly with the navigation's signal so superseded navigations
|
|
424
377
|
// abort immediately.
|
|
425
|
-
|
|
378
|
+
// Resample both the state tree and the suppression flag: if we fell
|
|
379
|
+
// through because an invalidation bumped the eviction gen,
|
|
380
|
+
// invalidateReuse() has suppressed segment/slot reuse since our
|
|
381
|
+
// original capture (TIM-1466, codex on #1167).
|
|
382
|
+
reuseSuppressedAtFetch = isSegmentReuseSuppressed();
|
|
383
|
+
const freshStateTree = currentStateTree();
|
|
384
|
+
result = await fetchRscPayload(url, deps, freshStateTree, currentUrl, options.signal);
|
|
426
385
|
}
|
|
427
386
|
|
|
428
387
|
// Update the browser history — skip when the Navigation API has already
|
|
@@ -450,9 +409,6 @@ export function createNavigationPipeline({
|
|
|
450
409
|
deps.setRouterNavigating?.(false);
|
|
451
410
|
};
|
|
452
411
|
|
|
453
|
-
// Resolve thenable payloads in the test path so popstate replay
|
|
454
|
-
// and renderPayload receive plain values (see resolveForFallback).
|
|
455
|
-
const payload = await resolveForFallback(result.payload);
|
|
456
412
|
const params = await result.params;
|
|
457
413
|
|
|
458
414
|
// Prepare the atomic navigation-state update. It is published by the
|
|
@@ -461,15 +417,23 @@ export function createNavigationPipeline({
|
|
|
461
417
|
// `prepareNavigation`'s decision, made from `skippedSegments` and
|
|
462
418
|
// `segmentInfo` (TIM-1432).
|
|
463
419
|
const { navState, commit } = prepareNavigation(url, {
|
|
464
|
-
payload,
|
|
420
|
+
payload: result.payload,
|
|
465
421
|
params,
|
|
466
422
|
segmentInfo: result.segmentInfo,
|
|
467
423
|
skippedSegments: result.skippedSegments,
|
|
468
424
|
});
|
|
469
425
|
|
|
426
|
+
// This navigation's fetch used the suppressed state tree (empty
|
|
427
|
+
// segments/slots), so the server sent a full render. The response
|
|
428
|
+
// data is post-invalidation — safe to restore reuse for subsequent
|
|
429
|
+
// navigations. Must happen here (at response time, before the commit
|
|
430
|
+
// thunk), not in set(), because a pre-invalidation navigation's
|
|
431
|
+
// commit thunk also calls set() and would lift suppression too early
|
|
432
|
+
// (codex on #1167).
|
|
433
|
+
if (reuseSuppressedAtFetch) restoreSegmentReuse();
|
|
434
|
+
|
|
470
435
|
return {
|
|
471
436
|
...result,
|
|
472
|
-
payload,
|
|
473
437
|
params,
|
|
474
438
|
navState,
|
|
475
439
|
commit: () => {
|
|
@@ -486,5 +450,5 @@ export function createNavigationPipeline({
|
|
|
486
450
|
};
|
|
487
451
|
}
|
|
488
452
|
|
|
489
|
-
return { performNavigationFetch, renderViaTransition
|
|
453
|
+
return { performNavigationFetch, renderViaTransition };
|
|
490
454
|
}
|
|
@@ -13,7 +13,6 @@ import type { NavigationState } from './navigation-context.ts';
|
|
|
13
13
|
import type { ParamsSource } from '../shared/payload-root.ts';
|
|
14
14
|
import type { SegmentInfo } from '../shared/segment-info.ts';
|
|
15
15
|
import type { SegmentCache, PrefetchCache } from './segment-cache.ts';
|
|
16
|
-
import type { HistoryStack } from './history.ts';
|
|
17
16
|
import type { TransitionResult, CommitOutcome, RenderOwner } from './navigation-transition.ts';
|
|
18
17
|
import type { NavigationEpoch } from './router-lifecycle.ts';
|
|
19
18
|
|
|
@@ -53,37 +52,13 @@ export interface NavigationOptions {
|
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
/**
|
|
56
|
-
* Function that decodes an RSC Flight stream into
|
|
57
|
-
* In production: createFromFetch from @vitejs/plugin-rsc/browser.
|
|
58
|
-
*
|
|
55
|
+
* Function that decodes an RSC Flight stream into the payload root.
|
|
56
|
+
* In production: createFromFetch from @vitejs/plugin-rsc/browser. Tests use
|
|
57
|
+
* the same Flight client over Flight bytes (tests/helpers/router-harness.ts),
|
|
58
|
+
* so every response is classified and decoded by the one path production runs.
|
|
59
59
|
*/
|
|
60
60
|
export type RscDecoder = (fetchPromise: Promise<Response>) => unknown;
|
|
61
61
|
|
|
62
|
-
/**
|
|
63
|
-
* Function that renders a decoded RSC element tree into the DOM.
|
|
64
|
-
* In production: reactRoot.render(element).
|
|
65
|
-
* In tests: a no-op or mock.
|
|
66
|
-
*
|
|
67
|
-
* Receives the current NavigationState explicitly — no temporal
|
|
68
|
-
* coupling with setNavigationState/getNavigationState. The renderer
|
|
69
|
-
* wraps the element in NavigationProvider with this state.
|
|
70
|
-
*/
|
|
71
|
-
export type RootRenderer = (
|
|
72
|
-
element: unknown,
|
|
73
|
-
navState: NavigationState,
|
|
74
|
-
params: ParamsSource,
|
|
75
|
-
/**
|
|
76
|
-
* Publishes the state that makes this tree the current page (segment
|
|
77
|
-
* cache, pathname, history stack, address bar). The renderer runs it when
|
|
78
|
-
* the tree is on screen — in production from React's commit of the tree
|
|
79
|
-
* (`NavigationRoot`'s layout effect), a test double synchronously. It is not run before
|
|
80
|
-
* handing the tree over: a replay or revalidation whose tree suspends is
|
|
81
|
-
* given to React without being on screen, and publishing then advertises
|
|
82
|
-
* slot content keys the slot content cache has not recorded (TIM-1423).
|
|
83
|
-
*/
|
|
84
|
-
commit: () => void
|
|
85
|
-
) => void;
|
|
86
|
-
|
|
87
62
|
/**
|
|
88
63
|
* Platform dependencies injected for testability. In production these
|
|
89
64
|
* map to browser APIs; in tests they're replaced with mocks.
|
|
@@ -95,10 +70,8 @@ export interface RouterDeps {
|
|
|
95
70
|
scrollTo: (x: number, y: number) => void;
|
|
96
71
|
getCurrentUrl: () => string;
|
|
97
72
|
getScrollY: () => number;
|
|
98
|
-
/** Decode RSC Flight stream into
|
|
99
|
-
decodeRsc
|
|
100
|
-
/** Render decoded RSC tree into the DOM. If not provided, rendering is a no-op. */
|
|
101
|
-
renderRoot?: RootRenderer;
|
|
73
|
+
/** Decode an RSC Flight stream into the payload root. */
|
|
74
|
+
decodeRsc: RscDecoder;
|
|
102
75
|
/**
|
|
103
76
|
* Schedule a callback after the next paint. In the browser, this is
|
|
104
77
|
* requestAnimationFrame + setTimeout(0) to run after React commits.
|
|
@@ -114,12 +87,14 @@ export interface RouterDeps {
|
|
|
114
87
|
* The `perform` callback receives a `wrapPayload` function to wrap the
|
|
115
88
|
* decoded RSC payload with NavigationProvider + NuqsAdapter before
|
|
116
89
|
* NavigationRoot sets it as the new element. The `wrapPayload` function
|
|
117
|
-
* receives the NavigationState explicitly — no
|
|
118
|
-
*
|
|
90
|
+
* receives the NavigationState explicitly — there is no store to read it
|
|
91
|
+
* from.
|
|
119
92
|
*
|
|
120
|
-
*
|
|
93
|
+
* Every render goes through here — a navigation, a refresh, a traversal
|
|
94
|
+
* (fetched or replayed) and a server action's revalidation — so each one
|
|
95
|
+
* gets the same handover, commit and supersession.
|
|
121
96
|
*/
|
|
122
|
-
navigateTransition
|
|
97
|
+
navigateTransition: (
|
|
123
98
|
pendingUrl: string,
|
|
124
99
|
owner: RenderOwner,
|
|
125
100
|
perform: (
|
|
@@ -225,6 +200,14 @@ export interface RouterInstance {
|
|
|
225
200
|
* Hand the epoch back to `applyActionResult` with the response (TIM-1474).
|
|
226
201
|
*/
|
|
227
202
|
epoch(): NavigationEpoch;
|
|
203
|
+
/**
|
|
204
|
+
* True when no navigation has started since `epoch` was taken and the
|
|
205
|
+
* router was idle then and is idle now — the same test
|
|
206
|
+
* `applyActionResult` applies. Action branches that never reach
|
|
207
|
+
* `applyActionResult` use it to detect a navigation that ran while the
|
|
208
|
+
* action was in flight and may have rendered pre-mutation data (TIM-1483).
|
|
209
|
+
*/
|
|
210
|
+
isEpochCurrent(epoch: NavigationEpoch): boolean;
|
|
228
211
|
/**
|
|
229
212
|
* Reconcile the page after a server action. `tree` is the piggybacked
|
|
230
213
|
* revalidation payload root, or `undefined` when the server sent none.
|
|
@@ -264,22 +247,41 @@ export interface RouterInstance {
|
|
|
264
247
|
* affect any route's data, not just the paths the server named, so every
|
|
265
248
|
* cached payload is stale. In-flight prefetch singleflights are fenced
|
|
266
249
|
* by the eviction generation — their results are discarded if they
|
|
267
|
-
* complete after eviction.
|
|
268
|
-
*
|
|
250
|
+
* complete after eviction. `applyActionResult` does not need the history
|
|
251
|
+
* stack: the current page's segment metadata is the committer's record.
|
|
269
252
|
*/
|
|
270
253
|
evictStaleCaches(): void;
|
|
271
254
|
/**
|
|
272
|
-
*
|
|
273
|
-
*
|
|
255
|
+
* Make the server-rendered page the current page — the hydration entry
|
|
256
|
+
* point, and the only one: bootstrap does not reach into the router's
|
|
257
|
+
* caches. Returns the `NavigationState` the page renders with.
|
|
258
|
+
*
|
|
259
|
+
* Goes through the same `prepareNavigation` every navigation uses, and
|
|
260
|
+
* commits at once rather than on React's hydration commit. The server's
|
|
261
|
+
* HTML is already the page on screen, and React does not promise that
|
|
262
|
+
* commit: a render that reaches the root while hydration is suspended (a
|
|
263
|
+
* shallow search update, a navigation the Navigation API intercepted
|
|
264
|
+
* before hydration) switches the root to client rendering, and the
|
|
265
|
+
* hydration tree — with any publish attached to it — never commits. A
|
|
266
|
+
* status document is still kept out of the cache: its `StatusPageMarker`
|
|
267
|
+
* clears the cache when it reports (navigation-commit.ts).
|
|
274
268
|
*/
|
|
275
|
-
|
|
269
|
+
hydrate(page: HydrationPage): NavigationState;
|
|
276
270
|
|
|
277
271
|
/** The segment cache (exposed for tests and <Link> prefetch) */
|
|
278
272
|
segmentCache: SegmentCache;
|
|
279
273
|
/** The prefetch cache (exposed for tests and <Link> prefetch) */
|
|
280
274
|
prefetchCache: PrefetchCache;
|
|
281
|
-
|
|
282
|
-
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** The page the server rendered, as the browser entry decoded it. */
|
|
278
|
+
export interface HydrationPage {
|
|
279
|
+
/** The inlined payload's tree, or null when the document carried none. */
|
|
280
|
+
payload: unknown;
|
|
281
|
+
/** The params published beside it. */
|
|
282
|
+
params: ParamsSource;
|
|
283
|
+
/** The rendered chain's metadata (`self.__timber_segments`), or null. */
|
|
284
|
+
segmentInfo: SegmentInfo[] | null;
|
|
283
285
|
}
|
|
284
286
|
|
|
285
287
|
/**
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the client router reads the URLs it is handed.
|
|
3
|
+
*
|
|
4
|
+
* One parser, so the places that key or compare by URL — the history stack,
|
|
5
|
+
* the navigation state a page renders with, the departing page sent as
|
|
6
|
+
* `X-Timber-URL` — cannot disagree about what a URL says. They did: a
|
|
7
|
+
* history entry stored under `navigate('/café')`'s spelling was looked up
|
|
8
|
+
* under the address bar's `/caf%C3%A9`, and missed (TIM-1541).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const BASE = 'http://localhost';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse a router URL. A URL that starts with "/" is a path — including one
|
|
15
|
+
* that starts with "//": that is the pathname a document at
|
|
16
|
+
* `https://host//a/b` reports, and resolved against a base it would parse as
|
|
17
|
+
* a scheme-relative reference to host `a`. Anything else resolves against a
|
|
18
|
+
* placeholder origin, so an absolute URL keeps its own.
|
|
19
|
+
*/
|
|
20
|
+
export function parseRouterUrl(url: string): URL {
|
|
21
|
+
return url.startsWith('/') ? new URL(BASE + url) : new URL(url, BASE);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The spelling a URL is stored and looked up under: the browser's own
|
|
26
|
+
* pathname + search, so `/a?` and `/a`, `/café` and `/caf%C3%A9`, are one
|
|
27
|
+
* key. The fragment is dropped — it is client-only.
|
|
28
|
+
*/
|
|
29
|
+
export function routerUrlKey(url: string): string {
|
|
30
|
+
const parsed = parseRouterUrl(url);
|
|
31
|
+
return parsed.pathname + parsed.search;
|
|
32
|
+
}
|