@timber-js/app 0.2.0-alpha.208 → 0.2.0-alpha.209
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
- package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
- package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
- package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
- package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
- package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
- package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
- package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
- package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
- package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
- package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
- package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
- package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
- package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
- package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
- package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
- package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
- package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
- package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
- package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
- package/dist/_chunks/{error-boundary-BrHmG-2X.js → error-boundary-tA7kVfs4.js} +84 -104
- package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
- package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
- package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
- package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
- package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
- package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
- package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
- package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
- package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
- package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
- package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
- package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
- package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
- package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
- package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
- package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
- package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
- package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
- package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
- package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
- package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
- package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
- package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
- package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
- package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
- package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
- package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
- package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
- package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
- package/dist/_chunks/{status-page-marker-CNbpUOPB.js → status-page-marker-gaihi0KZ.js} +53 -20
- package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
- package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
- package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +7 -7
- package/dist/adapters/build-output-helper.d.ts.map +1 -1
- package/dist/adapters/canonicalize-module.d.ts +8 -0
- package/dist/adapters/canonicalize-module.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +2 -2
- package/dist/adapters/cloudflare.d.ts +30 -8
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -2
- package/dist/adapters/compress-module.d.ts +8 -0
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +2 -3
- package/dist/adapters/fs-identity.d.ts.map +1 -1
- package/dist/adapters/nitro-presets.d.ts +0 -6
- package/dist/adapters/nitro-presets.d.ts.map +1 -1
- package/dist/adapters/nitro-preview.d.ts +43 -11
- package/dist/adapters/nitro-preview.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +1 -13
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +291 -176
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +7 -2
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +105 -21
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js +0 -0
- package/dist/analyze/crawl-entry.js +3 -3
- package/dist/analyze/graph-cache.d.ts.map +1 -1
- package/dist/analyze/graph-command.js +4 -4
- package/dist/cache/index.js +2 -2
- package/dist/cache/json-lossy-check.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts.map +1 -1
- package/dist/cache/stores/memory.js +1 -1
- package/dist/cache/tag-aware-handler.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.js +1 -1
- package/dist/cli-check.d.ts +7 -37
- package/dist/cli-check.d.ts.map +1 -1
- package/dist/cli-context.d.ts +54 -0
- package/dist/cli-context.d.ts.map +1 -0
- package/dist/cli.d.ts +9 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -24
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts +19 -29
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/index.d.ts +7 -7
- package/dist/client/browser-entry/post-hydration.d.ts +6 -9
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +6 -11
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +4 -3
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -1
- package/dist/client/error-reconstituter.d.ts +3 -9
- package/dist/client/error-reconstituter.d.ts.map +1 -1
- package/dist/client/history.d.ts +12 -11
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -6
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +3 -3
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +68 -104
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +16 -7
- package/dist/client/navigation-commit.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +3 -5
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/react-root.d.ts +3 -2
- package/dist/client/react-root.d.ts.map +1 -1
- package/dist/client/router-pipeline.d.ts +1 -6
- package/dist/client/router-pipeline.d.ts.map +1 -1
- package/dist/client/router-types.d.ts +45 -39
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router-url.d.ts +24 -0
- package/dist/client/router-url.d.ts.map +1 -0
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +8 -4
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/ssr-data.d.ts +18 -64
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +2 -5
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts +1 -1
- package/dist/config-types.d.ts +2 -1
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -1
- package/dist/dev-tools/dev-page-shell.d.ts +17 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
- package/dist/dev-tools/index.d.ts +1 -1
- package/dist/dev-tools/index.d.ts.map +1 -1
- package/dist/dev-tools/instrumentation.d.ts +17 -2
- package/dist/dev-tools/instrumentation.d.ts.map +1 -1
- package/dist/dev-tools/overlay.d.ts +6 -27
- package/dist/dev-tools/overlay.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +531 -373
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +26 -40
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +15 -2
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +19 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/post-build.d.ts +110 -0
- package/dist/plugins/post-build.d.ts.map +1 -0
- package/dist/plugins/prebuilt-capture.d.ts +11 -4
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
- package/dist/plugins/prebuilt.d.ts +17 -1
- package/dist/plugins/prebuilt.d.ts.map +1 -1
- package/dist/plugins/prerender-sugar.d.ts.map +1 -1
- package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
- package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +32 -9
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-write.d.ts +0 -9
- package/dist/routing/codegen-write.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/routing/segment-codegen.d.ts.map +1 -1
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts +5 -4
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +46 -7
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +58 -5
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/children-interception.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts +2 -23
- package/dist/server/cookie-context.d.ts.map +1 -1
- package/dist/server/csp-nonce.d.ts +0 -9
- package/dist/server/csp-nonce.d.ts.map +1 -1
- package/dist/server/csrf.d.ts +27 -4
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/debug.d.ts +0 -1
- package/dist/server/debug.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +2 -1
- package/dist/server/default-logger.d.ts.map +1 -1
- package/dist/server/deny-boundary.d.ts +12 -6
- package/dist/server/deny-boundary.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts +2 -2
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -3
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +9 -2
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +4 -4
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +10 -3
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/internal.d.ts +1 -4
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +961 -581
- package/dist/server/internal.js.map +1 -1
- package/dist/server/json-status-response.d.ts +34 -0
- package/dist/server/json-status-response.d.ts.map +1 -0
- package/dist/server/logger.d.ts +26 -0
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +11 -6
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-helpers.d.ts +95 -7
- package/dist/server/pipeline-helpers.d.ts.map +1 -1
- package/dist/server/pipeline-interception.d.ts +11 -0
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +11 -1
- package/dist/server/pipeline-outcome.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts +2 -2
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +23 -35
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/prebuilt/capture-render.d.ts +25 -0
- package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-routes.d.ts +37 -0
- package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +79 -35
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
- package/dist/server/prebuilt/lifetime.d.ts +38 -0
- package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +7 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -1
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
- package/dist/server/prebuilt-builder.d.ts.map +1 -1
- package/dist/server/prebuilt-runtime.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +6 -81
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/react-cache-bridge.d.ts +59 -0
- package/dist/server/react-cache-bridge.d.ts.map +1 -0
- package/dist/server/react-cache-scope.d.ts +49 -0
- package/dist/server/react-cache-scope.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +15 -0
- package/dist/server/render-timeout.d.ts.map +1 -1
- package/dist/server/render-utils.d.ts +9 -0
- package/dist/server/render-utils.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +26 -5
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +7 -0
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +7 -0
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +0 -1
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +5 -15
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +5 -6
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-signals.d.ts +65 -0
- package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
- package/dist/server/signal-identity.d.ts +43 -0
- package/dist/server/signal-identity.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +4 -3
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/slot-subtree-contain.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +91 -53
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +8 -5
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +26 -40
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +1 -1
- package/dist/server/static-generator.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +12 -0
- package/dist/server/stream-utils.d.ts.map +1 -1
- package/dist/server/tracing.d.ts +12 -16
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -1
- package/dist/server/version-skew.d.ts +3 -3
- package/dist/shared/csrf-reject.d.ts +16 -0
- package/dist/shared/csrf-reject.d.ts.map +1 -0
- package/dist/shared/error-digest.d.ts +28 -0
- package/dist/shared/error-digest.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +11 -10
- package/dist/shared/payload-root.d.ts.map +1 -1
- package/dist/shared/rsc-payload-path.d.ts +6 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -1
- package/dist/utils/write-file-atomic.d.ts +17 -0
- package/dist/utils/write-file-atomic.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +17 -14
- package/docs/api/32-api-cache.mdx +51 -23
- package/docs/api/34-api-config.mdx +34 -6
- package/docs/api/36-cli.mdx +11 -1
- package/docs/learn/03-fetching-data.mdx +17 -1
- package/docs/learn/04-access-control.mdx +1 -1
- package/docs/learn/10-caching.mdx +29 -11
- package/docs/learn/11-middleware.mdx +8 -2
- package/docs/learn/12-error-handling.mdx +6 -1
- package/package.json +5 -1
- package/src/adapters/build-output-helper.ts +55 -53
- package/src/adapters/canonicalize-module.ts +29 -0
- package/src/adapters/cloudflare.ts +105 -63
- package/src/adapters/compress-module.ts +16 -5
- package/src/adapters/fs-identity.ts +2 -3
- package/src/adapters/nitro-presets.ts +0 -15
- package/src/adapters/nitro-preview.ts +272 -136
- package/src/adapters/nitro.ts +119 -82
- package/src/adapters/shared.ts +23 -14
- package/src/adapters/types.ts +110 -21
- package/src/analyze/graph-cache.ts +3 -4
- package/src/cache/json-lossy-check.ts +3 -9
- package/src/cache/singleflight.ts +5 -2
- package/src/cache/sizeof.ts +3 -1
- package/src/cache/tag-aware-handler.ts +43 -26
- package/src/cli-check.ts +8 -98
- package/src/cli-context.ts +119 -0
- package/src/cli.ts +19 -28
- package/src/client/browser-dev.ts +1 -1
- package/src/client/browser-entry/action-dispatch.ts +26 -4
- package/src/client/browser-entry/hydrate.ts +53 -58
- package/src/client/browser-entry/index.ts +16 -27
- package/src/client/browser-entry/post-hydration.ts +6 -40
- package/src/client/browser-entry/router-init.ts +66 -84
- package/src/client/error-boundary.tsx +9 -41
- package/src/client/error-reconstituter.tsx +10 -5
- package/src/client/history.ts +18 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +35 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +65 -128
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +43 -22
- package/src/client/rsc-fetch.ts +117 -155
- package/src/client/ssr-data.ts +19 -80
- package/src/client/state.ts +2 -9
- package/src/client/use-pathname.ts +1 -1
- package/src/config-types.ts +2 -1
- package/src/config-validation.ts +2 -1
- package/src/dev-tools/dev-page-shell.ts +18 -0
- package/src/dev-tools/index.ts +0 -2
- package/src/dev-tools/instrumentation.ts +50 -2
- package/src/dev-tools/overlay.ts +8 -238
- package/src/index.ts +24 -14
- package/src/plugin-context.ts +39 -40
- package/src/plugins/build-manifest.ts +4 -11
- package/src/plugins/build-report.ts +70 -70
- package/src/plugins/dev-server.ts +24 -44
- package/src/plugins/entries.ts +2 -1
- package/src/plugins/fonts.ts +35 -7
- package/src/plugins/post-build.ts +327 -0
- package/src/plugins/prebuilt-capture.ts +28 -32
- package/src/plugins/prebuilt.ts +54 -39
- package/src/plugins/prerender-sugar.ts +0 -4
- package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
- package/src/plugins/shims.ts +1 -0
- package/src/plugins/static-build.ts +42 -74
- package/src/routing/codegen-write.ts +25 -3
- package/src/routing/segment-codegen.ts +3 -2
- package/src/rsc-runtime/vendor-types.d.ts +8 -0
- package/src/server/access-gate.tsx +2 -1
- package/src/server/action-client.ts +1 -1
- package/src/server/action-handler.ts +253 -110
- package/src/server/actions.ts +73 -25
- package/src/server/als-registry.ts +73 -5
- package/src/server/chain-url-parts.ts +1 -1
- package/src/server/children-interception.ts +2 -1
- package/src/server/cookie-context.ts +18 -48
- package/src/server/csp-nonce.ts +0 -12
- package/src/server/csrf.ts +140 -8
- package/src/server/debug.ts +0 -1
- package/src/server/default-logger.ts +2 -1
- package/src/server/deny-boundary.ts +25 -13
- package/src/server/deny-renderer.ts +30 -97
- package/src/server/error-boundary-wrapper.ts +7 -3
- package/src/server/fallback-error.ts +26 -11
- package/src/server/flight-scripts.ts +1 -1
- package/src/server/head-response.ts +4 -4
- package/src/server/html-injector-core.ts +2 -2
- package/src/server/html-injectors.ts +2 -4
- package/src/server/index.ts +0 -4
- package/src/server/instrumentation.ts +10 -3
- package/src/server/internal.ts +1 -6
- package/src/server/json-status-response.ts +105 -0
- package/src/server/logger.ts +39 -3
- package/src/server/param-coercion.ts +15 -12
- package/src/server/pipeline-helpers.ts +257 -12
- package/src/server/pipeline-interception.ts +133 -0
- package/src/server/pipeline-outcome.ts +103 -31
- package/src/server/pipeline-phases.ts +127 -237
- package/src/server/pipeline.ts +204 -207
- package/src/server/prebuilt/capture-render.ts +118 -0
- package/src/server/prebuilt/capture-routes.ts +104 -0
- package/src/server/prebuilt/capture-state.ts +155 -48
- package/src/server/prebuilt/lifetime.ts +151 -0
- package/src/server/prebuilt/slots.ts +14 -2
- package/src/server/prebuilt/synthetic-store.ts +3 -0
- package/src/server/prebuilt-builder.ts +30 -320
- package/src/server/prebuilt-runtime.ts +125 -129
- package/src/server/primitives.ts +8 -168
- package/src/server/react-cache-bridge.ts +124 -0
- package/src/server/react-cache-scope.ts +104 -0
- package/src/server/render-timeout.ts +20 -0
- package/src/server/render-utils.ts +11 -1
- package/src/server/request-context.ts +36 -9
- package/src/server/route-element-builder.ts +11 -6
- package/src/server/route-handler.ts +36 -23
- package/src/server/route-matcher.ts +15 -1
- package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
- package/src/server/rsc-entry/api-handler.ts +27 -103
- package/src/server/rsc-entry/deny-fallback.ts +93 -26
- package/src/server/rsc-entry/error-renderer.ts +39 -91
- package/src/server/rsc-entry/helpers.ts +2 -4
- package/src/server/rsc-entry/index.ts +64 -58
- package/src/server/rsc-entry/render-route.ts +15 -80
- package/src/server/rsc-entry/render-signals.ts +108 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
- package/src/server/rsc-entry/rsc-payload.ts +28 -61
- package/src/server/rsc-entry/rsc-stream.ts +113 -213
- package/src/server/rsc-entry/ssr-bridge.ts +2 -2
- package/src/server/rsc-entry/ssr-renderer.ts +182 -263
- package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
- package/src/server/signal-identity.ts +112 -0
- package/src/server/slot-resolver.ts +18 -18
- package/src/server/slot-subtree-contain.ts +2 -1
- package/src/server/ssr-bridge-types.ts +92 -56
- package/src/server/ssr-entry.ts +87 -111
- package/src/server/ssr-render.ts +55 -64
- package/src/server/ssr-wrappers.tsx +2 -2
- package/src/server/static-generator.ts +7 -42
- package/src/server/static-not-found.ts +3 -3
- package/src/server/stream-utils.ts +51 -0
- package/src/server/tracing.ts +58 -75
- package/src/server/types.ts +1 -1
- package/src/server/version-skew.ts +5 -5
- package/src/shared/csrf-reject.ts +15 -0
- package/src/shared/error-digest.ts +46 -0
- package/src/shared/payload-root.ts +11 -10
- package/src/shared/rsc-payload-path.ts +8 -1
- package/src/utils/write-file-atomic.ts +32 -0
- package/dist/_chunks/actions-jNrXdzgs.js +0 -346
- package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
- package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
- package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
- package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
- package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
- package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
- package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
- package/dist/_chunks/error-boundary-BrHmG-2X.js.map +0 -1
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
- package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
- package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
- package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
- package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
- package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
- package/dist/_chunks/segment-context-D9_89u34.js +0 -34
- package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
- package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
- package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
- package/dist/_chunks/state-FippDgxN.js.map +0 -1
- package/dist/_chunks/status-page-marker-CNbpUOPB.js.map +0 -1
- package/dist/client/types.d.ts +0 -14
- package/dist/client/types.d.ts.map +0 -1
- package/dist/plugins/adapter-build.d.ts +0 -38
- package/dist/plugins/adapter-build.d.ts.map +0 -1
- package/dist/server/asset-headers.d.ts +0 -32
- package/dist/server/asset-headers.d.ts.map +0 -1
- package/dist/server/dev-source-map.d.ts +0 -22
- package/dist/server/dev-source-map.d.ts.map +0 -1
- package/src/client/types.ts +0 -21
- package/src/server/asset-headers.ts +0 -59
- package/src/server/dev-source-map.ts +0 -31
|
@@ -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
|
/**
|
|
@@ -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
|
}
|
|
@@ -180,50 +172,13 @@ export function createNavigationPipeline({
|
|
|
180
172
|
forgetOlderHandoffs,
|
|
181
173
|
}: NavigationPipelineDeps): NavigationPipeline {
|
|
182
174
|
/**
|
|
183
|
-
*
|
|
184
|
-
* tree is current. The renderer owns that moment (see `RootRenderer`);
|
|
185
|
-
* with no renderer there is no tree to wait for, so it publishes now.
|
|
186
|
-
*/
|
|
187
|
-
function renderPayload(
|
|
188
|
-
payload: unknown,
|
|
189
|
-
navState: NavigationState,
|
|
190
|
-
params: ParamsSource,
|
|
191
|
-
commit: () => void
|
|
192
|
-
): void {
|
|
193
|
-
if (deps.renderRoot) {
|
|
194
|
-
deps.renderRoot(payload, navState, params, commit);
|
|
195
|
-
} else {
|
|
196
|
-
commit();
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Resolve thenable payloads in the test/fallback path (no navigateTransition).
|
|
202
|
-
* In production, React handles thenables from createFromFetch directly via
|
|
203
|
-
* Suspense. In tests, renderRoot is a plain mock that expects resolved values.
|
|
204
|
-
*/
|
|
205
|
-
async function resolveForFallback(payload: unknown): Promise<unknown> {
|
|
206
|
-
if (
|
|
207
|
-
!deps.navigateTransition &&
|
|
208
|
-
payload != null &&
|
|
209
|
-
typeof payload === 'object' &&
|
|
210
|
-
'then' in payload
|
|
211
|
-
) {
|
|
212
|
-
return await (payload as PromiseLike<unknown>);
|
|
213
|
-
}
|
|
214
|
-
return payload;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Render a payload via navigateTransition (production) or renderRoot (tests).
|
|
219
|
-
* 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
|
|
220
176
|
* FetchResult plus the NavigationState and the commit thunk.
|
|
221
177
|
*
|
|
222
178
|
* The thunk is handed *through* to NavigationRoot rather than called here:
|
|
223
|
-
* state management (
|
|
179
|
+
* state management (segment cache, history stack, address bar) has to happen on
|
|
224
180
|
* the far side of the supersession check, which only NavigationRoot can
|
|
225
|
-
* make (TIM-1301).
|
|
226
|
-
* superseded by, so it commits directly.
|
|
181
|
+
* make (TIM-1301).
|
|
227
182
|
*/
|
|
228
183
|
async function renderViaTransition(
|
|
229
184
|
url: string,
|
|
@@ -245,84 +200,70 @@ export function createNavigationPipeline({
|
|
|
245
200
|
commit();
|
|
246
201
|
};
|
|
247
202
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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;
|
|
266
229
|
|
|
267
|
-
|
|
268
|
-
|
|
230
|
+
if (isPartialNavigation(result.skippedSegments)) {
|
|
231
|
+
const segmentUpdates = buildSegmentUpdates(result, payload);
|
|
269
232
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
handOff();
|
|
281
|
-
return {
|
|
282
|
-
element,
|
|
283
|
-
decodePromise: observeSkew(result.decodePromise),
|
|
284
|
-
commit: commitAndForget(result.commit),
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Full navigation — empty updates, render the new tree.
|
|
289
|
-
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
|
+
);
|
|
290
243
|
handOff();
|
|
291
244
|
return {
|
|
292
245
|
element,
|
|
293
246
|
decodePromise: observeSkew(result.decodePromise),
|
|
294
247
|
commit: commitAndForget(result.commit),
|
|
295
248
|
};
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const commit = commitAndForget(result.commit);
|
|
310
|
-
if (isPartialNavigation(result.skippedSegments)) {
|
|
311
|
-
commit();
|
|
312
|
-
} else {
|
|
313
|
-
renderPayload(result.payload, result.navState, await result.params, commit);
|
|
314
|
-
}
|
|
315
|
-
} catch (error) {
|
|
316
|
-
fallbackOutcome = 'failed';
|
|
317
|
-
throw error;
|
|
318
|
-
} finally {
|
|
319
|
-
onCommit?.(fallbackOutcome);
|
|
320
|
-
}
|
|
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
|
+
);
|
|
321
262
|
}
|
|
322
263
|
|
|
323
264
|
/**
|
|
324
|
-
*
|
|
325
|
-
*
|
|
265
|
+
* Fetch (or take from the prefetch cache) a navigation's payload and
|
|
266
|
+
* prepare — without publishing — the commit that makes it current.
|
|
326
267
|
*/
|
|
327
268
|
async function performNavigationFetch(
|
|
328
269
|
url: string,
|
|
@@ -468,9 +409,6 @@ export function createNavigationPipeline({
|
|
|
468
409
|
deps.setRouterNavigating?.(false);
|
|
469
410
|
};
|
|
470
411
|
|
|
471
|
-
// Resolve thenable payloads in the test path so popstate replay
|
|
472
|
-
// and renderPayload receive plain values (see resolveForFallback).
|
|
473
|
-
const payload = await resolveForFallback(result.payload);
|
|
474
412
|
const params = await result.params;
|
|
475
413
|
|
|
476
414
|
// Prepare the atomic navigation-state update. It is published by the
|
|
@@ -479,7 +417,7 @@ export function createNavigationPipeline({
|
|
|
479
417
|
// `prepareNavigation`'s decision, made from `skippedSegments` and
|
|
480
418
|
// `segmentInfo` (TIM-1432).
|
|
481
419
|
const { navState, commit } = prepareNavigation(url, {
|
|
482
|
-
payload,
|
|
420
|
+
payload: result.payload,
|
|
483
421
|
params,
|
|
484
422
|
segmentInfo: result.segmentInfo,
|
|
485
423
|
skippedSegments: result.skippedSegments,
|
|
@@ -496,7 +434,6 @@ export function createNavigationPipeline({
|
|
|
496
434
|
|
|
497
435
|
return {
|
|
498
436
|
...result,
|
|
499
|
-
payload,
|
|
500
437
|
params,
|
|
501
438
|
navState,
|
|
502
439
|
commit: () => {
|
|
@@ -513,5 +450,5 @@ export function createNavigationPipeline({
|
|
|
513
450
|
};
|
|
514
451
|
}
|
|
515
452
|
|
|
516
|
-
return { performNavigationFetch, renderViaTransition
|
|
453
|
+
return { performNavigationFetch, renderViaTransition };
|
|
517
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
|
+
}
|
package/src/client/router.ts
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
// See design/19-client-navigation.md for the full architecture.
|
|
13
13
|
|
|
14
14
|
import { SegmentCache, PrefetchCache } from './segment-cache.ts';
|
|
15
|
-
import type { SegmentInfo } from '../shared/segment-info.ts';
|
|
16
15
|
import { HistoryStack } from './history.ts';
|
|
17
16
|
import { createNavigationCommitter } from './navigation-commit.ts';
|
|
18
17
|
|
|
@@ -42,7 +41,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
42
41
|
const {
|
|
43
42
|
prepareNavigation,
|
|
44
43
|
currentStateTree,
|
|
45
|
-
|
|
44
|
+
committedSegmentInfo,
|
|
46
45
|
isSegmentReuseSuppressed,
|
|
47
46
|
restoreSegmentReuse,
|
|
48
47
|
} = createNavigationCommitter({
|
|
@@ -66,17 +65,16 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
66
65
|
} = lifecycle;
|
|
67
66
|
|
|
68
67
|
// Fetch → commit → hand to React. See router-pipeline.ts.
|
|
69
|
-
const { performNavigationFetch, renderViaTransition
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
});
|
|
68
|
+
const { performNavigationFetch, renderViaTransition } = createNavigationPipeline({
|
|
69
|
+
deps,
|
|
70
|
+
prefetchCache,
|
|
71
|
+
currentStateTree,
|
|
72
|
+
prepareNavigation,
|
|
73
|
+
isSegmentReuseSuppressed,
|
|
74
|
+
restoreSegmentReuse,
|
|
75
|
+
markHandedOff,
|
|
76
|
+
forgetOlderHandoffs,
|
|
77
|
+
});
|
|
80
78
|
|
|
81
79
|
// Post-paint scroll effects.
|
|
82
80
|
const { restoreScrollAfterPaint, scrollToHashAfterPaint } = createScrollEffects(deps);
|
|
@@ -231,15 +229,14 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
231
229
|
undefined,
|
|
232
230
|
owner.fetchAbort.signal
|
|
233
231
|
);
|
|
234
|
-
const payload = await resolveForFallback(result.payload);
|
|
235
232
|
const params = await result.params;
|
|
236
233
|
const { navState, commit } = prepareNavigation(url, {
|
|
237
|
-
payload,
|
|
234
|
+
payload: result.payload,
|
|
238
235
|
params,
|
|
239
236
|
segmentInfo: result.segmentInfo,
|
|
240
237
|
skippedSegments: result.skippedSegments,
|
|
241
238
|
});
|
|
242
|
-
return { ...result,
|
|
239
|
+
return { ...result, params, navState, commit };
|
|
243
240
|
},
|
|
244
241
|
opts.onCommit
|
|
245
242
|
);
|
|
@@ -436,6 +433,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
436
433
|
onPendingChange,
|
|
437
434
|
prefetch,
|
|
438
435
|
epoch: () => lifecycle.epoch(),
|
|
436
|
+
isEpochCurrent: (epoch) => lifecycle.isEpochCurrent(epoch),
|
|
439
437
|
|
|
440
438
|
async applyActionResult(epoch, tree) {
|
|
441
439
|
if (!lifecycle.isEpochCurrent(epoch)) return false;
|
|
@@ -461,7 +459,12 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
461
459
|
const currentUrl = deps.getCurrentUrl();
|
|
462
460
|
const payloadTree = readPayloadTree(tree);
|
|
463
461
|
const params = readPublishedParams(tree);
|
|
464
|
-
|
|
462
|
+
// The response carries no segment metadata; the page it re-renders is
|
|
463
|
+
// the one the last commit made current, and the committer kept that
|
|
464
|
+
// page's. Not a history-stack lookup by `currentUrl`: the stack is keyed
|
|
465
|
+
// by the spelling `navigate()` was given, which need not be
|
|
466
|
+
// `window.location`'s (TIM-1541).
|
|
467
|
+
const segmentInfo = committedSegmentInfo();
|
|
465
468
|
|
|
466
469
|
let outcomeResolve!: (o: CommitOutcome) => void;
|
|
467
470
|
const outcomePromise = new Promise<CommitOutcome>((r) => (outcomeResolve = r));
|
|
@@ -479,7 +482,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
479
482
|
const { navState, commit } = prepareNavigation(currentUrl, {
|
|
480
483
|
payload: payloadTree,
|
|
481
484
|
params,
|
|
482
|
-
segmentInfo
|
|
485
|
+
segmentInfo,
|
|
483
486
|
});
|
|
484
487
|
return {
|
|
485
488
|
payload: payloadTree,
|
|
@@ -487,7 +490,7 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
487
490
|
navState,
|
|
488
491
|
commit,
|
|
489
492
|
decodePromise: null,
|
|
490
|
-
segmentInfo
|
|
493
|
+
segmentInfo,
|
|
491
494
|
skippedSegments: null,
|
|
492
495
|
};
|
|
493
496
|
},
|
|
@@ -517,11 +520,29 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
517
520
|
},
|
|
518
521
|
evictStaleCaches(): void {
|
|
519
522
|
prefetchCache.clearReady();
|
|
520
|
-
historyStack.
|
|
523
|
+
historyStack.clear();
|
|
524
|
+
},
|
|
525
|
+
hydrate(page) {
|
|
526
|
+
// Where hydration seeds the current page: the same prepare-and-commit
|
|
527
|
+
// every navigation goes through, so the segment cache, the committed
|
|
528
|
+
// segment metadata and the history entry are written by one commit
|
|
529
|
+
// rather than by bootstrap reaching into each (TIM-1541). Committed
|
|
530
|
+
// here, at once — see `RouterInstance.hydrate` for why not on React's
|
|
531
|
+
// hydration commit.
|
|
532
|
+
//
|
|
533
|
+
// Replaying this entry on a Back re-renders `payload` and republishes
|
|
534
|
+
// `params`. Both came out of one split of one decoded payload root
|
|
535
|
+
// (rsc-stream.ts), so the entry cannot replay with another route's
|
|
536
|
+
// params (TIM-1037, TIM-1285).
|
|
537
|
+
const { navState, commit } = prepareNavigation(deps.getCurrentUrl(), {
|
|
538
|
+
payload: page.payload,
|
|
539
|
+
params: page.params,
|
|
540
|
+
segmentInfo: page.segmentInfo,
|
|
541
|
+
});
|
|
542
|
+
commit();
|
|
543
|
+
return navState;
|
|
521
544
|
},
|
|
522
|
-
initSegmentCache: (segments: SegmentInfo[]) => updateSegmentCache(segments),
|
|
523
545
|
segmentCache,
|
|
524
546
|
prefetchCache,
|
|
525
|
-
historyStack,
|
|
526
547
|
};
|
|
527
548
|
}
|