vinext 0.1.1 → 0.1.3
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/README.md +2 -5
- package/dist/build/client-build-config.d.ts +7 -1
- package/dist/build/client-build-config.js +9 -1
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +41 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/check.js +4 -3
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/navigation-runtime.d.ts +3 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/window-next.d.ts +8 -5
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -4
- package/dist/config/config-matchers.js +88 -16
- package/dist/config/next-config.d.ts +59 -4
- package/dist/config/next-config.js +149 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +189 -101
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +71 -6
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +54 -9
- package/dist/entries/pages-server-entry.js +48 -11
- package/dist/index.d.ts +0 -2
- package/dist/index.js +285 -139
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +10 -5
- package/dist/plugins/optimize-imports.js +27 -21
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +25 -2
- package/dist/routing/app-route-graph.js +91 -22
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +23 -2
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +19 -10
- package/dist/server/app-browser-entry.js +269 -297
- package/dist/server/app-browser-error.d.ts +10 -3
- package/dist/server/app-browser-error.js +47 -6
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +7 -4
- package/dist/server/app-browser-navigation-controller.js +33 -9
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.js +4 -7
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -1
- package/dist/server/app-fallback-renderer.js +6 -2
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +24 -3
- package/dist/server/app-page-boundary-render.d.ts +3 -1
- package/dist/server/app-page-boundary-render.js +31 -16
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +71 -8
- package/dist/server/app-page-dispatch.d.ts +34 -0
- package/dist/server/app-page-dispatch.js +167 -97
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +42 -10
- package/dist/server/app-page-execution.d.ts +7 -2
- package/dist/server/app-page-execution.js +53 -18
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +13 -2
- package/dist/server/app-page-render.js +48 -17
- package/dist/server/app-page-request.d.ts +3 -0
- package/dist/server/app-page-request.js +5 -3
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +5 -1
- package/dist/server/app-page-route-wiring.js +21 -11
- package/dist/server/app-page-stream.d.ts +16 -9
- package/dist/server/app-page-stream.js +12 -9
- package/dist/server/app-pages-bridge.d.ts +18 -0
- package/dist/server/app-pages-bridge.js +22 -5
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.js +12 -1
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +25 -0
- package/dist/server/app-rsc-handler.js +153 -53
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +2 -0
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +12 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +81 -8
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +287 -63
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +186 -22
- package/dist/server/navigation-planner.js +302 -0
- package/dist/server/navigation-trace.d.ts +18 -1
- package/dist/server/navigation-trace.js +18 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +20 -3
- package/dist/server/pages-api-route.js +19 -3
- package/dist/server/pages-asset-tags.d.ts +16 -4
- package/dist/server/pages-asset-tags.js +22 -12
- package/dist/server/pages-data-route.d.ts +8 -1
- package/dist/server/pages-data-route.js +16 -3
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-node-compat.d.ts +3 -11
- package/dist/server/pages-node-compat.js +175 -122
- package/dist/server/pages-page-data.d.ts +39 -2
- package/dist/server/pages-page-data.js +261 -46
- package/dist/server/pages-page-handler.d.ts +5 -2
- package/dist/server/pages-page-handler.js +78 -25
- package/dist/server/pages-page-response.d.ts +47 -2
- package/dist/server/pages-page-response.js +73 -9
- package/dist/server/pages-readiness.d.ts +1 -1
- package/dist/server/pages-request-pipeline.d.ts +16 -1
- package/dist/server/pages-request-pipeline.js +96 -38
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +39 -1
- package/dist/server/prod-server.js +107 -37
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/cache-runtime.js +12 -4
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +79 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +6 -4
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +38 -11
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +11 -1
- package/dist/shims/fetch-cache.js +55 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +66 -5
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +18 -23
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +12 -5
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +14 -17
- package/dist/shims/navigation.js +93 -46
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +13 -2
- package/dist/shims/router.js +434 -116
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +33 -2
- package/dist/shims/server.js +75 -18
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/client-build-manifest.js +15 -5
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +8 -1
- package/dist/utils/path.js +13 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -14,34 +14,34 @@ type OperationToken = {
|
|
|
14
14
|
targetSnapshotFingerprint: string;
|
|
15
15
|
cacheVariantFingerprint?: string;
|
|
16
16
|
};
|
|
17
|
-
type
|
|
18
|
-
interception:
|
|
17
|
+
type RouteSnapshot = {
|
|
18
|
+
interception: InterceptionSnapshot | null;
|
|
19
19
|
interceptionContext: string | null;
|
|
20
20
|
routeId: string;
|
|
21
21
|
layoutIds: readonly string[];
|
|
22
|
-
mountedParallelSlots: readonly
|
|
22
|
+
mountedParallelSlots: readonly MountedParallelSlotSnapshot[];
|
|
23
23
|
rootBoundaryId: string | null;
|
|
24
24
|
displayUrl: string;
|
|
25
25
|
matchedUrl: string;
|
|
26
|
-
slotBindings: readonly
|
|
26
|
+
slotBindings: readonly ParallelSlotBindingSnapshot[];
|
|
27
27
|
};
|
|
28
|
-
type
|
|
28
|
+
type InterceptionSnapshot = {
|
|
29
29
|
sourceMatchedUrl: string;
|
|
30
30
|
sourceRouteId: string;
|
|
31
31
|
slotId: string;
|
|
32
32
|
targetMatchedUrl: string;
|
|
33
33
|
targetRouteId: string;
|
|
34
34
|
};
|
|
35
|
-
type
|
|
35
|
+
type MountedParallelSlotSnapshot = {
|
|
36
36
|
slotId: string;
|
|
37
37
|
ownerLayoutId: string | null;
|
|
38
38
|
};
|
|
39
|
-
type
|
|
40
|
-
type
|
|
39
|
+
type ParallelSlotBindingSnapshot = AppElementsSlotBinding;
|
|
40
|
+
type NavigationPlannerState = {
|
|
41
41
|
nextOperationToken: OperationToken;
|
|
42
42
|
traceFields?: NavigationTraceFields;
|
|
43
43
|
visibleCommitVersion: number;
|
|
44
|
-
visibleSnapshot:
|
|
44
|
+
visibleSnapshot: RouteSnapshot;
|
|
45
45
|
};
|
|
46
46
|
type RefreshScope = "visible";
|
|
47
47
|
type TraverseDirection = "back" | "forward" | "unknown";
|
|
@@ -62,7 +62,7 @@ type NavigationEvent = {
|
|
|
62
62
|
} | {
|
|
63
63
|
kind: "flightResponseArrived";
|
|
64
64
|
token: OperationToken;
|
|
65
|
-
result:
|
|
65
|
+
result: FlightResult;
|
|
66
66
|
};
|
|
67
67
|
type RequestedWork = {
|
|
68
68
|
kind: "flight";
|
|
@@ -82,12 +82,12 @@ type CommitProposal = {
|
|
|
82
82
|
preserveElementIds: readonly string[];
|
|
83
83
|
preservePreviousSlotIds: readonly string[];
|
|
84
84
|
reason: "currentRootBoundary" | "interceptedCurrentRootBoundary" | "unprovenTopologyFallback";
|
|
85
|
-
targetSnapshot:
|
|
85
|
+
targetSnapshot: RouteSnapshot;
|
|
86
86
|
};
|
|
87
87
|
type NoCommitReason = "prefetchOnly";
|
|
88
88
|
type HardNavigationReason = "cacheProofRejected" | "interceptionProofRejected" | "rootBoundaryChanged";
|
|
89
89
|
type RootBoundaryTransition = "currentRootBoundary" | "rootBoundaryChanged" | "rootBoundaryUnknown";
|
|
90
|
-
type
|
|
90
|
+
type NavigationDecision = {
|
|
91
91
|
kind: "requestWork";
|
|
92
92
|
token: OperationToken;
|
|
93
93
|
work: RequestedWork;
|
|
@@ -109,23 +109,148 @@ type NavigationDecisionV0 = {
|
|
|
109
109
|
reason: HardNavigationReason;
|
|
110
110
|
trace: NavigationTrace;
|
|
111
111
|
};
|
|
112
|
-
type
|
|
112
|
+
type FlightResult = {
|
|
113
113
|
cacheEntryReuseProof?: CacheEntryReuseProof;
|
|
114
114
|
href: string;
|
|
115
|
-
targetSnapshot:
|
|
115
|
+
targetSnapshot: RouteSnapshot;
|
|
116
|
+
};
|
|
117
|
+
type RscFetchResultSource = "cached" | "live";
|
|
118
|
+
type RscFetchResultFacts = {
|
|
119
|
+
source: RscFetchResultSource;
|
|
120
|
+
currentHref: string;
|
|
121
|
+
origin: string;
|
|
122
|
+
effectiveHistoryUpdateMode: "push" | "replace";
|
|
123
|
+
redirectDepth: number;
|
|
124
|
+
requestPreviousNextUrl: string | null;
|
|
125
|
+
clientCompatibilityId: string | null;
|
|
126
|
+
responseOk: boolean;
|
|
127
|
+
isRscContentType: boolean;
|
|
128
|
+
hasBody: boolean;
|
|
129
|
+
compatibilityIdHeader: string | null;
|
|
130
|
+
responseUrl: string | null;
|
|
131
|
+
streamedRedirectTarget: string | null;
|
|
132
|
+
};
|
|
133
|
+
type RscRedirectFollow = {
|
|
134
|
+
href: string;
|
|
135
|
+
historyUpdateMode: "push" | "replace";
|
|
136
|
+
previousNextUrl: string | null;
|
|
137
|
+
redirectDepth: number;
|
|
138
|
+
};
|
|
139
|
+
type RscFetchResultHardNavReason = "invalidRscPayload" | "rscCompatibilityMismatch" | "externalRedirectTarget" | "redirectDepthExhausted" | "streamedRedirectLoop";
|
|
140
|
+
type RscFetchResultDecision = {
|
|
141
|
+
kind: "proceedToCommit";
|
|
142
|
+
discardBody: false;
|
|
143
|
+
trace: NavigationTrace;
|
|
144
|
+
} | {
|
|
145
|
+
kind: "followRedirect";
|
|
146
|
+
discardBody: boolean;
|
|
147
|
+
redirect: RscRedirectFollow;
|
|
148
|
+
trace: NavigationTrace;
|
|
149
|
+
} | {
|
|
150
|
+
kind: "hardNavigate";
|
|
151
|
+
discardBody: boolean;
|
|
152
|
+
url: string;
|
|
153
|
+
reason: RscFetchResultHardNavReason;
|
|
154
|
+
trace: NavigationTrace;
|
|
155
|
+
};
|
|
156
|
+
type EarlyNavigationIntentFacts = {
|
|
157
|
+
basePath: string;
|
|
158
|
+
currentHref: string;
|
|
159
|
+
mode: "push" | "replace";
|
|
160
|
+
scroll: boolean;
|
|
161
|
+
targetHref: string;
|
|
162
|
+
};
|
|
163
|
+
type EarlyNavigationIntentDecision = {
|
|
164
|
+
kind: "sameDocumentScroll";
|
|
165
|
+
hash: string;
|
|
166
|
+
mode: "push" | "replace";
|
|
167
|
+
scroll: boolean;
|
|
168
|
+
trace: NavigationTrace;
|
|
169
|
+
} | {
|
|
170
|
+
kind: "flightNavigation";
|
|
171
|
+
bypassNavigationCache: boolean;
|
|
172
|
+
trace: NavigationTrace;
|
|
173
|
+
};
|
|
174
|
+
type NavigationReuseNavigationKind = "navigate" | "refresh" | "traverse";
|
|
175
|
+
type VisitedResponseCacheCandidateFacts = {
|
|
176
|
+
candidate: "missing";
|
|
177
|
+
navigationKind: NavigationReuseNavigationKind;
|
|
178
|
+
} | {
|
|
179
|
+
candidate: "present";
|
|
180
|
+
fresh: boolean;
|
|
181
|
+
mountedSlotsMatch: boolean;
|
|
182
|
+
navigationKind: NavigationReuseNavigationKind;
|
|
183
|
+
};
|
|
184
|
+
type VisitedResponseCacheCandidateDecision = {
|
|
185
|
+
kind: "miss";
|
|
186
|
+
} | {
|
|
187
|
+
kind: "evict";
|
|
188
|
+
reason: "mountedSlotsMismatch" | "refresh" | "stale";
|
|
189
|
+
} | {
|
|
190
|
+
kind: "reuse";
|
|
191
|
+
};
|
|
192
|
+
type NavigationReuseCandidateAvailability = {
|
|
193
|
+
status: "available";
|
|
194
|
+
} | {
|
|
195
|
+
status: "unavailable";
|
|
196
|
+
};
|
|
197
|
+
type OptimisticRouteShellCandidateAvailability = {
|
|
198
|
+
status: "available";
|
|
199
|
+
} | {
|
|
200
|
+
status: "unavailable";
|
|
201
|
+
reason: "routeManifestMissing";
|
|
202
|
+
};
|
|
203
|
+
type NavigationReuseFacts = {
|
|
204
|
+
bypassNavigationCache: boolean;
|
|
205
|
+
navigationKind: NavigationReuseNavigationKind;
|
|
206
|
+
optimisticRouteShell: OptimisticRouteShellCandidateAvailability;
|
|
207
|
+
prefetch: NavigationReuseCandidateAvailability;
|
|
208
|
+
targetHref: string;
|
|
209
|
+
visitedResponse: NavigationReuseCandidateAvailability;
|
|
210
|
+
};
|
|
211
|
+
type FreshFetchReason = "cacheBypassed" | "cacheMiss" | "refresh" | "routeManifestMissing";
|
|
212
|
+
type NavigationReuseDecision = {
|
|
213
|
+
kind: "reuseVisitedResponse";
|
|
214
|
+
trace: NavigationTrace;
|
|
215
|
+
} | {
|
|
216
|
+
kind: "consumePrefetch";
|
|
217
|
+
trace: NavigationTrace;
|
|
218
|
+
} | {
|
|
219
|
+
kind: "attemptOptimisticRouteShell";
|
|
220
|
+
trace: NavigationTrace;
|
|
221
|
+
} | {
|
|
222
|
+
kind: "fetchFresh";
|
|
223
|
+
reason: FreshFetchReason;
|
|
224
|
+
trace: NavigationTrace;
|
|
225
|
+
};
|
|
226
|
+
type NavigationPrefetchProbeFacts = {
|
|
227
|
+
bypassNavigationCache: boolean;
|
|
228
|
+
navigationKind: NavigationReuseNavigationKind;
|
|
229
|
+
visitedResponse: NavigationReuseCandidateAvailability;
|
|
230
|
+
};
|
|
231
|
+
type NavigationPrefetchProbeDecision = {
|
|
232
|
+
kind: "probe";
|
|
233
|
+
} | {
|
|
234
|
+
kind: "skip";
|
|
235
|
+
reason: "cacheBypassed" | "refresh" | "visitedResponseAvailable";
|
|
116
236
|
};
|
|
117
237
|
type NavigationPlannerInput = {
|
|
118
238
|
routeManifest: RouteManifest | null;
|
|
119
|
-
state:
|
|
239
|
+
state: NavigationPlannerState;
|
|
120
240
|
event: NavigationEvent;
|
|
121
241
|
};
|
|
122
242
|
type AcceptedCacheEntryReuseDecision = Extract<CacheEntryReuseDecision, {
|
|
123
243
|
canReuse: true;
|
|
124
244
|
}>;
|
|
245
|
+
declare function classifyRscFetchResult(facts: RscFetchResultFacts): RscFetchResultDecision;
|
|
246
|
+
declare function classifyEarlyNavigationIntent(facts: EarlyNavigationIntentFacts): EarlyNavigationIntentDecision;
|
|
247
|
+
declare function classifyVisitedResponseCacheCandidate(facts: VisitedResponseCacheCandidateFacts): VisitedResponseCacheCandidateDecision;
|
|
248
|
+
declare function classifyNavigationReuse(facts: NavigationReuseFacts): NavigationReuseDecision;
|
|
249
|
+
declare function classifyNavigationPrefetchProbe(facts: NavigationPrefetchProbeFacts): NavigationPrefetchProbeDecision;
|
|
125
250
|
declare function classifyRootBoundaryTransition(currentRootBoundaryId: string | null, nextRootBoundaryId: string | null): RootBoundaryTransition;
|
|
126
|
-
declare function resolveSameLayoutAncestorPersistence(currentSnapshot:
|
|
127
|
-
declare function resolveMountedParallelSlotPersistence(currentSnapshot:
|
|
128
|
-
declare function resolveCurrentRootBoundaryElementPersistence(currentSnapshot:
|
|
251
|
+
declare function resolveSameLayoutAncestorPersistence(currentSnapshot: RouteSnapshot, targetSnapshot: RouteSnapshot): readonly string[];
|
|
252
|
+
declare function resolveMountedParallelSlotPersistence(currentSnapshot: RouteSnapshot, targetSnapshot: RouteSnapshot): readonly string[];
|
|
253
|
+
declare function resolveCurrentRootBoundaryElementPersistence(currentSnapshot: RouteSnapshot, targetSnapshot: RouteSnapshot): readonly string[];
|
|
129
254
|
/**
|
|
130
255
|
* Default/unmatched slot preservation law:
|
|
131
256
|
*
|
|
@@ -137,17 +262,56 @@ declare function resolveCurrentRootBoundaryElementPersistence(currentSnapshot: R
|
|
|
137
262
|
* Wire absence and UNMATCHED_SLOT markers are not semantic proof.
|
|
138
263
|
*/
|
|
139
264
|
declare function resolveDefaultOrUnmatchedSlotPersistenceForLayouts(options: {
|
|
140
|
-
currentSlotBindings: readonly
|
|
265
|
+
currentSlotBindings: readonly ParallelSlotBindingSnapshot[];
|
|
141
266
|
preservedLayoutIds: readonly string[];
|
|
142
|
-
targetSlotBindings: readonly
|
|
267
|
+
targetSlotBindings: readonly ParallelSlotBindingSnapshot[];
|
|
143
268
|
}): readonly string[];
|
|
144
|
-
declare function planNavigation(input: NavigationPlannerInput):
|
|
269
|
+
declare function planNavigation(input: NavigationPlannerInput): NavigationDecision;
|
|
270
|
+
type ServerActionResultFacts = {
|
|
271
|
+
actionRedirectHref: string | null;
|
|
272
|
+
actionRedirectType: "push" | "replace";
|
|
273
|
+
clientCompatibilityId: string | null;
|
|
274
|
+
compatibilityIdHeader: string | null;
|
|
275
|
+
currentHref: string;
|
|
276
|
+
isRscContentType: boolean;
|
|
277
|
+
origin: string;
|
|
278
|
+
responseUrl: string | null;
|
|
279
|
+
};
|
|
280
|
+
type ServerActionResultDecision = {
|
|
281
|
+
kind: "proceed";
|
|
282
|
+
trace: NavigationTrace;
|
|
283
|
+
} | {
|
|
284
|
+
kind: "hardNavigate";
|
|
285
|
+
url: string;
|
|
286
|
+
historyMode?: "assign" | "replace";
|
|
287
|
+
clearClientNavigationCaches: boolean;
|
|
288
|
+
reason: "serverActionRedirectCompatibilityMismatch" | "serverActionRscCompatibilityMismatch";
|
|
289
|
+
trace: NavigationTrace;
|
|
290
|
+
};
|
|
291
|
+
type RscNavigationErrorFacts = {
|
|
292
|
+
currentHref: string;
|
|
293
|
+
};
|
|
294
|
+
type RscNavigationErrorDecision = {
|
|
295
|
+
kind: "hardNavigate";
|
|
296
|
+
url: string;
|
|
297
|
+
reason: "rscNavigationError";
|
|
298
|
+
trace: NavigationTrace;
|
|
299
|
+
};
|
|
300
|
+
declare function classifyServerActionResult(facts: ServerActionResultFacts): ServerActionResultDecision;
|
|
301
|
+
declare function classifyRscNavigationError(facts: RscNavigationErrorFacts): RscNavigationErrorDecision;
|
|
145
302
|
declare const navigationPlanner: {
|
|
303
|
+
classifyEarlyNavigationIntent: typeof classifyEarlyNavigationIntent;
|
|
304
|
+
classifyNavigationPrefetchProbe: typeof classifyNavigationPrefetchProbe;
|
|
305
|
+
classifyNavigationReuse: typeof classifyNavigationReuse;
|
|
306
|
+
classifyRscFetchResult: typeof classifyRscFetchResult;
|
|
307
|
+
classifyRscNavigationError: typeof classifyRscNavigationError;
|
|
146
308
|
classifyRootBoundaryTransition: typeof classifyRootBoundaryTransition;
|
|
309
|
+
classifyServerActionResult: typeof classifyServerActionResult;
|
|
310
|
+
classifyVisitedResponseCacheCandidate: typeof classifyVisitedResponseCacheCandidate;
|
|
147
311
|
plan: typeof planNavigation;
|
|
148
312
|
resolveCurrentRootBoundaryElementPersistence: typeof resolveCurrentRootBoundaryElementPersistence;
|
|
149
313
|
resolveMountedParallelSlotPersistence: typeof resolveMountedParallelSlotPersistence;
|
|
150
314
|
resolveSameLayoutAncestorPersistence: typeof resolveSameLayoutAncestorPersistence;
|
|
151
315
|
};
|
|
152
316
|
//#endregion
|
|
153
|
-
export {
|
|
317
|
+
export { EarlyNavigationIntentDecision, EarlyNavigationIntentFacts, FlightResult, InterceptionSnapshot, MountedParallelSlotSnapshot, NavigationDecision, NavigationEvent, NavigationPlannerInput, NavigationPlannerState, NavigationReuseDecision, NavigationReuseFacts, OperationLane, OperationToken, ParallelSlotBindingSnapshot, RefreshScope, RootBoundaryTransition, RouteSnapshot, RscFetchResultDecision, RscFetchResultFacts, RscNavigationErrorDecision, RscNavigationErrorFacts, ServerActionResultDecision, ServerActionResultFacts, TraverseDirection, VisitedResponseCacheCandidateFacts, navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
2
|
+
import { stripBasePath } from "../utils/base-path.js";
|
|
2
3
|
import { matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments } from "../routing/route-pattern.js";
|
|
3
4
|
import { compareAppElementsSlotIds } from "./app-elements-wire.js";
|
|
4
5
|
import "./app-elements.js";
|
|
6
|
+
import { resolveHardNavigationTargetFromRscResponse, resolveRscCompatibilityNavigationDecision } from "./app-rsc-cache-busting.js";
|
|
7
|
+
import { resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop } from "./app-browser-rsc-redirect.js";
|
|
5
8
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
6
9
|
//#region src/server/navigation-planner.ts
|
|
7
10
|
const ROUTE_INTERCEPTION_CONTEXT_SEPARATOR = "\0";
|
|
@@ -27,6 +30,254 @@ function getRequestedWorkTargetHref(work) {
|
|
|
27
30
|
default: throw new Error("[vinext] Unknown requested navigation work: " + String(work));
|
|
28
31
|
}
|
|
29
32
|
}
|
|
33
|
+
function createRscFetchResultTraceFields(facts, fields = {}) {
|
|
34
|
+
return {
|
|
35
|
+
fetchResultSource: facts.source,
|
|
36
|
+
...fields
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function createRscFetchResultHardNavigationDecision(options) {
|
|
40
|
+
return {
|
|
41
|
+
discardBody: options.discardBody,
|
|
42
|
+
kind: "hardNavigate",
|
|
43
|
+
reason: options.reason,
|
|
44
|
+
trace: createNavigationTrace(options.reasonCode, createRscFetchResultTraceFields(options.facts, {
|
|
45
|
+
...options.redirectSignal !== void 0 ? { redirectSignal: options.redirectSignal } : {},
|
|
46
|
+
redirectDepth: options.facts.redirectDepth,
|
|
47
|
+
targetHref: options.url
|
|
48
|
+
})),
|
|
49
|
+
url: options.url
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function createRscFetchResultFollowRedirectDecision(options) {
|
|
53
|
+
return {
|
|
54
|
+
discardBody: options.discardBody,
|
|
55
|
+
kind: "followRedirect",
|
|
56
|
+
redirect: options.redirect,
|
|
57
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.redirectFollow, createRscFetchResultTraceFields(options.facts, {
|
|
58
|
+
redirectDepth: options.redirect.redirectDepth,
|
|
59
|
+
redirectSignal: options.redirectSignal,
|
|
60
|
+
targetHref: options.redirect.href
|
|
61
|
+
}))
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function mapRscRedirectTerminalReason(reason) {
|
|
65
|
+
switch (reason) {
|
|
66
|
+
case "externalRedirect": return {
|
|
67
|
+
hardNavigationReason: "externalRedirectTarget",
|
|
68
|
+
traceReasonCode: NavigationTraceReasonCodes.redirectTerminalExternal
|
|
69
|
+
};
|
|
70
|
+
case "maxRedirectsExceeded": return {
|
|
71
|
+
hardNavigationReason: "redirectDepthExhausted",
|
|
72
|
+
traceReasonCode: NavigationTraceReasonCodes.redirectTerminalDepth
|
|
73
|
+
};
|
|
74
|
+
default: throw new Error("[vinext] Unknown RSC redirect terminal reason: " + String(reason));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function classifyRscFetchResult(facts) {
|
|
78
|
+
if (!facts.responseOk || !facts.isRscContentType || !facts.hasBody) {
|
|
79
|
+
const url = resolveHardNavigationTargetFromRscResponse(facts.responseUrl, facts.currentHref, facts.origin);
|
|
80
|
+
return createRscFetchResultHardNavigationDecision({
|
|
81
|
+
discardBody: false,
|
|
82
|
+
facts,
|
|
83
|
+
reason: "invalidRscPayload",
|
|
84
|
+
reasonCode: NavigationTraceReasonCodes.invalidRscPayload,
|
|
85
|
+
url
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const compatibilityDecision = resolveRscCompatibilityNavigationDecision({
|
|
89
|
+
clientCompatibilityId: facts.clientCompatibilityId,
|
|
90
|
+
currentHref: facts.currentHref,
|
|
91
|
+
origin: facts.origin,
|
|
92
|
+
responseCompatibilityId: facts.compatibilityIdHeader,
|
|
93
|
+
responseUrl: facts.responseUrl
|
|
94
|
+
});
|
|
95
|
+
if (compatibilityDecision.kind === "hard-navigate") return createRscFetchResultHardNavigationDecision({
|
|
96
|
+
discardBody: false,
|
|
97
|
+
facts,
|
|
98
|
+
reason: "rscCompatibilityMismatch",
|
|
99
|
+
reasonCode: NavigationTraceReasonCodes.rscCompatibilityMismatch,
|
|
100
|
+
url: compatibilityDecision.hardNavigationTarget
|
|
101
|
+
});
|
|
102
|
+
if (facts.responseUrl !== null) {
|
|
103
|
+
const redirectDecision = resolveRscRedirectLifecycleHop({
|
|
104
|
+
currentHref: facts.currentHref,
|
|
105
|
+
historyUpdateMode: facts.effectiveHistoryUpdateMode,
|
|
106
|
+
origin: facts.origin,
|
|
107
|
+
redirectDepth: facts.redirectDepth,
|
|
108
|
+
requestPreviousNextUrl: facts.requestPreviousNextUrl,
|
|
109
|
+
responseUrl: facts.responseUrl
|
|
110
|
+
});
|
|
111
|
+
if (redirectDecision.kind === "terminal-hard-navigation") {
|
|
112
|
+
const terminalReason = mapRscRedirectTerminalReason(redirectDecision.reason);
|
|
113
|
+
return createRscFetchResultHardNavigationDecision({
|
|
114
|
+
discardBody: false,
|
|
115
|
+
facts,
|
|
116
|
+
reason: terminalReason.hardNavigationReason,
|
|
117
|
+
reasonCode: terminalReason.traceReasonCode,
|
|
118
|
+
redirectSignal: "response-url",
|
|
119
|
+
url: redirectDecision.href
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (redirectDecision.kind === "follow") return createRscFetchResultFollowRedirectDecision({
|
|
123
|
+
discardBody: false,
|
|
124
|
+
facts,
|
|
125
|
+
redirect: {
|
|
126
|
+
href: redirectDecision.href,
|
|
127
|
+
historyUpdateMode: facts.effectiveHistoryUpdateMode,
|
|
128
|
+
previousNextUrl: redirectDecision.previousNextUrl,
|
|
129
|
+
redirectDepth: redirectDecision.redirectDepth
|
|
130
|
+
},
|
|
131
|
+
redirectSignal: "response-url"
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (facts.streamedRedirectTarget !== null) {
|
|
135
|
+
const redirectDecision = resolveStreamedRscRedirectLifecycleHop({
|
|
136
|
+
currentHref: facts.currentHref,
|
|
137
|
+
historyUpdateMode: facts.effectiveHistoryUpdateMode,
|
|
138
|
+
origin: facts.origin,
|
|
139
|
+
redirectDepth: facts.redirectDepth,
|
|
140
|
+
requestPreviousNextUrl: facts.requestPreviousNextUrl,
|
|
141
|
+
streamedRedirectTarget: facts.streamedRedirectTarget
|
|
142
|
+
});
|
|
143
|
+
if (redirectDecision.kind === "terminal-hard-navigation") {
|
|
144
|
+
const terminalReason = mapRscRedirectTerminalReason(redirectDecision.reason);
|
|
145
|
+
return createRscFetchResultHardNavigationDecision({
|
|
146
|
+
discardBody: true,
|
|
147
|
+
facts,
|
|
148
|
+
reason: terminalReason.hardNavigationReason,
|
|
149
|
+
reasonCode: terminalReason.traceReasonCode,
|
|
150
|
+
redirectSignal: "streamed-header",
|
|
151
|
+
url: redirectDecision.href
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (redirectDecision.kind === "follow") return createRscFetchResultFollowRedirectDecision({
|
|
155
|
+
discardBody: true,
|
|
156
|
+
facts,
|
|
157
|
+
redirect: {
|
|
158
|
+
href: redirectDecision.href,
|
|
159
|
+
historyUpdateMode: facts.effectiveHistoryUpdateMode,
|
|
160
|
+
previousNextUrl: redirectDecision.previousNextUrl,
|
|
161
|
+
redirectDepth: redirectDecision.redirectDepth
|
|
162
|
+
},
|
|
163
|
+
redirectSignal: "streamed-header"
|
|
164
|
+
});
|
|
165
|
+
return createRscFetchResultHardNavigationDecision({
|
|
166
|
+
discardBody: true,
|
|
167
|
+
facts,
|
|
168
|
+
reason: "streamedRedirectLoop",
|
|
169
|
+
reasonCode: NavigationTraceReasonCodes.streamedRedirectLoop,
|
|
170
|
+
redirectSignal: "streamed-header",
|
|
171
|
+
url: redirectDecision.href
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
discardBody: false,
|
|
176
|
+
kind: "proceedToCommit",
|
|
177
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.proceedToCommit, createRscFetchResultTraceFields(facts))
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function createEarlyNavigationIntentTrace(reasonCode, facts) {
|
|
181
|
+
return createNavigationTrace(reasonCode, { targetHref: facts.targetHref });
|
|
182
|
+
}
|
|
183
|
+
function classifyEarlyNavigationIntent(facts) {
|
|
184
|
+
let current;
|
|
185
|
+
let next;
|
|
186
|
+
try {
|
|
187
|
+
current = new URL(facts.currentHref);
|
|
188
|
+
next = new URL(facts.targetHref, facts.currentHref);
|
|
189
|
+
} catch {
|
|
190
|
+
return {
|
|
191
|
+
bypassNavigationCache: false,
|
|
192
|
+
kind: "flightNavigation",
|
|
193
|
+
trace: createEarlyNavigationIntentTrace(NavigationTraceReasonCodes.crossDocumentFlight, facts)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const samePathname = current.origin === next.origin && stripBasePath(current.pathname, facts.basePath) === stripBasePath(next.pathname, facts.basePath);
|
|
197
|
+
const sameSearch = current.searchParams.toString() === next.searchParams.toString();
|
|
198
|
+
if (samePathname && sameSearch && next.hash !== "") return {
|
|
199
|
+
hash: next.hash,
|
|
200
|
+
kind: "sameDocumentScroll",
|
|
201
|
+
mode: facts.mode,
|
|
202
|
+
scroll: facts.scroll,
|
|
203
|
+
trace: createEarlyNavigationIntentTrace(NavigationTraceReasonCodes.sameDocumentScroll, facts)
|
|
204
|
+
};
|
|
205
|
+
if (samePathname && !sameSearch) return {
|
|
206
|
+
bypassNavigationCache: true,
|
|
207
|
+
kind: "flightNavigation",
|
|
208
|
+
trace: createEarlyNavigationIntentTrace(NavigationTraceReasonCodes.samePageSearch, facts)
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
bypassNavigationCache: false,
|
|
212
|
+
kind: "flightNavigation",
|
|
213
|
+
trace: createEarlyNavigationIntentTrace(NavigationTraceReasonCodes.crossDocumentFlight, facts)
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function classifyVisitedResponseCacheCandidate(facts) {
|
|
217
|
+
if (facts.candidate === "missing") return { kind: "miss" };
|
|
218
|
+
if (!facts.mountedSlotsMatch) return {
|
|
219
|
+
kind: "evict",
|
|
220
|
+
reason: "mountedSlotsMismatch"
|
|
221
|
+
};
|
|
222
|
+
if (facts.navigationKind === "refresh") return {
|
|
223
|
+
kind: "evict",
|
|
224
|
+
reason: "refresh"
|
|
225
|
+
};
|
|
226
|
+
if (!facts.fresh) return {
|
|
227
|
+
kind: "evict",
|
|
228
|
+
reason: "stale"
|
|
229
|
+
};
|
|
230
|
+
return { kind: "reuse" };
|
|
231
|
+
}
|
|
232
|
+
function createNavigationReuseTrace(code, facts, fields = {}) {
|
|
233
|
+
return createNavigationTrace(code, {
|
|
234
|
+
eventKind: facts.navigationKind,
|
|
235
|
+
targetHref: facts.targetHref,
|
|
236
|
+
...fields
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
function createFreshFetchDecision(facts, reason) {
|
|
240
|
+
return {
|
|
241
|
+
kind: "fetchFresh",
|
|
242
|
+
reason,
|
|
243
|
+
trace: createNavigationReuseTrace(NavigationTraceReasonCodes.fetchFresh, facts, { freshFetchReason: reason })
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function classifyNavigationReuse(facts) {
|
|
247
|
+
if (facts.navigationKind === "refresh") return createFreshFetchDecision(facts, "refresh");
|
|
248
|
+
if (!facts.bypassNavigationCache && facts.visitedResponse.status === "available") return {
|
|
249
|
+
kind: "reuseVisitedResponse",
|
|
250
|
+
trace: createNavigationReuseTrace(NavigationTraceReasonCodes.visitedResponseReuse, facts)
|
|
251
|
+
};
|
|
252
|
+
if (!facts.bypassNavigationCache && facts.prefetch.status === "available") return {
|
|
253
|
+
kind: "consumePrefetch",
|
|
254
|
+
trace: createNavigationReuseTrace(NavigationTraceReasonCodes.prefetchResponseReuse, facts)
|
|
255
|
+
};
|
|
256
|
+
if (facts.navigationKind === "navigate") {
|
|
257
|
+
if (facts.optimisticRouteShell.status === "available") return {
|
|
258
|
+
kind: "attemptOptimisticRouteShell",
|
|
259
|
+
trace: createNavigationReuseTrace(NavigationTraceReasonCodes.optimisticRouteShell, facts)
|
|
260
|
+
};
|
|
261
|
+
return createFreshFetchDecision(facts, facts.bypassNavigationCache ? "cacheBypassed" : facts.optimisticRouteShell.reason);
|
|
262
|
+
}
|
|
263
|
+
if (facts.bypassNavigationCache) return createFreshFetchDecision(facts, "cacheBypassed");
|
|
264
|
+
return createFreshFetchDecision(facts, "cacheMiss");
|
|
265
|
+
}
|
|
266
|
+
function classifyNavigationPrefetchProbe(facts) {
|
|
267
|
+
if (facts.visitedResponse.status === "available") return {
|
|
268
|
+
kind: "skip",
|
|
269
|
+
reason: "visitedResponseAvailable"
|
|
270
|
+
};
|
|
271
|
+
if (facts.navigationKind === "refresh") return {
|
|
272
|
+
kind: "skip",
|
|
273
|
+
reason: "refresh"
|
|
274
|
+
};
|
|
275
|
+
if (facts.bypassNavigationCache) return {
|
|
276
|
+
kind: "skip",
|
|
277
|
+
reason: "cacheBypassed"
|
|
278
|
+
};
|
|
279
|
+
return { kind: "probe" };
|
|
280
|
+
}
|
|
30
281
|
function createSnapshotRouteTopology(snapshot) {
|
|
31
282
|
return {
|
|
32
283
|
layoutIds: snapshot.layoutIds,
|
|
@@ -494,8 +745,59 @@ function planNavigation(input) {
|
|
|
494
745
|
}
|
|
495
746
|
}
|
|
496
747
|
}
|
|
748
|
+
function classifyServerActionResult(facts) {
|
|
749
|
+
if (facts.clientCompatibilityId === null) return {
|
|
750
|
+
kind: "proceed",
|
|
751
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.proceedToCommit, {})
|
|
752
|
+
};
|
|
753
|
+
if (!facts.isRscContentType) return {
|
|
754
|
+
kind: "proceed",
|
|
755
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.proceedToCommit, {})
|
|
756
|
+
};
|
|
757
|
+
if (resolveRscCompatibilityNavigationDecision({
|
|
758
|
+
clientCompatibilityId: facts.clientCompatibilityId,
|
|
759
|
+
currentHref: facts.currentHref,
|
|
760
|
+
origin: facts.origin,
|
|
761
|
+
responseCompatibilityId: facts.compatibilityIdHeader,
|
|
762
|
+
responseUrl: facts.responseUrl
|
|
763
|
+
}).kind === "compatible") return {
|
|
764
|
+
kind: "proceed",
|
|
765
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.proceedToCommit, {})
|
|
766
|
+
};
|
|
767
|
+
if (facts.actionRedirectHref !== null) return {
|
|
768
|
+
kind: "hardNavigate",
|
|
769
|
+
url: facts.actionRedirectHref,
|
|
770
|
+
historyMode: facts.actionRedirectType === "push" ? "assign" : "replace",
|
|
771
|
+
clearClientNavigationCaches: true,
|
|
772
|
+
reason: "serverActionRedirectCompatibilityMismatch",
|
|
773
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.serverActionRedirectCompatibilityMismatch, { targetHref: facts.actionRedirectHref })
|
|
774
|
+
};
|
|
775
|
+
const targetUrl = facts.currentHref;
|
|
776
|
+
return {
|
|
777
|
+
kind: "hardNavigate",
|
|
778
|
+
url: targetUrl,
|
|
779
|
+
clearClientNavigationCaches: false,
|
|
780
|
+
reason: "serverActionRscCompatibilityMismatch",
|
|
781
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.serverActionRscCompatibilityMismatch, { targetHref: targetUrl })
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
function classifyRscNavigationError(facts) {
|
|
785
|
+
return {
|
|
786
|
+
kind: "hardNavigate",
|
|
787
|
+
url: facts.currentHref,
|
|
788
|
+
reason: "rscNavigationError",
|
|
789
|
+
trace: createNavigationTrace(NavigationTraceReasonCodes.rscNavigationError, { targetHref: facts.currentHref })
|
|
790
|
+
};
|
|
791
|
+
}
|
|
497
792
|
const navigationPlanner = {
|
|
793
|
+
classifyEarlyNavigationIntent,
|
|
794
|
+
classifyNavigationPrefetchProbe,
|
|
795
|
+
classifyNavigationReuse,
|
|
796
|
+
classifyRscFetchResult,
|
|
797
|
+
classifyRscNavigationError,
|
|
498
798
|
classifyRootBoundaryTransition,
|
|
799
|
+
classifyServerActionResult,
|
|
800
|
+
classifyVisitedResponseCacheCandidate,
|
|
499
801
|
plan: planNavigation,
|
|
500
802
|
resolveCurrentRootBoundaryElementPersistence,
|
|
501
803
|
resolveMountedParallelSlotPersistence,
|
|
@@ -4,6 +4,9 @@ type NavigationTraceSchemaVersion = 0;
|
|
|
4
4
|
declare const NavigationTraceReasonCodes: {
|
|
5
5
|
cacheProofRejected: "NC_CACHE_REJECT";
|
|
6
6
|
commitCurrent: "NC_COMMIT";
|
|
7
|
+
crossDocumentFlight: "NC_CROSS_DOC_FLIGHT";
|
|
8
|
+
fetchFresh: "NC_FETCH_FRESH";
|
|
9
|
+
invalidRscPayload: "NC_RSC_INVALID";
|
|
7
10
|
interceptedCommitCurrent: "NC_INTERCEPT_COMMIT";
|
|
8
11
|
interceptedRejectedIncompatibleRoot: "NC_INTERCEPT_REJECT_ROOT";
|
|
9
12
|
interceptedRejectedMissingProof: "NC_INTERCEPT_REJECT_MISSING_PROOF";
|
|
@@ -11,11 +14,25 @@ declare const NavigationTraceReasonCodes: {
|
|
|
11
14
|
interceptedRejectedTargetMismatch: "NC_INTERCEPT_REJECT_TARGET";
|
|
12
15
|
interceptedRejectedUndeclaredTopology: "NC_INTERCEPT_REJECT_GRAPH";
|
|
13
16
|
interceptedRejectedUnknownSource: "NC_INTERCEPT_REJECT_SOURCE";
|
|
17
|
+
optimisticRouteShell: "NC_OPTIMISTIC_SHELL";
|
|
14
18
|
prefetchOnly: "NC_PREFETCH_ONLY";
|
|
19
|
+
prefetchResponseReuse: "NC_PREFETCH_REUSE";
|
|
20
|
+
proceedToCommit: "NC_RSC_PROCEED";
|
|
21
|
+
redirectFollow: "NC_RSC_REDIRECT_FOLLOW";
|
|
22
|
+
redirectTerminalDepth: "NC_RSC_REDIRECT_DEPTH";
|
|
23
|
+
redirectTerminalExternal: "NC_RSC_REDIRECT_EXTERNAL";
|
|
15
24
|
requestWork: "NC_REQUEST";
|
|
16
25
|
rootBoundaryChanged: "NC_ROOT";
|
|
17
26
|
rootBoundaryUnknown: "NC_ROOT_UNKNOWN";
|
|
27
|
+
rscCompatibilityMismatch: "NC_RSC_COMPAT_MISMATCH";
|
|
28
|
+
rscNavigationError: "NC_RSC_NAV_ERROR";
|
|
29
|
+
sameDocumentScroll: "NC_SAME_DOC_SCROLL";
|
|
30
|
+
samePageSearch: "NC_SAME_PAGE_SEARCH";
|
|
31
|
+
serverActionRedirectCompatibilityMismatch: "NC_SA_REDIRECT_COMPAT";
|
|
32
|
+
serverActionRscCompatibilityMismatch: "NC_SA_RSC_COMPAT";
|
|
18
33
|
staleOperation: "NC_STALE";
|
|
34
|
+
streamedRedirectLoop: "NC_RSC_STREAMED_REDIRECT_LOOP";
|
|
35
|
+
visitedResponseReuse: "NC_VISITED_REUSE";
|
|
19
36
|
};
|
|
20
37
|
declare const NavigationTraceTransactionCodes: {
|
|
21
38
|
hardNavigate: "NT_HARD_NAVIGATE";
|
|
@@ -25,7 +42,7 @@ declare const NavigationTraceTransactionCodes: {
|
|
|
25
42
|
type NavigationTraceReasonCode = (typeof NavigationTraceReasonCodes)[keyof typeof NavigationTraceReasonCodes];
|
|
26
43
|
type NavigationTraceTransactionCode = (typeof NavigationTraceTransactionCodes)[keyof typeof NavigationTraceTransactionCodes];
|
|
27
44
|
type NavigationTraceCode = NavigationTraceReasonCode | NavigationTraceTransactionCode;
|
|
28
|
-
type NavigationTraceFieldName = "activeNavigationId" | "cacheProofCode" | "cacheProofMode" | "cacheProofReuseClass" | "cacheProofScope" | "currentRootLayoutTreePath" | "currentVisibleCommitVersion" | "nextRootLayoutTreePath" | "eventKind" | "operationLane" | "pendingOperationId" | "startedVisibleCommitVersion" | "startedNavigationId" | "targetHref" | "traverseDirection";
|
|
45
|
+
type NavigationTraceFieldName = "activeNavigationId" | "cacheProofCode" | "cacheProofMode" | "cacheProofReuseClass" | "cacheProofScope" | "currentRootLayoutTreePath" | "currentVisibleCommitVersion" | "nextRootLayoutTreePath" | "eventKind" | "fetchResultSource" | "freshFetchReason" | "operationLane" | "pendingOperationId" | "redirectDepth" | "redirectSignal" | "startedVisibleCommitVersion" | "startedNavigationId" | "targetHref" | "traverseDirection";
|
|
29
46
|
type NavigationTraceFieldValue = string | number | boolean | null;
|
|
30
47
|
type NavigationTraceFields = Readonly<Partial<Record<NavigationTraceFieldName, NavigationTraceFieldValue>>>;
|
|
31
48
|
type NavigationTraceEntry = Readonly<{
|
|
@@ -3,6 +3,9 @@ const NAVIGATION_TRACE_SCHEMA_VERSION = 0;
|
|
|
3
3
|
const NavigationTraceReasonCodes = {
|
|
4
4
|
cacheProofRejected: "NC_CACHE_REJECT",
|
|
5
5
|
commitCurrent: "NC_COMMIT",
|
|
6
|
+
crossDocumentFlight: "NC_CROSS_DOC_FLIGHT",
|
|
7
|
+
fetchFresh: "NC_FETCH_FRESH",
|
|
8
|
+
invalidRscPayload: "NC_RSC_INVALID",
|
|
6
9
|
interceptedCommitCurrent: "NC_INTERCEPT_COMMIT",
|
|
7
10
|
interceptedRejectedIncompatibleRoot: "NC_INTERCEPT_REJECT_ROOT",
|
|
8
11
|
interceptedRejectedMissingProof: "NC_INTERCEPT_REJECT_MISSING_PROOF",
|
|
@@ -10,11 +13,25 @@ const NavigationTraceReasonCodes = {
|
|
|
10
13
|
interceptedRejectedTargetMismatch: "NC_INTERCEPT_REJECT_TARGET",
|
|
11
14
|
interceptedRejectedUndeclaredTopology: "NC_INTERCEPT_REJECT_GRAPH",
|
|
12
15
|
interceptedRejectedUnknownSource: "NC_INTERCEPT_REJECT_SOURCE",
|
|
16
|
+
optimisticRouteShell: "NC_OPTIMISTIC_SHELL",
|
|
13
17
|
prefetchOnly: "NC_PREFETCH_ONLY",
|
|
18
|
+
prefetchResponseReuse: "NC_PREFETCH_REUSE",
|
|
19
|
+
proceedToCommit: "NC_RSC_PROCEED",
|
|
20
|
+
redirectFollow: "NC_RSC_REDIRECT_FOLLOW",
|
|
21
|
+
redirectTerminalDepth: "NC_RSC_REDIRECT_DEPTH",
|
|
22
|
+
redirectTerminalExternal: "NC_RSC_REDIRECT_EXTERNAL",
|
|
14
23
|
requestWork: "NC_REQUEST",
|
|
15
24
|
rootBoundaryChanged: "NC_ROOT",
|
|
16
25
|
rootBoundaryUnknown: "NC_ROOT_UNKNOWN",
|
|
17
|
-
|
|
26
|
+
rscCompatibilityMismatch: "NC_RSC_COMPAT_MISMATCH",
|
|
27
|
+
rscNavigationError: "NC_RSC_NAV_ERROR",
|
|
28
|
+
sameDocumentScroll: "NC_SAME_DOC_SCROLL",
|
|
29
|
+
samePageSearch: "NC_SAME_PAGE_SEARCH",
|
|
30
|
+
serverActionRedirectCompatibilityMismatch: "NC_SA_REDIRECT_COMPAT",
|
|
31
|
+
serverActionRscCompatibilityMismatch: "NC_SA_RSC_COMPAT",
|
|
32
|
+
staleOperation: "NC_STALE",
|
|
33
|
+
streamedRedirectLoop: "NC_RSC_STREAMED_REDIRECT_LOOP",
|
|
34
|
+
visitedResponseReuse: "NC_VISITED_REUSE"
|
|
18
35
|
};
|
|
19
36
|
const NavigationTraceTransactionCodes = {
|
|
20
37
|
hardNavigate: "NT_HARD_NAVIGATE",
|