@timber-js/app 0.2.0-alpha.16 → 0.2.0-alpha.160
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/agent-skill.md +344 -0
- package/dist/_chunks/actions-C9yAuoX3.js +314 -0
- package/dist/_chunks/actions-C9yAuoX3.js.map +1 -0
- package/dist/_chunks/build-output-helper-DF5uScqS.js +158 -0
- package/dist/_chunks/build-output-helper-DF5uScqS.js.map +1 -0
- package/dist/_chunks/cache-api-swbefQ6F.js +1125 -0
- package/dist/_chunks/cache-api-swbefQ6F.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-BhYDz_-x.js +638 -0
- package/dist/_chunks/cli-schema-sync-BhYDz_-x.js.map +1 -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/dist-BA3u1z3W.js +423 -0
- package/dist/_chunks/dist-BA3u1z3W.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-CMc5JRls.js +141 -0
- package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -0
- package/dist/_chunks/logger-CPoQkGK6.js +1523 -0
- package/dist/_chunks/logger-CPoQkGK6.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-DeAxFRMq.js +280 -0
- package/dist/_chunks/plugin-context-DeAxFRMq.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/sizeof-lXffQ1Vr.js +35 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.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/walkers-c8aReVgo.js +988 -0
- package/dist/_chunks/walkers-c8aReVgo.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +29 -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 +177 -20
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +342 -67
- 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 +1 -3
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +143 -144
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +6 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/cache/cache-api.d.ts +26 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/handler-store.d.ts +33 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +27 -7
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +3 -326
- 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 +97 -8
- package/dist/cache/redis-handler.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts +19 -2
- 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/store.d.ts +53 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.d.ts +38 -0
- package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.js +29 -0
- package/dist/cache/stores/cloudflare-kv.js.map +1 -0
- package/dist/cache/stores/memory.d.ts +42 -0
- package/dist/cache/stores/memory.d.ts.map +1 -0
- package/dist/cache/stores/memory.js +90 -0
- package/dist/cache/stores/memory.js.map +1 -0
- package/dist/cache/stores/redis.d.ts +69 -0
- package/dist/cache/stores/redis.d.ts.map +1 -0
- package/dist/cache/stores/redis.js +35 -0
- package/dist/cache/stores/redis.js.map +1 -0
- package/dist/cache/stores/vercel.d.ts +36 -0
- package/dist/cache/stores/vercel.d.ts.map +1 -0
- package/dist/cache/stores/vercel.js +33 -0
- package/dist/cache/stores/vercel.js.map +1 -0
- package/dist/cache/tag-aware-handler.d.ts +51 -0
- package/dist/cache/tag-aware-handler.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +20 -10
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cdn/cloudflare-purge.d.ts +23 -0
- package/dist/cdn/cloudflare-purge.d.ts.map +1 -0
- package/dist/cdn/fastly-purge.d.ts +25 -0
- package/dist/cdn/fastly-purge.d.ts.map +1 -0
- package/dist/cdn/headers.d.ts +97 -0
- package/dist/cdn/headers.d.ts.map +1 -0
- package/dist/cdn/index.d.ts +5 -0
- package/dist/cdn/index.d.ts.map +1 -0
- package/dist/cdn/purge-store.d.ts +23 -0
- package/dist/cdn/purge-store.d.ts.map +1 -0
- package/dist/cdn/workers-cache-purge.d.ts +16 -0
- package/dist/cdn/workers-cache-purge.d.ts.map +1 -0
- package/dist/cli-schema-sync.d.ts +59 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +34 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +107 -33
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +37 -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 -6
- 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 +182 -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 +825 -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.d.ts +120 -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 +87 -14
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +47 -14
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +4 -4
- 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 +304 -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 +253 -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 +40 -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 +82 -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 +7807 -13691
- 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 +190 -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 +43 -7
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/cache.d.ts +64 -0
- package/dist/plugins/cache.d.ts.map +1 -0
- package/dist/plugins/callsite-ast.d.ts +95 -0
- package/dist/plugins/callsite-ast.d.ts.map +1 -0
- package/dist/plugins/callsite-jsx.d.ts +35 -0
- package/dist/plugins/callsite-jsx.d.ts.map +1 -0
- package/dist/plugins/chunks.d.ts +11 -4
- package/dist/plugins/chunks.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +40 -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/prebuilt-capture.d.ts +60 -0
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -0
- package/dist/plugins/prebuilt.d.ts +82 -0
- package/dist/plugins/prebuilt.d.ts.map +1 -0
- package/dist/plugins/prerender-sugar.d.ts +42 -0
- package/dist/plugins/prerender-sugar.d.ts.map +1 -0
- 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/export-detect.d.ts +56 -0
- package/dist/routing/export-detect.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 +6 -30
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +85 -11
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/asset-headers.d.ts +8 -18
- 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 +65 -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 +41 -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 +82 -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 +49 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +3577 -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/prebuilt/cache-key.d.ts +58 -0
- package/dist/server/prebuilt/cache-key.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +57 -0
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts +27 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts.map +1 -0
- package/dist/server/prebuilt/overlay.d.ts +100 -0
- package/dist/server/prebuilt/overlay.d.ts.map +1 -0
- package/dist/server/prebuilt/payload-source.d.ts +78 -0
- package/dist/server/prebuilt/payload-source.d.ts.map +1 -0
- package/dist/server/prebuilt/synthetic-store.d.ts +66 -0
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -0
- package/dist/server/prebuilt-builder.d.ts +120 -0
- package/dist/server/prebuilt-builder.d.ts.map +1 -0
- package/dist/server/prebuilt-runtime.d.ts +101 -0
- package/dist/server/prebuilt-runtime.d.ts.map +1 -0
- package/dist/server/primitives.d.ts +83 -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 +39 -25
- 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 -28
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +30 -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 +5 -6
- 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 +47 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +44 -9
- 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/server/workers-cache-bridge.d.ts +26 -0
- package/dist/server/workers-cache-bridge.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/docs/api/30-api-server.mdx +233 -0
- package/docs/api/31-api-client.mdx +161 -0
- package/docs/api/32-api-cache.mdx +199 -0
- package/docs/api/33-api-search-params.mdx +141 -0
- package/docs/api/34-api-config.mdx +189 -0
- package/docs/api/35-api-typescript.mdx +170 -0
- package/docs/api/36-cli.mdx +143 -0
- package/docs/learn/00-introduction.mdx +76 -0
- package/docs/learn/01-quick-start.mdx +94 -0
- package/docs/learn/02-pages-and-layouts.mdx +147 -0
- package/docs/learn/03-fetching-data.mdx +211 -0
- package/docs/learn/03b-access-control.mdx +130 -0
- package/docs/learn/04-loading-states.mdx +67 -0
- package/docs/learn/04b-the-flush-point.mdx +115 -0
- package/docs/learn/05-typed-params.mdx +275 -0
- package/docs/learn/06-forms-and-actions.mdx +146 -0
- package/docs/learn/07-typed-routes.mdx +127 -0
- package/docs/learn/08-streaming.mdx +146 -0
- package/docs/learn/09-caching.mdx +136 -0
- package/docs/learn/10-middleware.mdx +157 -0
- package/docs/learn/11-error-handling.mdx +156 -0
- package/docs/learn/12-client-navigation.mdx +168 -0
- package/docs/learn/13-configuration.mdx +145 -0
- package/docs/learn/14-deploying.mdx +264 -0
- package/docs/more/01-advanced-routing.mdx +139 -0
- package/docs/more/02-advanced-forms.mdx +137 -0
- package/docs/more/03-coming-from-nextjs.mdx +186 -0
- package/docs/more/04-metadata-and-fonts.mdx +193 -0
- package/docs/more/04b-mdx.mdx +209 -0
- package/docs/more/05-content-collections.mdx +90 -0
- package/docs/more/06-instrumentation.mdx +214 -0
- package/docs/more/07-security.mdx +129 -0
- package/docs/more/08-developer-experience.mdx +134 -0
- package/docs/more/40-why-timber.mdx +50 -0
- package/docs/more/41-timber-vs-nextjs.mdx +81 -0
- package/docs/more/42-timber-vs-others.mdx +68 -0
- package/docs/more/50-ai-agent-instructions.mdx +169 -0
- package/llms.txt +55 -0
- package/package.json +102 -26
- package/src/adapters/build-output-helper.ts +199 -0
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +179 -0
- package/src/adapters/cloudflare.ts +594 -119
- package/src/adapters/compress-module.ts +27 -92
- package/src/adapters/nitro.ts +131 -96
- package/src/adapters/raw-imports.d.ts +5 -0
- package/src/adapters/shared.ts +68 -0
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +107 -0
- package/src/cache/handler-store.ts +76 -0
- package/src/cache/index.ts +88 -18
- package/src/cache/invalidation-epoch.ts +93 -0
- package/src/cache/redis-handler.ts +122 -15
- package/src/cache/singleflight.ts +64 -6
- package/src/cache/sizeof.ts +33 -0
- package/src/cache/stable-stringify.ts +65 -2
- package/src/cache/store.ts +71 -0
- package/src/cache/stores/cloudflare-kv.ts +52 -0
- package/src/cache/stores/memory.ts +125 -0
- package/src/cache/stores/redis.ts +97 -0
- package/src/cache/stores/vercel.ts +59 -0
- package/src/cache/tag-aware-handler.ts +233 -0
- package/src/cache/timber-cache.ts +142 -36
- package/src/cdn/cloudflare-purge.ts +50 -0
- package/src/cdn/fastly-purge.ts +63 -0
- package/src/cdn/headers.ts +153 -0
- package/src/cdn/index.ts +17 -0
- package/src/cdn/purge-store.ts +34 -0
- package/src/cdn/workers-cache-purge.ts +30 -0
- package/src/cli-schema-sync.ts +388 -0
- package/src/cli.ts +157 -34
- package/src/client/browser-dev.ts +156 -1
- package/src/client/browser-entry/action-dispatch.ts +124 -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 +103 -0
- package/src/client/browser-entry/router-init.ts +287 -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 -7
- 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.ts +341 -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 +482 -166
- package/src/client/rsc-fetch.ts +214 -33
- package/src/client/segment-cache.ts +7 -7
- 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 +49 -14
- 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 +302 -0
- package/src/config-validation.ts +328 -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 +55 -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/{server/dev-logger.ts → dev-tools/logger.ts} +33 -51
- 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 +182 -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 +63 -8
- 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 +305 -0
- package/src/fonts/types.ts +52 -1
- package/src/fonts/virtual-modules.ts +179 -0
- package/src/index.ts +431 -352
- 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 +378 -0
- package/src/plugins/adapter-build.ts +98 -4
- package/src/plugins/build-manifest.ts +168 -23
- package/src/plugins/build-report.ts +253 -35
- package/src/plugins/cache.ts +186 -0
- package/src/plugins/callsite-ast.ts +167 -0
- package/src/plugins/callsite-jsx.ts +243 -0
- package/src/plugins/chunks.ts +74 -5
- package/src/plugins/client-chunks.ts +144 -0
- package/src/plugins/cloudflare-wasm.ts +141 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-server.ts +293 -46
- package/src/plugins/entries.ts +129 -8
- package/src/plugins/fonts.ts +191 -664
- package/src/plugins/mdx.ts +47 -10
- package/src/plugins/prebuilt-capture.ts +210 -0
- package/src/plugins/prebuilt.ts +700 -0
- package/src/plugins/prerender-sugar.ts +329 -0
- package/src/plugins/routing.ts +237 -241
- package/src/plugins/server-bundle.ts +97 -12
- package/src/plugins/shims.ts +217 -64
- package/src/plugins/static-build.ts +15 -90
- package/src/routing/codegen-shared.ts +115 -0
- package/src/routing/codegen-types.ts +65 -0
- package/src/routing/codegen.ts +360 -178
- package/src/routing/convention-lint.ts +394 -0
- package/src/routing/export-detect.ts +304 -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 +281 -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 +9 -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 +123 -33
- package/src/server/actions.ts +39 -54
- package/src/server/als-registry.ts +129 -20
- package/src/server/asset-headers.ts +15 -37
- 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 +163 -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 +85 -77
- 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 +124 -12
- package/src/server/html-injector-core.ts +437 -0
- package/src/server/html-injectors.ts +267 -254
- package/src/server/index.ts +29 -183
- package/src/server/internal.ts +181 -0
- package/src/server/logger.ts +72 -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 +14 -0
- package/src/server/pipeline-outcome.ts +197 -0
- package/src/server/pipeline-phases.ts +538 -0
- package/src/server/pipeline.ts +226 -382
- package/src/server/port-resolution.ts +215 -0
- package/src/server/prebuilt/cache-key.ts +224 -0
- package/src/server/prebuilt/capture-state.ts +89 -0
- package/src/server/prebuilt/manifest-tag-index.ts +46 -0
- package/src/server/prebuilt/overlay.ts +256 -0
- package/src/server/prebuilt/payload-source.ts +201 -0
- package/src/server/prebuilt/synthetic-store.ts +121 -0
- package/src/server/prebuilt-builder.ts +696 -0
- package/src/server/prebuilt-runtime.ts +708 -0
- package/src/server/primitives.ts +155 -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 +523 -233
- 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 -76
- package/src/server/rsc-entry/index.ts +393 -329
- package/src/server/rsc-entry/render-route.ts +284 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +349 -0
- package/src/server/rsc-entry/rsc-payload.ts +72 -33
- 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 +344 -0
- package/src/server/sitemap-handler.ts +157 -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 +286 -0
- package/src/server/tracing.ts +126 -14
- 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/server/workers-cache-bridge.ts +33 -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/index.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/head.d.ts +0 -16
- package/dist/client/head.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/client-module-map.d.ts +0 -47
- package/dist/server/client-module-map.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/head.ts +0 -61
- 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/client-module-map.ts +0 -58
- 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
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hydration — pre-hydration sequence and React root creation.
|
|
3
|
+
*
|
|
4
|
+
* Handles two paths:
|
|
5
|
+
* 1. RSC payload available: hydrateRoot with NavigationProvider wrapping
|
|
6
|
+
* 2. No RSC payload: deferred root creation via installDeferredNavigation
|
|
7
|
+
*
|
|
8
|
+
* Pre-hydration ordering contract (MUST execute in this order):
|
|
9
|
+
* 1. initRouter() — creates the global router so useRouter()
|
|
10
|
+
* works during render
|
|
11
|
+
* 2. setCurrentParams() — populates params snapshot so
|
|
12
|
+
* + setNavigationState() useSegmentParams() and usePathname()
|
|
13
|
+
* return correct values during hydration
|
|
14
|
+
* 3. hydrateRoot() — synchronously executes component render
|
|
15
|
+
* functions that depend on steps 1-2
|
|
16
|
+
*
|
|
17
|
+
* See design/19-client-navigation.md §"NavigationContext"
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { createElement } from 'react';
|
|
21
|
+
import { hydrateRoot, createRoot } from 'react-dom/client';
|
|
22
|
+
import { getRouterOrNull, setCurrentParams } from '#client-internal';
|
|
23
|
+
import {
|
|
24
|
+
NavigationProvider,
|
|
25
|
+
getNavigationState,
|
|
26
|
+
setNavigationState,
|
|
27
|
+
} from '../navigation-context.js';
|
|
28
|
+
import { SegmentUpdateContext, EMPTY_SEGMENT_UPDATES } from '../segment-update-context.js';
|
|
29
|
+
import { TimberNuqsAdapter } from '../nuqs-adapter.js';
|
|
30
|
+
import { isPageUnloading } from '../unload-guard.js';
|
|
31
|
+
import { NavigationRoot, installDeferredNavigation } from '../navigation-root.js';
|
|
32
|
+
import type { TopLoaderConfig } from '../top-loader.js';
|
|
33
|
+
|
|
34
|
+
import type { RscStreamResult } from './rsc-stream.js';
|
|
35
|
+
|
|
36
|
+
let showHydrationError: ((error: unknown) => void) | null = null;
|
|
37
|
+
let isHydrationError: ((error: unknown) => boolean) | null = null;
|
|
38
|
+
let pendingHydrationErrors: unknown[] = [];
|
|
39
|
+
|
|
40
|
+
// React 19 emits attribute-only hydration mismatches via console.error
|
|
41
|
+
// with format substitution: console.error(fmt, link, diff). We must
|
|
42
|
+
// intercept before hydrateRoot() to catch errors during initial hydration.
|
|
43
|
+
const ATTR_MISMATCH_RE =
|
|
44
|
+
/A tree hydrated but some attributes of the server rendered HTML didn't match/;
|
|
45
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
46
|
+
const origConsoleError = console.error;
|
|
47
|
+
console.error = (...args: unknown[]) => {
|
|
48
|
+
origConsoleError.apply(console, args);
|
|
49
|
+
if (typeof args[0] === 'string' && ATTR_MISMATCH_RE.test(args[0])) {
|
|
50
|
+
const message = args
|
|
51
|
+
.slice(1)
|
|
52
|
+
.reduce<string>((s, arg) => s.replace('%s', String(arg)), args[0] as string);
|
|
53
|
+
queueOrShowHydrationError(new Error(message));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
import('../../dev-tools/hydration-overlay.js').then((m) => {
|
|
57
|
+
showHydrationError = m.showHydrationError;
|
|
58
|
+
isHydrationError = m.isHydrationError;
|
|
59
|
+
for (const err of pendingHydrationErrors) {
|
|
60
|
+
if (m.isHydrationError(err)) m.showHydrationError(err);
|
|
61
|
+
}
|
|
62
|
+
pendingHydrationErrors = [];
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function queueOrShowHydrationError(error: unknown): void {
|
|
67
|
+
if (showHydrationError && isHydrationError) {
|
|
68
|
+
if (isHydrationError(error)) showHydrationError(error);
|
|
69
|
+
} else {
|
|
70
|
+
pendingHydrationErrors.push(error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface HydrateOptions {
|
|
75
|
+
/** RSC stream result (null if no inlined payload) */
|
|
76
|
+
rscResult: RscStreamResult | null;
|
|
77
|
+
/** Runtime config from virtual:timber-config */
|
|
78
|
+
config: { topLoader?: TopLoaderConfig };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Run the pre-hydration sequence: read server-embedded params and
|
|
83
|
+
* set navigation state. Must be called AFTER initRouter().
|
|
84
|
+
*/
|
|
85
|
+
export function runPreHydration(): void {
|
|
86
|
+
const earlyParams = (self as unknown as Record<string, unknown>).__timber_params;
|
|
87
|
+
if (earlyParams && typeof earlyParams === 'object') {
|
|
88
|
+
setCurrentParams(earlyParams as Record<string, string | string[]>);
|
|
89
|
+
setNavigationState({
|
|
90
|
+
params: earlyParams as Record<string, string | string[]>,
|
|
91
|
+
pathname: window.location.pathname,
|
|
92
|
+
search: window.location.search,
|
|
93
|
+
});
|
|
94
|
+
delete (self as unknown as Record<string, unknown>).__timber_params;
|
|
95
|
+
} else {
|
|
96
|
+
setNavigationState({
|
|
97
|
+
params: {},
|
|
98
|
+
pathname: window.location.pathname,
|
|
99
|
+
search: window.location.search,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Hydrate the React tree or set up deferred root creation.
|
|
106
|
+
*
|
|
107
|
+
* When an RSC payload is available, wraps it with NavigationProvider +
|
|
108
|
+
* TimberNuqsAdapter + NavigationRoot and calls hydrateRoot on the
|
|
109
|
+
* document.
|
|
110
|
+
*
|
|
111
|
+
* When no RSC payload is available (JS-only client), sets up deferred
|
|
112
|
+
* navigation so the first client navigation creates the React root.
|
|
113
|
+
*/
|
|
114
|
+
export function hydrateApp({ rscResult, config }: HydrateOptions): void {
|
|
115
|
+
if (rscResult) {
|
|
116
|
+
const element = rscResult.element;
|
|
117
|
+
|
|
118
|
+
// Wrap with NavigationProvider (for atomic useParams/usePathname),
|
|
119
|
+
// TimberNuqsAdapter (for nuqs context), and NavigationRoot (for
|
|
120
|
+
// transition-based rendering during client navigation).
|
|
121
|
+
//
|
|
122
|
+
// NavigationRoot holds the element in React state and updates via
|
|
123
|
+
// startTransition, so React keeps old UI visible while new Suspense
|
|
124
|
+
// boundaries resolve during navigation. See design/05-streaming.md.
|
|
125
|
+
const navState = getNavigationState();
|
|
126
|
+
const withNav = createElement(
|
|
127
|
+
NavigationProvider,
|
|
128
|
+
{ value: navState },
|
|
129
|
+
element as React.ReactNode
|
|
130
|
+
);
|
|
131
|
+
const withUpdates = createElement(
|
|
132
|
+
SegmentUpdateContext.Provider,
|
|
133
|
+
{ value: EMPTY_SEGMENT_UPDATES },
|
|
134
|
+
withNav
|
|
135
|
+
);
|
|
136
|
+
const wrapped = createElement(TimberNuqsAdapter, null, withUpdates);
|
|
137
|
+
const rootElement = createElement(NavigationRoot, {
|
|
138
|
+
initial: wrapped,
|
|
139
|
+
topLoaderConfig: config.topLoader,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
143
|
+
if (!getRouterOrNull()) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
'[timber] hydrateRoot called before initRouter() — bootstrap order violated'
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
hydrateRoot(document, rootElement, {
|
|
151
|
+
// Suppress recoverable hydration errors from deny/error signals
|
|
152
|
+
// inside Suspense boundaries. The server already handled these
|
|
153
|
+
// (wrapStreamWithErrorHandling closes the stream cleanly after
|
|
154
|
+
// the shell is flushed). React replays the error during hydration
|
|
155
|
+
// but the server HTML is already correct — no recovery needed.
|
|
156
|
+
onRecoverableError(error: unknown) {
|
|
157
|
+
if (isPageUnloading()) return;
|
|
158
|
+
if (process.env.NODE_ENV === 'development') {
|
|
159
|
+
queueOrShowHydrationError(error);
|
|
160
|
+
console.debug('[timber] Hydration recoverable error:', error);
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
} else {
|
|
165
|
+
// No RSC payload available — defer React root creation until the
|
|
166
|
+
// first client navigation (TIM-600).
|
|
167
|
+
//
|
|
168
|
+
// We must NOT call createRoot(document).render() here — that would
|
|
169
|
+
// take React ownership of the entire document and blank the SSR HTML.
|
|
170
|
+
// Instead, installDeferredNavigation sets up one-shot callbacks so
|
|
171
|
+
// the first navigateTransition/transitionRender call creates the root
|
|
172
|
+
// on `document` with the navigated content. After that initial render,
|
|
173
|
+
// NavigationRoot's real startTransition-based callbacks take over.
|
|
174
|
+
//
|
|
175
|
+
// This also fixes TIM-580 (navigation from SSR-only pages) because
|
|
176
|
+
// the deferred callbacks ensure NavigationRoot is mounted before the
|
|
177
|
+
// first navigation completes.
|
|
178
|
+
installDeferredNavigation((initial) => {
|
|
179
|
+
const rootElement = createElement(NavigationRoot, {
|
|
180
|
+
initial,
|
|
181
|
+
topLoaderConfig: config.topLoader,
|
|
182
|
+
});
|
|
183
|
+
const root = createRoot(document);
|
|
184
|
+
root.render(rootElement);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Entry — Client-side hydration and navigation bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* This is the thin orchestrator that coordinates the bootstrap sequence.
|
|
5
|
+
* Each responsibility is extracted into a focused module:
|
|
6
|
+
*
|
|
7
|
+
* action-dispatch.ts — server action callServer callback
|
|
8
|
+
* rsc-stream.ts — __timber_f chunk handling + ReadableStream
|
|
9
|
+
* router-init.ts — createRouter + Navigation API setup
|
|
10
|
+
* hydrate.ts — pre-hydration sequence + hydrateRoot/createRoot
|
|
11
|
+
* post-hydration.ts — history stack, segment cache, popstate, scroll
|
|
12
|
+
* hmr.ts — dev-only HMR + error forwarding
|
|
13
|
+
* scroll.ts — getScrollY helper
|
|
14
|
+
*
|
|
15
|
+
* Bootstrap call order contract:
|
|
16
|
+
*
|
|
17
|
+
* 1. setupServerActions() — register callServer (independent)
|
|
18
|
+
* 2. createRscPayloadStream() — decode inlined RSC payload
|
|
19
|
+
* 3. createTimberRouter() — create router + Navigation API
|
|
20
|
+
* 4. runPreHydration() — set params + navigation state
|
|
21
|
+
* 5. hydrateApp() — hydrateRoot or deferred createRoot
|
|
22
|
+
* 6. setupPostHydration() — history stack, popstate, scroll
|
|
23
|
+
* 7. setupHmr() — dev-only HMR wiring
|
|
24
|
+
* 8. timber-ready signal — E2E test readiness indicator
|
|
25
|
+
*
|
|
26
|
+
* Design docs: 18-build-system.md §"Entry Files", 19-client-navigation.md
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// @ts-expect-error — virtual module provided by timber-entries plugin
|
|
30
|
+
import config from 'virtual:timber-config';
|
|
31
|
+
// TIM-830: Populate the search-params registry eagerly so <Link> on the
|
|
32
|
+
// client can serialize flat `Partial<T>` values synchronously during
|
|
33
|
+
// render and click handlers. Side-effect-only import.
|
|
34
|
+
// @ts-expect-error — virtual module provided by timber-routing plugin
|
|
35
|
+
import 'virtual:timber-search-params-registry';
|
|
36
|
+
// TIM-932: Populate the codec registry so Link's interpolateParams can
|
|
37
|
+
// use codec.serialize() for URL construction. Side-effect-only import.
|
|
38
|
+
// @ts-expect-error — virtual module provided by timber-routing plugin
|
|
39
|
+
import schemaCodecs from 'virtual:timber-schema';
|
|
40
|
+
import { setLinkCodecs } from '../../params/codec-registry.js';
|
|
41
|
+
setLinkCodecs(schemaCodecs);
|
|
42
|
+
|
|
43
|
+
import { setClientDeploymentId } from '../rsc-fetch.js';
|
|
44
|
+
|
|
45
|
+
import { setupServerActions } from './action-dispatch.js';
|
|
46
|
+
import { createRscPayloadStream } from './rsc-stream.js';
|
|
47
|
+
import { createTimberRouter } from './router-init.js';
|
|
48
|
+
import { runPreHydration, hydrateApp } from './hydrate.js';
|
|
49
|
+
import { setupPostHydration } from './post-hydration.js';
|
|
50
|
+
import { setupHmr } from './hmr.js';
|
|
51
|
+
|
|
52
|
+
// ─── 1. Server Action Dispatch (independent) ────────────────────
|
|
53
|
+
|
|
54
|
+
setupServerActions();
|
|
55
|
+
|
|
56
|
+
// ─── 2–7. Bootstrap ─────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
function bootstrap(runtimeConfig: typeof config): void {
|
|
59
|
+
// Initialize deployment ID for version skew detection (TIM-446).
|
|
60
|
+
// In dev mode this is null — skew checks are skipped.
|
|
61
|
+
const deploymentId = (runtimeConfig as Record<string, unknown>).deploymentId as string | null;
|
|
62
|
+
if (deploymentId) {
|
|
63
|
+
setClientDeploymentId(deploymentId);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Take manual control of scroll restoration. Even though segment tree
|
|
67
|
+
// merging preserves shared layout DOM via cloneElement (so React doesn't
|
|
68
|
+
// reset scroll on those elements), the root-level reactRoot.render() with
|
|
69
|
+
// a new element tree can still cause scroll resets on the document during
|
|
70
|
+
// reconciliation. Manual control ensures consistent behavior.
|
|
71
|
+
window.history.scrollRestoration = 'manual';
|
|
72
|
+
|
|
73
|
+
// Step 2: Decode inlined RSC payload (may be null for JS-only clients)
|
|
74
|
+
const rscResult = createRscPayloadStream();
|
|
75
|
+
|
|
76
|
+
// Step 3: Create router + Navigation API integration
|
|
77
|
+
const { router, navApiController } = createTimberRouter({
|
|
78
|
+
initialElement: rscResult?.element ?? undefined,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Step 4: Pre-hydration — set params + navigation state (MUST run after router init)
|
|
82
|
+
runPreHydration();
|
|
83
|
+
|
|
84
|
+
// Step 5: Hydrate or set up deferred root creation
|
|
85
|
+
hydrateApp({ rscResult, config: runtimeConfig });
|
|
86
|
+
|
|
87
|
+
// Step 6: Post-hydration wiring
|
|
88
|
+
setupPostHydration({
|
|
89
|
+
router,
|
|
90
|
+
navApiController,
|
|
91
|
+
initialElement: rscResult?.element ?? null,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Step 7: HMR (dev-only, no-op in production)
|
|
95
|
+
setupHmr(router);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
bootstrap(config);
|
|
99
|
+
|
|
100
|
+
// ─── 8. Ready Signal ────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
// Signal that the client runtime has been initialized.
|
|
103
|
+
// Used by E2E tests to wait for hydration before interacting.
|
|
104
|
+
// We append a <meta name="timber-ready"> tag rather than setting a
|
|
105
|
+
// data attribute on <html>. Since React owns the entire document
|
|
106
|
+
// via hydrateRoot(document, ...), mutating <html> attributes causes
|
|
107
|
+
// hydration mismatch warnings. Dynamically-added <meta> tags don't
|
|
108
|
+
// conflict because React doesn't reconcile them.
|
|
109
|
+
const readyMeta = document.createElement('meta');
|
|
110
|
+
readyMeta.name = 'timber-ready';
|
|
111
|
+
document.head.appendChild(readyMeta);
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-Hydration Wiring — history stack, segment cache, popstate, scroll.
|
|
3
|
+
*
|
|
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
|
+
* - Initializes scroll state for the initial entry
|
|
7
|
+
* - Populates segment cache from server-embedded metadata
|
|
8
|
+
* - Registers popstate handler for back/forward navigation
|
|
9
|
+
* - Sets up debounced scroll position saving
|
|
10
|
+
*
|
|
11
|
+
* See design/19-client-navigation.md §"History Stack"
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { RouterInstance } from '#client-internal';
|
|
15
|
+
import { getNavigationState } from '../navigation-context.js';
|
|
16
|
+
import type { NavigationApiController } from '../navigation-api.js';
|
|
17
|
+
import { getScrollY } from './scroll.js';
|
|
18
|
+
|
|
19
|
+
interface PostHydrationOptions {
|
|
20
|
+
router: RouterInstance;
|
|
21
|
+
navApiController: NavigationApiController | null;
|
|
22
|
+
/** Decoded RSC element from initial SSR (null if no RSC payload) */
|
|
23
|
+
initialElement: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Wire up post-hydration event handlers and state.
|
|
28
|
+
*/
|
|
29
|
+
export function setupPostHydration({
|
|
30
|
+
router,
|
|
31
|
+
navApiController,
|
|
32
|
+
initialElement,
|
|
33
|
+
}: PostHydrationOptions): void {
|
|
34
|
+
// Store the initial page in the history stack so back-button works
|
|
35
|
+
// after the first navigation. We store the decoded RSC element so
|
|
36
|
+
// back navigation can replay it instantly without a server fetch.
|
|
37
|
+
// Params were captured from the server-embedded __timber_params by
|
|
38
|
+
// runPreHydration() — without them on the entry, the cached replay on
|
|
39
|
+
// back-navigation would normalize params to {} and wipe every
|
|
40
|
+
// useSegmentParams() consumer on the initial page (TIM-1037).
|
|
41
|
+
router.historyStack.push(window.location.pathname + window.location.search, {
|
|
42
|
+
payload: initialElement,
|
|
43
|
+
params: getNavigationState().params,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Initialize scroll state for the initial entry.
|
|
47
|
+
// When Navigation API is available, use per-entry state.
|
|
48
|
+
// Otherwise fall back to history.state.
|
|
49
|
+
if (navApiController) {
|
|
50
|
+
navApiController.saveScrollPosition(0);
|
|
51
|
+
} else {
|
|
52
|
+
window.history.replaceState({ timber: true, scrollY: 0 }, '');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Populate the segment cache from server-embedded segment metadata.
|
|
56
|
+
// This enables state tree diffing from the very first client navigation.
|
|
57
|
+
// See design/19-client-navigation.md §"X-Timber-State-Tree Header"
|
|
58
|
+
const timberSegments = (self as unknown as Record<string, unknown>).__timber_segments;
|
|
59
|
+
if (Array.isArray(timberSegments)) {
|
|
60
|
+
router.initSegmentCache(timberSegments);
|
|
61
|
+
delete (self as unknown as Record<string, unknown>).__timber_segments;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Register popstate handler for back/forward navigation.
|
|
65
|
+
// When Navigation API is active, the navigate event covers traversals —
|
|
66
|
+
// popstate is a no-op. When unavailable, popstate handles back/forward.
|
|
67
|
+
//
|
|
68
|
+
// Use pathname+search (not full href) to match the URL format used by
|
|
69
|
+
// navigate() — Link hrefs are relative paths like "/scroll-test/page-a".
|
|
70
|
+
// Read scrollY from history.state — the browser maintains per-entry state
|
|
71
|
+
// so duplicate URLs in history each have their own scroll position.
|
|
72
|
+
window.addEventListener('popstate', () => {
|
|
73
|
+
// Navigation API handles traversals via the navigate event.
|
|
74
|
+
if (navApiController) return;
|
|
75
|
+
|
|
76
|
+
const state = window.history.state;
|
|
77
|
+
const scrollY = state && typeof state.scrollY === 'number' ? state.scrollY : 0;
|
|
78
|
+
void router.handlePopState(window.location.pathname + window.location.search, scrollY);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Keep scroll position up to date as the user scrolls.
|
|
82
|
+
// This ensures that when the user presses back/forward, the departing
|
|
83
|
+
// page's scroll position is already saved in its history entry.
|
|
84
|
+
// When Navigation API is available, uses per-entry state via
|
|
85
|
+
// navigation.updateCurrentEntry(). Otherwise falls back to history.state.
|
|
86
|
+
// Debounced to avoid excessive state updates during smooth scrolling.
|
|
87
|
+
let scrollTimer: ReturnType<typeof setTimeout>;
|
|
88
|
+
function saveScrollPosition(): void {
|
|
89
|
+
clearTimeout(scrollTimer);
|
|
90
|
+
scrollTimer = setTimeout(() => {
|
|
91
|
+
const y = getScrollY();
|
|
92
|
+
if (navApiController) {
|
|
93
|
+
navApiController.saveScrollPosition(y);
|
|
94
|
+
} else {
|
|
95
|
+
const state = window.history.state;
|
|
96
|
+
if (state && typeof state === 'object') {
|
|
97
|
+
window.history.replaceState({ ...state, scrollY: y }, '');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}, 100);
|
|
101
|
+
}
|
|
102
|
+
window.addEventListener('scroll', saveScrollPosition, { passive: true });
|
|
103
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Router Initialization — creates the timber router with all dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Wires up RouterDeps (fetch, history, scroll, RSC decoding, render
|
|
5
|
+
* callbacks) and optionally sets up Navigation API integration.
|
|
6
|
+
*
|
|
7
|
+
* See design/19-client-navigation.md §"Navigation API Integration"
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createElement } from 'react';
|
|
11
|
+
import { createFromFetch } from '../../rsc-runtime/browser.js';
|
|
12
|
+
import { createRouter, setGlobalRouter } from '#client-internal';
|
|
13
|
+
import type { RouterDeps, RouterInstance } from '#client-internal';
|
|
14
|
+
import type { NavigationState } from '#client-internal';
|
|
15
|
+
import { TimberNuqsAdapter } from '../nuqs-adapter.js';
|
|
16
|
+
import {
|
|
17
|
+
NavigationProvider,
|
|
18
|
+
getNavigationState,
|
|
19
|
+
setNavigationState,
|
|
20
|
+
} from '../navigation-context.js';
|
|
21
|
+
import { transitionRender, navigateTransition } from '../navigation-root.js';
|
|
22
|
+
import { SegmentUpdateContext, EMPTY_SEGMENT_UPDATES } from '../segment-update-context.js';
|
|
23
|
+
import {
|
|
24
|
+
hasNavigationApi,
|
|
25
|
+
setupNavigationApi,
|
|
26
|
+
type NavigationApiController,
|
|
27
|
+
} from '../navigation-api.js';
|
|
28
|
+
import { getScrollY, scrollToHashTarget } from './scroll.js';
|
|
29
|
+
|
|
30
|
+
export interface RouterInitOptions {
|
|
31
|
+
initialElement?: unknown;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface RouterInitResult {
|
|
35
|
+
router: RouterInstance;
|
|
36
|
+
navApiController: NavigationApiController | null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create and register the global timber router.
|
|
41
|
+
*
|
|
42
|
+
* Must be called before hydrateRoot so `useRouter()` works during
|
|
43
|
+
* the initial render (methods lazily resolve the router at invocation,
|
|
44
|
+
* not render time, but initRouter must still run first).
|
|
45
|
+
*/
|
|
46
|
+
export function createTimberRouter(options?: RouterInitOptions): RouterInitResult {
|
|
47
|
+
// Feature-detect Navigation API. When available, the navigate event
|
|
48
|
+
// replaces popstate for back/forward and catches external navigations.
|
|
49
|
+
// See design/19-client-navigation.md §"Navigation API Integration"
|
|
50
|
+
const useNavApi = hasNavigationApi();
|
|
51
|
+
|
|
52
|
+
// Track the current unwrapped RSC payload. On partial navigation, the
|
|
53
|
+
// router re-wraps this same element with new NavigationProvider context
|
|
54
|
+
// so mounted SegmentOutlets are preserved (they pick up changes via
|
|
55
|
+
// SegmentUpdateContext, not from new children props).
|
|
56
|
+
// Initialized from the hydration element so partial nav works on the
|
|
57
|
+
// very first client navigation (before any wrapPayload call).
|
|
58
|
+
let currentPayload: unknown = options?.initialElement ?? null;
|
|
59
|
+
|
|
60
|
+
// ─── History API Patch ──────────────────────────────────────────
|
|
61
|
+
// Patch pushState/replaceState to detect external URL changes (nuqs
|
|
62
|
+
// shallow updates, replaceUrl, third-party libraries). When the router
|
|
63
|
+
// itself calls pushState/replaceState, it sets a flag so the patch
|
|
64
|
+
// skips the sync — the router already updates NavigationContext.
|
|
65
|
+
//
|
|
66
|
+
// On Navigation API browsers, the navigate event catches most URL
|
|
67
|
+
// changes. The patch is defense-in-depth and the primary mechanism
|
|
68
|
+
// for History API-only browsers (older Safari/Firefox).
|
|
69
|
+
const ROUTER_HISTORY_FLAG = Symbol.for('__timber_router_history_update');
|
|
70
|
+
const gFlags = globalThis as Record<symbol, boolean>;
|
|
71
|
+
|
|
72
|
+
const originalPushState = window.history.pushState.bind(window.history);
|
|
73
|
+
const originalReplaceState = window.history.replaceState.bind(window.history);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Sync NavigationContext.search after a shallow URL update. Called by
|
|
77
|
+
* the Navigation API shallow handler and the History API patch.
|
|
78
|
+
*
|
|
79
|
+
* @param search — the new search string. The Navigation API path passes
|
|
80
|
+
* this from event.destination.url (window.location hasn't committed
|
|
81
|
+
* yet when the navigate listener fires). The History API patch omits
|
|
82
|
+
* it, reading window.location.search (already committed by the time
|
|
83
|
+
* the patched pushState/replaceState returns).
|
|
84
|
+
*
|
|
85
|
+
* Bails when search is unchanged (scroll saves, no-ops, dual-fire).
|
|
86
|
+
* Re-wraps currentPayload with updated NavigationProvider and commits
|
|
87
|
+
* via transitionRender (startTransition — non-blocking).
|
|
88
|
+
*/
|
|
89
|
+
function syncShallowSearch(search?: string): void {
|
|
90
|
+
const currentSearch = search ?? window.location.search;
|
|
91
|
+
const navState = getNavigationState();
|
|
92
|
+
if (currentSearch === navState.search) return;
|
|
93
|
+
if (!currentPayload) return;
|
|
94
|
+
|
|
95
|
+
const newNavState: NavigationState = {
|
|
96
|
+
params: navState.params,
|
|
97
|
+
pathname: navState.pathname,
|
|
98
|
+
search: currentSearch,
|
|
99
|
+
};
|
|
100
|
+
setNavigationState(newNavState);
|
|
101
|
+
|
|
102
|
+
const withNav = createElement(
|
|
103
|
+
NavigationProvider,
|
|
104
|
+
{ value: newNavState },
|
|
105
|
+
currentPayload as React.ReactNode
|
|
106
|
+
);
|
|
107
|
+
const withUpdates = createElement(
|
|
108
|
+
SegmentUpdateContext.Provider,
|
|
109
|
+
{ value: EMPTY_SEGMENT_UPDATES },
|
|
110
|
+
withNav
|
|
111
|
+
);
|
|
112
|
+
const wrapped = createElement(TimberNuqsAdapter, null, withUpdates);
|
|
113
|
+
transitionRender(wrapped);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
window.history.pushState = function (
|
|
117
|
+
data: unknown,
|
|
118
|
+
unused: string,
|
|
119
|
+
url?: string | URL | null
|
|
120
|
+
): void {
|
|
121
|
+
originalPushState(data, unused, url);
|
|
122
|
+
if (!gFlags[ROUTER_HISTORY_FLAG]) {
|
|
123
|
+
syncShallowSearch();
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
window.history.replaceState = function (
|
|
128
|
+
data: unknown,
|
|
129
|
+
unused: string,
|
|
130
|
+
url?: string | URL | null
|
|
131
|
+
): void {
|
|
132
|
+
originalReplaceState(data, unused, url);
|
|
133
|
+
if (!gFlags[ROUTER_HISTORY_FLAG]) {
|
|
134
|
+
syncShallowSearch();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const deps: RouterDeps = {
|
|
139
|
+
fetch: (url, init) => window.fetch(url, init),
|
|
140
|
+
pushState: (data, unused, url) => {
|
|
141
|
+
gFlags[ROUTER_HISTORY_FLAG] = true;
|
|
142
|
+
window.history.pushState(data, unused, url);
|
|
143
|
+
gFlags[ROUTER_HISTORY_FLAG] = false;
|
|
144
|
+
},
|
|
145
|
+
replaceState: (data, unused, url) => {
|
|
146
|
+
gFlags[ROUTER_HISTORY_FLAG] = true;
|
|
147
|
+
window.history.replaceState(data, unused, url);
|
|
148
|
+
gFlags[ROUTER_HISTORY_FLAG] = false;
|
|
149
|
+
},
|
|
150
|
+
navigationApiActive: useNavApi,
|
|
151
|
+
scrollTo: (x, y) => {
|
|
152
|
+
// Scroll the document viewport.
|
|
153
|
+
window.scrollTo(x, y);
|
|
154
|
+
document.documentElement.scrollTop = y;
|
|
155
|
+
document.body.scrollTop = y;
|
|
156
|
+
// Scroll any element explicitly marked as a scroll container.
|
|
157
|
+
// With segment tree merging, shared layouts (sidebars, nav bars)
|
|
158
|
+
// are reconciled in place via cloneElement — React preserves their
|
|
159
|
+
// DOM and scroll state naturally. We no longer auto-detect overflow
|
|
160
|
+
// containers, which previously found the wrong element (e.g.,
|
|
161
|
+
// scrolling a sidebar instead of the main content area).
|
|
162
|
+
// Use `data-timber-scroll-restoration` to opt in specific containers.
|
|
163
|
+
for (const el of document.querySelectorAll('[data-timber-scroll-restoration]')) {
|
|
164
|
+
(el as HTMLElement).scrollTop = y;
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
getCurrentUrl: () => window.location.pathname + window.location.search,
|
|
168
|
+
getScrollY,
|
|
169
|
+
scrollToHash: scrollToHashTarget,
|
|
170
|
+
|
|
171
|
+
decodeRsc: (fetchPromise: Promise<Response>) => {
|
|
172
|
+
return createFromFetch(fetchPromise);
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
// Render decoded RSC tree via NavigationRoot's state-based mechanism.
|
|
176
|
+
// Used for non-navigation renders (popstate cached replay, applyRevalidation).
|
|
177
|
+
// Wraps with NavigationProvider + TimberNuqsAdapter.
|
|
178
|
+
//
|
|
179
|
+
// For navigation renders (navigate, refresh, popstate-with-fetch),
|
|
180
|
+
// navigateTransition is used instead — it wraps the entire navigation
|
|
181
|
+
// in a React transition with useOptimistic for the pending URL.
|
|
182
|
+
//
|
|
183
|
+
// navState is passed explicitly by the router — no temporal coupling
|
|
184
|
+
// with getNavigationState().
|
|
185
|
+
renderRoot: (element: unknown, navState: NavigationState) => {
|
|
186
|
+
currentPayload = element;
|
|
187
|
+
const withNav = createElement(
|
|
188
|
+
NavigationProvider,
|
|
189
|
+
{ value: navState },
|
|
190
|
+
element as React.ReactNode
|
|
191
|
+
);
|
|
192
|
+
const withUpdates = createElement(
|
|
193
|
+
SegmentUpdateContext.Provider,
|
|
194
|
+
{ value: EMPTY_SEGMENT_UPDATES },
|
|
195
|
+
withNav
|
|
196
|
+
);
|
|
197
|
+
const wrapped = createElement(TimberNuqsAdapter, null, withUpdates);
|
|
198
|
+
transitionRender(wrapped);
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
// Run a navigation inside a React transition with optimistic pending URL.
|
|
202
|
+
// The entire fetch + state update runs inside startTransition. useOptimistic
|
|
203
|
+
// shows the pending URL immediately and reverts to null when the transition
|
|
204
|
+
// commits (atomic with the new tree + params).
|
|
205
|
+
//
|
|
206
|
+
// The perform callback receives a wrapPayload function that wraps the
|
|
207
|
+
// decoded RSC payload with NavigationProvider + NuqsAdapter. navState
|
|
208
|
+
// is passed explicitly by the router — no getNavigationState() needed.
|
|
209
|
+
navigateTransition: (pendingUrl: string, perform) => {
|
|
210
|
+
return navigateTransition(pendingUrl, async () => {
|
|
211
|
+
const { element, decodePromise } = await perform(
|
|
212
|
+
(
|
|
213
|
+
rawPayload: unknown,
|
|
214
|
+
navState: NavigationState,
|
|
215
|
+
segmentUpdates?: Map<string, unknown>
|
|
216
|
+
) => {
|
|
217
|
+
currentPayload = rawPayload;
|
|
218
|
+
const withNav = createElement(
|
|
219
|
+
NavigationProvider,
|
|
220
|
+
{ value: navState },
|
|
221
|
+
rawPayload as React.ReactNode
|
|
222
|
+
);
|
|
223
|
+
const withUpdates = createElement(
|
|
224
|
+
SegmentUpdateContext.Provider,
|
|
225
|
+
{ value: (segmentUpdates ?? EMPTY_SEGMENT_UPDATES) as Map<string, React.ReactNode> },
|
|
226
|
+
withNav
|
|
227
|
+
);
|
|
228
|
+
return createElement(TimberNuqsAdapter, null, withUpdates);
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
return { element: element as React.ReactNode, decodePromise };
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
|
|
235
|
+
_getCurrentPayload: () => currentPayload,
|
|
236
|
+
|
|
237
|
+
// Schedule a callback after the next paint so scroll operations
|
|
238
|
+
// happen after React commits the new content to the DOM.
|
|
239
|
+
// Double-rAF ensures the browser has painted the new frame.
|
|
240
|
+
afterPaint: (callback: () => void) => {
|
|
241
|
+
requestAnimationFrame(() => {
|
|
242
|
+
requestAnimationFrame(callback);
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const router = createRouter(deps);
|
|
248
|
+
setGlobalRouter(router);
|
|
249
|
+
|
|
250
|
+
// Set up Navigation API integration after router is created.
|
|
251
|
+
// The navigate event listener delegates to router.navigate and
|
|
252
|
+
// router.handlePopState for external navigations and traversals.
|
|
253
|
+
let navApiController: NavigationApiController | null = null;
|
|
254
|
+
if (useNavApi) {
|
|
255
|
+
navApiController = setupNavigationApi({
|
|
256
|
+
onExternalNavigate: async (url, { replace, signal, scroll }) => {
|
|
257
|
+
// Navigation intercepted by the Navigation API. Covers both
|
|
258
|
+
// Link <a> clicks (user-initiated) and external navigations.
|
|
259
|
+
// The Navigation API handles the URL update via intercept(),
|
|
260
|
+
// so pass _skipHistory to avoid double pushState.
|
|
261
|
+
await router.navigate(url, {
|
|
262
|
+
replace,
|
|
263
|
+
scroll,
|
|
264
|
+
_signal: signal,
|
|
265
|
+
_skipHistory: true,
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
onTraverse: async (url, scrollY, signal) => {
|
|
269
|
+
// Back/forward — delegate to the router's popstate handler.
|
|
270
|
+
await router.handlePopState(url, scrollY, signal);
|
|
271
|
+
},
|
|
272
|
+
onShallowNavigate: (destinationUrl: string) => {
|
|
273
|
+
const search = new URL(destinationUrl).search;
|
|
274
|
+
syncShallowSearch(search);
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Wire the router-navigating flag into RouterDeps.
|
|
279
|
+
// This must be done after setupNavigationApi returns the controller.
|
|
280
|
+
deps.setRouterNavigating = (v) => navApiController!.setRouterNavigating(v);
|
|
281
|
+
deps.saveNavigationEntryScroll = (y) => navApiController!.saveScrollPosition(y);
|
|
282
|
+
deps.completeRouterNavigation = () => navApiController!.completeRouterNavigation();
|
|
283
|
+
deps.navigationNavigate = (url, replace) => navApiController!.navigate(url, replace);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return { router, navApiController };
|
|
287
|
+
}
|