@timber-js/app 0.2.0-alpha.15 → 0.2.0-alpha.150
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/LICENSE +8 -0
- package/dist/_chunks/actions-a0RczDnB.js +1106 -0
- package/dist/_chunks/actions-a0RczDnB.js.map +1 -0
- package/dist/_chunks/build-output-helper-B20ZuTSA.js +102 -0
- package/dist/_chunks/build-output-helper-B20ZuTSA.js.map +1 -0
- package/dist/_chunks/cache-api-Co-yI-gP.js +424 -0
- package/dist/_chunks/cache-api-Co-yI-gP.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → canonicalize-P41GR6tY.js} +94 -18
- package/dist/_chunks/canonicalize-P41GR6tY.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-DJDdyEae.js +629 -0
- package/dist/_chunks/cli-schema-sync-DJDdyEae.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-D_IhHEUW.js +2 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
- package/dist/_chunks/define-Bssfp6ot.js +82 -0
- package/dist/_chunks/define-Bssfp6ot.js.map +1 -0
- package/dist/_chunks/define-CFmvb4Bt.js +203 -0
- package/dist/_chunks/define-CFmvb4Bt.js.map +1 -0
- package/dist/_chunks/fast-hash-D6hIVt1Y.js +36 -0
- package/dist/_chunks/fast-hash-D6hIVt1Y.js.map +1 -0
- package/dist/_chunks/format-CfwjgPz9.js +14 -0
- package/dist/_chunks/format-CfwjgPz9.js.map +1 -0
- package/dist/_chunks/href-validation-FiA_rToW.js +141 -0
- package/dist/_chunks/href-validation-FiA_rToW.js.map +1 -0
- package/dist/_chunks/logger-CM0clugc.js +645 -0
- package/dist/_chunks/logger-CM0clugc.js.map +1 -0
- package/dist/_chunks/navigation-root-bUDZLw74.js +124 -0
- package/dist/_chunks/navigation-root-bUDZLw74.js.map +1 -0
- package/dist/_chunks/plugin-context-DurqFBuY.js +2 -0
- package/dist/_chunks/plugin-context-GfDWsdd2.js +268 -0
- package/dist/_chunks/plugin-context-GfDWsdd2.js.map +1 -0
- package/dist/_chunks/registry-DbJPKoBp.js +20 -0
- package/dist/_chunks/registry-DbJPKoBp.js.map +1 -0
- package/dist/_chunks/resolve-schema-3iUvBV5T.js +50 -0
- package/dist/_chunks/resolve-schema-3iUvBV5T.js.map +1 -0
- package/dist/_chunks/router-ref-CtmF-aPv.js +28 -0
- package/dist/_chunks/router-ref-CtmF-aPv.js.map +1 -0
- package/dist/_chunks/schema-bridge-BY3QLBL7.js +119 -0
- package/dist/_chunks/schema-bridge-BY3QLBL7.js.map +1 -0
- package/dist/_chunks/segment-classify-CDDRVKs7.js +137 -0
- package/dist/_chunks/segment-classify-CDDRVKs7.js.map +1 -0
- package/dist/_chunks/segment-context-ZDnXDkbz.js +34 -0
- package/dist/_chunks/segment-context-ZDnXDkbz.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-BOWsq18U.js} +1 -1
- package/dist/_chunks/ssr-data-BOWsq18U.js.map +1 -0
- package/dist/_chunks/tree-match-D2l830j2.js +102 -0
- package/dist/_chunks/tree-match-D2l830j2.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-CbeQmext.js} +7 -20
- package/dist/_chunks/use-query-states-CbeQmext.js.map +1 -0
- package/dist/_chunks/use-segment-params-D1CzlgBo.js +151 -0
- package/dist/_chunks/use-segment-params-D1CzlgBo.js.map +1 -0
- package/dist/_chunks/validation-taUkvA4Q.js +113 -0
- package/dist/_chunks/validation-taUkvA4Q.js.map +1 -0
- package/dist/_chunks/walkers-DvWDj453.js +790 -0
- package/dist/_chunks/walkers-DvWDj453.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +28 -0
- package/dist/adapters/build-output-helper.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.d.ts +109 -0
- package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +73 -0
- package/dist/adapters/cloudflare-dev.js.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +117 -0
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +142 -20
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +150 -64
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/compress-module.d.ts +5 -4
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +17 -3
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +146 -147
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +16 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/cache/cache-api.d.ts +24 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/handler-store.d.ts +31 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +25 -7
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +100 -240
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/invalidation-epoch.d.ts +43 -0
- package/dist/cache/invalidation-epoch.d.ts.map +1 -0
- package/dist/cache/redis-handler.d.ts +85 -8
- package/dist/cache/redis-handler.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts +18 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts +22 -0
- package/dist/cache/sizeof.d.ts.map +1 -0
- package/dist/cache/stable-stringify.d.ts +9 -0
- package/dist/cache/stable-stringify.d.ts.map +1 -1
- package/dist/cache/timber-cache.d.ts +20 -10
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cli-schema-sync.d.ts +59 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +26 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +70 -33
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +34 -1
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
- package/dist/client/browser-entry/hmr.d.ts +21 -0
- package/dist/client/browser-entry/hmr.d.ts.map +1 -0
- package/dist/client/browser-entry/hydrate.d.ts +46 -0
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
- package/dist/client/browser-entry/index.d.ts +29 -0
- package/dist/client/browser-entry/index.d.ts.map +1 -0
- package/dist/client/browser-entry/post-hydration.d.ts +26 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +26 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +28 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +12 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +47 -10
- package/dist/client/error-boundary.js.map +1 -1
- package/dist/client/error-reconstituter.d.ts +61 -0
- package/dist/client/error-reconstituter.d.ts.map +1 -0
- package/dist/client/form.d.ts +16 -27
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/history.d.ts +11 -3
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +10 -24
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +183 -1134
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +19 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +900 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link.d.ts +69 -60
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/navigation-api-types.d.ts +90 -0
- package/dist/client/navigation-api-types.d.ts.map +1 -0
- package/dist/client/navigation-api.d.ts +122 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +3 -2
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/navigation-root.d.ts +119 -0
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts +1 -1
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/router-ref.d.ts +1 -1
- package/dist/client/router.d.ts +86 -10
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +46 -3
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +3 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +49 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/segment-update-context.d.ts +21 -0
- package/dist/client/segment-update-context.d.ts.map +1 -0
- package/dist/client/shallow-url.d.ts +10 -0
- package/dist/client/shallow-url.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +13 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +1 -1
- package/dist/client/top-loader.d.ts +5 -5
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/use-cookie.d.ts +12 -0
- package/dist/client/use-cookie.d.ts.map +1 -1
- package/dist/client/use-link-status.d.ts +5 -5
- package/dist/client/use-link-status.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts.map +1 -1
- package/dist/client/use-pending-navigation.d.ts +23 -0
- package/dist/client/use-pending-navigation.d.ts.map +1 -0
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +1 -1
- package/dist/client/use-router.d.ts.map +1 -1
- package/dist/client/use-search-params.d.ts +12 -5
- package/dist/client/use-search-params.d.ts.map +1 -1
- package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +8 -6
- package/dist/client/use-segment-params.d.ts.map +1 -0
- package/dist/codec.d.ts +69 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +75 -0
- package/dist/codec.js.map +1 -0
- package/dist/config-types.d.ts +294 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-validation.d.ts +51 -0
- package/dist/config-validation.d.ts.map +1 -0
- package/dist/content/index.d.ts +1 -10
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +0 -2
- package/dist/cookies/define-cookie.d.ts +58 -25
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +2 -1
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/cookies/index.js +249 -36
- package/dist/cookies/index.js.map +1 -1
- package/dist/cookies/json-cookie.d.ts +64 -0
- package/dist/cookies/json-cookie.d.ts.map +1 -0
- package/dist/cookies/validation.d.ts +34 -0
- package/dist/cookies/validation.d.ts.map +1 -0
- package/dist/dev-tools/404-page.d.ts +50 -0
- package/dist/dev-tools/404-page.d.ts.map +1 -0
- package/dist/dev-tools/browser-logs.d.ts +84 -0
- package/dist/dev-tools/browser-logs.d.ts.map +1 -0
- package/dist/dev-tools/dev-page-shell.d.ts +78 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -0
- package/dist/dev-tools/error-page.d.ts +32 -0
- package/dist/dev-tools/error-page.d.ts.map +1 -0
- package/dist/dev-tools/holding-server.d.ts +54 -0
- package/dist/dev-tools/holding-server.d.ts.map +1 -0
- package/dist/dev-tools/hydration-overlay.d.ts +11 -0
- package/dist/dev-tools/hydration-overlay.d.ts.map +1 -0
- package/dist/dev-tools/index.d.ts +31 -0
- package/dist/dev-tools/index.d.ts.map +1 -0
- package/dist/dev-tools/instrumentation.d.ts +59 -0
- package/dist/dev-tools/instrumentation.d.ts.map +1 -0
- package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
- package/dist/dev-tools/logger.d.ts.map +1 -0
- package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
- package/dist/dev-tools/logs.d.ts.map +1 -0
- package/dist/dev-tools/overlay.d.ts +91 -0
- package/dist/dev-tools/overlay.d.ts.map +1 -0
- package/dist/dev-tools/stack-classifier.d.ts +34 -0
- package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
- package/dist/dev-tools/terminal.d.ts +28 -0
- package/dist/dev-tools/terminal.d.ts.map +1 -0
- package/dist/fonts/ast-walk.d.ts +68 -0
- package/dist/fonts/ast-walk.d.ts.map +1 -0
- package/dist/fonts/ast.d.ts +110 -6
- package/dist/fonts/ast.d.ts.map +1 -1
- package/dist/fonts/bundle.d.ts +50 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/dev-middleware.d.ts +22 -0
- package/dist/fonts/dev-middleware.d.ts.map +1 -0
- package/dist/fonts/fallbacks.d.ts +0 -7
- package/dist/fonts/fallbacks.d.ts.map +1 -1
- package/dist/fonts/google.d.ts +4 -2
- package/dist/fonts/google.d.ts.map +1 -1
- package/dist/fonts/local.d.ts +4 -4
- package/dist/fonts/local.d.ts.map +1 -1
- package/dist/fonts/paths.d.ts +43 -0
- package/dist/fonts/paths.d.ts.map +1 -0
- package/dist/fonts/pipeline.d.ts +158 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +78 -0
- package/dist/fonts/transform.d.ts.map +1 -0
- package/dist/fonts/types.d.ts +47 -1
- package/dist/fonts/types.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts +77 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +46 -180
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6432 -13423
- package/dist/index.js.map +1 -1
- package/dist/params/codec-registry.d.ts +26 -0
- package/dist/params/codec-registry.d.ts.map +1 -0
- package/dist/params/define-schema.d.ts +81 -0
- package/dist/params/define-schema.d.ts.map +1 -0
- package/dist/params/index.d.ts +5 -0
- package/dist/params/index.d.ts.map +1 -0
- package/dist/params/index.js +34 -0
- package/dist/params/index.js.map +1 -0
- package/dist/params/resolve-schema.d.ts +34 -0
- package/dist/params/resolve-schema.d.ts.map +1 -0
- package/dist/plugin-context.d.ts +137 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +20 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +7 -3
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +9 -7
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/cache.d.ts +73 -0
- package/dist/plugins/cache.d.ts.map +1 -0
- package/dist/plugins/client-chunks.d.ts +39 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/cloudflare-wasm.d.ts +21 -0
- package/dist/plugins/cloudflare-wasm.d.ts.map +1 -0
- package/dist/plugins/content.d.ts +1 -1
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts +17 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +16 -73
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +1 -1
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts +29 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +5 -26
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +67 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +64 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts +7 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/convention-lint.d.ts +41 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/file-cache.d.ts +8 -0
- package/dist/routing/file-cache.d.ts.map +1 -0
- package/dist/routing/index.d.ts +7 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +4 -2
- package/dist/routing/interception.d.ts +0 -5
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/routing/link-codegen.d.ts +90 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/manifest-codegen.d.ts +32 -0
- package/dist/routing/manifest-codegen.d.ts.map +1 -0
- package/dist/routing/scanner.d.ts +1 -10
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/schema-validation.d.ts +35 -0
- package/dist/routing/schema-validation.d.ts.map +1 -0
- package/dist/routing/segment-classify.d.ts +75 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/segment-codegen.d.ts +38 -0
- package/dist/routing/segment-codegen.d.ts.map +1 -0
- package/dist/routing/types.d.ts +77 -25
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +51 -0
- package/dist/routing/walkers.d.ts.map +1 -0
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +12 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/schema-bridge.d.ts +91 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +157 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +37 -440
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/registry.d.ts +2 -2
- package/dist/search-params/registry.d.ts.map +1 -1
- package/dist/search-params/wrappers.d.ts +53 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/segment-params/define.d.ts +89 -0
- package/dist/segment-params/define.d.ts.map +1 -0
- package/dist/segment-params/index.d.ts +3 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +2 -0
- package/dist/server/access-gate.d.ts +8 -3
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +41 -6
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/action-encryption.d.ts +76 -0
- package/dist/server/action-encryption.d.ts.map +1 -0
- package/dist/server/action-handler.d.ts +35 -1
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +9 -30
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +70 -11
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/asset-headers.d.ts +1 -15
- package/dist/server/asset-headers.d.ts.map +1 -1
- package/dist/server/body-limits.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +6 -29
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/canonicalize.d.ts +10 -0
- package/dist/server/canonicalize.d.ts.map +1 -1
- package/dist/server/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- package/dist/server/cookie-context.d.ts +170 -0
- package/dist/server/cookie-context.d.ts.map +1 -0
- package/dist/server/cookie-parsing.d.ts +51 -0
- package/dist/server/cookie-parsing.d.ts.map +1 -0
- package/dist/server/csrf.d.ts +3 -2
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/deny-boundary.d.ts +115 -0
- package/dist/server/deny-boundary.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts +2 -2
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/early-hints-sender.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -11
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -1
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +12 -7
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/flight-injection-state.d.ts +66 -0
- package/dist/server/flight-injection-state.d.ts.map +1 -0
- package/dist/server/flight-scripts.d.ts +42 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/form-data.d.ts +29 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/html-injector-core.d.ts +221 -0
- package/dist/server/html-injector-core.d.ts.map +1 -0
- package/dist/server/html-injectors.d.ts +81 -41
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +10 -46
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +170 -2911
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +44 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +3015 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +39 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/metadata-routes.d.ts +23 -7
- package/dist/server/metadata-routes.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +36 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +119 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/param-coercion.d.ts +54 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +95 -0
- package/dist/server/pipeline-helpers.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +1 -1
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-metadata.d.ts +6 -0
- package/dist/server/pipeline-metadata.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +49 -0
- package/dist/server/pipeline-outcome.d.ts.map +1 -0
- package/dist/server/pipeline-phases.d.ts +56 -0
- package/dist/server/pipeline-phases.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +122 -19
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/port-resolution.d.ts +117 -0
- package/dist/server/port-resolution.d.ts.map +1 -0
- package/dist/server/primitives.d.ts +75 -31
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/render-utils.d.ts +25 -0
- package/dist/server/render-utils.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +62 -107
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +30 -18
- 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 +25 -36
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
- package/dist/server/rsc-entry/api-handler.d.ts +12 -3
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +51 -23
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +19 -8
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +50 -0
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +108 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -0
- package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +17 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +34 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sensitive-fields.d.ts +74 -0
- package/dist/server/sensitive-fields.d.ts.map +1 -0
- package/dist/server/sitemap-generator.d.ts +129 -0
- package/dist/server/sitemap-generator.d.ts.map +1 -0
- package/dist/server/sitemap-handler.d.ts +22 -0
- package/dist/server/sitemap-handler.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +7 -5
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +121 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -0
- package/dist/server/ssr-entry.d.ts +2 -43
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +64 -21
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +50 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/state-tree-diff.d.ts +12 -5
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/dist/server/status-code-resolver.d.ts +22 -11
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +36 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +7 -6
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +62 -30
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/tree-match.d.ts +49 -0
- package/dist/server/tree-match.d.ts.map +1 -0
- package/dist/server/types.d.ts +71 -6
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils/escape-html.d.ts +14 -0
- package/dist/server/utils/escape-html.d.ts.map +1 -0
- package/dist/server/utils/mdx-file.d.ts +15 -0
- package/dist/server/utils/mdx-file.d.ts.map +1 -0
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/shared/head-header.d.ts +54 -0
- package/dist/shared/head-header.d.ts.map +1 -0
- package/dist/shared/href-validation.d.ts +49 -0
- package/dist/shared/href-validation.d.ts.map +1 -0
- package/dist/shared/merge-search-params.d.ts +22 -0
- package/dist/shared/merge-search-params.d.ts.map +1 -0
- package/dist/shared/redirect-type.d.ts +17 -0
- package/dist/shared/redirect-type.d.ts.map +1 -0
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.js +42 -0
- package/dist/shims/font-google.js.map +1 -0
- package/dist/shims/font-local.d.ts +26 -0
- package/dist/shims/font-local.d.ts.map +1 -0
- package/dist/shims/font-local.js +20 -0
- package/dist/shims/font-local.js.map +1 -0
- package/dist/shims/headers.d.ts +53 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/image.d.ts +16 -16
- package/dist/shims/navigation-client.d.ts +35 -11
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +11 -5
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/state-machine.d.ts +80 -0
- package/dist/utils/state-machine.d.ts.map +1 -0
- package/package.json +63 -24
- package/src/adapters/build-output-helper.ts +139 -0
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +179 -0
- package/src/adapters/cloudflare.ts +356 -116
- package/src/adapters/compress-module.ts +27 -92
- package/src/adapters/nitro.ts +155 -99
- package/src/adapters/raw-imports.d.ts +5 -0
- package/src/adapters/shared.ts +40 -0
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +47 -0
- package/src/cache/handler-store.ts +68 -0
- package/src/cache/index.ts +84 -18
- package/src/cache/invalidation-epoch.ts +93 -0
- package/src/cache/redis-handler.ts +110 -15
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/sizeof.ts +33 -0
- package/src/cache/stable-stringify.ts +65 -2
- package/src/cache/timber-cache.ts +132 -36
- package/src/cli-schema-sync.ts +388 -0
- package/src/cli.ts +98 -34
- package/src/client/browser-dev.ts +153 -1
- package/src/client/browser-entry/action-dispatch.ts +119 -0
- package/src/client/browser-entry/hmr.ts +70 -0
- package/src/client/browser-entry/hydrate.ts +187 -0
- package/src/client/browser-entry/index.ts +111 -0
- package/src/client/browser-entry/post-hydration.ts +104 -0
- package/src/client/browser-entry/router-init.ts +292 -0
- package/src/client/browser-entry/rsc-stream.ts +157 -0
- package/src/client/browser-entry/scroll.ts +50 -0
- package/src/client/error-boundary.tsx +127 -22
- package/src/client/error-reconstituter.tsx +79 -0
- package/src/client/form.tsx +31 -32
- package/src/client/history.ts +11 -3
- package/src/client/index.ts +67 -45
- package/src/client/internal.ts +58 -0
- package/src/client/link.tsx +346 -150
- package/src/client/navigation-api-types.ts +112 -0
- package/src/client/navigation-api.ts +347 -0
- package/src/client/navigation-context.ts +15 -7
- package/src/client/navigation-root.tsx +355 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router-ref.ts +1 -1
- package/src/client/router.ts +490 -140
- package/src/client/rsc-fetch.ts +220 -17
- package/src/client/segment-cache.ts +6 -3
- package/src/client/segment-outlet.tsx +77 -0
- package/src/client/segment-update-context.ts +42 -0
- package/src/client/shallow-url.ts +22 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/state.ts +2 -2
- package/src/client/top-loader.tsx +11 -9
- package/src/client/use-cookie.ts +31 -2
- package/src/client/use-link-status.ts +7 -7
- package/src/client/use-pathname.ts +1 -0
- package/src/client/use-pending-navigation.ts +40 -0
- package/src/client/use-query-states.ts +9 -3
- package/src/client/use-router.ts +4 -1
- package/src/client/use-search-params.ts +31 -44
- package/src/client/{use-params.ts → use-segment-params.ts} +9 -6
- package/src/codec.ts +147 -0
- package/src/config-types.ts +292 -0
- package/src/config-validation.ts +311 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +217 -53
- package/src/cookies/index.ts +12 -1
- package/src/cookies/json-cookie.ts +105 -0
- package/src/cookies/validation.ts +192 -0
- package/src/dev-tools/404-page.ts +286 -0
- package/src/dev-tools/browser-logs.ts +291 -0
- package/src/dev-tools/dev-page-shell.ts +260 -0
- package/src/dev-tools/error-page.ts +331 -0
- package/src/dev-tools/holding-server.ts +187 -0
- package/src/dev-tools/hydration-overlay.ts +158 -0
- package/src/dev-tools/index.ts +83 -0
- package/src/dev-tools/instrumentation.ts +213 -0
- package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +9 -5
- package/src/dev-tools/overlay.ts +469 -0
- package/src/dev-tools/stack-classifier.ts +75 -0
- package/src/dev-tools/terminal.ts +183 -0
- package/src/fonts/ast-walk.ts +235 -0
- package/src/fonts/ast.ts +477 -126
- package/src/fonts/bundle.ts +138 -0
- package/src/fonts/dev-middleware.ts +85 -0
- package/src/fonts/fallbacks.ts +0 -23
- package/src/fonts/google.ts +7 -3
- package/src/fonts/local.ts +9 -8
- package/src/fonts/paths.ts +58 -0
- package/src/fonts/pipeline.ts +316 -0
- package/src/fonts/transform.ts +344 -0
- package/src/fonts/types.ts +52 -1
- package/src/fonts/virtual-modules.ts +179 -0
- package/src/index.ts +417 -346
- package/src/params/codec-registry.ts +34 -0
- package/src/params/define-schema.ts +115 -0
- package/src/params/index.ts +17 -0
- package/src/params/resolve-schema.ts +84 -0
- package/src/plugin-context.ts +325 -0
- package/src/plugins/adapter-build.ts +98 -4
- package/src/plugins/build-manifest.ts +168 -23
- package/src/plugins/build-report.ts +16 -25
- package/src/plugins/cache.ts +285 -0
- package/src/plugins/client-chunks.ts +113 -0
- package/src/plugins/cloudflare-wasm.ts +141 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-server.ts +264 -46
- package/src/plugins/entries.ts +110 -8
- package/src/plugins/fonts.ts +170 -663
- package/src/plugins/mdx.ts +47 -10
- package/src/plugins/routing.ts +237 -241
- package/src/plugins/server-bundle.ts +85 -12
- package/src/plugins/shims.ts +207 -64
- package/src/plugins/static-build.ts +15 -89
- package/src/routing/codegen-shared.ts +115 -0
- package/src/routing/codegen-types.ts +65 -0
- package/src/routing/codegen.ts +380 -178
- package/src/routing/convention-lint.ts +358 -0
- package/src/routing/file-cache.ts +23 -0
- package/src/routing/index.ts +10 -1
- package/src/routing/interception.ts +3 -22
- package/src/routing/link-codegen.ts +310 -0
- package/src/routing/manifest-codegen.ts +290 -0
- package/src/routing/scanner.ts +248 -188
- package/src/routing/schema-validation.ts +149 -0
- package/src/routing/segment-classify.ts +188 -0
- package/src/routing/segment-codegen.ts +98 -0
- package/src/routing/types.ts +78 -25
- package/src/routing/walkers.ts +90 -0
- package/src/rsc-runtime/rsc.ts +2 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/schema-bridge.ts +252 -0
- package/src/search-params/define.ts +570 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/registry.ts +2 -2
- package/src/search-params/wrappers.ts +110 -0
- package/src/segment-params/define.ts +249 -0
- package/src/segment-params/index.ts +9 -0
- package/src/server/access-gate.tsx +84 -34
- package/src/server/action-client.ts +119 -28
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +122 -16
- package/src/server/actions.ts +39 -53
- package/src/server/als-registry.ts +108 -20
- package/src/server/asset-headers.ts +8 -34
- package/src/server/body-limits.ts +10 -2
- package/src/server/build-manifest.ts +13 -56
- package/src/server/canonicalize.ts +6 -3
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/compress.ts +34 -7
- package/src/server/cookie-context.ts +484 -0
- package/src/server/cookie-parsing.ts +147 -0
- package/src/server/csrf.ts +39 -6
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-boundary.ts +311 -0
- package/src/server/deny-renderer.ts +80 -64
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/early-hints-sender.ts +3 -2
- package/src/server/early-hints.ts +37 -27
- package/src/server/error-boundary-wrapper.ts +61 -22
- package/src/server/fallback-error.ts +79 -102
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +62 -0
- package/src/server/form-data.ts +101 -5
- package/src/server/html-injector-core.ts +437 -0
- package/src/server/html-injectors.ts +256 -251
- package/src/server/index.ts +29 -183
- package/src/server/internal.ts +165 -0
- package/src/server/logger.ts +67 -36
- package/src/server/metadata-routes.ts +44 -19
- package/src/server/middleware-runner.ts +75 -4
- package/src/server/node-stream-transforms.ts +331 -0
- package/src/server/param-coercion.ts +206 -0
- package/src/server/pipeline-helpers.ts +204 -0
- package/src/server/pipeline-interception.ts +32 -18
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline-outcome.ts +197 -0
- package/src/server/pipeline-phases.ts +527 -0
- package/src/server/pipeline.ts +213 -382
- package/src/server/port-resolution.ts +215 -0
- package/src/server/primitives.ts +126 -63
- package/src/server/render-timeout.ts +108 -0
- package/src/server/render-utils.ts +31 -0
- package/src/server/request-context.ts +168 -337
- package/src/server/route-element-builder.ts +481 -222
- package/src/server/route-handler.ts +31 -4
- package/src/server/route-matcher.ts +144 -277
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/api-handler.ts +69 -32
- package/src/server/rsc-entry/error-renderer.ts +306 -89
- package/src/server/rsc-entry/helpers.ts +160 -59
- package/src/server/rsc-entry/index.ts +299 -329
- package/src/server/rsc-entry/render-route.ts +311 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +344 -0
- package/src/server/rsc-entry/rsc-payload.ts +71 -26
- package/src/server/rsc-entry/rsc-stream.ts +85 -13
- package/src/server/rsc-entry/ssr-bridge.ts +18 -5
- package/src/server/rsc-entry/ssr-renderer.ts +273 -43
- package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/sitemap-generator.ts +338 -0
- package/src/server/sitemap-handler.ts +148 -0
- package/src/server/slot-resolver.ts +258 -257
- package/src/server/ssr-bridge-types.ts +124 -0
- package/src/server/ssr-entry.ts +206 -78
- package/src/server/ssr-render.ts +345 -82
- package/src/server/ssr-wrappers.tsx +141 -0
- package/src/server/state-tree-diff.ts +30 -23
- package/src/server/status-code-resolver.ts +115 -130
- package/src/server/stream-utils.ts +213 -0
- package/src/server/tracing.ts +38 -11
- package/src/server/tree-builder.ts +204 -90
- package/src/server/tree-match.ts +220 -0
- package/src/server/types.ts +78 -9
- package/src/server/utils/escape-html.ts +20 -0
- package/src/server/utils/mdx-file.ts +22 -0
- package/src/server/version-skew.ts +104 -0
- package/src/shared/head-header.ts +69 -0
- package/src/shared/href-validation.ts +159 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shared/redirect-type.ts +17 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/headers.ts +122 -1
- package/src/shims/navigation-client.ts +51 -29
- package/src/shims/navigation.ts +14 -7
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-B3Gypr3D.js +0 -108
- package/dist/_chunks/debug-B3Gypr3D.js.map +0 -1
- package/dist/_chunks/format-RyoGQL74.js +0 -164
- package/dist/_chunks/format-RyoGQL74.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js +0 -676
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/metadata-routes-Cjmvi3rQ.js.map +0 -1
- package/dist/_chunks/request-context-BQUC8PHn.js +0 -330
- package/dist/_chunks/request-context-BQUC8PHn.js.map +0 -1
- package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
- package/dist/_chunks/tracing-CemImE6h.js +0 -187
- package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
- package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
- package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
- package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
- package/dist/cache/register-cached-function.d.ts +0 -17
- package/dist/cache/register-cached-function.d.ts.map +0 -1
- package/dist/client/browser-entry.d.ts +0 -21
- package/dist/client/browser-entry.d.ts.map +0 -1
- package/dist/client/link-status-provider.d.ts +0 -11
- package/dist/client/link-status-provider.d.ts.map +0 -1
- package/dist/client/segment-merger.d.ts +0 -119
- package/dist/client/segment-merger.d.ts.map +0 -1
- package/dist/client/stale-reload.d.ts +0 -44
- package/dist/client/stale-reload.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts +0 -74
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/client/use-navigation-pending.d.ts +0 -26
- package/dist/client/use-navigation-pending.d.ts.map +0 -1
- package/dist/client/use-params.d.ts.map +0 -1
- package/dist/plugins/cache-transform.d.ts +0 -36
- package/dist/plugins/cache-transform.d.ts.map +0 -1
- package/dist/plugins/dev-error-overlay.d.ts +0 -60
- package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
- package/dist/plugins/dev-logs.d.ts.map +0 -1
- package/dist/plugins/dynamic-transform.d.ts +0 -72
- package/dist/plugins/dynamic-transform.d.ts.map +0 -1
- package/dist/plugins/server-action-exports.d.ts +0 -26
- package/dist/plugins/server-action-exports.d.ts.map +0 -1
- package/dist/routing/status-file-lint.d.ts +0 -33
- package/dist/routing/status-file-lint.d.ts.map +0 -1
- package/dist/search-params/analyze.d.ts +0 -54
- package/dist/search-params/analyze.d.ts.map +0 -1
- package/dist/search-params/builtin-codecs.d.ts +0 -105
- package/dist/search-params/builtin-codecs.d.ts.map +0 -1
- package/dist/search-params/codecs.d.ts +0 -53
- package/dist/search-params/codecs.d.ts.map +0 -1
- package/dist/search-params/create.d.ts +0 -106
- package/dist/search-params/create.d.ts.map +0 -1
- package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
- package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
- package/dist/server/dev-logger.d.ts.map +0 -1
- package/dist/server/dev-span-processor.d.ts +0 -29
- package/dist/server/dev-span-processor.d.ts.map +0 -1
- package/dist/server/dev-warnings.d.ts +0 -129
- package/dist/server/dev-warnings.d.ts.map +0 -1
- package/dist/server/flush.d.ts +0 -74
- package/dist/server/flush.d.ts.map +0 -1
- package/dist/server/manifest-status-resolver.d.ts +0 -58
- package/dist/server/manifest-status-resolver.d.ts.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/utils/directive-parser.d.ts +0 -70
- package/dist/utils/directive-parser.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -103
- package/src/client/browser-entry.ts +0 -678
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/segment-merger.ts +0 -339
- package/src/client/stale-reload.ts +0 -87
- package/src/client/transition-root.tsx +0 -166
- package/src/client/use-navigation-pending.ts +0 -38
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dev-error-overlay.ts +0 -230
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/plugins/server-action-exports.ts +0 -220
- package/src/routing/status-file-lint.ts +0 -112
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/codecs.ts +0 -153
- package/src/search-params/create.ts +0 -321
- package/src/server/dev-fetch-instrumentation.ts +0 -96
- package/src/server/dev-span-processor.ts +0 -78
- package/src/server/dev-warnings.ts +0 -283
- package/src/server/flush.ts +0 -182
- package/src/server/manifest-status-resolver.ts +0 -215
- package/src/server/prerender.ts +0 -139
- package/src/utils/directive-parser.ts +0 -529
- /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
package/src/client/router.ts
CHANGED
|
@@ -5,10 +5,20 @@ import { SegmentCache, PrefetchCache, buildSegmentTree } from './segment-cache';
|
|
|
5
5
|
import type { SegmentInfo } from './segment-cache';
|
|
6
6
|
import { HistoryStack } from './history';
|
|
7
7
|
import type { HeadElement } from './head';
|
|
8
|
-
import { setCurrentParams } from './use-params.js';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
import { setCurrentParams } from './use-segment-params.js';
|
|
9
|
+
import {
|
|
10
|
+
setNavigationState,
|
|
11
|
+
getNavigationState,
|
|
12
|
+
type NavigationState,
|
|
13
|
+
} from './navigation-context.js';
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
fetchRscPayload,
|
|
17
|
+
RedirectError,
|
|
18
|
+
ServerErrorResponse,
|
|
19
|
+
VersionSkewError,
|
|
20
|
+
} from './rsc-fetch.js';
|
|
21
|
+
import { setHardNavigating, supersedeNavigationTransitions } from './navigation-root.js';
|
|
12
22
|
import type { FetchResult } from './rsc-fetch.js';
|
|
13
23
|
|
|
14
24
|
// ─── Types ───────────────────────────────────────────────────────
|
|
@@ -18,6 +28,19 @@ export interface NavigationOptions {
|
|
|
18
28
|
scroll?: boolean;
|
|
19
29
|
/** Use replaceState instead of pushState (replaces current history entry) */
|
|
20
30
|
replace?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* @internal AbortSignal from the Navigation API's NavigateEvent.
|
|
33
|
+
* When provided, the signal is linked to the router's per-navigation
|
|
34
|
+
* AbortController so in-flight RSC fetches are cancelled when a new
|
|
35
|
+
* navigation starts.
|
|
36
|
+
*/
|
|
37
|
+
_signal?: AbortSignal;
|
|
38
|
+
/**
|
|
39
|
+
* @internal Skip pushState/replaceState — the Navigation API has already
|
|
40
|
+
* updated the URL via event.intercept(). Used for external navigations
|
|
41
|
+
* intercepted by the navigate event handler.
|
|
42
|
+
*/
|
|
43
|
+
_skipHistory?: boolean;
|
|
21
44
|
}
|
|
22
45
|
|
|
23
46
|
/**
|
|
@@ -31,8 +54,12 @@ export type RscDecoder = (fetchPromise: Promise<Response>) => unknown;
|
|
|
31
54
|
* Function that renders a decoded RSC element tree into the DOM.
|
|
32
55
|
* In production: reactRoot.render(element).
|
|
33
56
|
* In tests: a no-op or mock.
|
|
57
|
+
*
|
|
58
|
+
* Receives the current NavigationState explicitly — no temporal
|
|
59
|
+
* coupling with setNavigationState/getNavigationState. The renderer
|
|
60
|
+
* wraps the element in NavigationProvider with this state.
|
|
34
61
|
*/
|
|
35
|
-
export type RootRenderer = (element: unknown) => void;
|
|
62
|
+
export type RootRenderer = (element: unknown, navState: NavigationState) => void;
|
|
36
63
|
|
|
37
64
|
/**
|
|
38
65
|
* Platform dependencies injected for testability. In production these
|
|
@@ -64,14 +91,73 @@ export interface RouterDeps {
|
|
|
64
91
|
*
|
|
65
92
|
* The `perform` callback receives a `wrapPayload` function to wrap the
|
|
66
93
|
* decoded RSC payload with NavigationProvider + NuqsAdapter before
|
|
67
|
-
*
|
|
94
|
+
* NavigationRoot sets it as the new element. The `wrapPayload` function
|
|
95
|
+
* receives the NavigationState explicitly — no temporal coupling with
|
|
96
|
+
* getNavigationState().
|
|
68
97
|
*
|
|
69
98
|
* If not provided (tests), the router falls back to renderRoot.
|
|
70
99
|
*/
|
|
71
100
|
navigateTransition?: (
|
|
72
101
|
pendingUrl: string,
|
|
73
|
-
perform: (
|
|
102
|
+
perform: (
|
|
103
|
+
wrapPayload: (
|
|
104
|
+
payload: unknown,
|
|
105
|
+
navState: NavigationState,
|
|
106
|
+
segmentUpdates?: Map<string, unknown>
|
|
107
|
+
) => unknown
|
|
108
|
+
) => Promise<{ element: unknown; decodePromise: Promise<void> | null }>
|
|
74
109
|
) => Promise<void>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Whether the Navigation API is active and handling traversals.
|
|
113
|
+
* When true, the popstate handler is a no-op — the Navigation API's
|
|
114
|
+
* navigate event covers back/forward button presses.
|
|
115
|
+
*/
|
|
116
|
+
navigationApiActive?: boolean;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Called around pushState/replaceState to set a flag that prevents
|
|
120
|
+
* the Navigation API's navigate listener from double-handling
|
|
121
|
+
* router-initiated navigations.
|
|
122
|
+
*/
|
|
123
|
+
setRouterNavigating?: (value: boolean) => void;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Save scroll position via the Navigation API's per-entry state.
|
|
127
|
+
* When provided, used instead of history.replaceState for scroll storage.
|
|
128
|
+
*/
|
|
129
|
+
saveNavigationEntryScroll?: (scrollY: number) => void;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Signal that a router-initiated navigation has completed. Resolves the
|
|
133
|
+
* deferred promise that ties the browser's native loading state to the
|
|
134
|
+
* navigation lifecycle. Called in the finally block of navigate/refresh,
|
|
135
|
+
* aligned with when the TopLoader's pendingUrl clears.
|
|
136
|
+
*/
|
|
137
|
+
completeRouterNavigation?: () => void;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get the current unwrapped RSC payload element. Used for partial
|
|
141
|
+
* navigation: the router re-wraps the same element with new
|
|
142
|
+
* NavigationProvider context so mounted SegmentOutlets are preserved.
|
|
143
|
+
*/
|
|
144
|
+
_getCurrentPayload?: () => unknown;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Initiate a navigation via the Navigation API (`navigation.navigate()`).
|
|
148
|
+
* Fires the navigate event BEFORE committing the URL, allowing Chrome
|
|
149
|
+
* to show its native loading indicator. Falls back to pushState when
|
|
150
|
+
* unavailable.
|
|
151
|
+
*/
|
|
152
|
+
navigationNavigate?: (url: string, replace: boolean) => void;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Scroll the element matching a URL #fragment into view. Returns true
|
|
156
|
+
* when a matching element was found and scrolled. When absent or false,
|
|
157
|
+
* the router falls back to scroll-to-top on forward navigation — same
|
|
158
|
+
* as a full page load with an unknown fragment landing at the top.
|
|
159
|
+
*/
|
|
160
|
+
scrollToHash?: (hash: string) => boolean;
|
|
75
161
|
}
|
|
76
162
|
|
|
77
163
|
export interface RouterInstance {
|
|
@@ -80,7 +166,7 @@ export interface RouterInstance {
|
|
|
80
166
|
/** Full re-render of the current URL — no state tree sent */
|
|
81
167
|
refresh(): Promise<void>;
|
|
82
168
|
/** Handle a popstate event (back/forward button). scrollY is read from history.state. */
|
|
83
|
-
handlePopState(url: string, scrollY?: number): Promise<void>;
|
|
169
|
+
handlePopState(url: string, scrollY?: number, externalSignal?: AbortSignal): Promise<void>;
|
|
84
170
|
/** Whether a navigation is currently in flight */
|
|
85
171
|
isPending(): boolean;
|
|
86
172
|
/** The URL currently being navigated to, or null if idle */
|
|
@@ -100,12 +186,7 @@ export interface RouterInstance {
|
|
|
100
186
|
* Called on initial hydration with segment info embedded in the HTML.
|
|
101
187
|
*/
|
|
102
188
|
initSegmentCache(segments: SegmentInfo[]): void;
|
|
103
|
-
|
|
104
|
-
* Cache segment elements from a decoded RSC element tree.
|
|
105
|
-
* Called on initial hydration to populate the element cache so the
|
|
106
|
-
* first client navigation can use partial payloads.
|
|
107
|
-
*/
|
|
108
|
-
cacheElementTree(element: unknown): void;
|
|
189
|
+
|
|
109
190
|
/** The segment cache (exposed for tests and <Link> prefetch) */
|
|
110
191
|
segmentCache: SegmentCache;
|
|
111
192
|
/** The prefetch cache (exposed for tests and <Link> prefetch) */
|
|
@@ -130,24 +211,83 @@ function isAbortError(error: unknown): boolean {
|
|
|
130
211
|
* Create a router instance. In production, called once at app hydration
|
|
131
212
|
* with real browser APIs. In tests, called with mock dependencies.
|
|
132
213
|
*/
|
|
214
|
+
/**
|
|
215
|
+
* Router navigation phase — discriminated union replacing scattered
|
|
216
|
+
* `pending` + `pendingUrl` boolean flags.
|
|
217
|
+
*
|
|
218
|
+
* - `idle`: No navigation in flight. The committed params/pathname
|
|
219
|
+
* are current.
|
|
220
|
+
* - `navigating`: A fetch or render is in progress. `targetUrl` is
|
|
221
|
+
* the destination being navigated to.
|
|
222
|
+
*/
|
|
223
|
+
export type RouterPhase = { phase: 'idle' } | { phase: 'navigating'; targetUrl: string };
|
|
224
|
+
|
|
133
225
|
export function createRouter(deps: RouterDeps): RouterInstance {
|
|
134
226
|
const segmentCache = new SegmentCache();
|
|
135
227
|
const prefetchCache = new PrefetchCache();
|
|
136
228
|
const historyStack = new HistoryStack();
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
let pending = false;
|
|
140
|
-
let pendingUrl: string | null = null;
|
|
229
|
+
let routerPhase: RouterPhase = { phase: 'idle' };
|
|
141
230
|
const pendingListeners = new Set<(pending: boolean) => void>();
|
|
142
231
|
|
|
232
|
+
// AbortController for the current in-flight navigation.
|
|
233
|
+
// When a new navigation starts, the previous controller is aborted,
|
|
234
|
+
// cancelling any in-progress RSC fetch. This provides automatic
|
|
235
|
+
// cancellation of stale fetches regardless of Navigation API support.
|
|
236
|
+
let currentNavAbort: AbortController | null = null;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Create a new AbortController for a navigation, superseding any
|
|
240
|
+
* previous in-flight navigation. Optionally links to an external
|
|
241
|
+
* signal (e.g., from the Navigation API's NavigateEvent.signal).
|
|
242
|
+
*
|
|
243
|
+
* Superseding is one operation with three parts:
|
|
244
|
+
* 1. Abort the previous navigation's fetch.
|
|
245
|
+
* 2. Invalidate its render transition so a response that already
|
|
246
|
+
* arrived can't commit a stale tree (NavigationRoot's transId guard).
|
|
247
|
+
* 3. Resolve its Navigation API deferred — the superseded navigation's
|
|
248
|
+
* finally block is staleness-guarded (see TIM-1034) and no longer
|
|
249
|
+
* cleans up after itself, so the browser's native loading state for
|
|
250
|
+
* the dead navigation is cleared here.
|
|
251
|
+
*/
|
|
252
|
+
function createNavAbort(externalSignal?: AbortSignal): AbortController {
|
|
253
|
+
if (currentNavAbort) {
|
|
254
|
+
currentNavAbort.abort();
|
|
255
|
+
supersedeNavigationTransitions();
|
|
256
|
+
deps.completeRouterNavigation?.();
|
|
257
|
+
}
|
|
258
|
+
const controller = new AbortController();
|
|
259
|
+
currentNavAbort = controller;
|
|
260
|
+
|
|
261
|
+
// If an external signal is provided (e.g., Navigation API),
|
|
262
|
+
// forward its abort to our controller.
|
|
263
|
+
if (externalSignal) {
|
|
264
|
+
if (externalSignal.aborted) {
|
|
265
|
+
controller.abort();
|
|
266
|
+
} else {
|
|
267
|
+
externalSignal.addEventListener('abort', () => controller.abort(), { once: true });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return controller;
|
|
272
|
+
}
|
|
273
|
+
|
|
143
274
|
function setPending(value: boolean, url?: string): void {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
275
|
+
const next: RouterPhase =
|
|
276
|
+
value && url ? { phase: 'navigating', targetUrl: url } : { phase: 'idle' };
|
|
277
|
+
// Skip no-op updates
|
|
278
|
+
if (
|
|
279
|
+
routerPhase.phase === next.phase &&
|
|
280
|
+
(routerPhase.phase === 'idle' ||
|
|
281
|
+
(routerPhase.phase === 'navigating' &&
|
|
282
|
+
next.phase === 'navigating' &&
|
|
283
|
+
routerPhase.targetUrl === next.targetUrl))
|
|
284
|
+
) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
routerPhase = next;
|
|
148
288
|
// Notify external store listeners (non-React consumers).
|
|
149
289
|
// React-facing pending state is handled by useOptimistic in
|
|
150
|
-
//
|
|
290
|
+
// NavigationRoot via navigateTransition — not this function.
|
|
151
291
|
for (const listener of pendingListeners) {
|
|
152
292
|
listener(value);
|
|
153
293
|
}
|
|
@@ -163,94 +303,139 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
163
303
|
}
|
|
164
304
|
|
|
165
305
|
/** Render a decoded RSC payload into the DOM if a renderer is available. */
|
|
166
|
-
function renderPayload(payload: unknown): void {
|
|
306
|
+
function renderPayload(payload: unknown, navState: NavigationState): void {
|
|
167
307
|
if (deps.renderRoot) {
|
|
168
|
-
deps.renderRoot(payload);
|
|
308
|
+
deps.renderRoot(payload, navState);
|
|
169
309
|
}
|
|
170
310
|
}
|
|
171
311
|
|
|
312
|
+
function isPartialNavigation(skippedSegments: string[] | null | undefined): boolean {
|
|
313
|
+
return skippedSegments != null && skippedSegments.length > 0;
|
|
314
|
+
}
|
|
315
|
+
|
|
172
316
|
/**
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* Returns the merged payload ready for rendering.
|
|
317
|
+
* Build a segment updates map for partial navigation. Identifies the
|
|
318
|
+
* first non-skipped segment and maps it to the payload content.
|
|
176
319
|
*/
|
|
177
|
-
function
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
320
|
+
function buildSegmentUpdates(result: FetchResult): Map<string, unknown> {
|
|
321
|
+
const skipped = new Set(result.skippedSegments!);
|
|
322
|
+
const segmentInfo = result.segmentInfo;
|
|
323
|
+
const updates = new Map<string, unknown>();
|
|
324
|
+
if (segmentInfo) {
|
|
325
|
+
for (const info of segmentInfo) {
|
|
326
|
+
if (!skipped.has(info.segmentId ?? info.path)) {
|
|
327
|
+
// Use segmentId (outlet key) when available — route groups
|
|
328
|
+
// use a disambiguated key like "/(marketing)" instead of "/".
|
|
329
|
+
updates.set(info.segmentId ?? info.path, result.payload);
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
186
333
|
}
|
|
187
|
-
|
|
188
|
-
// Cache segment elements from the (merged) payload for future merges
|
|
189
|
-
cacheSegmentElements(merged, segmentElementCache);
|
|
190
|
-
|
|
191
|
-
return merged;
|
|
334
|
+
return updates;
|
|
192
335
|
}
|
|
193
336
|
|
|
194
337
|
/**
|
|
195
338
|
* Update navigation state (params + pathname) for the next render.
|
|
196
339
|
*
|
|
197
|
-
* Sets
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
340
|
+
* Sets the module-level fallback (for tests and SSR) and the
|
|
341
|
+
* globalThis bridge, then returns the NavigationState so callers
|
|
342
|
+
* can pass it explicitly to renderRoot/wrapPayload — eliminating
|
|
343
|
+
* temporal coupling with getNavigationState().
|
|
201
344
|
*/
|
|
202
345
|
function updateNavigationState(
|
|
203
346
|
params: Record<string, string | string[]> | null | undefined,
|
|
204
347
|
url: string
|
|
205
|
-
):
|
|
348
|
+
): NavigationState {
|
|
206
349
|
const resolvedParams = params ?? {};
|
|
207
350
|
// Module-level fallback for tests (no NavigationProvider) and SSR
|
|
208
351
|
setCurrentParams(resolvedParams);
|
|
209
|
-
//
|
|
210
|
-
const
|
|
211
|
-
|
|
352
|
+
// globalThis bridge — kept for backward compat
|
|
353
|
+
const parsed = new URL(url, 'http://localhost');
|
|
354
|
+
const pathname = parsed.pathname || '/';
|
|
355
|
+
const search = parsed.search;
|
|
356
|
+
const navState: NavigationState = { params: resolvedParams, pathname, search };
|
|
357
|
+
setNavigationState(navState);
|
|
358
|
+
return navState;
|
|
212
359
|
}
|
|
213
360
|
|
|
214
361
|
/**
|
|
215
362
|
* Render a payload via navigateTransition (production) or renderRoot (tests).
|
|
216
|
-
* The perform callback should fetch data, update state, and return the
|
|
217
|
-
*
|
|
218
|
-
*
|
|
363
|
+
* The perform callback should fetch data, update state, and return the
|
|
364
|
+
* FetchResult plus the NavigationState (so it can be passed explicitly
|
|
365
|
+
* to wrapPayload/renderRoot without temporal coupling).
|
|
219
366
|
*/
|
|
367
|
+
interface TransitionResult {
|
|
368
|
+
headElements: HeadElement[] | null;
|
|
369
|
+
decodePromise: Promise<void> | null;
|
|
370
|
+
}
|
|
371
|
+
|
|
220
372
|
async function renderViaTransition(
|
|
221
373
|
url: string,
|
|
222
|
-
perform: () => Promise<FetchResult>
|
|
223
|
-
): Promise<
|
|
374
|
+
perform: () => Promise<FetchResult & { navState: NavigationState }>
|
|
375
|
+
): Promise<TransitionResult> {
|
|
224
376
|
if (deps.navigateTransition) {
|
|
225
377
|
let headElements: HeadElement[] | null = null;
|
|
226
378
|
await deps.navigateTransition(url, async (wrapPayload) => {
|
|
227
379
|
const result = await perform();
|
|
228
380
|
headElements = result.headElements;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
381
|
+
|
|
382
|
+
if (isPartialNavigation(result.skippedSegments)) {
|
|
383
|
+
const segmentUpdates = buildSegmentUpdates(result);
|
|
384
|
+
|
|
385
|
+
historyStack.push(url, {
|
|
386
|
+
payload: null,
|
|
387
|
+
headElements: result.headElements,
|
|
388
|
+
params: result.params,
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// Re-wrap the CURRENT element with new context values.
|
|
392
|
+
// SegmentOutlets read updates from SegmentUpdateContext;
|
|
393
|
+
// NavigationProvider gets new params/pathname.
|
|
394
|
+
const element = wrapPayload(
|
|
395
|
+
deps._getCurrentPayload?.() ?? result.payload,
|
|
396
|
+
result.navState,
|
|
397
|
+
segmentUpdates
|
|
398
|
+
);
|
|
399
|
+
return { element, decodePromise: result.decodePromise };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Full navigation — empty updates, render the new tree.
|
|
233
403
|
historyStack.push(url, {
|
|
234
|
-
payload:
|
|
404
|
+
payload: result.payload,
|
|
235
405
|
headElements: result.headElements,
|
|
236
406
|
params: result.params,
|
|
237
407
|
});
|
|
238
|
-
|
|
408
|
+
const element = wrapPayload(result.payload, result.navState);
|
|
409
|
+
return { element, decodePromise: result.decodePromise };
|
|
239
410
|
});
|
|
240
|
-
|
|
411
|
+
// decodePromise is awaited inside the transition's startTransition
|
|
412
|
+
// callback (NavigationRoot), so we don't need it here.
|
|
413
|
+
return { headElements, decodePromise: null };
|
|
241
414
|
}
|
|
242
415
|
// Fallback: no transition (tests, no React tree)
|
|
243
416
|
const result = await perform();
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
417
|
+
if (isPartialNavigation(result.skippedSegments)) {
|
|
418
|
+
historyStack.push(url, {
|
|
419
|
+
payload: null,
|
|
420
|
+
headElements: result.headElements,
|
|
421
|
+
params: result.params,
|
|
422
|
+
});
|
|
423
|
+
} else {
|
|
424
|
+
// Resolve thenables before storing/rendering in the fallback path
|
|
425
|
+
// (tests without navigateTransition). In production, React handles
|
|
426
|
+
// thenables via Suspense; in tests, renderRoot expects resolved values.
|
|
427
|
+
const payload =
|
|
428
|
+
result.payload != null && typeof result.payload === 'object' && 'then' in result.payload
|
|
429
|
+
? await (result.payload as PromiseLike<unknown>)
|
|
430
|
+
: result.payload;
|
|
431
|
+
historyStack.push(url, {
|
|
432
|
+
payload,
|
|
433
|
+
headElements: result.headElements,
|
|
434
|
+
params: result.params,
|
|
435
|
+
});
|
|
436
|
+
renderPayload(payload, result.navState);
|
|
437
|
+
}
|
|
438
|
+
return { headElements: result.headElements, decodePromise: result.decodePromise };
|
|
254
439
|
}
|
|
255
440
|
|
|
256
441
|
/** Apply head elements (title, meta tags) to the DOM if available. */
|
|
@@ -269,20 +454,47 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
269
454
|
}
|
|
270
455
|
}
|
|
271
456
|
|
|
457
|
+
/**
|
|
458
|
+
* Schedule scroll restoration after the next paint and fire the
|
|
459
|
+
* scroll-restored event. Used by navigate, popstate, and refresh.
|
|
460
|
+
*/
|
|
461
|
+
function restoreScrollAfterPaint(scrollY: number): void {
|
|
462
|
+
afterPaint(() => {
|
|
463
|
+
deps.scrollTo(0, scrollY);
|
|
464
|
+
window.dispatchEvent(new Event('timber:scroll-restored'));
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Scroll to the element matching the URL #fragment after paint, falling
|
|
470
|
+
* back to scroll-to-top when no element matches (matching full-page-load
|
|
471
|
+
* behavior for an unknown fragment). Used by forward navigation to a
|
|
472
|
+
* hash-bearing URL (TIM-1035).
|
|
473
|
+
*/
|
|
474
|
+
function scrollToHashAfterPaint(hash: string): void {
|
|
475
|
+
afterPaint(() => {
|
|
476
|
+
if (deps.scrollToHash?.(hash) !== true) {
|
|
477
|
+
deps.scrollTo(0, 0);
|
|
478
|
+
}
|
|
479
|
+
window.dispatchEvent(new Event('timber:scroll-restored'));
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
|
|
272
483
|
/**
|
|
273
484
|
* Core navigation logic shared between the transition and fallback paths.
|
|
274
485
|
* Fetches the RSC payload, updates all state, and returns the result.
|
|
275
486
|
*/
|
|
276
487
|
async function performNavigationFetch(
|
|
277
488
|
url: string,
|
|
278
|
-
options: { replace: boolean }
|
|
279
|
-
): Promise<FetchResult> {
|
|
489
|
+
options: { replace: boolean; commitUrl?: string; signal?: AbortSignal; skipHistory?: boolean }
|
|
490
|
+
): Promise<FetchResult & { navState: NavigationState }> {
|
|
280
491
|
// Check prefetch cache first. PrefetchResult has optional segmentInfo/params
|
|
281
492
|
// fields — normalize to null for FetchResult compatibility.
|
|
282
493
|
const prefetched = prefetchCache.consume(url);
|
|
283
494
|
let result: FetchResult | undefined = prefetched
|
|
284
495
|
? {
|
|
285
496
|
payload: prefetched.payload,
|
|
497
|
+
decodePromise: null,
|
|
286
498
|
headElements: prefetched.headElements,
|
|
287
499
|
segmentInfo: prefetched.segmentInfo ?? null,
|
|
288
500
|
params: prefetched.params ?? null,
|
|
@@ -293,19 +505,29 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
293
505
|
if (result === undefined) {
|
|
294
506
|
// Fetch RSC payload with state tree for partial rendering.
|
|
295
507
|
// Send current URL for intercepting route resolution (modal pattern).
|
|
296
|
-
const stateTree = segmentCache.serializeStateTree(
|
|
508
|
+
const stateTree = segmentCache.serializeStateTree();
|
|
297
509
|
const rawCurrentUrl = deps.getCurrentUrl();
|
|
298
510
|
const currentUrl = rawCurrentUrl.startsWith('http')
|
|
299
511
|
? new URL(rawCurrentUrl).pathname
|
|
300
512
|
: new URL(rawCurrentUrl, 'http://localhost').pathname;
|
|
301
|
-
result = await fetchRscPayload(url, deps, stateTree, currentUrl);
|
|
513
|
+
result = await fetchRscPayload(url, deps, stateTree, currentUrl, options.signal);
|
|
302
514
|
}
|
|
303
515
|
|
|
304
|
-
// Update the browser history —
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
516
|
+
// Update the browser history — skip when the Navigation API has already
|
|
517
|
+
// updated the URL via event.intercept() (external navigations).
|
|
518
|
+
// The committed URL keeps the #fragment (commitUrl) even though the
|
|
519
|
+
// fetch/history-stack URL is hash-less (TIM-1035).
|
|
520
|
+
if (!options.skipHistory) {
|
|
521
|
+
const commitUrl = options.commitUrl ?? url;
|
|
522
|
+
// Set the router-navigating flag so the Navigation API's navigate
|
|
523
|
+
// listener doesn't double-intercept this pushState/replaceState.
|
|
524
|
+
deps.setRouterNavigating?.(true);
|
|
525
|
+
if (options.replace) {
|
|
526
|
+
deps.replaceState({ timber: true, scrollY: 0 }, '', commitUrl);
|
|
527
|
+
} else {
|
|
528
|
+
deps.pushState({ timber: true, scrollY: 0 }, '', commitUrl);
|
|
529
|
+
}
|
|
530
|
+
deps.setRouterNavigating?.(false);
|
|
309
531
|
}
|
|
310
532
|
|
|
311
533
|
// NOTE: History push is deferred — the merged payload (after segment
|
|
@@ -316,29 +538,67 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
316
538
|
// Update the segment cache with the new route's segment tree.
|
|
317
539
|
updateSegmentCache(result.segmentInfo);
|
|
318
540
|
|
|
319
|
-
// Update navigation state
|
|
320
|
-
updateNavigationState(result.params, url);
|
|
541
|
+
// Update navigation state and capture it for explicit passing.
|
|
542
|
+
const navState = updateNavigationState(result.params, url);
|
|
321
543
|
|
|
322
|
-
return result;
|
|
544
|
+
return { ...result, navState };
|
|
323
545
|
}
|
|
324
546
|
|
|
325
547
|
async function navigate(url: string, options: NavigationOptions = {}): Promise<void> {
|
|
326
548
|
const scroll = options.scroll !== false;
|
|
327
549
|
const replace = options.replace === true;
|
|
550
|
+
const externalSignal = options._signal as AbortSignal | undefined;
|
|
551
|
+
const skipHistory = options._skipHistory === true;
|
|
552
|
+
|
|
553
|
+
// Split the #fragment off the navigation URL (TIM-1035). The full URL
|
|
554
|
+
// (with hash) is committed to the address bar; the hash-less URL is used
|
|
555
|
+
// for the RSC fetch (fragments are client-only — keeping it would also
|
|
556
|
+
// swallow the ?_rsc cache-bust param into the fragment) and for
|
|
557
|
+
// history-stack/prefetch keys (popstate lookups use pathname + search).
|
|
558
|
+
const hashIndex = url.indexOf('#');
|
|
559
|
+
const hash = hashIndex === -1 ? '' : url.slice(hashIndex);
|
|
560
|
+
const fetchUrl = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
561
|
+
|
|
562
|
+
// Create an abort controller for this navigation. Links to the external
|
|
563
|
+
// signal (Navigation API's event.signal) when provided.
|
|
564
|
+
const navAbort = createNavAbort(externalSignal);
|
|
328
565
|
|
|
329
566
|
// Capture the departing page's scroll position for scroll={false} preservation.
|
|
330
567
|
const currentScrollY = deps.getScrollY();
|
|
331
568
|
|
|
332
|
-
// Save the departing page's scroll position
|
|
333
|
-
//
|
|
334
|
-
|
|
335
|
-
|
|
569
|
+
// Save the departing page's scroll position — use Navigation API entry
|
|
570
|
+
// state when available, otherwise fall back to history.state.
|
|
571
|
+
if (deps.saveNavigationEntryScroll) {
|
|
572
|
+
deps.saveNavigationEntryScroll(currentScrollY);
|
|
573
|
+
} else {
|
|
574
|
+
deps.replaceState({ timber: true, scrollY: currentScrollY }, '', deps.getCurrentUrl());
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// When Navigation API is active, initiate the navigation via
|
|
578
|
+
// navigation.navigate() BEFORE the fetch. Unlike history.pushState()
|
|
579
|
+
// which commits the URL synchronously (so Chrome sees it as "done"),
|
|
580
|
+
// navigation.navigate() fires the navigate event before committing.
|
|
581
|
+
// Our handler intercepts with a deferred promise, and Chrome shows
|
|
582
|
+
// its native loading indicator until completeRouterNavigation()
|
|
583
|
+
// resolves it in the finally block (same time as TopLoader clears).
|
|
584
|
+
let effectiveSkipHistory = skipHistory;
|
|
585
|
+
if (!skipHistory && deps.navigationNavigate) {
|
|
586
|
+
deps.setRouterNavigating?.(true);
|
|
587
|
+
deps.navigationNavigate(url, replace);
|
|
588
|
+
deps.setRouterNavigating?.(false);
|
|
589
|
+
effectiveSkipHistory = true;
|
|
590
|
+
}
|
|
336
591
|
|
|
337
592
|
setPending(true, url);
|
|
338
593
|
|
|
339
594
|
try {
|
|
340
|
-
const headElements = await renderViaTransition(
|
|
341
|
-
performNavigationFetch(
|
|
595
|
+
const { headElements } = await renderViaTransition(fetchUrl, () =>
|
|
596
|
+
performNavigationFetch(fetchUrl, {
|
|
597
|
+
replace,
|
|
598
|
+
commitUrl: url,
|
|
599
|
+
signal: navAbort.signal,
|
|
600
|
+
skipHistory: effectiveSkipHistory,
|
|
601
|
+
})
|
|
342
602
|
);
|
|
343
603
|
|
|
344
604
|
// Update document.title and <meta> tags with the new page's metadata
|
|
@@ -347,93 +607,168 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
347
607
|
// Notify nuqs adapter (and any other listeners) that navigation completed.
|
|
348
608
|
window.dispatchEvent(new Event('timber:navigation-end'));
|
|
349
609
|
|
|
350
|
-
// Scroll-to-top on forward navigation,
|
|
351
|
-
//
|
|
352
|
-
//
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
window.dispatchEvent(new Event('timber:scroll-restored'));
|
|
360
|
-
});
|
|
610
|
+
// Scroll-to-top on forward navigation, scroll to the #fragment target
|
|
611
|
+
// when the URL has one, or restore captured position for scroll={false}.
|
|
612
|
+
// React's render() on the document root can reset scroll during DOM
|
|
613
|
+
// reconciliation, so all scroll must be actively managed.
|
|
614
|
+
if (scroll && hash) {
|
|
615
|
+
scrollToHashAfterPaint(hash);
|
|
616
|
+
} else {
|
|
617
|
+
restoreScrollAfterPaint(scroll ? 0 : currentScrollY);
|
|
618
|
+
}
|
|
361
619
|
} catch (error) {
|
|
620
|
+
// Version skew — server has been redeployed. Full page reload
|
|
621
|
+
// so the browser fetches the new bundle. See TIM-446.
|
|
622
|
+
if (error instanceof VersionSkewError) {
|
|
623
|
+
setHardNavigating(true);
|
|
624
|
+
window.location.reload();
|
|
625
|
+
return new Promise(() => {}) as never;
|
|
626
|
+
}
|
|
362
627
|
// Server-side redirect during RSC fetch → soft router navigation.
|
|
628
|
+
// The redirect navigate will push/replace its own URL.
|
|
363
629
|
if (error instanceof RedirectError) {
|
|
364
|
-
|
|
630
|
+
// Drop the redirect if a newer navigation superseded this one
|
|
631
|
+
// while the redirect response was in flight — the newer
|
|
632
|
+
// navigation wins, same as the stale-transition guard.
|
|
633
|
+
if (currentNavAbort !== navAbort) return;
|
|
634
|
+
// The recursive navigate() supersedes this one via createNavAbort,
|
|
635
|
+
// which also resolves this navigation's Navigation API deferred.
|
|
365
636
|
await navigate(error.redirectUrl, { replace: true });
|
|
366
637
|
return;
|
|
367
638
|
}
|
|
639
|
+
// Server 5xx error — hard-navigate so the server renders the
|
|
640
|
+
// error page as HTML. See design/10-error-handling.md
|
|
641
|
+
// §"Error Page Rendering for Client Navigation".
|
|
642
|
+
//
|
|
643
|
+
// Set hard-navigating flag BEFORE setting window.location.href:
|
|
644
|
+
// 1. Prevents Navigation API from intercepting → infinite loop
|
|
645
|
+
// 2. Causes NavigationRoot to throw unresolvedThenable → prevents
|
|
646
|
+
// React from rendering children during page teardown (avoids
|
|
647
|
+
// "Rendered more hooks" crashes). See TIM-626.
|
|
648
|
+
if (error instanceof ServerErrorResponse) {
|
|
649
|
+
setHardNavigating(true);
|
|
650
|
+
window.location.href = error.url;
|
|
651
|
+
return new Promise(() => {}) as never;
|
|
652
|
+
}
|
|
368
653
|
// Abort errors are not application errors — swallow silently.
|
|
369
654
|
if (isAbortError(error)) return;
|
|
370
655
|
throw error;
|
|
371
656
|
} finally {
|
|
372
|
-
|
|
657
|
+
// Staleness guard (TIM-1034): only clean up when this navigation
|
|
658
|
+
// still owns the abort controller. When a newer navigation
|
|
659
|
+
// superseded this one, createNavAbort() already replaced
|
|
660
|
+
// currentNavAbort — running setPending(false) /
|
|
661
|
+
// completeRouterNavigation() here would clear the NEWER
|
|
662
|
+
// navigation's pending state and resolve its Navigation API
|
|
663
|
+
// deferred. The superseding navigation resolved OUR deferred in
|
|
664
|
+
// createNavAbort().
|
|
665
|
+
if (currentNavAbort === navAbort) {
|
|
666
|
+
// Clear the abort controller so we don't abort a completed
|
|
667
|
+
// navigation when the next one starts. In dev mode, the RSC body
|
|
668
|
+
// stream stays open after data arrives (React's Flight client
|
|
669
|
+
// waits for debug rows). Aborting a "completed" navigation kills
|
|
670
|
+
// the open stream reader → "BodyStreamBuffer was aborted".
|
|
671
|
+
currentNavAbort = null;
|
|
672
|
+
setPending(false);
|
|
673
|
+
// Resolve the Navigation API deferred — clears the browser's
|
|
674
|
+
// native loading state (tab spinner) at the same time as the
|
|
675
|
+
// TopLoader.
|
|
676
|
+
deps.completeRouterNavigation?.();
|
|
677
|
+
}
|
|
373
678
|
}
|
|
374
679
|
}
|
|
375
680
|
|
|
376
681
|
async function refresh(): Promise<void> {
|
|
377
682
|
const currentUrl = deps.getCurrentUrl();
|
|
683
|
+
const navAbort = createNavAbort();
|
|
378
684
|
|
|
379
685
|
setPending(true, currentUrl);
|
|
380
686
|
|
|
381
687
|
try {
|
|
382
|
-
const headElements = await renderViaTransition(currentUrl, async () => {
|
|
688
|
+
const { headElements } = await renderViaTransition(currentUrl, async () => {
|
|
383
689
|
// No state tree sent — server renders the complete RSC payload
|
|
384
|
-
const result = await fetchRscPayload(
|
|
690
|
+
const result = await fetchRscPayload(
|
|
691
|
+
currentUrl,
|
|
692
|
+
deps,
|
|
693
|
+
undefined,
|
|
694
|
+
undefined,
|
|
695
|
+
navAbort.signal
|
|
696
|
+
);
|
|
385
697
|
// History push handled by renderViaTransition (stores merged payload)
|
|
386
698
|
updateSegmentCache(result.segmentInfo);
|
|
387
|
-
updateNavigationState(result.params, currentUrl);
|
|
388
|
-
return result;
|
|
699
|
+
const navState = updateNavigationState(result.params, currentUrl);
|
|
700
|
+
return { ...result, navState };
|
|
389
701
|
});
|
|
390
702
|
|
|
391
703
|
applyHead(headElements);
|
|
704
|
+
} catch (error) {
|
|
705
|
+
if (isAbortError(error)) return;
|
|
706
|
+
throw error;
|
|
392
707
|
} finally {
|
|
393
|
-
|
|
708
|
+
// Staleness guard (TIM-1034) — see navigate()'s finally block.
|
|
709
|
+
if (currentNavAbort === navAbort) {
|
|
710
|
+
currentNavAbort = null;
|
|
711
|
+
setPending(false);
|
|
712
|
+
deps.completeRouterNavigation?.();
|
|
713
|
+
}
|
|
394
714
|
}
|
|
395
715
|
}
|
|
396
716
|
|
|
397
|
-
async function handlePopState(
|
|
717
|
+
async function handlePopState(
|
|
718
|
+
url: string,
|
|
719
|
+
scrollY: number = 0,
|
|
720
|
+
externalSignal?: AbortSignal
|
|
721
|
+
): Promise<void> {
|
|
398
722
|
// Scroll position is read from history.state by the caller (browser-entry.ts)
|
|
399
723
|
// and passed in. This is more reliable than tracking scroll per-URL in memory
|
|
400
724
|
// because the browser maintains per-entry state even with duplicate URLs.
|
|
401
725
|
const entry = historyStack.get(url);
|
|
402
726
|
|
|
403
727
|
if (entry && entry.payload !== null) {
|
|
404
|
-
// Replay cached payload — no server roundtrip
|
|
405
|
-
|
|
406
|
-
|
|
728
|
+
// Replay cached payload — no server roundtrip.
|
|
729
|
+
//
|
|
730
|
+
// A forward navigation may still be in flight (back pressed while a
|
|
731
|
+
// slow RSC fetch was pending). createNavAbort() supersedes it: aborts
|
|
732
|
+
// its fetch and invalidates its render transition so the stale
|
|
733
|
+
// forward payload can't commit over this replay (TIM-1022). The
|
|
734
|
+
// replay itself is synchronous — nothing to abort later — so the
|
|
735
|
+
// controller is cleared immediately, and any pending state left by
|
|
736
|
+
// the superseded navigation is reset.
|
|
737
|
+
createNavAbort(externalSignal);
|
|
738
|
+
currentNavAbort = null;
|
|
739
|
+
setPending(false);
|
|
740
|
+
const navState = updateNavigationState(entry.params, url);
|
|
741
|
+
renderPayload(entry.payload, navState);
|
|
407
742
|
applyHead(entry.headElements);
|
|
408
|
-
|
|
409
|
-
deps.scrollTo(0, scrollY);
|
|
410
|
-
window.dispatchEvent(new Event('timber:scroll-restored'));
|
|
411
|
-
});
|
|
743
|
+
restoreScrollAfterPaint(scrollY);
|
|
412
744
|
} else {
|
|
413
745
|
// No cached payload — fetch from server.
|
|
414
746
|
// This happens when navigating back to the initial SSR'd page
|
|
415
747
|
// (its payload is null since it was rendered via SSR, not RSC fetch)
|
|
416
748
|
// or when the entry doesn't exist at all.
|
|
749
|
+
const navAbort = createNavAbort(externalSignal);
|
|
417
750
|
setPending(true, url);
|
|
418
751
|
try {
|
|
419
|
-
const headElements = await renderViaTransition(url, async () => {
|
|
420
|
-
const stateTree = segmentCache.serializeStateTree(
|
|
421
|
-
|
|
422
|
-
);
|
|
423
|
-
const result = await fetchRscPayload(url, deps, stateTree);
|
|
752
|
+
const { headElements } = await renderViaTransition(url, async () => {
|
|
753
|
+
const stateTree = segmentCache.serializeStateTree();
|
|
754
|
+
const result = await fetchRscPayload(url, deps, stateTree, undefined, navAbort.signal);
|
|
424
755
|
updateSegmentCache(result.segmentInfo);
|
|
425
|
-
updateNavigationState(result.params, url);
|
|
756
|
+
const navState = updateNavigationState(result.params, url);
|
|
426
757
|
// History push handled by renderViaTransition (stores merged payload)
|
|
427
|
-
return result;
|
|
758
|
+
return { ...result, navState };
|
|
428
759
|
});
|
|
429
760
|
|
|
430
761
|
applyHead(headElements);
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
762
|
+
restoreScrollAfterPaint(scrollY);
|
|
763
|
+
} catch (error) {
|
|
764
|
+
if (isAbortError(error)) return;
|
|
765
|
+
throw error;
|
|
435
766
|
} finally {
|
|
436
|
-
|
|
767
|
+
// Staleness guard (TIM-1034) — see navigate()'s finally block.
|
|
768
|
+
if (currentNavAbort === navAbort) {
|
|
769
|
+
currentNavAbort = null;
|
|
770
|
+
setPending(false);
|
|
771
|
+
}
|
|
437
772
|
}
|
|
438
773
|
}
|
|
439
774
|
}
|
|
@@ -443,15 +778,21 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
443
778
|
* Called on hover of <Link prefetch> elements.
|
|
444
779
|
*/
|
|
445
780
|
function prefetch(url: string): void {
|
|
781
|
+
// Strip fragment — it's client-only and would swallow the _rsc cache-bust
|
|
782
|
+
// param into the hash. The hash-less key also matches navigate()'s fetchUrl.
|
|
783
|
+
const hashIndex = url.indexOf('#');
|
|
784
|
+
const fetchUrl = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
785
|
+
|
|
446
786
|
// Don't prefetch if already cached
|
|
447
|
-
if (prefetchCache.get(
|
|
448
|
-
if (historyStack.has(
|
|
787
|
+
if (prefetchCache.get(fetchUrl) !== undefined) return;
|
|
788
|
+
if (historyStack.has(fetchUrl)) return;
|
|
449
789
|
|
|
450
790
|
// Fire-and-forget fetch
|
|
451
|
-
const stateTree = segmentCache.serializeStateTree(
|
|
452
|
-
void fetchRscPayload(
|
|
791
|
+
const stateTree = segmentCache.serializeStateTree();
|
|
792
|
+
void fetchRscPayload(fetchUrl, deps, stateTree).then(
|
|
453
793
|
(result) => {
|
|
454
|
-
|
|
794
|
+
result.decodePromise?.catch(() => {});
|
|
795
|
+
prefetchCache.set(fetchUrl, result);
|
|
455
796
|
},
|
|
456
797
|
() => {
|
|
457
798
|
// Prefetch failure is non-fatal — navigation will fetch fresh
|
|
@@ -463,8 +804,8 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
463
804
|
navigate,
|
|
464
805
|
refresh,
|
|
465
806
|
handlePopState,
|
|
466
|
-
isPending: () =>
|
|
467
|
-
getPendingUrl: () =>
|
|
807
|
+
isPending: () => routerPhase.phase === 'navigating',
|
|
808
|
+
getPendingUrl: () => (routerPhase.phase === 'navigating' ? routerPhase.targetUrl : null),
|
|
468
809
|
onPendingChange(listener) {
|
|
469
810
|
pendingListeners.add(listener);
|
|
470
811
|
return () => pendingListeners.delete(listener);
|
|
@@ -474,18 +815,27 @@ export function createRouter(deps: RouterDeps): RouterInstance {
|
|
|
474
815
|
// Render the piggybacked element tree from a server action response.
|
|
475
816
|
// Updates the current history entry with the fresh payload and applies
|
|
476
817
|
// head elements — same as refresh() but without a server fetch.
|
|
477
|
-
//
|
|
818
|
+
// Revalidation payloads are already resolved (no Flight thenable),
|
|
819
|
+
// so no segment merging is needed — just cache and render.
|
|
478
820
|
const currentUrl = deps.getCurrentUrl();
|
|
479
|
-
|
|
821
|
+
|
|
822
|
+
// Revalidation doesn't change params/pathname — preserve current state.
|
|
823
|
+
// DO NOT call updateNavigationState(null, ...) here: that normalizes
|
|
824
|
+
// params to {}, clearing dynamic route params on every action response.
|
|
825
|
+
const navState = getNavigationState();
|
|
826
|
+
|
|
827
|
+
// Keep params on the overwritten entry — dropping them would make
|
|
828
|
+
// away-and-back navigation replay this page with params normalized
|
|
829
|
+
// to {} (TIM-1037).
|
|
480
830
|
historyStack.push(currentUrl, {
|
|
481
|
-
payload:
|
|
831
|
+
payload: element,
|
|
482
832
|
headElements,
|
|
833
|
+
params: navState.params,
|
|
483
834
|
});
|
|
484
|
-
renderPayload(
|
|
835
|
+
renderPayload(element, navState);
|
|
485
836
|
applyHead(headElements);
|
|
486
837
|
},
|
|
487
838
|
initSegmentCache: (segments: SegmentInfo[]) => updateSegmentCache(segments),
|
|
488
|
-
cacheElementTree: (element: unknown) => cacheSegmentElements(element, segmentElementCache),
|
|
489
839
|
segmentCache,
|
|
490
840
|
prefetchCache,
|
|
491
841
|
historyStack,
|