@rangojs/router 0.0.0-experimental.32 → 0.0.0-experimental.3232cd17
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 +4 -0
- package/README.md +198 -44
- package/dist/bin/rango.js +287 -105
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3248 -1117
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +73 -21
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +107 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +245 -21
- package/skills/caching/SKILL.md +302 -6
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +270 -30
- package/skills/host-router/SKILL.md +82 -22
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +49 -5
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +294 -30
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +203 -7
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +250 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +122 -47
- package/skills/route/SKILL.md +97 -5
- package/skills/router-setup/SKILL.md +90 -5
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -0
- package/skills/testing/bindings.md +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -0
- package/skills/testing/handles.md +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +120 -0
- package/skills/typesafety/SKILL.md +329 -27
- package/skills/use-cache/SKILL.md +36 -5
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +67 -40
- 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/app-version.ts +14 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +86 -147
- 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/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +148 -19
- package/src/browser/navigation-client.ts +187 -67
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/partial-update.ts +123 -94
- package/src/browser/prefetch/cache.ts +214 -36
- package/src/browser/prefetch/fetch.ts +260 -38
- package/src/browser/prefetch/policy.ts +6 -0
- package/src/browser/prefetch/queue.ts +126 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +93 -11
- package/src/browser/react/NavigationProvider.tsx +115 -34
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +49 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +166 -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 +23 -69
- package/src/browser/react/use-link-status.ts +0 -4
- package/src/browser/react/use-navigation.ts +22 -5
- 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 +46 -11
- 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 +52 -1
- package/src/browser/rsc-router.tsx +215 -76
- package/src/browser/scroll-restoration.ts +46 -39
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +176 -50
- package/src/browser/types.ts +95 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +5 -0
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +137 -32
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +278 -96
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-policy.ts +68 -28
- package/src/cache/cache-runtime.ts +149 -43
- package/src/cache/cache-scope.ts +148 -81
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2550 -93
- package/src/cache/cf/index.ts +11 -17
- package/src/cache/document-cache.ts +78 -27
- package/src/cache/handle-snapshot.ts +63 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +6 -30
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +0 -16
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +33 -100
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +799 -0
- package/src/client.rsc.tsx +6 -21
- package/src/client.tsx +108 -290
- package/src/component-utils.ts +19 -0
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +30 -4
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +0 -14
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/handles/meta.ts +0 -39
- package/src/host/cookie-handler.ts +0 -36
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +7 -50
- 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 +52 -26
- package/src/index.ts +100 -38
- package/src/internal-debug.ts +2 -4
- 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/network-error-thrower.tsx +1 -6
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +10 -11
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +7 -72
- package/src/route-definition/dsl-helpers.ts +437 -274
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +113 -37
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +52 -10
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +7 -17
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +108 -9
- package/src/router/error-handling.ts +13 -17
- package/src/router/find-match.ts +45 -22
- package/src/router/handler-context.ts +83 -41
- package/src/router/intercept-resolution.ts +25 -23
- package/src/router/lazy-includes.ts +19 -53
- package/src/router/loader-resolution.ts +213 -30
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +49 -45
- package/src/router/match-api.ts +120 -204
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +27 -6
- package/src/router/match-middleware/cache-lookup.ts +205 -249
- package/src/router/match-middleware/cache-store.ts +45 -32
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +104 -40
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +173 -143
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +109 -63
- package/src/router/prerender-match.ts +190 -54
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +63 -55
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +6 -28
- package/src/router/router-interfaces.ts +100 -35
- package/src/router/router-options.ts +91 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +242 -75
- package/src/router/segment-resolution/helpers.ts +63 -24
- package/src/router/segment-resolution/loader-cache.ts +41 -37
- package/src/router/segment-resolution/revalidation.ts +456 -372
- 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 +36 -0
- package/src/router/segment-resolution.ts +4 -1
- package/src/router/segment-wrappers.ts +2 -3
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +0 -20
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/trie-matching.ts +91 -46
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +134 -43
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +492 -383
- package/src/rsc/helpers.ts +162 -46
- package/src/rsc/index.ts +1 -1
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +30 -3
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +90 -63
- package/src/rsc/rsc-rendering.ts +56 -54
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +74 -67
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +25 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +4 -20
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +272 -129
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +309 -61
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +26 -24
- package/src/server/loader-registry.ts +10 -28
- package/src/server/request-context.ts +338 -126
- package/src/ssr/index.tsx +23 -15
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +618 -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 +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -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 +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -0
- package/src/testing/run-middleware.ts +205 -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 +0 -52
- package/src/theme/ThemeScript.tsx +0 -6
- package/src/theme/constants.ts +0 -12
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +0 -14
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +233 -81
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +107 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +37 -14
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +192 -99
- 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 +51 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +8 -0
- package/src/vite/plugin-types.ts +187 -69
- package/src/vite/plugins/cjs-to-esm.ts +8 -18
- 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 +49 -98
- package/src/vite/plugins/expose-id-utils.ts +11 -50
- package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
- package/src/vite/plugins/expose-internal-ids.ts +554 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +258 -0
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +41 -20
- package/src/vite/plugins/virtual-entries.ts +2 -17
- package/src/vite/rango.ts +257 -289
- package/src/vite/router-discovery.ts +930 -140
- package/src/vite/utils/ast-handler-extract.ts +15 -31
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -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 +27 -29
- package/src/vite/utils/shared-utils.ts +92 -42
- 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/router/middleware-cookies.ts +0 -55
|
@@ -70,9 +70,11 @@
|
|
|
70
70
|
* - No segments yielded from this middleware
|
|
71
71
|
*
|
|
72
72
|
* Loaders:
|
|
73
|
-
* - NEVER cached
|
|
73
|
+
* - NEVER cached in the segment cache
|
|
74
74
|
* - Always resolved fresh on every request
|
|
75
75
|
* - Ensures data freshness even with cached UI components
|
|
76
|
+
* - Segment cache staleness does NOT propagate to loader revalidation;
|
|
77
|
+
* loaders use their own revalidation rules (actionId, user-defined)
|
|
76
78
|
*
|
|
77
79
|
*
|
|
78
80
|
* REVALIDATION RULES
|
|
@@ -91,15 +93,17 @@
|
|
|
91
93
|
*/
|
|
92
94
|
import type { ResolvedSegment } from "../../types.js";
|
|
93
95
|
import type { MatchContext, MatchPipelineState } from "../match-context.js";
|
|
94
|
-
import { getRouterContext } from "../router-context.js";
|
|
96
|
+
import { getRouterContext, type RouterContext } from "../router-context.js";
|
|
95
97
|
import { resolveSink, safeEmit } from "../telemetry.js";
|
|
96
98
|
import { pushRevalidationTraceEntry, isTraceActive } from "../logging.js";
|
|
99
|
+
import { treeHasStreaming } from "./segment-resolution.js";
|
|
97
100
|
import type { PrerenderStore, PrerenderEntry } from "../../prerender/store.js";
|
|
98
101
|
import type { HandleStore } from "../../server/handle-store.js";
|
|
99
102
|
import {
|
|
100
103
|
getRequestContext,
|
|
101
104
|
_getRequestContext,
|
|
102
105
|
} from "../../server/request-context.js";
|
|
106
|
+
import { paramsEqual } from "../params-util.js";
|
|
103
107
|
|
|
104
108
|
// Lazily initialized prerender store singleton and dynamically imported deps.
|
|
105
109
|
// Dynamic imports prevent pulling in @vitejs/plugin-rsc/rsc virtual module at
|
|
@@ -111,6 +115,9 @@ let _deserializeSegments:
|
|
|
111
115
|
let _restoreHandles:
|
|
112
116
|
| typeof import("../../cache/handle-snapshot.js").restoreHandles
|
|
113
117
|
| undefined;
|
|
118
|
+
let _decodeHandles:
|
|
119
|
+
| typeof import("../../cache/handle-snapshot.js").decodeHandles
|
|
120
|
+
| undefined;
|
|
114
121
|
let _hashParams:
|
|
115
122
|
| typeof import("../../prerender/param-hash.js").hashParams
|
|
116
123
|
| undefined;
|
|
@@ -118,22 +125,6 @@ let _lazyGetRequestContext:
|
|
|
118
125
|
| typeof import("../../server/request-context.js").getRequestContext
|
|
119
126
|
| undefined;
|
|
120
127
|
|
|
121
|
-
function paramsEqual(
|
|
122
|
-
a: Record<string, string>,
|
|
123
|
-
b: Record<string, string>,
|
|
124
|
-
): boolean {
|
|
125
|
-
if (a === b) return true;
|
|
126
|
-
|
|
127
|
-
const keysA = Object.keys(a);
|
|
128
|
-
if (keysA.length !== Object.keys(b).length) return false;
|
|
129
|
-
|
|
130
|
-
for (const key of keysA) {
|
|
131
|
-
if (a[key] !== b[key]) return false;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return true;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
128
|
async function ensurePrerenderDeps() {
|
|
138
129
|
if (!_deserializeSegments) {
|
|
139
130
|
const [codec, snapshot, paramHash, reqCtx, store] = await Promise.all([
|
|
@@ -145,6 +136,7 @@ async function ensurePrerenderDeps() {
|
|
|
145
136
|
]);
|
|
146
137
|
_deserializeSegments = codec.deserializeSegments;
|
|
147
138
|
_restoreHandles = snapshot.restoreHandles;
|
|
139
|
+
_decodeHandles = snapshot.decodeHandles;
|
|
148
140
|
_hashParams = paramHash.hashParams;
|
|
149
141
|
_lazyGetRequestContext = reqCtx.getRequestContext;
|
|
150
142
|
if (prerenderStoreInstance === undefined) {
|
|
@@ -158,58 +150,23 @@ async function ensurePrerenderDeps() {
|
|
|
158
150
|
* Deserializes segments, replays handle data, yields segments with partial
|
|
159
151
|
* navigation nullification, and resolves fresh loaders.
|
|
160
152
|
*/
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
// Resolve loaders fresh on a cache hit (loaders are NEVER cached) and yield
|
|
154
|
+
// the loader segments, updating state.matchedIds and pushing the loader-resolve
|
|
155
|
+
// + cache-hit metrics. Shared verbatim by the prerender-store path
|
|
156
|
+
// (yieldFromStore) and the runtime cache-hit path (withCacheLookup). The router
|
|
157
|
+
// resolve fns are passed in (captured early by the callers) rather than re-read
|
|
158
|
+
// from getRouterContext() here, because that is ALS-backed and the callers run
|
|
159
|
+
// awaits before reaching this point (workerd can disrupt ALS mid-pipeline).
|
|
160
|
+
async function* resolveFreshLoadersAndYield<TEnv>(
|
|
163
161
|
ctx: MatchContext<TEnv>,
|
|
164
162
|
state: MatchPipelineState,
|
|
165
163
|
pipelineStart: number,
|
|
166
|
-
|
|
164
|
+
ms: MatchContext<TEnv>["metricsStore"],
|
|
165
|
+
resolveLoadersOnly: RouterContext<TEnv>["resolveLoadersOnly"],
|
|
166
|
+
resolveLoadersOnlyWithRevalidation: RouterContext<TEnv>["resolveLoadersOnlyWithRevalidation"],
|
|
167
167
|
): AsyncGenerator<ResolvedSegment> {
|
|
168
|
-
const
|
|
169
|
-
getRouterContext<TEnv>();
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
!_deserializeSegments ||
|
|
173
|
-
!_restoreHandles ||
|
|
174
|
-
!_hashParams ||
|
|
175
|
-
!_lazyGetRequestContext
|
|
176
|
-
) {
|
|
177
|
-
throw new Error("yieldFromStore called before ensurePrerenderDeps");
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const segments = await _deserializeSegments(entry.segments);
|
|
181
|
-
|
|
182
|
-
// Replay handle data (same as runtime cache hit path).
|
|
183
|
-
// Prefer the eagerly-captured handleStoreRef to avoid ALS disruption in workerd.
|
|
184
|
-
const handleStore = handleStoreRef ?? _lazyGetRequestContext()?._handleStore;
|
|
185
|
-
if (handleStore) {
|
|
186
|
-
_restoreHandles(entry.handles, handleStore);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
state.cacheHit = true;
|
|
190
|
-
state.cacheSource = "prerender";
|
|
191
|
-
state.cachedSegments = segments;
|
|
192
|
-
state.cachedMatchedIds = segments.map((s) => s.id);
|
|
193
|
-
|
|
194
|
-
// For partial navigation, nullify components the client already has
|
|
195
|
-
// so parent layouts stay live (client keeps its existing versions).
|
|
196
|
-
// When params changed (e.g., different guide slug), the segments have
|
|
197
|
-
// different content, so we must NOT nullify.
|
|
198
|
-
const paramsChanged =
|
|
199
|
-
!ctx.isFullMatch && !paramsEqual(ctx.matched.params, ctx.prevParams);
|
|
200
|
-
for (const segment of segments) {
|
|
201
|
-
if (
|
|
202
|
-
!ctx.isFullMatch &&
|
|
203
|
-
!paramsChanged &&
|
|
204
|
-
ctx.clientSegmentSet.has(segment.id)
|
|
205
|
-
) {
|
|
206
|
-
segment.component = null;
|
|
207
|
-
segment.loading = undefined;
|
|
208
|
-
}
|
|
209
|
-
yield segment;
|
|
210
|
-
}
|
|
168
|
+
const loaderStart = performance.now();
|
|
211
169
|
|
|
212
|
-
// Resolve loaders fresh (loaders are never pre-rendered/cached)
|
|
213
170
|
if (ctx.isFullMatch) {
|
|
214
171
|
if (resolveLoadersOnly) {
|
|
215
172
|
const loaderSegments = await ctx.Store.run(() =>
|
|
@@ -235,6 +192,9 @@ async function* yieldFromStore<TEnv>(
|
|
|
235
192
|
ctx.url,
|
|
236
193
|
ctx.routeKey,
|
|
237
194
|
ctx.actionContext,
|
|
195
|
+
// Loaders are never cached in the segment cache, so segment staleness
|
|
196
|
+
// must not propagate; browser-sent staleness (ctx.stale) still must.
|
|
197
|
+
ctx.stale || undefined,
|
|
238
198
|
),
|
|
239
199
|
);
|
|
240
200
|
state.matchedIds = [
|
|
@@ -249,16 +209,131 @@ async function* yieldFromStore<TEnv>(
|
|
|
249
209
|
}
|
|
250
210
|
}
|
|
251
211
|
|
|
252
|
-
const ms = ctx.metricsStore;
|
|
253
212
|
if (ms) {
|
|
213
|
+
const loaderEnd = performance.now();
|
|
214
|
+
ms.metrics.push({
|
|
215
|
+
label: "pipeline:loader-resolve",
|
|
216
|
+
duration: loaderEnd - loaderStart,
|
|
217
|
+
startTime: loaderStart - ms.requestStart,
|
|
218
|
+
depth: 1,
|
|
219
|
+
});
|
|
254
220
|
ms.metrics.push({
|
|
255
|
-
label: "pipeline:cache-
|
|
256
|
-
duration:
|
|
221
|
+
label: "pipeline:cache-hit",
|
|
222
|
+
duration: loaderEnd - pipelineStart,
|
|
257
223
|
startTime: pipelineStart - ms.requestStart,
|
|
258
224
|
});
|
|
259
225
|
}
|
|
260
226
|
}
|
|
261
227
|
|
|
228
|
+
async function* yieldFromStore<TEnv>(
|
|
229
|
+
entry: PrerenderEntry,
|
|
230
|
+
ctx: MatchContext<TEnv>,
|
|
231
|
+
state: MatchPipelineState,
|
|
232
|
+
pipelineStart: number,
|
|
233
|
+
handleStoreRef?: HandleStore,
|
|
234
|
+
): AsyncGenerator<ResolvedSegment> {
|
|
235
|
+
const { resolveLoadersOnlyWithRevalidation, resolveLoadersOnly } =
|
|
236
|
+
getRouterContext<TEnv>();
|
|
237
|
+
|
|
238
|
+
if (
|
|
239
|
+
!_deserializeSegments ||
|
|
240
|
+
!_restoreHandles ||
|
|
241
|
+
!_decodeHandles ||
|
|
242
|
+
!_hashParams ||
|
|
243
|
+
!_lazyGetRequestContext
|
|
244
|
+
) {
|
|
245
|
+
throw new Error("yieldFromStore called before ensurePrerenderDeps");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const segments = await _deserializeSegments(entry.segments);
|
|
249
|
+
|
|
250
|
+
// Replay handle data (same as runtime cache hit path). entry.handles is a
|
|
251
|
+
// Flight-encoded string ("" when none) — decode before restore so
|
|
252
|
+
// Promise/ReactNode handle values are revived, not the corrupted JSON form.
|
|
253
|
+
const handleStore = handleStoreRef ?? _lazyGetRequestContext()?._handleStore;
|
|
254
|
+
if (handleStore && entry.handles) {
|
|
255
|
+
const handlesRecord = await _decodeHandles(entry.handles);
|
|
256
|
+
if (handlesRecord) {
|
|
257
|
+
_restoreHandles(handlesRecord, handleStore);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
state.cacheHit = true;
|
|
262
|
+
state.cacheSource = "prerender";
|
|
263
|
+
state.cachedSegments = segments;
|
|
264
|
+
state.cachedMatchedIds = segments.map((s) => s.id);
|
|
265
|
+
|
|
266
|
+
// Set streaming flag (once) and resolve render barrier.
|
|
267
|
+
const reqCtx = handleStoreRef ? undefined : _lazyGetRequestContext?.();
|
|
268
|
+
const barrierReqCtx = reqCtx ?? _getRequestContext();
|
|
269
|
+
if (barrierReqCtx) {
|
|
270
|
+
if (barrierReqCtx._treeHasStreaming === undefined) {
|
|
271
|
+
barrierReqCtx._treeHasStreaming = treeHasStreaming(ctx.entries);
|
|
272
|
+
}
|
|
273
|
+
barrierReqCtx._resolveRenderBarrier(segments);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// For partial navigation, nullify components the client already has
|
|
277
|
+
// so parent layouts stay live (client keeps its existing versions).
|
|
278
|
+
// When params changed (e.g., different guide slug), the segments have
|
|
279
|
+
// different content, so we must NOT nullify.
|
|
280
|
+
const paramsChanged =
|
|
281
|
+
!ctx.isFullMatch && !paramsEqual(ctx.matched.params, ctx.prevParams);
|
|
282
|
+
for (const segment of segments) {
|
|
283
|
+
if (
|
|
284
|
+
!ctx.isFullMatch &&
|
|
285
|
+
!paramsChanged &&
|
|
286
|
+
ctx.clientSegmentSet.has(segment.id)
|
|
287
|
+
) {
|
|
288
|
+
segment.component = null;
|
|
289
|
+
segment.loading = undefined;
|
|
290
|
+
}
|
|
291
|
+
yield segment;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Resolve loaders fresh (loaders are never pre-rendered/cached).
|
|
295
|
+
yield* resolveFreshLoadersAndYield(
|
|
296
|
+
ctx,
|
|
297
|
+
state,
|
|
298
|
+
pipelineStart,
|
|
299
|
+
ctx.metricsStore,
|
|
300
|
+
resolveLoadersOnly,
|
|
301
|
+
resolveLoadersOnlyWithRevalidation,
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Look up a prerendered (build-time cached) entry for the current route and, on
|
|
307
|
+
* a hit, yield its segments. Returns true when an entry was served (the caller
|
|
308
|
+
* should stop the pipeline) and false on a miss. Intercept navigations consult
|
|
309
|
+
* only the intercept-specific entry (`paramHash + "/i"`); a miss there falls
|
|
310
|
+
* through to the normal pipeline so intercept-resolution can run. Callers must
|
|
311
|
+
* guard on `prerenderStoreInstance` after `ensurePrerenderDeps()`.
|
|
312
|
+
*/
|
|
313
|
+
async function* tryPrerenderLookup<TEnv>(
|
|
314
|
+
ctx: MatchContext<TEnv>,
|
|
315
|
+
state: MatchPipelineState,
|
|
316
|
+
pipelineStart: number,
|
|
317
|
+
handleStoreRef?: HandleStore,
|
|
318
|
+
): AsyncGenerator<ResolvedSegment, boolean> {
|
|
319
|
+
const paramHash = _hashParams!(ctx.matched.params);
|
|
320
|
+
const isPassthroughPrerenderRoute = ctx.entries.some(
|
|
321
|
+
(entry) => entry.type === "route" && entry.isPassthrough === true,
|
|
322
|
+
);
|
|
323
|
+
const lookupHash = ctx.isIntercept ? paramHash + "/i" : paramHash;
|
|
324
|
+
const entry = await prerenderStoreInstance!.get(
|
|
325
|
+
ctx.matched.routeKey,
|
|
326
|
+
lookupHash,
|
|
327
|
+
{
|
|
328
|
+
pathname: ctx.pathname,
|
|
329
|
+
isPassthroughRoute: isPassthroughPrerenderRoute,
|
|
330
|
+
},
|
|
331
|
+
);
|
|
332
|
+
if (!entry) return false;
|
|
333
|
+
yield* yieldFromStore(entry, ctx, state, pipelineStart, handleStoreRef);
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
|
|
262
337
|
/**
|
|
263
338
|
* Async generator middleware type
|
|
264
339
|
*/
|
|
@@ -303,72 +378,20 @@ export function withCacheLookup<TEnv>(
|
|
|
303
378
|
resolveLoadersOnly,
|
|
304
379
|
} = getRouterContext<TEnv>();
|
|
305
380
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (!ctx.isAction && ctx.matched.pr) {
|
|
381
|
+
const isHmr = !!ctx.request.headers.get("X-RSC-HMR");
|
|
382
|
+
if (!ctx.isAction && !isHmr && ctx.matched.pr) {
|
|
309
383
|
await ensurePrerenderDeps();
|
|
310
384
|
if (prerenderStoreInstance) {
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
385
|
+
const served = yield* tryPrerenderLookup(
|
|
386
|
+
ctx,
|
|
387
|
+
state,
|
|
388
|
+
pipelineStart,
|
|
389
|
+
handleStoreRef,
|
|
316
390
|
);
|
|
317
|
-
|
|
318
|
-
if (ctx.isIntercept) {
|
|
319
|
-
// Intercept navigation: try intercept-specific prerender entry
|
|
320
|
-
const entry = await prerenderStoreInstance.get(
|
|
321
|
-
ctx.matched.routeKey,
|
|
322
|
-
paramHash + "/i",
|
|
323
|
-
{
|
|
324
|
-
pathname: ctx.pathname,
|
|
325
|
-
isPassthroughRoute: isPassthroughPrerenderRoute,
|
|
326
|
-
},
|
|
327
|
-
);
|
|
328
|
-
if (entry) {
|
|
329
|
-
yield* yieldFromStore(
|
|
330
|
-
entry,
|
|
331
|
-
ctx,
|
|
332
|
-
state,
|
|
333
|
-
pipelineStart,
|
|
334
|
-
handleStoreRef,
|
|
335
|
-
);
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
// No intercept prerender -- fall through to normal pipeline
|
|
339
|
-
// (skip non-intercept prerender to let intercept-resolution run)
|
|
340
|
-
} else {
|
|
341
|
-
// Normal navigation: existing behavior
|
|
342
|
-
const entry = await prerenderStoreInstance.get(
|
|
343
|
-
ctx.matched.routeKey,
|
|
344
|
-
paramHash,
|
|
345
|
-
{
|
|
346
|
-
pathname: ctx.pathname,
|
|
347
|
-
isPassthroughRoute: isPassthroughPrerenderRoute,
|
|
348
|
-
},
|
|
349
|
-
);
|
|
350
|
-
if (entry) {
|
|
351
|
-
yield* yieldFromStore(
|
|
352
|
-
entry,
|
|
353
|
-
ctx,
|
|
354
|
-
state,
|
|
355
|
-
pipelineStart,
|
|
356
|
-
handleStoreRef,
|
|
357
|
-
);
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
391
|
+
if (served) return;
|
|
361
392
|
}
|
|
362
393
|
}
|
|
363
394
|
|
|
364
|
-
// Dev-mode static handler interception for non-Node.js runtimes.
|
|
365
|
-
// __PRERENDER_DEV_URL is set by the Vite plugin when the RSC environment
|
|
366
|
-
// lacks a Node.js module runner (e.g. workerd, Deno workers). In those
|
|
367
|
-
// runtimes, handlers that depend on Node APIs like node:fs can't run
|
|
368
|
-
// in-process. We redirect them to the /__rsc_prerender endpoint which
|
|
369
|
-
// resolves segments in a Node.js temp server, same as prerender routes.
|
|
370
|
-
// In Node.js dev mode this variable is undefined -- handlers run
|
|
371
|
-
// in-process where Node APIs work, so no interception is needed.
|
|
372
395
|
if (!ctx.isAction && !ctx.matched.pr && globalThis.__PRERENDER_DEV_URL) {
|
|
373
396
|
const hasStatic = ctx.entries.some(
|
|
374
397
|
(e) =>
|
|
@@ -380,64 +403,22 @@ export function withCacheLookup<TEnv>(
|
|
|
380
403
|
if (hasStatic) {
|
|
381
404
|
await ensurePrerenderDeps();
|
|
382
405
|
if (prerenderStoreInstance) {
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
406
|
+
const served = yield* tryPrerenderLookup(
|
|
407
|
+
ctx,
|
|
408
|
+
state,
|
|
409
|
+
pipelineStart,
|
|
410
|
+
handleStoreRef,
|
|
388
411
|
);
|
|
389
|
-
|
|
390
|
-
if (ctx.isIntercept) {
|
|
391
|
-
const entry = await prerenderStoreInstance.get(
|
|
392
|
-
ctx.matched.routeKey,
|
|
393
|
-
paramHash + "/i",
|
|
394
|
-
{
|
|
395
|
-
pathname: ctx.pathname,
|
|
396
|
-
isPassthroughRoute: isPassthroughPrerenderRoute,
|
|
397
|
-
},
|
|
398
|
-
);
|
|
399
|
-
if (entry) {
|
|
400
|
-
yield* yieldFromStore(
|
|
401
|
-
entry,
|
|
402
|
-
ctx,
|
|
403
|
-
state,
|
|
404
|
-
pipelineStart,
|
|
405
|
-
handleStoreRef,
|
|
406
|
-
);
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
// No intercept prerender -- fall through to normal pipeline
|
|
410
|
-
} else {
|
|
411
|
-
const entry = await prerenderStoreInstance.get(
|
|
412
|
-
ctx.matched.routeKey,
|
|
413
|
-
paramHash,
|
|
414
|
-
{
|
|
415
|
-
pathname: ctx.pathname,
|
|
416
|
-
isPassthroughRoute: isPassthroughPrerenderRoute,
|
|
417
|
-
},
|
|
418
|
-
);
|
|
419
|
-
if (entry) {
|
|
420
|
-
yield* yieldFromStore(
|
|
421
|
-
entry,
|
|
422
|
-
ctx,
|
|
423
|
-
state,
|
|
424
|
-
pipelineStart,
|
|
425
|
-
handleStoreRef,
|
|
426
|
-
);
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
412
|
+
if (served) return;
|
|
430
413
|
}
|
|
431
414
|
}
|
|
432
415
|
}
|
|
433
416
|
|
|
434
|
-
// Skip cache during actions
|
|
435
417
|
if (ctx.isAction || !ctx.cacheScope?.enabled) {
|
|
436
|
-
// Cache miss - pass through to segment resolution
|
|
437
418
|
yield* source;
|
|
438
419
|
if (ms) {
|
|
439
420
|
ms.metrics.push({
|
|
440
|
-
label: "pipeline:cache-
|
|
421
|
+
label: "pipeline:cache-miss",
|
|
441
422
|
duration: performance.now() - pipelineStart,
|
|
442
423
|
startTime: pipelineStart - ms.requestStart,
|
|
443
424
|
});
|
|
@@ -445,7 +426,6 @@ export function withCacheLookup<TEnv>(
|
|
|
445
426
|
return;
|
|
446
427
|
}
|
|
447
428
|
|
|
448
|
-
// Lookup cache
|
|
449
429
|
const cacheResult = await ctx.cacheScope.lookupRoute(
|
|
450
430
|
ctx.pathname,
|
|
451
431
|
ctx.matched.params,
|
|
@@ -453,11 +433,10 @@ export function withCacheLookup<TEnv>(
|
|
|
453
433
|
);
|
|
454
434
|
|
|
455
435
|
if (!cacheResult) {
|
|
456
|
-
// Cache miss - pass through to segment resolution
|
|
457
436
|
yield* source;
|
|
458
437
|
if (ms) {
|
|
459
438
|
ms.metrics.push({
|
|
460
|
-
label: "pipeline:cache-
|
|
439
|
+
label: "pipeline:cache-miss",
|
|
461
440
|
duration: performance.now() - pipelineStart,
|
|
462
441
|
startTime: pipelineStart - ms.requestStart,
|
|
463
442
|
});
|
|
@@ -465,16 +444,12 @@ export function withCacheLookup<TEnv>(
|
|
|
465
444
|
return;
|
|
466
445
|
}
|
|
467
446
|
|
|
468
|
-
// Cache HIT
|
|
469
447
|
state.cacheHit = true;
|
|
470
448
|
state.cacheSource = "runtime";
|
|
471
449
|
state.shouldRevalidate = cacheResult.shouldRevalidate;
|
|
472
450
|
state.cachedSegments = cacheResult.segments;
|
|
473
451
|
state.cachedMatchedIds = cacheResult.segments.map((s) => s.id);
|
|
474
452
|
|
|
475
|
-
// Apply revalidation to cached segments.
|
|
476
|
-
// For full matches or empty client segment sets, this map is unnecessary:
|
|
477
|
-
// we never run segment-level revalidation and can stream segments directly.
|
|
478
453
|
const canCheckSegmentRevalidation =
|
|
479
454
|
!ctx.isFullMatch &&
|
|
480
455
|
ctx.clientSegmentSet.size > 0 &&
|
|
@@ -484,7 +459,6 @@ export function withCacheLookup<TEnv>(
|
|
|
484
459
|
: undefined;
|
|
485
460
|
|
|
486
461
|
for (const segment of cacheResult.segments) {
|
|
487
|
-
// Skip segments client doesn't have - they need their component
|
|
488
462
|
if (!ctx.clientSegmentSet.has(segment.id)) {
|
|
489
463
|
if (isTraceActive()) {
|
|
490
464
|
pushRevalidationTraceEntry({
|
|
@@ -501,16 +475,42 @@ export function withCacheLookup<TEnv>(
|
|
|
501
475
|
continue;
|
|
502
476
|
}
|
|
503
477
|
|
|
504
|
-
// Skip intercept segments - they're handled separately
|
|
505
478
|
if (segment.namespace?.startsWith("intercept:")) {
|
|
506
479
|
yield segment;
|
|
507
480
|
continue;
|
|
508
481
|
}
|
|
509
482
|
|
|
510
|
-
// Look up revalidation rules for this segment
|
|
511
483
|
const entryInfo = entryRevalidateMap?.get(segment.id);
|
|
484
|
+
|
|
485
|
+
const searchChanged = ctx.prevUrl.search !== ctx.url.search;
|
|
486
|
+
const routeParamsChanged = !paramsEqual(
|
|
487
|
+
ctx.matched.params,
|
|
488
|
+
ctx.prevParams,
|
|
489
|
+
);
|
|
490
|
+
const shouldDefaultRevalidate =
|
|
491
|
+
(searchChanged || routeParamsChanged) &&
|
|
492
|
+
(segment.type === "route" ||
|
|
493
|
+
(segment.belongsToRoute &&
|
|
494
|
+
(segment.type === "layout" || segment.type === "parallel")));
|
|
495
|
+
|
|
512
496
|
if (!entryInfo || entryInfo.revalidate.length === 0) {
|
|
513
|
-
|
|
497
|
+
if (shouldDefaultRevalidate) {
|
|
498
|
+
if (isTraceActive()) {
|
|
499
|
+
pushRevalidationTraceEntry({
|
|
500
|
+
segmentId: segment.id,
|
|
501
|
+
segmentType: segment.type,
|
|
502
|
+
belongsToRoute: segment.belongsToRoute ?? false,
|
|
503
|
+
source: "cache-hit",
|
|
504
|
+
defaultShouldRevalidate: true,
|
|
505
|
+
finalShouldRevalidate: true,
|
|
506
|
+
reason: routeParamsChanged
|
|
507
|
+
? "cached-params-changed"
|
|
508
|
+
: "cached-search-changed",
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
yield segment;
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
514
|
if (isTraceActive()) {
|
|
515
515
|
pushRevalidationTraceEntry({
|
|
516
516
|
segmentId: segment.id,
|
|
@@ -528,7 +528,6 @@ export function withCacheLookup<TEnv>(
|
|
|
528
528
|
continue;
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
-
// Evaluate revalidation rules
|
|
532
531
|
const shouldRevalidate = await evaluateRevalidation({
|
|
533
532
|
segment,
|
|
534
533
|
prevParams: ctx.prevParams,
|
|
@@ -543,7 +542,7 @@ export function withCacheLookup<TEnv>(
|
|
|
543
542
|
routeKey: ctx.routeKey,
|
|
544
543
|
context: ctx.handlerContext,
|
|
545
544
|
actionContext: ctx.actionContext,
|
|
546
|
-
stale: cacheResult.shouldRevalidate || undefined,
|
|
545
|
+
stale: cacheResult.shouldRevalidate || ctx.stale || undefined,
|
|
547
546
|
traceSource: "cache-hit",
|
|
548
547
|
});
|
|
549
548
|
|
|
@@ -562,7 +561,6 @@ export function withCacheLookup<TEnv>(
|
|
|
562
561
|
}
|
|
563
562
|
|
|
564
563
|
if (!shouldRevalidate) {
|
|
565
|
-
// Client has it, no revalidation needed
|
|
566
564
|
segment.component = null;
|
|
567
565
|
segment.loading = undefined;
|
|
568
566
|
}
|
|
@@ -570,65 +568,23 @@ export function withCacheLookup<TEnv>(
|
|
|
570
568
|
yield segment;
|
|
571
569
|
}
|
|
572
570
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
if (ctx.isFullMatch) {
|
|
578
|
-
// Full match (document request) - simple loader resolution without revalidation
|
|
579
|
-
if (resolveLoadersOnly) {
|
|
580
|
-
const loaderSegments = await Store.run(() =>
|
|
581
|
-
resolveLoadersOnly(ctx.entries, ctx.handlerContext),
|
|
582
|
-
);
|
|
583
|
-
|
|
584
|
-
// Update state - full match doesn't track matchedIds separately
|
|
585
|
-
state.matchedIds = state.cachedMatchedIds!;
|
|
586
|
-
|
|
587
|
-
// Yield fresh loader segments
|
|
588
|
-
for (const segment of loaderSegments) {
|
|
589
|
-
yield segment;
|
|
590
|
-
}
|
|
591
|
-
} else {
|
|
592
|
-
state.matchedIds = state.cachedMatchedIds!;
|
|
593
|
-
}
|
|
594
|
-
} else {
|
|
595
|
-
// Partial match (navigation) - loader resolution with revalidation
|
|
596
|
-
if (resolveLoadersOnlyWithRevalidation) {
|
|
597
|
-
const loaderResult = await Store.run(() =>
|
|
598
|
-
resolveLoadersOnlyWithRevalidation(
|
|
599
|
-
ctx.entries,
|
|
600
|
-
ctx.handlerContext,
|
|
601
|
-
ctx.clientSegmentSet,
|
|
602
|
-
ctx.prevParams,
|
|
603
|
-
ctx.request,
|
|
604
|
-
ctx.prevUrl,
|
|
605
|
-
ctx.url,
|
|
606
|
-
ctx.routeKey,
|
|
607
|
-
ctx.actionContext,
|
|
608
|
-
cacheResult.shouldRevalidate || undefined,
|
|
609
|
-
),
|
|
610
|
-
);
|
|
611
|
-
|
|
612
|
-
// Update state with fresh loader matchedIds
|
|
613
|
-
state.matchedIds = [
|
|
614
|
-
...state.cachedMatchedIds!,
|
|
615
|
-
...loaderResult.matchedIds,
|
|
616
|
-
];
|
|
617
|
-
|
|
618
|
-
// Yield fresh loader segments
|
|
619
|
-
for (const segment of loaderResult.segments) {
|
|
620
|
-
yield segment;
|
|
621
|
-
}
|
|
622
|
-
} else {
|
|
623
|
-
state.matchedIds = state.cachedMatchedIds!;
|
|
571
|
+
const barrierReqCtx = _getRequestContext();
|
|
572
|
+
if (barrierReqCtx) {
|
|
573
|
+
if (barrierReqCtx._treeHasStreaming === undefined) {
|
|
574
|
+
barrierReqCtx._treeHasStreaming = treeHasStreaming(ctx.entries);
|
|
624
575
|
}
|
|
576
|
+
barrierReqCtx._resolveRenderBarrier(cacheResult.segments);
|
|
625
577
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
578
|
+
|
|
579
|
+
// Resolve loaders fresh (loaders are never cached). Shared with the
|
|
580
|
+
// prerender-store path via resolveFreshLoadersAndYield.
|
|
581
|
+
yield* resolveFreshLoadersAndYield(
|
|
582
|
+
ctx,
|
|
583
|
+
state,
|
|
584
|
+
pipelineStart,
|
|
585
|
+
ms,
|
|
586
|
+
resolveLoadersOnly,
|
|
587
|
+
resolveLoadersOnlyWithRevalidation,
|
|
588
|
+
);
|
|
633
589
|
};
|
|
634
590
|
}
|