vinext 1.0.0-beta.1 → 1.0.0-beta.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 +10 -10
- package/dist/build/client-build-config.js +8 -1
- package/dist/build/report.d.ts +8 -1
- package/dist/build/report.js +12 -2
- package/dist/check.js +19 -2
- package/dist/cli.js +3 -2
- package/dist/config/config-matchers.d.ts +13 -37
- package/dist/config/config-matchers.js +35 -122
- package/dist/config/next-config.d.ts +15 -5
- package/dist/config/next-config.js +7 -1
- package/dist/config/request-context.d.ts +14 -0
- package/dist/config/request-context.js +26 -0
- package/dist/entries/app-browser-entry.d.ts +4 -10
- package/dist/entries/app-browser-entry.js +20 -4
- package/dist/entries/app-rsc-entry.js +30 -9
- package/dist/entries/app-rsc-manifest.js +36 -0
- package/dist/entries/pages-client-entry.js +0 -1
- package/dist/entries/pages-server-entry.js +13 -5
- package/dist/index.js +194 -101
- package/dist/init-cloudflare.d.ts +3 -1
- package/dist/init-cloudflare.js +59 -5
- package/dist/init.d.ts +6 -4
- package/dist/init.js +20 -22
- package/dist/plugins/extensionless-dynamic-import.js +23 -18
- package/dist/plugins/ignore-dynamic-requests.js +3 -1
- package/dist/plugins/import-meta-url.js +17 -6
- package/dist/plugins/og-assets.js +1 -1
- package/dist/plugins/require-context.js +20 -15
- package/dist/plugins/transform-cache.d.ts +19 -0
- package/dist/plugins/transform-cache.js +36 -0
- package/dist/routing/app-route-graph.d.ts +27 -11
- package/dist/routing/app-route-graph.js +158 -22
- package/dist/routing/app-router.js +12 -6
- package/dist/routing/file-matcher.d.ts +11 -22
- package/dist/routing/file-matcher.js +21 -33
- package/dist/routing/pages-router.js +23 -29
- package/dist/routing/route-matching.d.ts +14 -1
- package/dist/routing/route-matching.js +13 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +7 -4
- package/dist/routing/route-trie.d.ts +5 -1
- package/dist/routing/route-trie.js +5 -2
- package/dist/server/api-handler.d.ts +2 -0
- package/dist/server/api-handler.js +3 -3
- package/dist/server/app-browser-entry.js +110 -37
- package/dist/server/app-browser-history-controller.d.ts +1 -1
- package/dist/server/app-browser-history-controller.js +3 -3
- package/dist/server/app-browser-navigation-controller.d.ts +23 -21
- package/dist/server/app-browser-navigation-controller.js +2 -2
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-fallback-renderer.d.ts +3 -0
- package/dist/server/app-fallback-renderer.js +4 -2
- package/dist/server/app-middleware.js +2 -1
- package/dist/server/app-page-boundary-render.d.ts +12 -1
- package/dist/server/app-page-boundary-render.js +84 -2
- package/dist/server/app-page-cache-finalizer.d.ts +1 -1
- package/dist/server/app-page-cache-finalizer.js +1 -1
- package/dist/server/app-page-cache.d.ts +2 -2
- package/dist/server/app-page-cache.js +16 -2
- package/dist/server/app-page-dispatch.d.ts +19 -2
- package/dist/server/app-page-dispatch.js +45 -23
- package/dist/server/app-page-element-builder.d.ts +9 -2
- package/dist/server/app-page-element-builder.js +144 -33
- package/dist/server/app-page-head.d.ts +56 -4
- package/dist/server/app-page-head.js +216 -85
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
- package/dist/server/app-page-http-access-fallback-metadata.js +114 -0
- package/dist/server/app-page-probe.d.ts +4 -0
- package/dist/server/app-page-probe.js +6 -2
- package/dist/server/app-page-render.d.ts +2 -2
- package/dist/server/app-page-render.js +1 -1
- package/dist/server/app-page-request.d.ts +15 -0
- package/dist/server/app-page-request.js +134 -14
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +16 -0
- package/dist/server/app-page-route-wiring.js +254 -52
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +2 -1
- package/dist/server/app-post-middleware-context.d.ts +1 -1
- package/dist/server/app-post-middleware-context.js +1 -1
- package/dist/server/app-route-handler-cache.js +4 -0
- package/dist/server/app-route-handler-dispatch.js +40 -20
- package/dist/server/app-route-handler-execution.d.ts +6 -1
- package/dist/server/app-route-handler-execution.js +42 -16
- package/dist/server/app-route-handler-policy.d.ts +2 -0
- package/dist/server/app-route-handler-policy.js +3 -3
- package/dist/server/app-route-handler-response.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +9 -1
- package/dist/server/app-route-module-loader.js +4 -0
- package/dist/server/app-router-entry.js +6 -3
- package/dist/server/app-rsc-cache-busting.d.ts +1 -1
- package/dist/server/app-rsc-errors.d.ts +1 -1
- package/dist/server/app-rsc-errors.js +22 -2
- package/dist/server/app-rsc-handler.d.ts +10 -5
- package/dist/server/app-rsc-handler.js +73 -33
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +8 -2
- package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
- package/dist/server/app-rsc-response-finalizer.js +5 -11
- package/dist/server/app-rsc-route-matching.d.ts +29 -0
- package/dist/server/app-rsc-route-matching.js +93 -11
- package/dist/server/app-segment-config.js +13 -3
- package/dist/server/app-server-action-execution.d.ts +3 -1
- package/dist/server/app-server-action-execution.js +9 -7
- package/dist/server/app-ssr-entry.js +6 -6
- package/dist/server/app-ssr-stream.d.ts +1 -7
- package/dist/server/app-ssr-stream.js +2 -10
- package/dist/server/cache-control.d.ts +2 -2
- package/dist/server/cache-control.js +2 -1
- package/dist/server/config-headers.d.ts +24 -0
- package/dist/server/config-headers.js +52 -0
- package/dist/server/dev-initial-server-error.d.ts +1 -1
- package/dist/server/dev-server.d.ts +3 -1
- package/dist/server/dev-server.js +170 -321
- package/dist/server/headers.d.ts +2 -2
- package/dist/server/headers.js +4 -3
- package/dist/server/isr-cache.d.ts +11 -34
- package/dist/server/isr-cache.js +33 -43
- package/dist/server/isr-decision.d.ts +2 -2
- package/dist/server/middleware-matcher-pattern.d.ts +22 -0
- package/dist/server/middleware-matcher-pattern.js +219 -0
- package/dist/server/middleware-matcher.d.ts +2 -7
- package/dist/server/middleware-matcher.js +13 -60
- package/dist/server/middleware-path-to-regexp.d.ts +14 -0
- package/dist/server/middleware-path-to-regexp.js +228 -0
- package/dist/server/middleware-runtime.js +4 -3
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +2 -1
- package/dist/server/pages-api-route.d.ts +2 -0
- package/dist/server/pages-api-route.js +4 -1
- package/dist/server/pages-data-route.d.ts +11 -1
- package/dist/server/pages-data-route.js +16 -1
- package/dist/server/pages-dev-hydration.js +0 -1
- package/dist/server/pages-get-initial-props.d.ts +16 -3
- package/dist/server/pages-get-initial-props.js +17 -10
- package/dist/server/pages-i18n.js +64 -16
- package/dist/server/pages-node-compat.d.ts +2 -0
- package/dist/server/pages-node-compat.js +7 -3
- package/dist/server/pages-page-data.d.ts +64 -10
- package/dist/server/pages-page-data.js +349 -80
- package/dist/server/pages-page-handler.d.ts +9 -3
- package/dist/server/pages-page-handler.js +131 -36
- package/dist/server/pages-page-response.d.ts +5 -3
- package/dist/server/pages-page-response.js +24 -27
- package/dist/server/pages-readiness.d.ts +3 -3
- package/dist/server/pages-request-pipeline.d.ts +8 -0
- package/dist/server/pages-request-pipeline.js +30 -12
- package/dist/server/pages-revalidate.d.ts +1 -1
- package/dist/server/pages-revalidate.js +54 -8
- package/dist/server/pages-router-entry.d.ts +1 -0
- package/dist/server/pages-router-entry.js +16 -4
- package/dist/server/prerender-route-params.js +2 -2
- package/dist/server/prod-server.d.ts +3 -5
- package/dist/server/prod-server.js +72 -35
- package/dist/server/request-pipeline.d.ts +15 -29
- package/dist/server/request-pipeline.js +24 -59
- package/dist/server/revalidation-host.d.ts +11 -0
- package/dist/server/revalidation-host.js +19 -0
- package/dist/server/rsc-stream-hints.js +122 -18
- package/dist/server/worker-revalidation-context.d.ts +13 -0
- package/dist/server/worker-revalidation-context.js +29 -0
- package/dist/shims/app.d.ts +1 -1
- package/dist/shims/cache-handler.d.ts +1 -1
- package/dist/shims/cache-handler.js +10 -7
- package/dist/shims/cache-request-state.d.ts +27 -1
- package/dist/shims/cache-request-state.js +60 -1
- package/dist/shims/cache-runtime.d.ts +18 -1
- package/dist/shims/cache-runtime.js +26 -8
- package/dist/shims/cache.d.ts +5 -5
- package/dist/shims/cache.js +27 -11
- package/dist/shims/document.d.ts +42 -83
- package/dist/shims/document.js +62 -53
- package/dist/shims/dynamic.d.ts +5 -25
- package/dist/shims/dynamic.js +29 -8
- package/dist/shims/error.d.ts +1 -1
- package/dist/shims/error.js +2 -2
- package/dist/shims/fetch-cache.js +13 -4
- package/dist/shims/font-google-base.d.ts +11 -4
- package/dist/shims/font-google-base.js +17 -8
- package/dist/shims/font-local.d.ts +10 -3
- package/dist/shims/font-local.js +41 -10
- package/dist/shims/head.d.ts +13 -2
- package/dist/shims/head.js +3 -3
- package/dist/shims/headers.d.ts +37 -43
- package/dist/shims/headers.js +183 -74
- package/dist/shims/image.d.ts +27 -37
- package/dist/shims/image.js +21 -14
- package/dist/shims/internal/cookie-serialize.d.ts +12 -9
- package/dist/shims/internal/cookie-serialize.js +10 -7
- package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
- package/dist/shims/internal/interpolate-as.d.ts +15 -1
- package/dist/shims/internal/interpolate-as.js +27 -2
- package/dist/shims/internal/utils.d.ts +3 -3
- package/dist/shims/legacy-image.d.ts +3 -37
- package/dist/shims/legacy-image.js +6 -16
- package/dist/shims/link.d.ts +15 -22
- package/dist/shims/link.js +34 -13
- package/dist/shims/metadata.d.ts +7 -17
- package/dist/shims/metadata.js +74 -24
- package/dist/shims/navigation-context-state.d.ts +1 -1
- package/dist/shims/navigation.d.ts +7 -3
- package/dist/shims/navigation.js +25 -14
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/next-shims-augmentations.d.ts +1 -0
- package/dist/shims/next-shims-public.d.ts +1 -0
- package/dist/shims/public-shim-map.json.js +103 -0
- package/dist/shims/readonly-url-search-params.d.ts +3 -3
- package/dist/shims/readonly-url-search-params.js +3 -3
- package/dist/shims/request-context.d.ts +4 -1
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/router.d.ts +55 -21
- package/dist/shims/router.js +180 -44
- package/dist/shims/script.d.ts +6 -10
- package/dist/shims/script.js +7 -4
- package/dist/shims/server.d.ts +50 -26
- package/dist/shims/server.js +193 -55
- package/dist/shims/unified-request-context.d.ts +22 -3
- package/dist/shims/unified-request-context.js +84 -1
- package/dist/shims/url-safety.d.ts +1 -1
- package/dist/shims/url-safety.js +2 -2
- package/dist/typegen.d.ts +8 -2
- package/dist/typegen.js +76 -15
- package/dist/utils/cache-control-metadata.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +5 -1
- package/dist/utils/domain-locale.d.ts +2 -2
- package/dist/utils/external-url.d.ts +5 -0
- package/dist/utils/external-url.js +7 -0
- package/dist/utils/html-limited-bots.js +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/dist/utils/regex-safety.d.ts +8 -0
- package/dist/utils/regex-safety.js +737 -0
- package/package.json +13 -2
|
@@ -4,6 +4,7 @@ declare function routePatternParts(pathname: string): string[];
|
|
|
4
4
|
declare function routePattern(pathname: string): string;
|
|
5
5
|
declare function fillRoutePatternSegments(pathname: string, params: RoutePatternParams): string | null;
|
|
6
6
|
declare function matchRoutePattern(urlParts: readonly string[], patternParts: readonly string[]): RoutePatternParams | null;
|
|
7
|
+
declare function matchRoutePatternRaw(urlParts: readonly string[], patternParts: readonly string[]): RoutePatternParams | null;
|
|
7
8
|
declare function matchRoutePatternPrefix(pathParts: readonly string[], patternParts: readonly string[]): boolean;
|
|
8
9
|
declare function matchRoutePatternWithOptionalDynamicSegments(pathParts: readonly string[], patternParts: readonly string[]): boolean;
|
|
9
10
|
/**
|
|
@@ -61,4 +62,4 @@ declare function normalizeStaticPathname(pathname: string): string;
|
|
|
61
62
|
*/
|
|
62
63
|
declare function normalizeStaticPathsEntry(entry: StaticPathsEntry, routePattern: string): NormalizedStaticPathsEntry;
|
|
63
64
|
//#endregion
|
|
64
|
-
export { RoutePatternParams, StaticPathsEntry, fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
65
|
+
export { RoutePatternParams, StaticPathsEntry, fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternRaw, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
@@ -56,6 +56,11 @@ function fillRoutePatternSegments(pathname, params) {
|
|
|
56
56
|
return resolvedSegments.length > 0 ? `/${resolvedSegments.join("/")}` : "/";
|
|
57
57
|
}
|
|
58
58
|
function matchRoutePattern(urlParts, patternParts) {
|
|
59
|
+
const params = matchRoutePatternRaw(urlParts, patternParts);
|
|
60
|
+
if (params) decodeMatchedParams(params);
|
|
61
|
+
return params;
|
|
62
|
+
}
|
|
63
|
+
function matchRoutePatternRaw(urlParts, patternParts) {
|
|
59
64
|
const params = Object.create(null);
|
|
60
65
|
function matchFrom(urlIndex, patternIndex) {
|
|
61
66
|
if (patternIndex === patternParts.length) return urlIndex === urlParts.length;
|
|
@@ -83,9 +88,7 @@ function matchRoutePattern(urlParts, patternParts) {
|
|
|
83
88
|
if (urlIndex >= urlParts.length || urlParts[urlIndex] !== patternPart) return false;
|
|
84
89
|
return matchFrom(urlIndex + 1, patternIndex + 1);
|
|
85
90
|
}
|
|
86
|
-
|
|
87
|
-
decodeMatchedParams(params);
|
|
88
|
-
return params;
|
|
91
|
+
return matchFrom(0, 0) ? params : null;
|
|
89
92
|
}
|
|
90
93
|
function matchRoutePatternPrefix(pathParts, patternParts) {
|
|
91
94
|
let pathIndex = 0;
|
|
@@ -162,4 +165,4 @@ function normalizeStaticPathsEntry(entry, routePattern) {
|
|
|
162
165
|
return { params };
|
|
163
166
|
}
|
|
164
167
|
//#endregion
|
|
165
|
-
export { fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
168
|
+
export { fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternRaw, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
@@ -63,5 +63,9 @@ declare function trieMatch<R>(root: TrieNode<R>, urlParts: string[]): {
|
|
|
63
63
|
route: R;
|
|
64
64
|
params: Record<string, string | string[]>;
|
|
65
65
|
} | null;
|
|
66
|
+
declare function trieMatchRaw<R>(root: TrieNode<R>, urlParts: string[]): {
|
|
67
|
+
route: R;
|
|
68
|
+
params: Record<string, string | string[]>;
|
|
69
|
+
} | null;
|
|
66
70
|
//#endregion
|
|
67
|
-
export { TrieNode, buildRouteTrie, trieMatch };
|
|
71
|
+
export { TrieNode, buildRouteTrie, trieMatch, trieMatchRaw };
|
|
@@ -92,10 +92,13 @@ function buildRouteTrie(routes) {
|
|
|
92
92
|
* @returns Match result with route and extracted params, or null
|
|
93
93
|
*/
|
|
94
94
|
function trieMatch(root, urlParts) {
|
|
95
|
-
const result =
|
|
95
|
+
const result = trieMatchRaw(root, urlParts);
|
|
96
96
|
if (result) decodeMatchedParams(result.params);
|
|
97
97
|
return result;
|
|
98
98
|
}
|
|
99
|
+
function trieMatchRaw(root, urlParts) {
|
|
100
|
+
return match(root, urlParts, 0, []);
|
|
101
|
+
}
|
|
99
102
|
function match(node, urlParts, index, entries) {
|
|
100
103
|
if (index === urlParts.length) {
|
|
101
104
|
if (node.route !== null) return {
|
|
@@ -140,4 +143,4 @@ function match(node, urlParts, index, entries) {
|
|
|
140
143
|
return null;
|
|
141
144
|
}
|
|
142
145
|
//#endregion
|
|
143
|
-
export { buildRouteTrie, trieMatch };
|
|
146
|
+
export { buildRouteTrie, trieMatch, trieMatchRaw };
|
|
@@ -11,6 +11,8 @@ import { IncomingMessage, ServerResponse } from "node:http";
|
|
|
11
11
|
declare function handleApiRoute(runner: ModuleImporter, req: IncomingMessage, res: ServerResponse, url: string, apiRoutes: Route[], nextConfig?: {
|
|
12
12
|
basePath?: string;
|
|
13
13
|
i18n?: NextI18nConfig | null;
|
|
14
|
+
trustedRevalidateOrigin?: string;
|
|
15
|
+
allowedRevalidateHeaderKeys?: readonly string[];
|
|
14
16
|
trailingSlash?: boolean;
|
|
15
17
|
}): Promise<boolean>;
|
|
16
18
|
//#endregion
|
|
@@ -160,7 +160,7 @@ async function writeEdgeApiResponseBody(res, body) {
|
|
|
160
160
|
/**
|
|
161
161
|
* Enhance a Node.js req/res pair with Next.js API route helpers.
|
|
162
162
|
*/
|
|
163
|
-
function enhanceApiObjects(req, res, query, body) {
|
|
163
|
+
function enhanceApiObjects(req, res, query, body, trustedRevalidateOrigin, allowedRevalidateHeaderKeys = [], dev = false) {
|
|
164
164
|
const apiReq = Object.assign(req, {
|
|
165
165
|
body,
|
|
166
166
|
query
|
|
@@ -202,7 +202,7 @@ function enhanceApiObjects(req, res, query, body) {
|
|
|
202
202
|
return this;
|
|
203
203
|
},
|
|
204
204
|
async revalidate(urlPath, opts) {
|
|
205
|
-
await performOnDemandRevalidate(req, urlPath, opts);
|
|
205
|
+
await performOnDemandRevalidate(req, urlPath, opts, trustedRevalidateOrigin, allowedRevalidateHeaderKeys, dev);
|
|
206
206
|
}
|
|
207
207
|
});
|
|
208
208
|
attachPagesPreviewApi(apiReq, apiRes);
|
|
@@ -248,7 +248,7 @@ async function handleApiRoute(runner, req, res, url, apiRoutes, nextConfig) {
|
|
|
248
248
|
}
|
|
249
249
|
const query = mergeRouteParamsIntoQuery(parseQueryString(url), params);
|
|
250
250
|
const bodyParserConfig = resolveBodyParserConfig(apiModule.config);
|
|
251
|
-
const { apiReq, apiRes } = enhanceApiObjects(req, res, query, bodyParserConfig.enabled ? await parseBody(req, bodyParserConfig.sizeLimit) : void 0);
|
|
251
|
+
const { apiReq, apiRes } = enhanceApiObjects(req, res, query, bodyParserConfig.enabled ? await parseBody(req, bodyParserConfig.sizeLimit) : void 0, nextConfig?.trustedRevalidateOrigin, nextConfig?.allowedRevalidateHeaderKeys, true);
|
|
252
252
|
await handler(apiReq, apiRes);
|
|
253
253
|
return true;
|
|
254
254
|
} catch (e) {
|
|
@@ -16,16 +16,15 @@ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscR
|
|
|
16
16
|
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
17
17
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
18
18
|
import "../client/instrumentation-client.js";
|
|
19
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
20
|
+
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
|
|
21
|
+
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
19
22
|
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
20
23
|
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
21
24
|
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
22
25
|
import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
|
|
23
26
|
import { navigationPlanner } from "./navigation-planner.js";
|
|
24
|
-
import {
|
|
25
|
-
import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
26
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
27
|
-
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
|
|
28
|
-
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
27
|
+
import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, preloadHybridClientRouteOwner, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveLoadedHybridClientRewriteHref, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
29
28
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
30
29
|
import { COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, isCompleteAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl } from "./app-browser-state.js";
|
|
31
30
|
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
@@ -43,6 +42,7 @@ import { createRoot, hydrateRoot } from "react-dom/client";
|
|
|
43
42
|
import { createFromFetch, createFromReadableStream, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
44
43
|
import { hasServerActions, loadServerActionClient } from "virtual:vinext-app-capabilities";
|
|
45
44
|
//#region src/server/app-browser-entry.ts
|
|
45
|
+
const HAS_CLIENT_REWRITES = process.env.__VINEXT_HAS_CLIENT_REWRITES !== "false";
|
|
46
46
|
function toActionType(kind) {
|
|
47
47
|
return kind === "traverse" ? "traverse" : "navigate";
|
|
48
48
|
}
|
|
@@ -302,28 +302,29 @@ function createNavigationCommitEffect(options) {
|
|
|
302
302
|
commitClientNavigationState(navId);
|
|
303
303
|
};
|
|
304
304
|
}
|
|
305
|
-
async function renderNavigationPayload(
|
|
305
|
+
async function renderNavigationPayload(options) {
|
|
306
306
|
syncServerActionHttpFallbackHead(null);
|
|
307
307
|
return browserNavigationController.renderNavigationPayload({
|
|
308
|
-
actionType,
|
|
308
|
+
actionType: options.actionType ?? "navigate",
|
|
309
309
|
createNavigationCommitEffect,
|
|
310
|
-
historyUpdateMode,
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
310
|
+
historyUpdateMode: options.historyUpdateMode,
|
|
311
|
+
navigationCommitKind: options.navigationCommitKind,
|
|
312
|
+
navigationInitiationState: options.navigationInitiationState,
|
|
313
|
+
navigationSnapshot: options.navigationSnapshot,
|
|
314
|
+
navId: options.navId,
|
|
315
|
+
nextElements: options.payload,
|
|
316
|
+
onCommittedState: options.onCommittedState,
|
|
317
|
+
operationLane: options.operationLane ?? "navigation",
|
|
318
|
+
params: options.params,
|
|
319
|
+
payloadOrigin: options.payloadOrigin,
|
|
320
|
+
pendingRouterState: options.pendingRouterState,
|
|
321
|
+
previousNextUrl: options.previousNextUrl,
|
|
322
|
+
restoredBfcacheIds: options.restoredBfcacheIds ?? null,
|
|
323
|
+
reuseCurrentBfcacheIds: options.reuseCurrentBfcacheIds ?? true,
|
|
324
|
+
scrollIntent: options.scrollIntent ?? null,
|
|
325
|
+
targetHistoryIndex: options.traversalIntent?.targetHistoryIndex,
|
|
326
|
+
targetHref: options.targetHref,
|
|
327
|
+
visibleCommitMode: options.visibleCommitMode ?? "transition"
|
|
327
328
|
});
|
|
328
329
|
}
|
|
329
330
|
async function commitSameUrlNavigatePayload(nextElements, actionInitiation, returnValue, revalidation = "none") {
|
|
@@ -725,7 +726,21 @@ function registerServerActionCallback() {
|
|
|
725
726
|
const hashIdx = target.href.indexOf("#");
|
|
726
727
|
const actionScrollIntent = beginAppRouterScrollIntent((hashIdx !== -1 ? target.href.slice(hashIdx) : "") || null);
|
|
727
728
|
if (target.type === "push") saveScrollPosition();
|
|
728
|
-
renderNavigationPayload(
|
|
729
|
+
renderNavigationPayload({
|
|
730
|
+
actionType: target.type === "push" ? "navigate" : "replace",
|
|
731
|
+
historyUpdateMode: target.type === "push" ? "push" : "replace",
|
|
732
|
+
navigationInitiationState: actionInitiation.routerState,
|
|
733
|
+
navigationSnapshot: createClientNavigationRenderSnapshot(target.href, actionInitiation.routerState.navigationSnapshot.params),
|
|
734
|
+
navId: actionInitiation.navigationId,
|
|
735
|
+
operationLane: resolveServerActionOperationLane(revalidation),
|
|
736
|
+
params: {},
|
|
737
|
+
payload: Promise.resolve(elements),
|
|
738
|
+
payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
|
|
739
|
+
pendingRouterState: null,
|
|
740
|
+
previousNextUrl: null,
|
|
741
|
+
scrollIntent: actionScrollIntent,
|
|
742
|
+
targetHref: target.href
|
|
743
|
+
}).catch(() => {
|
|
729
744
|
browserNavigationController.performHardNavigation(target.href);
|
|
730
745
|
});
|
|
731
746
|
},
|
|
@@ -738,6 +753,7 @@ async function main() {
|
|
|
738
753
|
if (!claimInitialAppRouterBootstrap()) return;
|
|
739
754
|
if (hasServerActions) registerServerActionCallback();
|
|
740
755
|
installAppNavigationFailureListeners();
|
|
756
|
+
if (HAS_CLIENT_REWRITES) await preloadHybridClientRouteOwner();
|
|
741
757
|
let devErrorOverlay = null;
|
|
742
758
|
if (import.meta.env.DEV) {
|
|
743
759
|
devErrorOverlay = await import("../client/dev-error-overlay.js");
|
|
@@ -869,6 +885,8 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
869
885
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
870
886
|
if (shouldUsePendingRouterState) pendingRouterState = beginPendingBrowserRouterState();
|
|
871
887
|
}
|
|
888
|
+
const navigationInitiationState = getBrowserRouterState();
|
|
889
|
+
const mountedSlotsHeader = getMountedSlotIdsHeader(navigationInitiationState.elements);
|
|
872
890
|
while (true) {
|
|
873
891
|
const url = new URL(currentHref, window.location.origin);
|
|
874
892
|
const requestState = getRequestState(navigationKind, url.pathname, currentPrevNextUrl, activeTraversalIntent?.historyState);
|
|
@@ -876,12 +894,9 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
876
894
|
const requestPreviousNextUrl = requestState.previousNextUrl;
|
|
877
895
|
if (navigationKind === "refresh") historyController.syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
|
|
878
896
|
setPendingPathname(url.pathname, navId);
|
|
879
|
-
const routerStateAtNavStart = getBrowserRouterState();
|
|
880
|
-
const elementsAtNavStart = routerStateAtNavStart.elements;
|
|
881
|
-
const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
|
|
882
897
|
const earlyIntentDecision = navigationKind === "navigate" ? navigationPlanner.classifyEarlyNavigationIntent({
|
|
883
898
|
basePath: __basePath,
|
|
884
|
-
currentHref: clientNavigationSnapshotHref(
|
|
899
|
+
currentHref: clientNavigationSnapshotHref(navigationInitiationState.navigationSnapshot),
|
|
885
900
|
mode: "push",
|
|
886
901
|
scroll: false,
|
|
887
902
|
targetHref: url.href
|
|
@@ -892,7 +907,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
892
907
|
mountedSlotsHeader
|
|
893
908
|
});
|
|
894
909
|
const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
|
|
895
|
-
const rewrittenNavigationHref = navigationKind === "navigate" ?
|
|
910
|
+
const rewrittenNavigationHref = navigationKind === "navigate" && HAS_CLIENT_REWRITES ? resolveLoadedHybridClientRewriteHref(currentHref, __basePath) : null;
|
|
896
911
|
const additionalPrefetchRscUrls = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [await createRscRequestUrl(rewrittenNavigationHref, requestHeaders)] : [];
|
|
897
912
|
const visitedResponseCandidate = shouldBypassNavigationCache ? {
|
|
898
913
|
cacheKey: AppElementsWire.encodeCacheKey(rscUrl, requestInterceptionContext),
|
|
@@ -959,7 +974,26 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
959
974
|
const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
|
|
960
975
|
const cachedPayload = cachedRoute.elements ? Promise.resolve(cachedRoute.elements) : decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
|
|
961
976
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
962
|
-
if (await renderNavigationPayload(
|
|
977
|
+
if (await renderNavigationPayload({
|
|
978
|
+
actionType: toActionType(navigationKind),
|
|
979
|
+
historyUpdateMode: currentHistoryMode,
|
|
980
|
+
navigationCommitKind: detachedNavigationCommits ? "authoritative" : void 0,
|
|
981
|
+
navigationInitiationState,
|
|
982
|
+
navigationSnapshot: cachedNavigationSnapshot,
|
|
983
|
+
navId,
|
|
984
|
+
operationLane: toOperationLane(navigationKind),
|
|
985
|
+
params: cachedParams,
|
|
986
|
+
payload: cachedPayload,
|
|
987
|
+
payloadOrigin: cachedRoute.elements ? COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN : VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN,
|
|
988
|
+
pendingRouterState: detachedNavigationCommits ? null : pendingRouterState,
|
|
989
|
+
previousNextUrl: requestPreviousNextUrl,
|
|
990
|
+
restoredBfcacheIds,
|
|
991
|
+
reuseCurrentBfcacheIds,
|
|
992
|
+
scrollIntent,
|
|
993
|
+
targetHref: currentHref,
|
|
994
|
+
traversalIntent: activeTraversalIntent,
|
|
995
|
+
visibleCommitMode
|
|
996
|
+
}) === "no-commit") {
|
|
963
997
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
964
998
|
deleteVisitedResponse(rscUrl, requestInterceptionContext);
|
|
965
999
|
continue;
|
|
@@ -1015,7 +1049,26 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
1015
1049
|
if (optimisticPayload !== null) {
|
|
1016
1050
|
detachedNavigationCommits = true;
|
|
1017
1051
|
const optimisticNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, optimisticPayload.params);
|
|
1018
|
-
renderNavigationPayload(
|
|
1052
|
+
renderNavigationPayload({
|
|
1053
|
+
actionType: toActionType(navigationKind),
|
|
1054
|
+
historyUpdateMode: currentHistoryMode,
|
|
1055
|
+
navigationCommitKind: "detached",
|
|
1056
|
+
navigationInitiationState,
|
|
1057
|
+
navigationSnapshot: optimisticNavigationSnapshot,
|
|
1058
|
+
navId,
|
|
1059
|
+
operationLane: toOperationLane(navigationKind),
|
|
1060
|
+
params: optimisticPayload.params,
|
|
1061
|
+
payload: Promise.resolve(optimisticPayload.elements),
|
|
1062
|
+
payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
|
|
1063
|
+
pendingRouterState: null,
|
|
1064
|
+
previousNextUrl: requestPreviousNextUrl,
|
|
1065
|
+
restoredBfcacheIds,
|
|
1066
|
+
reuseCurrentBfcacheIds,
|
|
1067
|
+
scrollIntent,
|
|
1068
|
+
targetHref: currentHref,
|
|
1069
|
+
traversalIntent: activeTraversalIntent,
|
|
1070
|
+
visibleCommitMode
|
|
1071
|
+
}).catch((error) => {
|
|
1019
1072
|
if (browserNavigationController.isCurrentNavigation(navId)) console.error("[vinext] Optimistic RSC navigation error:", error);
|
|
1020
1073
|
});
|
|
1021
1074
|
}
|
|
@@ -1023,7 +1076,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
1023
1076
|
}
|
|
1024
1077
|
if (!navResponse) {
|
|
1025
1078
|
if (navigationKind === "navigate") {
|
|
1026
|
-
const clientReuseManifestHeader = createClientReuseManifestHeaderFromVisibleAppState(
|
|
1079
|
+
const clientReuseManifestHeader = createClientReuseManifestHeaderFromVisibleAppState(navigationInitiationState);
|
|
1027
1080
|
if (clientReuseManifestHeader !== null) requestHeaders.set(VINEXT_CLIENT_REUSE_MANIFEST_HEADER, clientReuseManifestHeader);
|
|
1028
1081
|
}
|
|
1029
1082
|
navResponse = await fetch(rscUrl, {
|
|
@@ -1085,10 +1138,30 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
1085
1138
|
const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(reactResponse)));
|
|
1086
1139
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1087
1140
|
let committedState = null;
|
|
1088
|
-
if (await renderNavigationPayload(
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1141
|
+
if (await renderNavigationPayload({
|
|
1142
|
+
actionType: toActionType(navigationKind),
|
|
1143
|
+
historyUpdateMode: currentHistoryMode,
|
|
1144
|
+
navigationCommitKind: detachedNavigationCommits ? "authoritative" : void 0,
|
|
1145
|
+
navigationInitiationState,
|
|
1146
|
+
navigationSnapshot,
|
|
1147
|
+
navId,
|
|
1148
|
+
onCommittedState: (state) => {
|
|
1149
|
+
committedState = state;
|
|
1150
|
+
if (activeNavigationAbortController === navigationAbortController) activeNavigationAbortController = null;
|
|
1151
|
+
},
|
|
1152
|
+
operationLane: toOperationLane(navigationKind),
|
|
1153
|
+
params: navParams,
|
|
1154
|
+
payload: rscPayload,
|
|
1155
|
+
payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
|
|
1156
|
+
pendingRouterState: detachedNavigationCommits ? null : pendingRouterState,
|
|
1157
|
+
previousNextUrl: requestPreviousNextUrl,
|
|
1158
|
+
restoredBfcacheIds,
|
|
1159
|
+
reuseCurrentBfcacheIds,
|
|
1160
|
+
scrollIntent,
|
|
1161
|
+
targetHref: currentHref,
|
|
1162
|
+
traversalIntent: activeTraversalIntent,
|
|
1163
|
+
visibleCommitMode
|
|
1164
|
+
}) !== "committed") return;
|
|
1092
1165
|
try {
|
|
1093
1166
|
const renderedElements = await rscPayload;
|
|
1094
1167
|
if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
|
|
@@ -18,7 +18,7 @@ type AppBrowserHistoryControllerDeps = {
|
|
|
18
18
|
readHistoryState: () => unknown; /** Reads `window.location.href`. Injected so the controller stays unit-testable. */
|
|
19
19
|
readCurrentHref: () => string; /** Wraps `pushHistoryStateWithoutNotify(state, "", href)`. */
|
|
20
20
|
pushHistoryState: (state: unknown, href: string) => void; /** Wraps `replaceHistoryStateWithoutNotify(state, "", href)`. */
|
|
21
|
-
replaceHistoryState: (state: unknown, href
|
|
21
|
+
replaceHistoryState: (state: unknown, href?: string) => void;
|
|
22
22
|
readVisibleNavigationMetadata: () => VisibleNavigationMetadata | null;
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
@@ -158,9 +158,9 @@ var AppBrowserHistoryController = class {
|
|
|
158
158
|
bfcacheVersion: bfcacheIds === void 0 ? void 0 : this.#restorableClientState.currentBfcacheVersion,
|
|
159
159
|
previousNextUrl
|
|
160
160
|
});
|
|
161
|
-
this.#replaceHistoryState(nextHistoryState
|
|
161
|
+
this.#replaceHistoryState(nextHistoryState);
|
|
162
162
|
if (this.#isHistoryStateNavigationMetadataInSync(this.#readHistoryState(), previousNextUrl, bfcacheIds)) return;
|
|
163
|
-
this.#replaceHistoryState(nextHistoryState
|
|
163
|
+
this.#replaceHistoryState(nextHistoryState);
|
|
164
164
|
}
|
|
165
165
|
#isHistoryStateNavigationMetadataInSync(state, previousNextUrl, bfcacheIds) {
|
|
166
166
|
return readHistoryStatePreviousNextUrl(state) === previousNextUrl && (bfcacheIds === void 0 || areBfcacheIdMapsEqual(readHistoryStateBfcacheIds(state), bfcacheIds) && this.#restorableClientState.isCurrentBfcacheVersion(state));
|
|
@@ -179,7 +179,7 @@ var AppBrowserHistoryController = class {
|
|
|
179
179
|
bfcacheVersion: this.#restorableClientState.currentBfcacheVersion,
|
|
180
180
|
previousNextUrl: options.previousNextUrl,
|
|
181
181
|
traversalIndex: this.#currentHistoryTraversalIndex
|
|
182
|
-
})
|
|
182
|
+
}));
|
|
183
183
|
}
|
|
184
184
|
/**
|
|
185
185
|
* Resolves a restorable snapshot candidate for the given history entry and
|
|
@@ -43,6 +43,28 @@ type BrowserNavigationControllerDeps = {
|
|
|
43
43
|
getRouteManifest?: () => RouteManifest | null;
|
|
44
44
|
syncHistoryStatePreviousNextUrl?: (previousNextUrl: string | null, bfcacheIds?: Readonly<Record<string, string>> | null) => void;
|
|
45
45
|
};
|
|
46
|
+
type BrowserNavigationPayloadOptions = {
|
|
47
|
+
actionType: "navigate" | "replace" | "traverse";
|
|
48
|
+
createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;
|
|
49
|
+
historyUpdateMode: HistoryUpdateMode | undefined;
|
|
50
|
+
navigationCommitKind?: "authoritative" | "detached";
|
|
51
|
+
navigationInitiationState: AppRouterState;
|
|
52
|
+
navigationSnapshot: ClientNavigationRenderSnapshot;
|
|
53
|
+
navId: number;
|
|
54
|
+
nextElements: Promise<AppElements>;
|
|
55
|
+
onCommittedState?: (state: AppRouterState) => void;
|
|
56
|
+
operationLane: OperationLane;
|
|
57
|
+
params: Record<string, string | string[]>;
|
|
58
|
+
payloadOrigin: AppNavigationPayloadOrigin;
|
|
59
|
+
pendingRouterState: PendingBrowserRouterState | null;
|
|
60
|
+
previousNextUrl: string | null;
|
|
61
|
+
restoredBfcacheIds?: Readonly<Record<string, string>> | null;
|
|
62
|
+
reuseCurrentBfcacheIds?: boolean;
|
|
63
|
+
scrollIntent?: AppRouterScrollIntent | null;
|
|
64
|
+
targetHistoryIndex?: number | null;
|
|
65
|
+
targetHref: string;
|
|
66
|
+
visibleCommitMode?: NavigationRuntimeVisibleCommitMode;
|
|
67
|
+
};
|
|
46
68
|
type BrowserNavigationController = {
|
|
47
69
|
beginNavigation(): number;
|
|
48
70
|
getActiveNavigationId(): number;
|
|
@@ -60,27 +82,7 @@ type BrowserNavigationController = {
|
|
|
60
82
|
state: AppRouterState;
|
|
61
83
|
targetHref: string;
|
|
62
84
|
}): boolean;
|
|
63
|
-
renderNavigationPayload(options:
|
|
64
|
-
actionType: "navigate" | "replace" | "traverse";
|
|
65
|
-
createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;
|
|
66
|
-
historyUpdateMode: HistoryUpdateMode | undefined;
|
|
67
|
-
navigationSnapshot: ClientNavigationRenderSnapshot;
|
|
68
|
-
nextElements: Promise<AppElements>;
|
|
69
|
-
operationLane: OperationLane;
|
|
70
|
-
payloadOrigin: AppNavigationPayloadOrigin;
|
|
71
|
-
params: Record<string, string | string[]>;
|
|
72
|
-
pendingRouterState: PendingBrowserRouterState | null;
|
|
73
|
-
previousNextUrl: string | null;
|
|
74
|
-
scrollIntent?: AppRouterScrollIntent | null;
|
|
75
|
-
restoredBfcacheIds?: Readonly<Record<string, string>> | null;
|
|
76
|
-
reuseCurrentBfcacheIds?: boolean;
|
|
77
|
-
targetHistoryIndex?: number | null;
|
|
78
|
-
targetHref: string;
|
|
79
|
-
navId: number;
|
|
80
|
-
navigationCommitKind?: "authoritative" | "detached";
|
|
81
|
-
visibleCommitMode?: NavigationRuntimeVisibleCommitMode;
|
|
82
|
-
onCommittedState?: (state: AppRouterState) => void;
|
|
83
|
-
}): Promise<NavigationPayloadOutcome>;
|
|
85
|
+
renderNavigationPayload(options: BrowserNavigationPayloadOptions): Promise<NavigationPayloadOutcome>;
|
|
84
86
|
commitSameUrlNavigatePayload(nextElements: Promise<AppElements>, navigationSnapshot: ClientNavigationRenderSnapshot, returnValue?: {
|
|
85
87
|
ok: boolean;
|
|
86
88
|
data: unknown;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
|
|
3
3
|
import { claimAppRouterScrollIntentForCommit, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
4
|
-
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
5
4
|
import { resolveServerActionOperationLane, shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
|
|
5
|
+
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
6
6
|
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit } from "./app-browser-state.js";
|
|
7
7
|
import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
|
|
8
8
|
import { startTransition, useInsertionEffect, useLayoutEffect } from "react";
|
|
@@ -349,7 +349,7 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
349
349
|
let snapshotActivated = false;
|
|
350
350
|
try {
|
|
351
351
|
const pending = await createPendingNavigationCommit({
|
|
352
|
-
currentState:
|
|
352
|
+
currentState: options.navigationInitiationState,
|
|
353
353
|
navigationCommitKind: options.navigationCommitKind,
|
|
354
354
|
navigationId: options.navId,
|
|
355
355
|
nextElements: options.nextElements,
|
|
@@ -6,12 +6,12 @@ import { AppElementsWire } from "./app-elements-wire.js";
|
|
|
6
6
|
import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
|
|
7
7
|
import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
|
|
8
8
|
import { createCacheEntryReuseProof } from "./cache-proof.js";
|
|
9
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
9
10
|
import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
|
|
10
11
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
11
12
|
import { verifyOperationTokenForCommit } from "./operation-token.js";
|
|
12
13
|
import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
|
|
13
14
|
import { createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
14
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
15
15
|
//#region src/server/app-browser-state.ts
|
|
16
16
|
const COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "committed-cache" };
|
|
17
17
|
const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
2
2
|
import "./app-elements.js";
|
|
3
3
|
import { mergeElements } from "../shims/slot.js";
|
|
4
|
-
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
5
4
|
import { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
5
|
+
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
6
6
|
import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
|
|
7
7
|
//#region src/server/app-browser-visible-commit.ts
|
|
8
8
|
const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
|
|
@@ -5,6 +5,7 @@ import { AppPageParams } from "./app-page-boundary.js";
|
|
|
5
5
|
import { AppPageFontPreload } from "./app-page-execution.js";
|
|
6
6
|
import { AppPageMiddlewareContext } from "./app-page-response.js";
|
|
7
7
|
import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
|
|
8
|
+
import { AppPageInterceptOptions } from "./app-page-element-builder.js";
|
|
8
9
|
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
9
10
|
import { AppPageBoundaryRoute } from "./app-page-boundary-render.js";
|
|
10
11
|
import { ReactNode } from "react";
|
|
@@ -81,6 +82,7 @@ type AppFallbackRendererCallContext = {
|
|
|
81
82
|
* render path. Defaults to `false` when no route is matched.
|
|
82
83
|
*/
|
|
83
84
|
isEdgeRuntime?: boolean;
|
|
85
|
+
routePathname?: string;
|
|
84
86
|
sourcePageSegments?: readonly string[] | null;
|
|
85
87
|
};
|
|
86
88
|
type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
|
|
@@ -88,6 +90,7 @@ type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
|
|
|
88
90
|
renderHttpAccessFallback: (route: AppPageBoundaryRoute<TModule> | null, statusCode: number, isRscRequest: boolean, request: Request, opts: {
|
|
89
91
|
boundaryComponent?: AppPageComponent | null;
|
|
90
92
|
boundaryModule?: TModule | null;
|
|
93
|
+
intercept?: AppPageInterceptOptions<TModule> | null;
|
|
91
94
|
layouts?: readonly (TModule | null | undefined)[] | null;
|
|
92
95
|
matchedParams?: AppPageParams;
|
|
93
96
|
}, scriptNonce: string | undefined, middlewareContext: AppPageMiddlewareContext, callContext?: AppFallbackRendererCallContext) => Promise<Response | null>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
|
|
2
1
|
import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
|
|
2
|
+
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
3
|
+
import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
|
|
3
4
|
import { DEFAULT_GLOBAL_NOT_FOUND_MODULE } from "./default-global-not-found-module.js";
|
|
4
5
|
import { DEFAULT_NOT_FOUND_MODULE } from "./default-not-found-module.js";
|
|
5
|
-
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
6
6
|
//#region src/server/app-fallback-renderer.ts
|
|
7
7
|
const EMPTY_MW_CTX = {
|
|
8
8
|
headers: null,
|
|
@@ -84,6 +84,7 @@ function createAppFallbackRenderer(options) {
|
|
|
84
84
|
getAndClearPendingCookies,
|
|
85
85
|
getNavigationContext,
|
|
86
86
|
globalErrorModule: effectiveGlobalErrorModule,
|
|
87
|
+
intercept: opts?.intercept ?? null,
|
|
87
88
|
isEdgeRuntime: callContext?.isEdgeRuntime,
|
|
88
89
|
isRscRequest,
|
|
89
90
|
layoutModules: useGlobalNotFound ? [] : opts?.layouts ?? null,
|
|
@@ -100,6 +101,7 @@ function createAppFallbackRenderer(options) {
|
|
|
100
101
|
rootNotFoundModule: routeMissRootNotFoundModule,
|
|
101
102
|
rootUnauthorizedModule,
|
|
102
103
|
route: useGlobalNotFound ? null : route,
|
|
104
|
+
routePathname: callContext?.routePathname,
|
|
103
105
|
renderToReadableStream: rscRenderer,
|
|
104
106
|
scriptNonce,
|
|
105
107
|
serveStreamingMetadata,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VINEXT_MW_CTX_HEADER } from "../utils/protocol-headers.js";
|
|
2
2
|
import { FLIGHT_HEADERS } from "./headers.js";
|
|
3
3
|
import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
|
|
4
|
-
import { isExternalUrl
|
|
4
|
+
import { isExternalUrl } from "../utils/external-url.js";
|
|
5
5
|
import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
6
6
|
import { cloneRequestWithHeaders, processMiddlewareHeaders } from "./request-pipeline.js";
|
|
7
7
|
import { executeMiddleware } from "./middleware-runtime.js";
|
|
@@ -58,6 +58,7 @@ async function proxyExternalMiddlewareRewrite(request, rewriteUrl, context) {
|
|
|
58
58
|
const proxyRequest = requestWithMiddlewareRequestHeaders(request, context.requestHeaders ?? context.headers);
|
|
59
59
|
setHeadersContext(null);
|
|
60
60
|
setNavigationContext(null);
|
|
61
|
+
const { proxyExternalRequest } = await import("../config/config-matchers.js");
|
|
61
62
|
const proxyResponse = await proxyExternalRequest(proxyRequest, rewriteUrl);
|
|
62
63
|
const headers = new Headers(proxyResponse.headers);
|
|
63
64
|
processMiddlewareHeaders(headers);
|
|
@@ -5,6 +5,8 @@ import { AppPageParams } from "./app-page-boundary.js";
|
|
|
5
5
|
import { AppPageFontPreload } from "./app-page-execution.js";
|
|
6
6
|
import { AppPageMiddlewareContext } from "./app-page-response.js";
|
|
7
7
|
import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
|
|
8
|
+
import { AppPageRouteWiringRoute } from "./app-page-route-wiring.js";
|
|
9
|
+
import { AppPageInterceptOptions } from "./app-page-element-builder.js";
|
|
8
10
|
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
9
11
|
import { ComponentType, ReactNode } from "react";
|
|
10
12
|
|
|
@@ -19,13 +21,20 @@ type AppPageBoundaryRoute<TModule extends AppPageModule = AppPageModule> = {
|
|
|
19
21
|
errorPaths?: readonly TModule[] | null;
|
|
20
22
|
errors?: readonly (TModule | null | undefined)[] | null;
|
|
21
23
|
forbidden?: TModule | null;
|
|
24
|
+
forbiddenTreePosition?: number | null;
|
|
25
|
+
forbiddens?: readonly (TModule | null | undefined)[] | null;
|
|
22
26
|
layoutTreePositions?: readonly number[] | null;
|
|
23
27
|
layouts?: readonly (TModule | null | undefined)[];
|
|
24
28
|
notFound?: TModule | null;
|
|
29
|
+
notFounds?: readonly (TModule | null | undefined)[] | null;
|
|
30
|
+
notFoundTreePosition?: number | null;
|
|
25
31
|
params?: AppPageParams;
|
|
26
32
|
pattern?: string;
|
|
27
33
|
routeSegments?: readonly string[];
|
|
34
|
+
slots?: AppPageRouteWiringRoute<TModule>["slots"];
|
|
28
35
|
unauthorized?: TModule | null;
|
|
36
|
+
unauthorizedTreePosition?: number | null;
|
|
37
|
+
unauthorizeds?: readonly (TModule | null | undefined)[] | null;
|
|
29
38
|
};
|
|
30
39
|
type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
31
40
|
applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
|
|
@@ -70,11 +79,13 @@ type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageM
|
|
|
70
79
|
type RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
71
80
|
boundaryComponent?: AppPageComponent | null;
|
|
72
81
|
boundaryModule?: TModule | null;
|
|
82
|
+
intercept?: AppPageInterceptOptions<TModule> | null;
|
|
73
83
|
layoutModules?: readonly (TModule | null | undefined)[] | null;
|
|
74
84
|
matchedParams: AppPageParams;
|
|
75
85
|
rootForbiddenModule?: TModule | null;
|
|
76
86
|
rootNotFoundModule?: TModule | null;
|
|
77
|
-
rootUnauthorizedModule?: TModule | null;
|
|
87
|
+
rootUnauthorizedModule?: TModule | null; /** Normalized, basePath-free application pathname used for route matching. */
|
|
88
|
+
routePathname?: string;
|
|
78
89
|
route?: AppPageBoundaryRoute<TModule> | null;
|
|
79
90
|
/**
|
|
80
91
|
* When true, the resolved boundary is rendered without wrapping it in the
|