@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327
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/AGENTS.md +8 -4
- package/README.md +301 -797
- package/dist/bin/rango.js +603 -145
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3750 -1160
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +96 -24
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +12 -10
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +75 -19
- package/skills/layout/SKILL.md +40 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +25 -13
- package/skills/migrate-nextjs/SKILL.md +205 -20
- package/skills/migrate-react-router/SKILL.md +59 -670
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +40 -10
- package/skills/ppr/SKILL.md +616 -0
- package/skills/prerender/SKILL.md +72 -60
- package/skills/rango/SKILL.md +318 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +117 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +45 -626
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +0 -65
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +94 -25
- package/src/browser/navigation-client.ts +144 -79
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +183 -144
- package/src/browser/prefetch/cache.ts +242 -77
- package/src/browser/prefetch/fetch.ts +325 -69
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +58 -20
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +17 -14
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +25 -3
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +145 -28
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +203 -154
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -21
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +456 -62
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +128 -51
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +421 -58
- package/src/cache/cache-scope.ts +187 -96
- package/src/cache/cache-tag.ts +149 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2202 -372
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +180 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1127 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +33 -61
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +67 -37
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +97 -12
- package/src/index.ts +98 -14
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +32 -37
- package/src/prerender.ts +78 -10
- package/src/redirect-origin.ts +114 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +65 -39
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +304 -309
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +87 -59
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +12 -1
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +19 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +73 -25
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +27 -42
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +82 -59
- package/src/router/loader-resolution.ts +167 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +80 -55
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +159 -285
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +69 -79
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- package/src/router/navigation-snapshot.ts +7 -56
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +112 -67
- package/src/router/preview-match.ts +6 -2
- package/src/router/request-classification.ts +50 -69
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +115 -36
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +131 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +139 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +251 -0
- package/src/router/segment-resolution/revalidation.ts +272 -320
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +157 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +291 -217
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +114 -38
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +124 -13
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +421 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +282 -116
- package/src/rsc/shell-capture.ts +1158 -0
- package/src/rsc/shell-serve.ts +150 -0
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +53 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +350 -149
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +208 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +395 -176
- package/src/ssr/index.tsx +458 -178
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +110 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +11 -9
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +19 -64
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +63 -17
- package/src/urls/path-helper.ts +22 -106
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +8 -7
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +96 -68
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +45 -1
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +4 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +210 -10
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +88 -55
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +505 -486
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +236 -138
- package/src/vite/router-discovery.ts +927 -136
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +71 -43
- package/src/vite/utils/shared-utils.ts +142 -43
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Evaluates whether segments should revalidate based on params, actions, and custom functions.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { ResolvedSegment, HandlerContext } from "../types";
|
|
7
|
+
import type { ResolvedSegment, HandlerContext, ActionRef } from "../types";
|
|
8
8
|
import type { ActionContext } from "./types";
|
|
9
9
|
import {
|
|
10
10
|
debugLog,
|
|
@@ -14,21 +14,52 @@ import {
|
|
|
14
14
|
import type { RevalidationTraceEntry } from "./logging.js";
|
|
15
15
|
import { _getRequestContext } from "../server/request-context.js";
|
|
16
16
|
import { isAutoGeneratedRouteName } from "../route-name.js";
|
|
17
|
+
import { paramsEqual } from "./params-util.js";
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
):
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a server-action reference's stable id, mirroring how the action
|
|
21
|
+
* boundary derives `actionContext.actionId` in `rsc/server-action.ts`
|
|
22
|
+
* (`$id ?? $$id`): the file-path `$id` set by the expose-action-id plugin in a
|
|
23
|
+
* production RSC build when present, otherwise React's `$$id`. Resolving both
|
|
24
|
+
* the incoming `actionId` and the reference with the same precedence makes
|
|
25
|
+
* `isAction()` form-agnostic across dev and production.
|
|
26
|
+
*/
|
|
27
|
+
function resolveActionRefId(ref: unknown): string | undefined {
|
|
28
|
+
if (ref == null) return undefined;
|
|
29
|
+
const r = ref as { $id?: unknown; $$id?: unknown };
|
|
30
|
+
if (typeof r.$id === "string") return r.$id;
|
|
31
|
+
if (typeof r.$$id === "string") return r.$$id;
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Build the `isAction()` helper bound to the current action's id. Called with no
|
|
37
|
+
* arguments it answers "is this request an action at all?" (any action) — `true`
|
|
38
|
+
* during action handling, `false` on plain navigation. Called with one or more
|
|
39
|
+
* action references it narrows to those: a single imported action, several
|
|
40
|
+
* (variadic), or any export of a namespace import (`import * as Mod`). Returns
|
|
41
|
+
* `false` when there is no action (plain navigation) or nothing matches.
|
|
42
|
+
*/
|
|
43
|
+
function makeIsAction(
|
|
44
|
+
currentActionId: string | undefined,
|
|
45
|
+
): (...actions: ActionRef[]) => boolean {
|
|
46
|
+
return (...actions: ActionRef[]): boolean => {
|
|
47
|
+
if (!currentActionId) return false;
|
|
48
|
+
// Bare isAction(): an action is in flight (currentActionId is set) and the
|
|
49
|
+
// caller did not narrow to a specific action, so this is "any action".
|
|
50
|
+
if (actions.length === 0) return true;
|
|
51
|
+
for (const action of actions) {
|
|
52
|
+
if (typeof action === "function") {
|
|
53
|
+
if (resolveActionRefId(action) === currentActionId) return true;
|
|
54
|
+
} else if (action && typeof action === "object") {
|
|
55
|
+
// Namespace import: match any export of the module.
|
|
56
|
+
for (const value of Object.values(action)) {
|
|
57
|
+
if (resolveActionRefId(value) === currentActionId) return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
};
|
|
32
63
|
}
|
|
33
64
|
|
|
34
65
|
/**
|
|
@@ -59,6 +90,14 @@ interface EvaluateRevalidationOptions<TEnv> {
|
|
|
59
90
|
stale?: boolean;
|
|
60
91
|
/** Trace source hint for the revalidation trace */
|
|
61
92
|
traceSource?: RevalidationTraceEntry["source"];
|
|
93
|
+
/**
|
|
94
|
+
* Override the segment-type-derived default. When set, the value is used as
|
|
95
|
+
* the seed `defaultShouldRevalidate` passed to user revalidate fns and the
|
|
96
|
+
* reason flows into the trace. Callers use this when client-knowledge
|
|
97
|
+
* (e.g. parallel slot not in clientSegmentIds) should dictate the seed
|
|
98
|
+
* instead of the params/method-based heuristic.
|
|
99
|
+
*/
|
|
100
|
+
defaultOverride?: { value: boolean; reason: string };
|
|
62
101
|
}
|
|
63
102
|
|
|
64
103
|
/**
|
|
@@ -81,13 +120,12 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
81
120
|
actionContext,
|
|
82
121
|
stale,
|
|
83
122
|
traceSource,
|
|
123
|
+
defaultOverride,
|
|
84
124
|
} = options;
|
|
85
125
|
const nextParams = segment.params || {};
|
|
86
126
|
const paramsChanged = !paramsEqual(nextParams, prevParams);
|
|
87
127
|
const searchChanged = prevUrl.search !== nextUrl.search;
|
|
88
128
|
|
|
89
|
-
// Trace helper: push a structured entry to the request-scoped trace buffer.
|
|
90
|
-
// Guarded by isTraceActive() so object construction is skipped in production.
|
|
91
129
|
function pushTrace(
|
|
92
130
|
defaultVal: boolean,
|
|
93
131
|
finalVal: boolean,
|
|
@@ -106,38 +144,28 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
106
144
|
});
|
|
107
145
|
}
|
|
108
146
|
|
|
109
|
-
// Calculate default revalidation based on segment type and request method
|
|
110
147
|
let defaultShouldRevalidate: boolean;
|
|
111
148
|
let defaultReason: string;
|
|
112
149
|
|
|
113
|
-
if (
|
|
114
|
-
|
|
150
|
+
if (defaultOverride) {
|
|
151
|
+
defaultShouldRevalidate = defaultOverride.value;
|
|
152
|
+
defaultReason = defaultOverride.reason;
|
|
153
|
+
} else if (request.method === "POST") {
|
|
115
154
|
if (segment.type === "route") {
|
|
116
|
-
// Route segment always revalidates on actions
|
|
117
155
|
defaultShouldRevalidate = true;
|
|
118
156
|
defaultReason = "action:route-segment";
|
|
119
157
|
} else if (segment.type === "loader") {
|
|
120
|
-
// Loaders always revalidate on actions - they often contain action-sensitive data
|
|
121
|
-
// (e.g., cart count after add-to-cart action)
|
|
122
158
|
defaultShouldRevalidate = true;
|
|
123
159
|
defaultReason = "action:loader-segment";
|
|
124
160
|
} else if (segment.belongsToRoute) {
|
|
125
|
-
// Segment belongs to route (orphan layouts/parallels) - revalidate
|
|
126
161
|
defaultShouldRevalidate = true;
|
|
127
162
|
defaultReason = "action:belongs-to-route";
|
|
128
163
|
} else {
|
|
129
|
-
// Parent chain segment (shared layouts/parallels) - don't revalidate
|
|
130
164
|
defaultShouldRevalidate = false;
|
|
131
165
|
defaultReason = "action:parent-chain-skip";
|
|
132
166
|
}
|
|
133
167
|
} else {
|
|
134
|
-
// Navigation (GET): Conservative defaults to minimize unnecessary revalidations
|
|
135
|
-
// Only the route segment revalidates by default - all others require explicit opt-in
|
|
136
|
-
|
|
137
168
|
if (segment.type === "route") {
|
|
138
|
-
// Route segments revalidate when path params OR search params change.
|
|
139
|
-
// Search params (e.g., ?page=2&sort=price) are server-parsed via ctx.search,
|
|
140
|
-
// so the handler must re-execute to produce updated content.
|
|
141
169
|
const routeChanged = paramsChanged || searchChanged;
|
|
142
170
|
defaultShouldRevalidate = routeChanged;
|
|
143
171
|
defaultReason = paramsChanged
|
|
@@ -153,8 +181,6 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
153
181
|
});
|
|
154
182
|
}
|
|
155
183
|
} else if (segment.belongsToRoute && (paramsChanged || searchChanged)) {
|
|
156
|
-
// Children of the route path (loaders, orphan layouts/parallels)
|
|
157
|
-
// revalidate when path params or search params change
|
|
158
184
|
defaultShouldRevalidate = true;
|
|
159
185
|
defaultReason = paramsChanged
|
|
160
186
|
? "nav:route-child-params-changed"
|
|
@@ -166,9 +192,6 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
166
192
|
searchChanged,
|
|
167
193
|
});
|
|
168
194
|
} else {
|
|
169
|
-
// Parent layouts and parallels default to no revalidation
|
|
170
|
-
// Cannot assume these segments depend on params without explicit declaration
|
|
171
|
-
// Use custom revalidation functions to opt-in when needed
|
|
172
195
|
defaultShouldRevalidate = false;
|
|
173
196
|
defaultReason = "nav:non-route-skip";
|
|
174
197
|
debugLog("revalidation", "non-route segment skipped by default", {
|
|
@@ -178,7 +201,6 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
178
201
|
}
|
|
179
202
|
}
|
|
180
203
|
|
|
181
|
-
// No custom revalidations defined - return default behavior without prev segment
|
|
182
204
|
if (revalidations.length === 0) {
|
|
183
205
|
if (defaultShouldRevalidate) {
|
|
184
206
|
debugLog("revalidation", "default revalidate=true", {
|
|
@@ -195,14 +217,10 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
195
217
|
return defaultShouldRevalidate;
|
|
196
218
|
}
|
|
197
219
|
|
|
198
|
-
// Custom revalidations exist - may need full prev segment
|
|
199
|
-
// Lazy load prev segment only if getPrevSegment provided
|
|
200
220
|
const prevSegment = getPrevSegment ? await getPrevSegment() : null;
|
|
201
221
|
|
|
202
|
-
// Execute revalidation functions with soft/hard decision pattern
|
|
203
222
|
let currentSuggestion = defaultShouldRevalidate;
|
|
204
223
|
|
|
205
|
-
// Compute public route names (filtered: undefined for auto-generated routes)
|
|
206
224
|
const toRouteName =
|
|
207
225
|
routeKey && !isAutoGeneratedRouteName(routeKey) ? routeKey : undefined;
|
|
208
226
|
const reqCtx = _getRequestContext();
|
|
@@ -213,36 +231,73 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
213
231
|
: undefined;
|
|
214
232
|
|
|
215
233
|
for (const { name, fn } of revalidations) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
let result: any;
|
|
235
|
+
try {
|
|
236
|
+
result = fn({
|
|
237
|
+
currentParams: prevSegment?.params || prevParams, // Use segment params if available, else route params
|
|
238
|
+
currentUrl: prevUrl,
|
|
239
|
+
nextParams,
|
|
240
|
+
nextUrl,
|
|
241
|
+
defaultShouldRevalidate: currentSuggestion,
|
|
242
|
+
context,
|
|
243
|
+
// Segment metadata (which segment is being evaluated)
|
|
244
|
+
segmentType: segment.type,
|
|
245
|
+
layoutName: segment.layoutName,
|
|
246
|
+
slotName: segment.slot,
|
|
247
|
+
// Action context (only populated when triggered by server action)
|
|
248
|
+
actionId: actionContext?.actionId,
|
|
249
|
+
isAction: makeIsAction(actionContext?.actionId),
|
|
250
|
+
actionUrl: actionContext?.actionUrl,
|
|
251
|
+
actionResult: actionContext?.actionResult,
|
|
252
|
+
formData: actionContext?.formData,
|
|
253
|
+
method: request.method,
|
|
254
|
+
routeName: toRouteName,
|
|
255
|
+
fromRouteName,
|
|
256
|
+
toRouteName,
|
|
257
|
+
stale,
|
|
258
|
+
});
|
|
259
|
+
} catch (error) {
|
|
260
|
+
// A thrown Response is control flow (e.g. `throw redirect(...)`), not a
|
|
261
|
+
// failure: re-throw it so the handler chokepoint (match-handlers.ts)
|
|
262
|
+
// turns it into the intended redirect/response. This mirrors how that
|
|
263
|
+
// catch special-cases `error instanceof Response`.
|
|
264
|
+
if (error instanceof Response) throw error;
|
|
265
|
+
// Fail open for genuine errors: a buggy user revalidate fn must not
|
|
266
|
+
// collapse the whole entry's loader batch into a failed partial render.
|
|
267
|
+
// Mirror the dynamic-tags fail-open in cache/cache-policy.ts: log and
|
|
268
|
+
// defer to the current default decision, leaving currentSuggestion
|
|
269
|
+
// unchanged. TODO: route through callOnError(phase "revalidation") once
|
|
270
|
+
// evaluateRevalidation is given the onError seam (today the error only
|
|
271
|
+
// reaches onError via the entry-collapse path in match-handlers.ts).
|
|
272
|
+
console.error(
|
|
273
|
+
`[revalidate] "${name}" threw for segment "${segment.id}"; using default decision:`,
|
|
274
|
+
error,
|
|
275
|
+
);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// The revalidate fn contract (handler-context.ts) is SYNCHRONOUS: it must
|
|
280
|
+
// return a boolean, a { defaultShouldRevalidate } object, or null/undefined.
|
|
281
|
+
// A Promise-returning (async) fn matches none of the decision branches below
|
|
282
|
+
// and silently falls through keeping the current default — a hard-to-find
|
|
283
|
+
// misuse. We do NOT await it (that would change the sync contract); instead
|
|
284
|
+
// we surface it as a dev-mode warning so the silent drop is diagnosable.
|
|
285
|
+
// Mirrors defer.ts: gated to dev, stripped from production builds.
|
|
286
|
+
if (
|
|
287
|
+
process.env.NODE_ENV !== "production" &&
|
|
288
|
+
result != null &&
|
|
289
|
+
typeof (result as { then?: unknown }).then === "function"
|
|
290
|
+
) {
|
|
291
|
+
console.warn(
|
|
292
|
+
`[rango] revalidate fn "${name}" returned a Promise; revalidate ` +
|
|
293
|
+
`functions must be synchronous (return a boolean, ` +
|
|
294
|
+
`{ defaultShouldRevalidate }, or null/undefined). The async result ` +
|
|
295
|
+
`was IGNORED and the default (${currentSuggestion}) was kept. ` +
|
|
296
|
+
`Move async work into a loader instead.`,
|
|
297
|
+
);
|
|
298
|
+
}
|
|
239
299
|
|
|
240
|
-
// Check return type:
|
|
241
|
-
// - boolean: hard decision, short-circuit immediately
|
|
242
|
-
// - { defaultShouldRevalidate: boolean }: soft decision, update suggestion and continue
|
|
243
|
-
// - null/undefined: use default behavior (equivalent to returning { defaultShouldRevalidate })
|
|
244
300
|
if (typeof result === "boolean") {
|
|
245
|
-
// Hard decision - short-circuit
|
|
246
301
|
debugLog("revalidation", "hard decision", {
|
|
247
302
|
segmentId: segment.id,
|
|
248
303
|
revalidator: name,
|
|
@@ -255,7 +310,6 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
255
310
|
typeof result === "object" &&
|
|
256
311
|
"defaultShouldRevalidate" in result
|
|
257
312
|
) {
|
|
258
|
-
// Soft decision - update suggestion and continue
|
|
259
313
|
currentSuggestion = result.defaultShouldRevalidate;
|
|
260
314
|
debugLog("revalidation", "soft decision", {
|
|
261
315
|
segmentId: segment.id,
|
|
@@ -263,18 +317,14 @@ export async function evaluateRevalidation<TEnv>(
|
|
|
263
317
|
revalidate: currentSuggestion,
|
|
264
318
|
});
|
|
265
319
|
} else if (result === null || result === undefined) {
|
|
266
|
-
// Defer to default - equivalent to { defaultShouldRevalidate: currentSuggestion }
|
|
267
|
-
// This means "I don't care, use whatever the default is"
|
|
268
320
|
debugLog("revalidation", "deferred to current default", {
|
|
269
321
|
segmentId: segment.id,
|
|
270
322
|
revalidator: name,
|
|
271
323
|
revalidate: currentSuggestion,
|
|
272
324
|
});
|
|
273
|
-
// currentSuggestion stays the same, continue to next function
|
|
274
325
|
}
|
|
275
326
|
}
|
|
276
327
|
|
|
277
|
-
// All revalidators completed - use final suggestion
|
|
278
328
|
debugLog("revalidation", "final decision", {
|
|
279
329
|
segmentId: segment.id,
|
|
280
330
|
revalidate: currentSuggestion,
|
|
@@ -48,6 +48,15 @@ export interface RouteSnapshot<TEnv = any> {
|
|
|
48
48
|
isPassthrough: boolean;
|
|
49
49
|
/** Response type for non-RSC routes (e.g. "application/json") */
|
|
50
50
|
responseType?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The isSSR flag the manifest was resolved with. Recorded so consumers can
|
|
53
|
+
* decide whether the snapshot is reusable: a snapshot resolved with isSSR
|
|
54
|
+
* differs (loading({ ssr: false }) entries) and is cached under a different
|
|
55
|
+
* manifest partition, so the full (document) path only reuses an isSSR:true
|
|
56
|
+
* snapshot and the partial path only reuses a non-isSSR one. Undefined on
|
|
57
|
+
* inline snapshots (redirect / not-found) that are never reused.
|
|
58
|
+
*/
|
|
59
|
+
isSSR?: boolean;
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
export type ResolveRouteResult<TEnv = any> =
|
|
@@ -56,7 +65,9 @@ export type ResolveRouteResult<TEnv = any> =
|
|
|
56
65
|
| null;
|
|
57
66
|
|
|
58
67
|
export interface ResolveRouteDeps<TEnv = any> {
|
|
59
|
-
findMatch: (
|
|
68
|
+
findMatch: (
|
|
69
|
+
pathname: string,
|
|
70
|
+
) => RouteMatchResult<TEnv> | null | Promise<RouteMatchResult<TEnv> | null>;
|
|
60
71
|
metricsStore?: MetricsStore;
|
|
61
72
|
isSSR?: boolean;
|
|
62
73
|
/**
|
|
@@ -105,7 +116,7 @@ export async function resolveRoute<TEnv = any>(
|
|
|
105
116
|
|
|
106
117
|
const routeMatchStart =
|
|
107
118
|
metricsStore && !skipRouteMatchMetric ? performance.now() : 0;
|
|
108
|
-
const matched = deps.findMatch(pathname);
|
|
119
|
+
const matched = await deps.findMatch(pathname);
|
|
109
120
|
if (metricsStore && !skipRouteMatchMetric) {
|
|
110
121
|
metricsStore.metrics.push({
|
|
111
122
|
label: "route-matching",
|
|
@@ -175,6 +186,7 @@ export async function resolveRoute<TEnv = any>(
|
|
|
175
186
|
cacheScope,
|
|
176
187
|
isPassthrough,
|
|
177
188
|
responseType,
|
|
189
|
+
isSSR,
|
|
178
190
|
},
|
|
179
191
|
};
|
|
180
192
|
}
|
|
@@ -230,7 +242,6 @@ export function createRouteSnapshot<TEnv = any>(
|
|
|
230
242
|
entry: {} as any,
|
|
231
243
|
routeKey: "test",
|
|
232
244
|
params: {},
|
|
233
|
-
optionalParams: new Set(),
|
|
234
245
|
} as RouteMatchResult<TEnv>,
|
|
235
246
|
manifestEntry: { type: "route", shortCode: "R0", parent: null } as any,
|
|
236
247
|
entries: [],
|
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
} from "../types.js";
|
|
20
20
|
import type { RouteMatchResult } from "./pattern-matching.js";
|
|
21
21
|
import type { TelemetrySink } from "./telemetry.js";
|
|
22
|
+
import type { ResolveSegmentOptions } from "./segment-resolution.js";
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Revalidation context passed to segment resolution
|
|
@@ -54,10 +55,10 @@ export interface InterceptResult {
|
|
|
54
55
|
* Instead of passing 20+ parameters, middleware calls getRouterContext() to access them.
|
|
55
56
|
*/
|
|
56
57
|
export interface RouterContext<TEnv = any> {
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
findMatch: (
|
|
59
|
+
pathname: string,
|
|
60
|
+
) => RouteMatchResult | null | Promise<RouteMatchResult | null>;
|
|
59
61
|
|
|
60
|
-
// Manifest loading
|
|
61
62
|
loadManifest: (
|
|
62
63
|
entry: any,
|
|
63
64
|
routeKey: string,
|
|
@@ -66,10 +67,8 @@ export interface RouterContext<TEnv = any> {
|
|
|
66
67
|
isSSR?: boolean,
|
|
67
68
|
) => Promise<EntryData>;
|
|
68
69
|
|
|
69
|
-
// Entry traversal
|
|
70
70
|
traverseBack: (entry: EntryData) => Generator<EntryData>;
|
|
71
71
|
|
|
72
|
-
// Handler context creation
|
|
73
72
|
createHandlerContext: (
|
|
74
73
|
params: Record<string, string>,
|
|
75
74
|
request: Request,
|
|
@@ -83,7 +82,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
83
82
|
isPassthroughRoute?: boolean,
|
|
84
83
|
) => HandlerContext<any, TEnv>;
|
|
85
84
|
|
|
86
|
-
// Loader setup
|
|
87
85
|
setupLoaderAccess: (
|
|
88
86
|
ctx: HandlerContext<any, TEnv>,
|
|
89
87
|
loaderPromises: Map<string, Promise<any>>,
|
|
@@ -94,7 +92,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
94
92
|
loaderPromises: Map<string, Promise<any>>,
|
|
95
93
|
) => void;
|
|
96
94
|
|
|
97
|
-
// Context access
|
|
98
95
|
getContext: () => {
|
|
99
96
|
getOrCreateStore: (key: string) => any;
|
|
100
97
|
runWithStore: <T>(
|
|
@@ -105,16 +102,13 @@ export interface RouterContext<TEnv = any> {
|
|
|
105
102
|
) => T;
|
|
106
103
|
};
|
|
107
104
|
|
|
108
|
-
// Metrics
|
|
109
105
|
getMetricsStore: () => MetricsStore | undefined;
|
|
110
106
|
|
|
111
|
-
// Cache
|
|
112
107
|
createCacheScope: (
|
|
113
108
|
cacheConfig: any,
|
|
114
109
|
parent: CacheScope | null,
|
|
115
110
|
) => CacheScope | null;
|
|
116
111
|
|
|
117
|
-
// Intercept detection
|
|
118
112
|
findInterceptForRoute: (
|
|
119
113
|
routeKey: string,
|
|
120
114
|
parentEntry: EntryData | null,
|
|
@@ -122,7 +116,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
122
116
|
isAction: boolean,
|
|
123
117
|
) => InterceptResult | null;
|
|
124
118
|
|
|
125
|
-
// Segment resolution (with revalidation)
|
|
126
119
|
resolveAllSegmentsWithRevalidation: (
|
|
127
120
|
entries: EntryData[],
|
|
128
121
|
routeKey: string,
|
|
@@ -133,7 +126,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
133
126
|
request: Request,
|
|
134
127
|
prevUrl: URL,
|
|
135
128
|
nextUrl: URL,
|
|
136
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
137
129
|
actionContext: any | undefined,
|
|
138
130
|
interceptResult: InterceptResult | null,
|
|
139
131
|
localRouteName: string,
|
|
@@ -164,14 +156,13 @@ export interface RouterContext<TEnv = any> {
|
|
|
164
156
|
handlerContext: HandlerContext<any, TEnv>,
|
|
165
157
|
belongsToRoute: boolean,
|
|
166
158
|
revalidationContext?: RevalidationContext,
|
|
159
|
+
options?: { skipMiddleware?: boolean },
|
|
167
160
|
) => Promise<ResolvedSegment[]>;
|
|
168
161
|
|
|
169
|
-
// Collect with markers
|
|
170
162
|
collectWithMarkers?: <T>(
|
|
171
163
|
gen: AsyncGenerator<T | { __type: "id"; id: string }>,
|
|
172
164
|
) => Promise<{ items: T[]; matchedIds: string[] }>;
|
|
173
165
|
|
|
174
|
-
// Revalidation evaluation
|
|
175
166
|
evaluateRevalidation: (params: {
|
|
176
167
|
segment: ResolvedSegment;
|
|
177
168
|
prevParams: Record<string, string>;
|
|
@@ -195,7 +186,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
195
186
|
| "intercept-loader";
|
|
196
187
|
}) => Promise<boolean>;
|
|
197
188
|
|
|
198
|
-
// Request context
|
|
199
189
|
getRequestContext: () =>
|
|
200
190
|
| {
|
|
201
191
|
waitUntil: (fn: () => Promise<void>) => void;
|
|
@@ -203,17 +193,15 @@ export interface RouterContext<TEnv = any> {
|
|
|
203
193
|
}
|
|
204
194
|
| undefined;
|
|
205
195
|
|
|
206
|
-
// Simple segment resolution (without revalidation - for full match)
|
|
207
196
|
resolveAllSegments: (
|
|
208
197
|
entries: EntryData[],
|
|
209
198
|
routeKey: string,
|
|
210
199
|
params: Record<string, string>,
|
|
211
200
|
handlerContext: HandlerContext<any, TEnv>,
|
|
212
201
|
loaderPromises: Map<string, Promise<any>>,
|
|
213
|
-
options?:
|
|
202
|
+
options?: ResolveSegmentOptions,
|
|
214
203
|
) => Promise<ResolvedSegment[]>;
|
|
215
204
|
|
|
216
|
-
// Generator-based simple resolution
|
|
217
205
|
resolveAllSegmentsGenerator?: (
|
|
218
206
|
entries: EntryData[],
|
|
219
207
|
routeKey: string,
|
|
@@ -222,21 +210,17 @@ export interface RouterContext<TEnv = any> {
|
|
|
222
210
|
loaderPromises: Map<string, Promise<any>>,
|
|
223
211
|
) => AsyncGenerator<ResolvedSegment | { __type: "id"; id: string }>;
|
|
224
212
|
|
|
225
|
-
// Collect segments from generator
|
|
226
213
|
collectSegmentsFromGenerator?: <T>(
|
|
227
214
|
gen: AsyncGenerator<T | { __type: "id"; id: string }>,
|
|
228
215
|
) => Promise<T[]>;
|
|
229
216
|
|
|
230
|
-
// Handle store
|
|
231
217
|
createHandleStore: () => any;
|
|
232
218
|
|
|
233
|
-
// Loaders-only resolution (for full match cache hit - no revalidation)
|
|
234
219
|
resolveLoadersOnly?: (
|
|
235
220
|
entries: EntryData[],
|
|
236
221
|
handlerContext: HandlerContext<any, TEnv>,
|
|
237
222
|
) => Promise<ResolvedSegment[]>;
|
|
238
223
|
|
|
239
|
-
// Loaders-only resolution (for cache hit scenarios)
|
|
240
224
|
resolveLoadersOnlyWithRevalidation?: (
|
|
241
225
|
entries: EntryData[],
|
|
242
226
|
handlerContext: HandlerContext<any, TEnv>,
|
|
@@ -258,10 +242,8 @@ export interface RouterContext<TEnv = any> {
|
|
|
258
242
|
// Telemetry sink (optional, no-op when undefined)
|
|
259
243
|
telemetry?: TelemetrySink;
|
|
260
244
|
|
|
261
|
-
// Request ID for telemetry span correlation (set per-request in match handlers)
|
|
262
245
|
requestId?: string;
|
|
263
246
|
|
|
264
|
-
// Intercept loaders only (for cache hit + intercept scenarios)
|
|
265
247
|
resolveInterceptLoadersOnly?: (
|
|
266
248
|
intercept: InterceptEntry,
|
|
267
249
|
entry: EntryData,
|
|
@@ -284,7 +266,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
284
266
|
} | null>;
|
|
285
267
|
}
|
|
286
268
|
|
|
287
|
-
// AsyncLocalStorage instance for router context
|
|
288
269
|
const routerContext = new AsyncLocalStorage<RouterContext<any>>();
|
|
289
270
|
|
|
290
271
|
/**
|
|
@@ -308,10 +289,6 @@ export function getRouterContext<TEnv = any>(): RouterContext<TEnv> {
|
|
|
308
289
|
*
|
|
309
290
|
* All async code within fn() can call getRouterContext() to access router closures.
|
|
310
291
|
* This works across async boundaries thanks to AsyncLocalStorage.
|
|
311
|
-
*
|
|
312
|
-
* @param deps Router dependencies to make available
|
|
313
|
-
* @param fn Function to run with dependencies available
|
|
314
|
-
* @returns Result of fn()
|
|
315
292
|
*/
|
|
316
293
|
export function runWithRouterContext<T, TEnv = any>(
|
|
317
294
|
deps: RouterContext<TEnv>,
|