@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
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hydration —
|
|
2
|
+
* Hydration — making the server-rendered page current and hydrating the
|
|
3
|
+
* React root with it.
|
|
3
4
|
*
|
|
4
5
|
* Handles two paths:
|
|
5
6
|
* 1. RSC payload available: hydrate the router's React root with the payload
|
|
6
|
-
* 2. No RSC payload: nothing — the root is created by the first
|
|
7
|
-
* (client/react-root.ts)
|
|
7
|
+
* 2. No RSC payload: nothing to hydrate — the root is created by the first
|
|
8
|
+
* render (client/react-root.ts) — but the page is still made current
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* functions that depend on steps 1-2
|
|
10
|
+
* Either way the page becomes current through `RouterInstance.hydrate`, the
|
|
11
|
+
* same prepare-and-commit every navigation uses, committed before the tree
|
|
12
|
+
* is handed to React. The one ordering left is that the router exists
|
|
13
|
+
* before `hydrateRoot()`, so `useRouter()` works during render. Pathname
|
|
14
|
+
* and search reach the tree as props of its NavigationProvider, from the
|
|
15
|
+
* router's prepared navState — there is no store to seed first (TIM-1541).
|
|
16
16
|
*
|
|
17
|
-
* Params are not part of this sequence. They arrive on the payload root and
|
|
17
|
+
* Params are not part of this sequence either. They arrive on the payload root and
|
|
18
18
|
* are published by `PayloadRoot` at the top of the tree, so
|
|
19
19
|
* `useSegmentParams()` is correct during hydration without anything having to
|
|
20
20
|
* run before it (TIM-1294, TIM-1297).
|
|
@@ -22,11 +22,10 @@
|
|
|
22
22
|
* See design/19-client-navigation.md §"NavigationContext"
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import { getRouterOrNull } from '#client-internal';
|
|
26
|
-
import { getNavigationState, setNavigationState } from '../navigation-context.ts';
|
|
27
25
|
import { isPageUnloading } from '../unload-guard.ts';
|
|
28
|
-
import { locationSearch } from '../location-search.ts';
|
|
29
26
|
import type { ReactRootHost } from '../react-root.ts';
|
|
27
|
+
import { readPublishedParams } from '../../shared/payload-root.ts';
|
|
28
|
+
import type { SegmentInfo } from '../../shared/segment-info.ts';
|
|
30
29
|
|
|
31
30
|
import type { RscStreamResult } from './rsc-stream.ts';
|
|
32
31
|
import type { RouterInitResult } from './router-init.ts';
|
|
@@ -74,45 +73,39 @@ interface HydrateOptions {
|
|
|
74
73
|
rscResult: RscStreamResult | null;
|
|
75
74
|
/** The router's React root — the one every navigation renders through. */
|
|
76
75
|
reactRoot: ReactRootHost;
|
|
77
|
-
/**
|
|
78
|
-
|
|
76
|
+
/** Makes the page current and builds its tree — see `RouterInitResult.hydrate`. */
|
|
77
|
+
hydrate: RouterInitResult['hydrate'];
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* that had to execute before `hydrateRoot()`, because hydration synchronously
|
|
87
|
-
* renders components that read them. They now ride the payload root, and the
|
|
88
|
-
* provider that publishes them renders before its own descendants — so the
|
|
89
|
-
* ordering the step existed to guarantee is now a property of the tree rather
|
|
90
|
-
* than of the bootstrap sequence (TIM-1294, TIM-1297).
|
|
81
|
+
* Take the segment metadata the server embedded in the document
|
|
82
|
+
* (`self.__timber_segments`), and remove it. It describes the chain the
|
|
83
|
+
* server rendered, so the first client navigation can send a state tree.
|
|
84
|
+
* See design/19-client-navigation.md §"X-Timber-State-Tree Header".
|
|
91
85
|
*/
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
86
|
+
function takeEmbeddedSegmentInfo(): SegmentInfo[] | null {
|
|
87
|
+
const embedded: unknown = Reflect.get(self, '__timber_segments');
|
|
88
|
+
Reflect.deleteProperty(self, '__timber_segments');
|
|
89
|
+
return Array.isArray(embedded) ? embedded : null;
|
|
97
90
|
}
|
|
98
91
|
|
|
99
92
|
/**
|
|
100
|
-
*
|
|
93
|
+
* Make the server-rendered page current, and hydrate the React tree with it
|
|
94
|
+
* when an RSC payload is available.
|
|
101
95
|
*
|
|
102
96
|
* Wraps the payload with the router's chain (NavigationProvider,
|
|
103
97
|
* TimberNuqsAdapter, the slot content cache, ...) and hydrates the router's
|
|
104
98
|
* React root with it, on the document.
|
|
105
99
|
*
|
|
106
|
-
* When no RSC payload is available (JS-only client)
|
|
107
|
-
*
|
|
100
|
+
* When no RSC payload is available (JS-only client) the page is committed
|
|
101
|
+
* at once and there is nothing to hydrate: the root must not be created at
|
|
102
|
+
* bootstrap —
|
|
108
103
|
* `createRoot(document).render()` would take React ownership of the entire
|
|
109
104
|
* document and blank the SSR HTML — so the router's first render, i.e. the
|
|
110
105
|
* first navigation or revalidation, creates it with the tree it renders
|
|
111
106
|
* (`createReactRoot`, TIM-600 / TIM-580).
|
|
112
107
|
*/
|
|
113
|
-
export function hydrateApp({ rscResult, reactRoot,
|
|
114
|
-
if (!rscResult) return;
|
|
115
|
-
|
|
108
|
+
export function hydrateApp({ rscResult, reactRoot, hydrate }: HydrateOptions): void {
|
|
116
109
|
// The chain is the router's own `renderTree`, not a copy: an element type
|
|
117
110
|
// that is present here and absent on the first navigation (or the
|
|
118
111
|
// reverse) changes the type at that position, and React remounts
|
|
@@ -123,26 +116,28 @@ export function hydrateApp({ rscResult, reactRoot, renderTree }: HydrateOptions)
|
|
|
123
116
|
// record: the inlined Flight stream is still arriving and hydration cannot
|
|
124
117
|
// wait for it. PayloadRoot suspends on it exactly where React was going to
|
|
125
118
|
// suspend on `element` (TIM-1297).
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
119
|
+
const page = {
|
|
120
|
+
payload: rscResult?.element ?? null,
|
|
121
|
+
params: rscResult?.params ?? readPublishedParams(undefined),
|
|
122
|
+
segmentInfo: takeEmbeddedSegmentInfo(),
|
|
123
|
+
};
|
|
124
|
+
//
|
|
125
|
+
// `hydrate` comes from the router's own init, so the router exists by
|
|
126
|
+
// construction when the tree it builds renders.
|
|
127
|
+
hydrate(page, (element) =>
|
|
128
|
+
reactRoot.hydrate(element, {
|
|
129
|
+
// Suppress recoverable hydration errors from deny/error signals
|
|
130
|
+
// inside Suspense boundaries. The server already handled these
|
|
131
|
+
// (wrapStreamWithErrorHandling closes the stream cleanly after
|
|
132
|
+
// the shell is flushed). React replays the error during hydration
|
|
133
|
+
// but the server HTML is already correct — no recovery needed.
|
|
134
|
+
onRecoverableError(error: unknown) {
|
|
135
|
+
if (isPageUnloading()) return;
|
|
136
|
+
if (process.env.NODE_ENV === 'development') {
|
|
137
|
+
queueOrShowHydrationError(error);
|
|
138
|
+
console.debug('[timber] Hydration recoverable error:', error);
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
);
|
|
148
143
|
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* action-dispatch.ts — server action callServer callback
|
|
8
8
|
* rsc-stream.ts — __timber_f chunk handling + ReadableStream
|
|
9
9
|
* router-init.ts — createRouter + Navigation API setup
|
|
10
|
-
* hydrate.ts —
|
|
11
|
-
* post-hydration.ts —
|
|
10
|
+
* hydrate.ts — makes the server page current + hydrates the root
|
|
11
|
+
* post-hydration.ts — popstate, scroll
|
|
12
12
|
* hmr.ts — dev-only HMR + error forwarding
|
|
13
13
|
* scroll.ts — getScrollY helper
|
|
14
14
|
*
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
* 2. createRscPayloadStream() — decode inlined RSC payload
|
|
19
19
|
* 3. createReactRoot() + — the root host the router renders through,
|
|
20
20
|
* createTimberRouter() then the router + Navigation API
|
|
21
|
-
* 4.
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* 4. hydrateApp() — make the page current through the router,
|
|
22
|
+
* hydrate the root (no root without a payload)
|
|
23
|
+
* 5. setupPostHydration() — popstate, scroll
|
|
24
|
+
* 6. setupHmr() — dev-only HMR wiring
|
|
25
|
+
* 7. timber-ready signal — E2E test readiness indicator
|
|
26
26
|
*
|
|
27
27
|
* Design docs: 18-build-system.md §"Entry Files", 19-client-navigation.md
|
|
28
28
|
*/
|
|
@@ -44,8 +44,7 @@ import { createRscPayloadStream } from './rsc-stream.ts';
|
|
|
44
44
|
import { createTimberRouter } from './router-init.ts';
|
|
45
45
|
import { createReactRoot } from '../react-root.ts';
|
|
46
46
|
import type { TopLoaderConfig } from '../top-loader.tsx';
|
|
47
|
-
import {
|
|
48
|
-
import { runPreHydration, hydrateApp } from './hydrate.ts';
|
|
47
|
+
import { hydrateApp } from './hydrate.ts';
|
|
49
48
|
import { setupPostHydration } from './post-hydration.ts';
|
|
50
49
|
import { setupHmr } from './hmr.ts';
|
|
51
50
|
|
|
@@ -53,7 +52,7 @@ import { setupHmr } from './hmr.ts';
|
|
|
53
52
|
|
|
54
53
|
setupServerActions();
|
|
55
54
|
|
|
56
|
-
// ─── 2–
|
|
55
|
+
// ─── 2–6. Bootstrap ─────────────────────────────────────────────
|
|
57
56
|
|
|
58
57
|
function bootstrap(runtimeConfig: typeof config): void {
|
|
59
58
|
// Initialize deployment ID for version skew detection (TIM-446).
|
|
@@ -89,35 +88,25 @@ function bootstrap(runtimeConfig: typeof config): void {
|
|
|
89
88
|
container: document,
|
|
90
89
|
topLoaderConfig: (runtimeConfig as { topLoader?: TopLoaderConfig }).topLoader,
|
|
91
90
|
});
|
|
92
|
-
const { router, navApiController,
|
|
91
|
+
const { router, navApiController, hydrate } = createTimberRouter({
|
|
93
92
|
render: reactRoot.render,
|
|
94
|
-
initialElement: rscResult?.element ?? undefined,
|
|
95
|
-
initialParams: rscResult?.params,
|
|
96
93
|
clientSegmentCache:
|
|
97
94
|
((runtimeConfig as Record<string, unknown>).clientSegmentCache as boolean) ?? false,
|
|
98
95
|
});
|
|
99
96
|
|
|
100
|
-
// Step 4:
|
|
101
|
-
|
|
97
|
+
// Step 4: Make the page current and hydrate (no root without a payload)
|
|
98
|
+
hydrateApp({ rscResult, reactRoot, hydrate });
|
|
102
99
|
|
|
103
|
-
// Step 5:
|
|
104
|
-
|
|
100
|
+
// Step 5: Post-hydration wiring
|
|
101
|
+
setupPostHydration({ router, navApiController });
|
|
105
102
|
|
|
106
|
-
// Step 6:
|
|
107
|
-
setupPostHydration({
|
|
108
|
-
router,
|
|
109
|
-
navApiController,
|
|
110
|
-
initialElement: rscResult?.element ?? null,
|
|
111
|
-
initialParams: rscResult?.params ?? readPublishedParams(undefined),
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Step 7: HMR (dev-only, no-op in production)
|
|
103
|
+
// Step 6: HMR (dev-only, no-op in production)
|
|
115
104
|
setupHmr(router);
|
|
116
105
|
}
|
|
117
106
|
|
|
118
107
|
bootstrap(config);
|
|
119
108
|
|
|
120
|
-
// ───
|
|
109
|
+
// ─── 7. Ready Signal ────────────────────────────────────────────
|
|
121
110
|
|
|
122
111
|
// Signal that the client runtime has been initialized.
|
|
123
112
|
// Used by E2E tests to wait for hydration before interacting.
|
|
@@ -1,66 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Post-Hydration Wiring —
|
|
2
|
+
* Post-Hydration Wiring — popstate and scroll.
|
|
3
3
|
*
|
|
4
4
|
* Sets up everything that needs to happen after the React root exists:
|
|
5
|
-
* - Stores initial page in history stack for instant back navigation
|
|
6
5
|
* - Initializes scroll state for the initial entry
|
|
7
|
-
* - Populates segment cache from server-embedded metadata
|
|
8
6
|
* - Registers popstate handler for back/forward navigation
|
|
9
7
|
* - Sets up debounced scroll position saving
|
|
10
8
|
*
|
|
9
|
+
* The initial page's history entry and segment cache are not written here:
|
|
10
|
+
* they are the router's, and hydration makes the page current through
|
|
11
|
+
* `RouterInstance.hydrate` like any other commit (TIM-1541).
|
|
12
|
+
*
|
|
11
13
|
* See design/19-client-navigation.md §"History Stack"
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
16
|
import type { RouterInstance } from '#client-internal';
|
|
15
|
-
import { getNavigationState } from '../navigation-context.ts';
|
|
16
17
|
import type { NavigationApiController } from '../navigation-api.ts';
|
|
17
18
|
import { getScrollY } from './scroll.ts';
|
|
18
|
-
import type { ParamsSource } from '../../shared/payload-root.ts';
|
|
19
19
|
import { locationSearch } from '../location-search.ts';
|
|
20
20
|
|
|
21
21
|
interface PostHydrationOptions {
|
|
22
22
|
router: RouterInstance;
|
|
23
23
|
navApiController: NavigationApiController | null;
|
|
24
|
-
/** Decoded RSC element from initial SSR (null if no RSC payload) */
|
|
25
|
-
initialElement: unknown;
|
|
26
|
-
/** The params that payload published, from the same decode. */
|
|
27
|
-
initialParams: ParamsSource;
|
|
28
24
|
}
|
|
29
25
|
|
|
30
26
|
/**
|
|
31
27
|
* Wire up post-hydration event handlers and state.
|
|
32
28
|
*/
|
|
33
|
-
export function setupPostHydration({
|
|
34
|
-
router,
|
|
35
|
-
navApiController,
|
|
36
|
-
initialElement,
|
|
37
|
-
initialParams,
|
|
38
|
-
}: PostHydrationOptions): void {
|
|
39
|
-
// Populate the segment cache from server-embedded segment metadata.
|
|
40
|
-
// This enables state tree diffing from the very first client navigation.
|
|
41
|
-
// See design/19-client-navigation.md §"X-Timber-State-Tree Header"
|
|
42
|
-
const timberSegments = (self as unknown as Record<string, unknown>).__timber_segments;
|
|
43
|
-
const initialSegmentInfo = Array.isArray(timberSegments)
|
|
44
|
-
? (timberSegments as import('../../shared/segment-info.ts').SegmentInfo[])
|
|
45
|
-
: null;
|
|
46
|
-
if (initialSegmentInfo) {
|
|
47
|
-
router.initSegmentCache(initialSegmentInfo);
|
|
48
|
-
delete (self as unknown as Record<string, unknown>).__timber_segments;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Store the initial page in the history stack so back-button works
|
|
52
|
-
// after the first navigation. Include segmentInfo so the segment
|
|
53
|
-
// cache is restored correctly on popstate cached replay.
|
|
54
|
-
// Replaying this entry on a Back re-renders `initialElement` and republishes
|
|
55
|
-
// `initialParams`. Both came out of one split of one decoded payload root
|
|
56
|
-
// (rsc-stream.ts), so the entry cannot replay with another route's params —
|
|
57
|
-
// which is what a separately-seeded copy used to do (TIM-1037, TIM-1285).
|
|
58
|
-
router.historyStack.push(window.location.pathname + locationSearch(), {
|
|
59
|
-
payload: initialElement,
|
|
60
|
-
params: initialParams,
|
|
61
|
-
segmentInfo: initialSegmentInfo,
|
|
62
|
-
});
|
|
63
|
-
|
|
29
|
+
export function setupPostHydration({ router, navApiController }: PostHydrationOptions): void {
|
|
64
30
|
// Leave scrollRestoration = 'auto' so the browser natively restores
|
|
65
31
|
// scroll on reload, tab restore, and back-from-external-page — cases
|
|
66
32
|
// JS cannot reliably cover because 'manual' persists on the session
|
|
@@ -10,16 +10,13 @@
|
|
|
10
10
|
import { createElement } from 'react';
|
|
11
11
|
import { createFromFetch } from '../../rsc-runtime/browser.ts';
|
|
12
12
|
import { PayloadRoot } from '../params-context.ts';
|
|
13
|
-
import {
|
|
13
|
+
import type { ParamsSource } from '../../shared/payload-root.ts';
|
|
14
14
|
import { createRouter, setGlobalRouter } from '#client-internal';
|
|
15
15
|
import type { RouterDeps, RouterInstance } from '#client-internal';
|
|
16
16
|
import type { NavigationState } from '#client-internal';
|
|
17
|
+
import type { HydrationPage } from '../router-types.ts';
|
|
17
18
|
import { TimberNuqsAdapter } from '../nuqs-adapter.tsx';
|
|
18
|
-
import {
|
|
19
|
-
NavigationProvider,
|
|
20
|
-
getNavigationState,
|
|
21
|
-
setNavigationState,
|
|
22
|
-
} from '../navigation-context.ts';
|
|
19
|
+
import { NavigationProvider } from '../navigation-context.ts';
|
|
23
20
|
import { navigateTransition, type RenderOwner } from '../navigation-transition.ts';
|
|
24
21
|
import type { NavigationRender } from '../navigation-root.tsx';
|
|
25
22
|
import { SegmentUpdateContext, EMPTY_SEGMENT_UPDATES } from '../segment-update-context.ts';
|
|
@@ -40,9 +37,6 @@ export interface RouterInitOptions {
|
|
|
40
37
|
* around `root.render`, and the `publish` it takes runs on React's commit.
|
|
41
38
|
*/
|
|
42
39
|
render: NavigationRender;
|
|
43
|
-
initialElement?: unknown;
|
|
44
|
-
/** The params the hydration payload published, beside `initialElement`. */
|
|
45
|
-
initialParams?: ParamsSource;
|
|
46
40
|
clientSegmentCache?: boolean;
|
|
47
41
|
}
|
|
48
42
|
|
|
@@ -50,17 +44,12 @@ export interface RouterInitResult {
|
|
|
50
44
|
router: RouterInstance;
|
|
51
45
|
navApiController: NavigationApiController | null;
|
|
52
46
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* below it) and share the router's slot content cache.
|
|
47
|
+
* Make the server-rendered page current and hand its tree to React
|
|
48
|
+
* hydration. `hydrateRoot` receives the tree, built by the same
|
|
49
|
+
* `renderTree` every navigation renders through. With no payload there is
|
|
50
|
+
* no tree to hydrate and `hydrateRoot` is not called.
|
|
58
51
|
*/
|
|
59
|
-
|
|
60
|
-
tree: unknown,
|
|
61
|
-
navState: NavigationState,
|
|
62
|
-
params: ParamsSource
|
|
63
|
-
) => React.ReactElement;
|
|
52
|
+
hydrate: (page: HydrationPage, hydrateRoot: (element: React.ReactElement) => void) => void;
|
|
64
53
|
}
|
|
65
54
|
|
|
66
55
|
/**
|
|
@@ -78,20 +67,23 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
78
67
|
// See design/19-client-navigation.md §"Navigation API Integration"
|
|
79
68
|
const useNavApi = hasNavigationApi();
|
|
80
69
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
70
|
+
/**
|
|
71
|
+
* The tree on screen, with the params published over it and the location
|
|
72
|
+
* it renders — the client's one record of the displayed page. Null until
|
|
73
|
+
* a page with a payload is on screen (a document hydrated without one).
|
|
74
|
+
*
|
|
75
|
+
* The unwrapped tree is kept because a partial navigation re-wraps this
|
|
76
|
+
* same element with new context so mounted SegmentOutlets are preserved
|
|
77
|
+
* (they pick up changes via SegmentUpdateContext, not from new children
|
|
78
|
+
* props). The params and location are kept beside it because the render
|
|
79
|
+
* paths that do NOT receive a payload — a shallow search update, a partial
|
|
80
|
+
* navigation — must republish them rather than drop them.
|
|
81
|
+
*
|
|
82
|
+
* The location used to live in a separate `globalThis` store as well,
|
|
83
|
+
* written by the router's commit, by hydration and by the shallow search
|
|
84
|
+
* path, and read back here. It was a second record of this one (TIM-1541).
|
|
85
|
+
*/
|
|
86
|
+
let displayed: { tree: unknown; params: ParamsSource; navState: NavigationState } | null = null;
|
|
95
87
|
|
|
96
88
|
// The slot content the client has committed, by segmentPath. Owned here so
|
|
97
89
|
// there is exactly one per router (never a module or globalThis singleton —
|
|
@@ -114,14 +106,14 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
114
106
|
* tests/e2e/segment-merge-navigation.test.ts when the params wrapper was
|
|
115
107
|
* conditional).
|
|
116
108
|
*
|
|
117
|
-
* `PayloadRoot` is *above*
|
|
109
|
+
* `PayloadRoot` is *above* the displayed tree, which on a partial navigation
|
|
118
110
|
* is the retained tree. That position is the whole design: it is the only
|
|
119
111
|
* provider a reader in a skipped layout can resolve to (TIM-1297).
|
|
120
112
|
*
|
|
121
113
|
* Pure — building the element does not make it the displayed one. Every
|
|
122
114
|
* caller pairs this with `publishTree` at the point the tree is actually
|
|
123
115
|
* handed to React, because a navigation builds its element before it is
|
|
124
|
-
* known to have won and a superseded one must leave
|
|
116
|
+
* known to have won and a superseded one must leave the displayed record
|
|
125
117
|
* describing the route still on screen (TIM-1301).
|
|
126
118
|
*/
|
|
127
119
|
function renderTree(
|
|
@@ -146,14 +138,14 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
146
138
|
}
|
|
147
139
|
|
|
148
140
|
/**
|
|
149
|
-
* Record the tree the client is now displaying,
|
|
150
|
-
*
|
|
151
|
-
* payload (a shallow search update, a partial navigation)
|
|
152
|
-
*
|
|
141
|
+
* Record the tree the client is now displaying, the params published over
|
|
142
|
+
* it and the location it renders. Written together — the paths that re-wrap
|
|
143
|
+
* without a fresh payload (a shallow search update, a partial navigation)
|
|
144
|
+
* read them back as one and would otherwise restore one route's tree with
|
|
145
|
+
* another's params or pathname.
|
|
153
146
|
*/
|
|
154
|
-
function publishTree(tree: unknown, params: ParamsSource): void {
|
|
155
|
-
|
|
156
|
-
currentParams = params;
|
|
147
|
+
function publishTree(tree: unknown, params: ParamsSource, navState: NavigationState): void {
|
|
148
|
+
displayed = { tree, params, navState };
|
|
157
149
|
}
|
|
158
150
|
|
|
159
151
|
// Late-bound: syncShallowSearch is defined before createRouter, but only
|
|
@@ -187,26 +179,25 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
187
179
|
* the patched pushState/replaceState returns).
|
|
188
180
|
*
|
|
189
181
|
* Bails when search is unchanged (scroll saves, no-ops, dual-fire).
|
|
190
|
-
* Re-wraps
|
|
182
|
+
* Re-wraps the displayed tree with updated NavigationProvider and hands it to
|
|
191
183
|
* React through the root's `render` (startTransition — non-blocking).
|
|
192
184
|
*/
|
|
193
185
|
function syncShallowSearch(search?: string): void {
|
|
186
|
+
if (!displayed) return;
|
|
194
187
|
const currentSearch = search != null ? stripRscCacheKey(search) : locationSearch();
|
|
195
|
-
|
|
196
|
-
if (currentSearch === navState.search) return;
|
|
197
|
-
if (!currentPayload) return;
|
|
188
|
+
if (currentSearch === displayed.navState.search) return;
|
|
198
189
|
|
|
199
190
|
// A shallow search update does not re-render the tree from the server, so
|
|
200
191
|
// the params are unchanged — but they are the client's to publish now, and
|
|
201
|
-
// this path rebuilds the whole chain. Republishing `
|
|
192
|
+
// this path rebuilds the whole chain. Republishing `displayed.params` is what
|
|
202
193
|
// keeps a `?q=` change from silently clearing the route's params
|
|
203
194
|
// (TIM-1285's failure mode, on a path that used to be exempt from it
|
|
204
195
|
// because the record lived inside the payload).
|
|
196
|
+
const { tree, params } = displayed;
|
|
205
197
|
const newNavState: NavigationState = {
|
|
206
|
-
pathname: navState.pathname,
|
|
198
|
+
pathname: displayed.navState.pathname,
|
|
207
199
|
search: currentSearch,
|
|
208
200
|
};
|
|
209
|
-
setNavigationState(newNavState);
|
|
210
201
|
|
|
211
202
|
// A shallow search update displaces whatever React is rendering. If a
|
|
212
203
|
// handed-off tree is still suspended (e.g. a cached popstate replay whose
|
|
@@ -223,8 +214,8 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
223
214
|
// (TIM-1480).
|
|
224
215
|
queueMicrotask(() => router?.settleHandoffs());
|
|
225
216
|
|
|
226
|
-
publishTree(
|
|
227
|
-
render(renderTree(
|
|
217
|
+
publishTree(tree, params, newNavState);
|
|
218
|
+
render(renderTree(tree, newNavState, params), null);
|
|
228
219
|
}
|
|
229
220
|
|
|
230
221
|
window.history.pushState = function (
|
|
@@ -287,33 +278,6 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
287
278
|
return createFromFetch(fetchPromise);
|
|
288
279
|
},
|
|
289
280
|
|
|
290
|
-
// Render a decoded RSC tree through the router's React root. Used for
|
|
291
|
-
// non-navigation renders (popstate cached replay, applyActionResult).
|
|
292
|
-
// Wraps with NavigationProvider + TimberNuqsAdapter.
|
|
293
|
-
//
|
|
294
|
-
// For navigation renders (navigate, refresh, popstate-with-fetch),
|
|
295
|
-
// navigateTransition is used instead — it hands the destination tree to
|
|
296
|
-
// React in a transition so the departing page stays visible.
|
|
297
|
-
//
|
|
298
|
-
// navState is passed explicitly by the router — no temporal coupling
|
|
299
|
-
// with getNavigationState().
|
|
300
|
-
renderRoot: (
|
|
301
|
-
element: unknown,
|
|
302
|
-
navState: NavigationState,
|
|
303
|
-
params: ParamsSource,
|
|
304
|
-
commit: () => void
|
|
305
|
-
) => {
|
|
306
|
-
// These paths render what is already decided (a replay, a
|
|
307
|
-
// revalidation), but "decided" is not "on screen": the tree goes out in
|
|
308
|
-
// a transition React may hold. The publish — the router's and this
|
|
309
|
-
// module's record of the displayed tree — runs when React commits it,
|
|
310
|
-
// the same way a navigation's does (TIM-1301, TIM-1423).
|
|
311
|
-
render(renderTree(element, navState, params), () => {
|
|
312
|
-
publishTree(element, params);
|
|
313
|
-
commit();
|
|
314
|
-
});
|
|
315
|
-
},
|
|
316
|
-
|
|
317
281
|
// Hand a navigation's tree to React in a transition
|
|
318
282
|
// (navigation-transition.ts). The fetch runs outside any transition
|
|
319
283
|
// scope; only the render that hands the tree over is wrapped, and in a
|
|
@@ -323,7 +287,10 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
323
287
|
//
|
|
324
288
|
// The perform callback receives a wrapPayload function that wraps the
|
|
325
289
|
// decoded RSC payload with NavigationProvider + NuqsAdapter. navState
|
|
326
|
-
// is passed explicitly by the router
|
|
290
|
+
// is passed explicitly by the router.
|
|
291
|
+
//
|
|
292
|
+
// Every render the router makes comes through here — navigations,
|
|
293
|
+
// refreshes, traversals (fetched or replayed) and revalidations.
|
|
327
294
|
//
|
|
328
295
|
// `_url` names the pending URL the router already published to its own
|
|
329
296
|
// pending store before calling here; the transition has no use for it.
|
|
@@ -335,7 +302,8 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
335
302
|
// record of the displayed tree is navigation state like any other, so
|
|
336
303
|
// it rides the same commit as the segment cache rather than being
|
|
337
304
|
// written as a side effect of building the element (TIM-1301).
|
|
338
|
-
let
|
|
305
|
+
let built: { tree: unknown; params: ParamsSource; navState: NavigationState } | null =
|
|
306
|
+
null;
|
|
339
307
|
const { element, decodePromise, commit } = await perform(
|
|
340
308
|
(
|
|
341
309
|
rawPayload: unknown,
|
|
@@ -343,7 +311,7 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
343
311
|
params: ParamsSource,
|
|
344
312
|
segmentUpdates?: Map<string, unknown>
|
|
345
313
|
) => {
|
|
346
|
-
|
|
314
|
+
built = { tree: rawPayload, params, navState };
|
|
347
315
|
return renderTree(
|
|
348
316
|
rawPayload,
|
|
349
317
|
navState,
|
|
@@ -356,7 +324,7 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
356
324
|
element: element as React.ReactNode,
|
|
357
325
|
decodePromise,
|
|
358
326
|
commit: () => {
|
|
359
|
-
if (
|
|
327
|
+
if (built) publishTree(built.tree, built.params, built.navState);
|
|
360
328
|
commit();
|
|
361
329
|
},
|
|
362
330
|
};
|
|
@@ -366,7 +334,7 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
366
334
|
);
|
|
367
335
|
},
|
|
368
336
|
|
|
369
|
-
_getCurrentPayload: () =>
|
|
337
|
+
_getCurrentPayload: () => displayed?.tree ?? null,
|
|
370
338
|
|
|
371
339
|
// Schedule a callback after the next paint so scroll operations
|
|
372
340
|
// happen after React commits the new content to the DOM.
|
|
@@ -414,5 +382,19 @@ export function createTimberRouter(options: RouterInitOptions): RouterInitResult
|
|
|
414
382
|
deps.navigationNavigate = (url, replace) => navApiController!.navigate(url, replace);
|
|
415
383
|
}
|
|
416
384
|
|
|
417
|
-
|
|
385
|
+
/**
|
|
386
|
+
* See `RouterInitResult.hydrate`.
|
|
387
|
+
*
|
|
388
|
+
* Everything is recorded at handover, not on hydration's commit: the
|
|
389
|
+
* server's HTML for this tree is already what the user is looking at, and
|
|
390
|
+
* React may never commit the hydration render — see `RouterInstance.hydrate`.
|
|
391
|
+
*/
|
|
392
|
+
const hydrate: RouterInitResult['hydrate'] = (page, hydrateRoot) => {
|
|
393
|
+
const navState = router.hydrate(page);
|
|
394
|
+
if (page.payload == null) return;
|
|
395
|
+
publishTree(page.payload, page.params, navState);
|
|
396
|
+
hydrateRoot(renderTree(page.payload, navState, page.params));
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
return { router, navApiController, hydrate };
|
|
418
400
|
}
|