vinext 1.2.0 → 1.3.0
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 +13 -10
- package/dist/build/client-build-config.d.ts +64 -3
- package/dist/build/client-build-config.js +131 -4
- package/dist/build/client-reference-groups.d.ts +163 -0
- package/dist/build/client-reference-groups.js +534 -0
- package/dist/build/module-dependency-cache.d.ts +31 -0
- package/dist/build/module-dependency-cache.js +51 -1
- package/dist/build/next-client-runtime-manifests.d.ts +10 -1
- package/dist/build/next-client-runtime-manifests.js +19 -4
- package/dist/build/nitro-public-files.d.ts +24 -0
- package/dist/build/nitro-public-files.js +60 -0
- package/dist/build/output-root-externals.d.ts +21 -0
- package/dist/build/output-root-externals.js +40 -0
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/prerender-paths.js +6 -3
- package/dist/build/prerender.js +1 -1
- package/dist/build/server-actions-encryption-key.d.ts +23 -0
- package/dist/build/server-actions-encryption-key.js +101 -0
- package/dist/build/ssr-manifest.d.ts +3 -0
- package/dist/build/ssr-manifest.js +10 -1
- package/dist/check.js +5 -6
- package/dist/cli-dev-config.js +3 -3
- package/dist/cli.js +1 -1
- package/dist/client/client-rewrite-params.d.ts +9 -0
- package/dist/client/client-rewrite-params.js +20 -0
- package/dist/client/dev-error-overlay.js +2 -1
- package/dist/client/navigation-runtime.d.ts +25 -2
- package/dist/client/navigation-runtime.js +42 -11
- package/dist/client/vinext-next-data.d.ts +0 -1
- package/dist/config/config-matchers.d.ts +15 -40
- package/dist/config/config-matchers.js +195 -262
- package/dist/config/config-source.d.ts +34 -0
- package/dist/config/config-source.js +141 -0
- package/dist/config/header-params.d.ts +29 -0
- package/dist/config/header-params.js +106 -0
- package/dist/config/next-config.d.ts +7 -5
- package/dist/config/next-config.js +120 -7
- package/dist/entries/app-browser-entry.d.ts +14 -1
- package/dist/entries/app-browser-entry.js +26 -36
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +92 -57
- package/dist/entries/app-rsc-manifest.d.ts +10 -0
- package/dist/entries/app-rsc-manifest.js +20 -1
- package/dist/entries/app-ssr-entry.d.ts +4 -1
- package/dist/entries/app-ssr-entry.js +9 -2
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +6 -6
- package/dist/entries/pages-server-entry.js +17 -14
- package/dist/index.d.ts +11 -0
- package/dist/index.js +350 -175
- package/dist/init.d.ts +1 -1
- package/dist/init.js +103 -6
- package/dist/plugins/ast-utils.d.ts +53 -2
- package/dist/plugins/ast-utils.js +90 -2
- package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
- package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
- package/dist/plugins/commonjs-esm-facade.js +2 -2
- package/dist/plugins/css-module-imports.js +13 -20
- package/dist/plugins/dynamic-preload-metadata.js +2 -3
- package/dist/plugins/extensionless-dynamic-import.js +2 -3
- package/dist/plugins/fonts.d.ts +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +2 -3
- package/dist/plugins/import-meta-url.js +3 -4
- package/dist/plugins/instrumentation-client.js +3 -2
- package/dist/plugins/middleware-export-validation.js +2 -3
- package/dist/plugins/og-harfbuzz.js +2 -3
- package/dist/plugins/optimize-imports.d.ts +25 -2
- package/dist/plugins/optimize-imports.js +109 -24
- package/dist/plugins/pages-node-externals.js +2 -3
- package/dist/plugins/remove-console.js +2 -18
- package/dist/plugins/require-condition-resolution.js +3 -3
- package/dist/plugins/require-context.js +2 -3
- package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
- package/dist/plugins/rsc-client-reference-loaders.js +336 -18
- package/dist/plugins/strip-server-exports.js +3 -4
- package/dist/plugins/styled-jsx.js +2 -3
- package/dist/plugins/use-cache-callable.d.ts +26 -2
- package/dist/plugins/use-cache-callable.js +101 -36
- package/dist/plugins/worker-image-imports.d.ts +1 -0
- package/dist/plugins/worker-image-imports.js +31 -34
- package/dist/plugins/worker-use-server.js +38 -14
- package/dist/routing/app-route-graph.d.ts +1 -1
- package/dist/routing/browser-route-manifest.d.ts +43 -0
- package/dist/routing/browser-route-manifest.js +195 -0
- package/dist/routing/hashed-route-patterns.d.ts +4 -0
- package/dist/routing/hashed-route-patterns.js +22 -0
- package/dist/routing/optimistic-route-trie.d.ts +27 -0
- package/dist/routing/optimistic-route-trie.js +102 -0
- package/dist/routing/route-validation.d.ts +6 -1
- package/dist/routing/route-validation.js +26 -10
- package/dist/server/api-handler.js +1 -1
- package/dist/server/app-action-forwarding.d.ts +8 -0
- package/dist/server/app-action-forwarding.js +17 -3
- package/dist/server/app-browser-entry.js +149 -62
- package/dist/server/app-browser-error.d.ts +3 -1
- package/dist/server/app-browser-error.js +7 -2
- package/dist/server/app-browser-interception-context.d.ts +2 -2
- package/dist/server/app-browser-interception-context.js +1 -1
- package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
- package/dist/server/app-browser-mpa-navigation.js +6 -5
- package/dist/server/app-browser-navigation-controller.d.ts +17 -6
- package/dist/server/app-browser-navigation-controller.js +88 -26
- package/dist/server/app-browser-prefetch-response.js +2 -2
- package/dist/server/app-browser-state.d.ts +2 -2
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-supplemental-refresh.js +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +4 -4
- package/dist/server/app-client-reference-preloader.d.ts +23 -0
- package/dist/server/app-client-reference-preloader.js +30 -7
- package/dist/server/app-fallback-renderer.js +2 -1
- package/dist/server/app-middleware.d.ts +6 -0
- package/dist/server/app-middleware.js +8 -10
- package/dist/server/app-optimistic-routing.d.ts +8 -10
- package/dist/server/app-optimistic-routing.js +4 -95
- package/dist/server/app-page-boundary-render.js +8 -1
- package/dist/server/app-page-cache-render.js +1 -0
- package/dist/server/app-page-dispatch.js +3 -1
- package/dist/server/app-page-render.js +4 -2
- package/dist/server/app-page-rsc-render-status.d.ts +1 -0
- package/dist/server/app-page-rsc-render-status.js +1 -0
- package/dist/server/app-page-search-params-observation.d.ts +1 -4
- package/dist/server/app-page-search-params-observation.js +8 -10
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +12 -8
- package/dist/server/app-prerender-endpoints.js +1 -1
- package/dist/server/app-prerender-static-params.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +19 -0
- package/dist/server/app-render-abort-error.js +31 -1
- package/dist/server/app-render-dependency.js +42 -2
- package/dist/server/app-request-stage-independent-entry.js +7 -7
- package/dist/server/app-response-stage-entry.js +5 -5
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-execution.d.ts +2 -0
- package/dist/server/app-route-handler-execution.js +9 -2
- package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
- package/dist/server/app-route-handler-middleware-context.js +3 -3
- package/dist/server/app-route-handler-response.d.ts +2 -1
- package/dist/server/app-route-handler-response.js +2 -2
- package/dist/server/app-route-handler-runtime.d.ts +2 -0
- package/dist/server/app-route-handler-runtime.js +21 -4
- package/dist/server/app-route-module-loader.js +7 -6
- package/dist/server/app-route-tree.d.ts +20 -0
- package/dist/server/app-route-tree.js +18 -0
- package/dist/server/app-router-entry.js +7 -7
- package/dist/server/app-rsc-cache-busting.d.ts +16 -0
- package/dist/server/app-rsc-cache-busting.js +29 -12
- package/dist/server/app-rsc-combined-handler.js +8 -1
- package/dist/server/app-rsc-errors.d.ts +7 -0
- package/dist/server/app-rsc-errors.js +9 -2
- package/dist/server/app-rsc-handler.d.ts +4 -1
- package/dist/server/app-rsc-handler.js +151 -135
- package/dist/server/app-rsc-request-normalization.js +3 -3
- package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.js +5 -3
- package/dist/server/app-rsc-route-matching.d.ts +1 -0
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +23 -6
- package/dist/server/app-server-action-execution.js +51 -57
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +21 -11
- package/dist/server/app-ssr-stream.d.ts +7 -0
- package/dist/server/app-ssr-stream.js +13 -1
- package/dist/server/app-visited-response-cache.js +2 -2
- package/dist/server/config-headers.js +13 -4
- package/dist/server/defer-until-stream-consumed.d.ts +2 -1
- package/dist/server/defer-until-stream-consumed.js +3 -1
- package/dist/server/dev-server.js +1 -1
- package/dist/server/image-optimization.js +1 -0
- package/dist/server/isolate-shared-promise.d.ts +10 -0
- package/dist/server/isolate-shared-promise.js +33 -0
- package/dist/server/isr-cache.js +3 -2
- package/dist/server/metadata-route-response.js +2 -2
- package/dist/server/middleware-matcher-pattern.d.ts +0 -1
- package/dist/server/middleware-matcher-pattern.js +11 -140
- package/dist/server/middleware-matcher.js +5 -6
- package/dist/server/middleware-response-headers.d.ts +31 -0
- package/dist/server/middleware-response-headers.js +57 -1
- package/dist/server/middleware-runtime.js +30 -17
- package/dist/server/navigation-planner.d.ts +2 -2
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/nitro-public-files-plugin.d.ts +38 -0
- package/dist/server/nitro-public-files-plugin.js +106 -0
- package/dist/server/nitro-public-files.d.ts +21 -0
- package/dist/server/nitro-public-files.js +39 -0
- package/dist/server/open-redirect.d.ts +11 -4
- package/dist/server/open-redirect.js +11 -4
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +5 -0
- package/dist/server/pages-asset-tags.js +9 -2
- package/dist/server/pages-client-assets.d.ts +4 -1
- package/dist/server/pages-data-route.js +2 -1
- package/dist/server/pages-i18n.d.ts +18 -0
- package/dist/server/pages-i18n.js +18 -2
- package/dist/server/pages-node-compat.d.ts +5 -3
- package/dist/server/pages-node-compat.js +35 -16
- package/dist/server/pages-page-data.js +1 -1
- package/dist/server/pages-page-handler.js +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +6 -1
- package/dist/server/pages-request-pipeline.js +35 -39
- package/dist/server/pages-request-stage-entry.js +20 -10
- package/dist/server/pages-response-stage-entry.js +1 -1
- package/dist/server/pages-revalidate.js +3 -2
- package/dist/server/pages-router-entry.js +2 -2
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +74 -36
- package/dist/server/proxy-trust.d.ts +6 -0
- package/dist/server/proxy-trust.js +12 -6
- package/dist/server/request-pipeline.d.ts +5 -0
- package/dist/server/request-pipeline.js +12 -1
- package/dist/server/rsc-stream-hints.d.ts +1 -1
- package/dist/server/rsc-stream-hints.js +21 -3
- package/dist/server/server-reference-loader.js +10 -1
- package/dist/server/static-file-cache.js +15 -3
- package/dist/server/worker-image-optimization.js +19 -6
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache-handler.js +3 -2
- package/dist/shims/cache-request-state.d.ts +40 -3
- package/dist/shims/cache-request-state.js +70 -5
- package/dist/shims/cache-runtime.js +47 -19
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +17 -8
- package/dist/shims/cdn-purge-routes.d.ts +24 -0
- package/dist/shims/cdn-purge-routes.js +77 -0
- package/dist/shims/dynamic.js +17 -4
- package/dist/shims/form.js +8 -3
- package/dist/shims/head.js +1 -1
- package/dist/shims/headers.js +2 -2
- package/dist/shims/image-props.d.ts +93 -0
- package/dist/shims/image-props.js +323 -0
- package/dist/shims/image.d.ts +4 -18
- package/dist/shims/image.js +4 -319
- package/dist/shims/internal/headers-state.d.ts +7 -0
- package/dist/shims/internal/headers-state.js +14 -2
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +32 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -8
- package/dist/shims/link-prefetch.js +5 -4
- package/dist/shims/link.js +7 -5
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +21 -10
- package/dist/shims/og.js +35 -10
- package/dist/shims/request-context.d.ts +13 -0
- package/dist/shims/router.js +28 -52
- package/dist/shims/server.d.ts +42 -8
- package/dist/shims/server.js +99 -15
- package/dist/shims/thenable-params.d.ts +6 -1
- package/dist/shims/thenable-params.js +11 -2
- package/dist/shims/unified-request-context.d.ts +5 -0
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/url-utils.d.ts +7 -0
- package/dist/shims/url-utils.js +12 -3
- package/dist/utils/asset-prefix.d.ts +7 -0
- package/dist/utils/asset-prefix.js +10 -1
- package/dist/utils/client-build-manifest.js +12 -5
- package/dist/utils/client-runtime-metadata.d.ts +1 -0
- package/dist/utils/client-runtime-metadata.js +15 -2
- package/dist/utils/domain-locale.js +1 -1
- package/dist/utils/lazy-chunks.d.ts +4 -0
- package/dist/utils/manifest-paths.d.ts +14 -0
- package/dist/utils/manifest-paths.js +22 -1
- package/dist/utils/path-to-regexp.d.ts +21 -0
- package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
- package/dist/utils/plugin-react-version.d.ts +15 -0
- package/dist/utils/plugin-react-version.js +64 -0
- package/dist/utils/plugin-rsc-version.d.ts +2 -0
- package/dist/utils/plugin-rsc-version.js +28 -2
- package/dist/utils/public-routes.d.ts +2 -0
- package/dist/utils/public-routes.js +18 -7
- package/dist/utils/react-version.d.ts +7 -0
- package/dist/utils/react-version.js +39 -16
- package/package.json +6 -6
- package/dist/build/nitro-route-rules.d.ts +0 -47
- package/dist/build/nitro-route-rules.js +0 -79
- package/dist/plugins/cache-flight-codec.d.ts +0 -19
- package/dist/plugins/cache-flight-codec.js +0 -68
- package/dist/server/middleware-path-to-regexp.d.ts +0 -13
- package/dist/utils/regex-safety.d.ts +0 -17
- package/dist/utils/regex-safety.js +0 -789
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HistoryUpdateMode } from "./app-browser-navigation-controller.js";
|
|
2
2
|
//#region src/server/app-browser-mpa-navigation.d.ts
|
|
3
3
|
export type AppBrowserMpaNavigationWindow = {
|
|
4
|
+
document?: Pick<Document, "visibilityState">;
|
|
4
5
|
location: Pick<Location, "assign" | "replace">;
|
|
5
6
|
requestAnimationFrame?: (callback: FrameRequestCallback) => unknown;
|
|
6
7
|
setTimeout(callback: () => void, timeout: number): unknown;
|
|
@@ -14,21 +14,22 @@ var AppBrowserMpaNavigationScheduler = class {
|
|
|
14
14
|
this.#pendingNavigation = null;
|
|
15
15
|
}
|
|
16
16
|
navigate(targetWindow, href, historyUpdateMode) {
|
|
17
|
-
|
|
18
|
-
if (pendingNavigation?.href === href && pendingNavigation.historyUpdateMode === historyUpdateMode) return;
|
|
17
|
+
if (this.#pendingNavigation?.href === href) return;
|
|
19
18
|
const token = this.#nextToken + 1;
|
|
20
19
|
this.#nextToken = token;
|
|
21
20
|
this.#pendingNavigation = {
|
|
22
21
|
href,
|
|
23
|
-
historyUpdateMode,
|
|
24
22
|
token
|
|
25
23
|
};
|
|
26
24
|
const navigate = () => {
|
|
27
|
-
|
|
28
|
-
if (currentNavigation?.href !== href || currentNavigation.historyUpdateMode !== historyUpdateMode || currentNavigation.token !== token) return;
|
|
25
|
+
if (this.#pendingNavigation?.token !== token) return;
|
|
29
26
|
if (historyUpdateMode === "replace") targetWindow.location.replace(href);
|
|
30
27
|
else targetWindow.location.assign(href);
|
|
31
28
|
};
|
|
29
|
+
if (targetWindow.document?.visibilityState === "hidden") {
|
|
30
|
+
navigate();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
32
33
|
if (typeof targetWindow.requestAnimationFrame === "function") {
|
|
33
34
|
targetWindow.requestAnimationFrame(() => {
|
|
34
35
|
targetWindow.setTimeout(navigate, 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BrowserRouteManifest } from "../routing/browser-route-manifest.js";
|
|
2
2
|
import { AppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
3
3
|
import { NavigationRuntimeVisibleCommitMode } from "../client/navigation-runtime.js";
|
|
4
4
|
import { AppElements } from "./app-elements-wire.js";
|
|
@@ -17,10 +17,14 @@ export type PendingBrowserRouterState = {
|
|
|
17
17
|
};
|
|
18
18
|
export type NavigationPayloadOutcome = "committed" | "no-commit" | "hard-navigate";
|
|
19
19
|
type HardNavigationMode = "assign" | "replace";
|
|
20
|
-
type BrowserNavigationCommitEffect =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
})
|
|
20
|
+
type BrowserNavigationCommitEffect = {
|
|
21
|
+
writeHistory(options: {
|
|
22
|
+
keepCurrentUrl: boolean;
|
|
23
|
+
}): void;
|
|
24
|
+
publish(options: {
|
|
25
|
+
releaseSnapshot: boolean;
|
|
26
|
+
}): void;
|
|
27
|
+
};
|
|
24
28
|
type BrowserNavigationCommitEffectFactory = (options: {
|
|
25
29
|
activeRoutePaths: readonly string[];
|
|
26
30
|
bfcacheIds: Readonly<Record<string, string>>;
|
|
@@ -43,8 +47,10 @@ type SameUrlServerActionLifecycleOptions = {
|
|
|
43
47
|
type BrowserNavigationControllerDeps = {
|
|
44
48
|
basePath?: string;
|
|
45
49
|
commitClientNavigationState?: typeof commitClientNavigationState;
|
|
50
|
+
navigateDocument?: (href: string, mode: HardNavigationMode) => void;
|
|
46
51
|
performHardNavigation?: (href: string, mode?: HardNavigationMode) => boolean;
|
|
47
|
-
getRouteManifest?: () =>
|
|
52
|
+
getRouteManifest?: () => BrowserRouteManifest | null;
|
|
53
|
+
loadRouteManifest?: () => Promise<boolean> | null;
|
|
48
54
|
syncHistoryStatePreviousNextUrl?: (previousNextUrl: string | null, bfcacheIds?: Readonly<Record<string, string>> | null) => void;
|
|
49
55
|
};
|
|
50
56
|
type BrowserNavigationPayloadOptions = {
|
|
@@ -80,6 +86,7 @@ type BrowserNavigationController = {
|
|
|
80
86
|
waitForBrowserRouterStateReady(): Promise<void>;
|
|
81
87
|
attachBrowserRouterState(setter: Dispatch<AppRouterState | Promise<AppRouterState>>, stateRef: BrowserRouterStateRef): () => void;
|
|
82
88
|
beginPendingBrowserRouterState(): PendingBrowserRouterState;
|
|
89
|
+
abandonPendingBrowserRouterState(pending: PendingBrowserRouterState | null | undefined): void;
|
|
83
90
|
finalizeNavigation(navId: number, pending: PendingBrowserRouterState | null | undefined): void;
|
|
84
91
|
discardPendingNavigation(visibleState: AppRouterState | null): boolean;
|
|
85
92
|
flushCommittingNavigationUrl(): void;
|
|
@@ -112,8 +119,12 @@ type BrowserNavigationController = {
|
|
|
112
119
|
renderId: number;
|
|
113
120
|
children?: ReactNode;
|
|
114
121
|
}): ReactNode;
|
|
122
|
+
NavigationHistoryCommit(this: void, { renderId }: {
|
|
123
|
+
renderId: number;
|
|
124
|
+
}): null;
|
|
115
125
|
};
|
|
116
126
|
export declare function clearHardNavigationLoopGuard(): void;
|
|
127
|
+
export declare function navigateDocumentDirectly(href: string, mode: HardNavigationMode): void;
|
|
117
128
|
export declare function createBasePathStrippedPathAndSearch(url: URL, basePath: string): string;
|
|
118
129
|
export declare function createAppBrowserNavigationController(deps?: BrowserNavigationControllerDeps): BrowserNavigationController;
|
|
119
130
|
//#endregion
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { withBasePath } from "../shims/url-utils.js";
|
|
2
3
|
import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
|
|
3
4
|
import { claimAppRouterScrollIntentForCommit, clearAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
4
5
|
import { resolveServerActionOperationLane, shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
|
|
@@ -37,7 +38,11 @@ function clearHardNavigationLoopGuard() {
|
|
|
37
38
|
window.sessionStorage.removeItem(HARD_NAVIGATION_LOOP_GUARD_KEY);
|
|
38
39
|
} catch {}
|
|
39
40
|
}
|
|
40
|
-
function
|
|
41
|
+
function navigateDocumentDirectly(href, mode) {
|
|
42
|
+
if (mode === "replace") window.location.replace(href);
|
|
43
|
+
else window.location.assign(href);
|
|
44
|
+
}
|
|
45
|
+
function performHardNavigationWithLoopGuard(href, mode = "assign", navigateDocument = navigateDocumentDirectly) {
|
|
41
46
|
const targetHref = normalizeBrowserHref(href);
|
|
42
47
|
const currentHref = normalizeBrowserHref(window.location.href);
|
|
43
48
|
if (readHardNavigationLoopGuard() === targetHref && currentHref === targetHref) {
|
|
@@ -49,8 +54,7 @@ function performHardNavigationWithLoopGuard(href, mode = "assign") {
|
|
|
49
54
|
console.error(`[vinext] Hard navigation to ${targetHref} requires a reload-loop guard, but sessionStorage is unavailable; leaving the current document in place.`);
|
|
50
55
|
return false;
|
|
51
56
|
}
|
|
52
|
-
|
|
53
|
-
else window.location.assign(href);
|
|
57
|
+
navigateDocument(href, mode);
|
|
54
58
|
return true;
|
|
55
59
|
}
|
|
56
60
|
function createBasePathStrippedPathAndSearch(url, basePath) {
|
|
@@ -69,8 +73,9 @@ function isSnapshotTargetHref(basePath, snapshot, targetHref) {
|
|
|
69
73
|
function createAppBrowserNavigationController(deps = {}) {
|
|
70
74
|
const basePath = deps.basePath ?? "";
|
|
71
75
|
const commitClientNavigationStateImpl = deps.commitClientNavigationState ?? commitClientNavigationState;
|
|
72
|
-
const performHardNavigation = deps.performHardNavigation ?? performHardNavigationWithLoopGuard;
|
|
76
|
+
const performHardNavigation = deps.performHardNavigation ?? ((href, mode) => performHardNavigationWithLoopGuard(href, mode, deps.navigateDocument));
|
|
73
77
|
const getRouteManifest = deps.getRouteManifest ?? (() => null);
|
|
78
|
+
const loadRouteManifest = deps.loadRouteManifest ?? (() => null);
|
|
74
79
|
const syncHistoryStatePreviousNextUrl = deps.syncHistoryStatePreviousNextUrl ?? (() => {});
|
|
75
80
|
let nextNavigationRenderId = 0;
|
|
76
81
|
let activeNavigationId = 0;
|
|
@@ -162,6 +167,11 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
162
167
|
pending.resolve(getBrowserRouterState());
|
|
163
168
|
if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
|
|
164
169
|
}
|
|
170
|
+
function abandonPendingBrowserRouterState(pending) {
|
|
171
|
+
if (!pending || pending.settled) return;
|
|
172
|
+
pending.settled = true;
|
|
173
|
+
if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
|
|
174
|
+
}
|
|
165
175
|
function finalizeNavigation(navId, pending) {
|
|
166
176
|
settlePendingBrowserRouterState(pending);
|
|
167
177
|
if (isCurrentNavigation(navId)) {
|
|
@@ -209,11 +219,11 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
209
219
|
return true;
|
|
210
220
|
}
|
|
211
221
|
/**
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* top of the destination
|
|
222
|
+
* Publish the URL update of a navigation render React is committing right
|
|
223
|
+
* now. Its history entry is already written, but publishing normally runs in
|
|
224
|
+
* NavigationCommitSignal's layout effect, after the route's own layout
|
|
225
|
+
* effects. Called before a raw history write from such an effect, so the
|
|
226
|
+
* write is published on top of the destination's.
|
|
217
227
|
*/
|
|
218
228
|
function flushCommittingNavigationUrl() {
|
|
219
229
|
if (committingNavigationRenderId !== null) drainPrePaintEffects(committingNavigationRenderId);
|
|
@@ -224,9 +234,12 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
224
234
|
function isRetiredNavigationUrl(navId, targetHref) {
|
|
225
235
|
return retiredNavigationUrl !== null && retiredNavigationUrl.navigationId === navId && retiredNavigationUrl.href === normalizeBrowserHref(targetHref);
|
|
226
236
|
}
|
|
227
|
-
function
|
|
228
|
-
|
|
229
|
-
|
|
237
|
+
function writeNavigationRenderHistory(renderId) {
|
|
238
|
+
const effect = pendingNavigationPrePaintEffects.get(renderId);
|
|
239
|
+
const writeHistory = effect?.writeHistory;
|
|
240
|
+
if (!effect || !writeHistory) return;
|
|
241
|
+
effect.writeHistory = null;
|
|
242
|
+
writeHistory();
|
|
230
243
|
}
|
|
231
244
|
/**
|
|
232
245
|
* Run all queued pre-paint effects for renderIds up to and including the
|
|
@@ -243,8 +256,10 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
243
256
|
for (const [id, effect] of pendingNavigationPrePaintEffects) {
|
|
244
257
|
if (id > upToRenderId) continue;
|
|
245
258
|
pendingNavigationPrePaintEffects.delete(id);
|
|
246
|
-
if (id === upToRenderId)
|
|
247
|
-
|
|
259
|
+
if (id === upToRenderId) {
|
|
260
|
+
effect.writeHistory?.();
|
|
261
|
+
effect.publish();
|
|
262
|
+
} else releaseRenderSnapshot(id);
|
|
248
263
|
}
|
|
249
264
|
}
|
|
250
265
|
/**
|
|
@@ -261,7 +276,10 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
261
276
|
pendingCommit.resolve(didCommit);
|
|
262
277
|
}
|
|
263
278
|
}
|
|
264
|
-
/**
|
|
279
|
+
/**
|
|
280
|
+
* Runs when React starts committing a render, before it changes the route
|
|
281
|
+
* tree's DOM, and writes the render's history entry.
|
|
282
|
+
*/
|
|
265
283
|
function beginNavigationRenderCommit(renderId) {
|
|
266
284
|
committingNavigationRenderId = renderId;
|
|
267
285
|
const committingCommit = pendingNavigationCommits.get(renderId);
|
|
@@ -269,6 +287,7 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
269
287
|
if (committingCommit && committingOperation?.navigationCommitKind === "detached" && committingOperation.navigationId === pendingUserNavigationId) pendingUserNavigationShellHref = normalizeBrowserHref(committingCommit.targetHref);
|
|
270
288
|
else pendingUserNavigationCommitStarted = true;
|
|
271
289
|
clearCommittedNavigationFailureTargets(renderId);
|
|
290
|
+
writeNavigationRenderHistory(renderId);
|
|
272
291
|
}
|
|
273
292
|
function commitNavigationRender(renderId) {
|
|
274
293
|
committingNavigationRenderId = null;
|
|
@@ -288,7 +307,11 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
288
307
|
if (!hasBrowserRouterState()) return;
|
|
289
308
|
const currentState = getBrowserRouterState();
|
|
290
309
|
const renderId = allocateRenderId();
|
|
291
|
-
const [navigationSnapshot] = await Promise.all([
|
|
310
|
+
const [navigationSnapshot, , routeManifestLoaded] = await Promise.all([
|
|
311
|
+
pendingNavigationSnapshot,
|
|
312
|
+
nextElements,
|
|
313
|
+
loadRouteManifest()
|
|
314
|
+
]);
|
|
292
315
|
const pending = await createPendingNavigationCommit({
|
|
293
316
|
currentState,
|
|
294
317
|
nextElements,
|
|
@@ -300,6 +323,10 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
300
323
|
});
|
|
301
324
|
if (hmrUpdateId !== latestHmrUpdateId || startedDuringUserNavigation) return;
|
|
302
325
|
if (!hasBrowserRouterState()) return;
|
|
326
|
+
if (routeManifestLoaded === false) {
|
|
327
|
+
performHardNavigation(withBasePath(createSnapshotPathAndSearch(navigationSnapshot), basePath));
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
303
330
|
const approval = approveHmrVisibleCommit({
|
|
304
331
|
currentState: getBrowserRouterState(),
|
|
305
332
|
pending,
|
|
@@ -309,10 +336,19 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
309
336
|
if (approval.approvedCommit) dispatchSynchronousVisibleCommit(approval.approvedCommit);
|
|
310
337
|
else if (approval.decision.disposition === "hard-navigate") performHardNavigation(createSnapshotPathAndSearch(navigationSnapshot));
|
|
311
338
|
}
|
|
312
|
-
|
|
339
|
+
/**
|
|
340
|
+
* Rendered before the route tree (see createAppRouteTree). Insertion effects
|
|
341
|
+
* run in the mutation phase, in tree order, after each component's own
|
|
342
|
+
* subtree mutations, so this one runs before React changes the route tree's
|
|
343
|
+
* DOM. An effect on NavigationCommitSignal itself would run after them.
|
|
344
|
+
*/
|
|
345
|
+
function NavigationHistoryCommit({ renderId }) {
|
|
313
346
|
useInsertionEffect(() => {
|
|
314
347
|
beginNavigationRenderCommit(renderId);
|
|
315
348
|
}, [renderId]);
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
function NavigationCommitSignal({ renderId, children }) {
|
|
316
352
|
useLayoutEffect(() => {
|
|
317
353
|
commitNavigationRender(renderId);
|
|
318
354
|
return () => {
|
|
@@ -433,6 +469,13 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
433
469
|
return isSamePathSearchHashCommit(options.targetHref);
|
|
434
470
|
}
|
|
435
471
|
async function renderNavigationPayload(options) {
|
|
472
|
+
const routeManifestLoad = loadRouteManifest();
|
|
473
|
+
if (routeManifestLoad !== null && !await routeManifestLoad) {
|
|
474
|
+
settlePendingBrowserRouterState(options.pendingRouterState);
|
|
475
|
+
consumeAppRouterScrollIntent(options.scrollIntent ?? null);
|
|
476
|
+
if (isCurrentNavigation(options.navId)) performHardNavigation(options.targetHref, options.historyUpdateMode === "push" ? "assign" : "replace");
|
|
477
|
+
return "no-commit";
|
|
478
|
+
}
|
|
436
479
|
if (options.navId === pendingUserNavigationId) pendingUserNavigationLane = options.operationLane;
|
|
437
480
|
const renderId = allocateRenderId();
|
|
438
481
|
const failureTarget = getAppNavigationFailureTarget(options.targetHref);
|
|
@@ -486,11 +529,14 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
486
529
|
return "no-commit";
|
|
487
530
|
}
|
|
488
531
|
if (approval.decision.disposition === "hard-navigate") {
|
|
489
|
-
settlePendingBrowserRouterState(options.pendingRouterState);
|
|
490
532
|
pendingNavigationFailureTargets.delete(renderId);
|
|
491
533
|
pendingNavigationCommits.delete(renderId);
|
|
492
534
|
consumeAppRouterScrollIntent(options.scrollIntent ?? null);
|
|
493
|
-
if (performHardNavigation(options.targetHref
|
|
535
|
+
if (performHardNavigation(options.targetHref, options.historyUpdateMode === "push" ? "assign" : "replace")) {
|
|
536
|
+
abandonPendingBrowserRouterState(options.pendingRouterState);
|
|
537
|
+
return "hard-navigate";
|
|
538
|
+
}
|
|
539
|
+
settlePendingBrowserRouterState(options.pendingRouterState);
|
|
494
540
|
if (failureTarget) clearAppNavigationFailureTarget(failureTarget);
|
|
495
541
|
return "no-commit";
|
|
496
542
|
}
|
|
@@ -507,11 +553,13 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
507
553
|
previousNextUrl: approvedCommit.previousNextUrl,
|
|
508
554
|
targetHistoryIndex: options.targetHistoryIndex
|
|
509
555
|
});
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
keepCurrentUrl: isRetiredNavigationUrl(options.navId, options.targetHref)
|
|
513
|
-
|
|
514
|
-
|
|
556
|
+
pendingNavigationPrePaintEffects.set(renderId, {
|
|
557
|
+
writeHistory: () => {
|
|
558
|
+
commitEffect.writeHistory({ keepCurrentUrl: isRetiredNavigationUrl(options.navId, options.targetHref) });
|
|
559
|
+
},
|
|
560
|
+
publish: () => {
|
|
561
|
+
commitEffect.publish({ releaseSnapshot: snapshotRenderIds.delete(renderId) });
|
|
562
|
+
}
|
|
515
563
|
});
|
|
516
564
|
claimAppRouterScrollIntentForCommit(options.scrollIntent, renderId);
|
|
517
565
|
if (!isRetiredNavigationUrl(options.navId, options.targetHref)) {
|
|
@@ -542,6 +590,15 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
542
590
|
const currentState = actionInitiationState ?? getBrowserRouterState();
|
|
543
591
|
const startedNavigationId = lifecycleOptions?.startedNavigationId ?? activeNavigationId;
|
|
544
592
|
const targetHref = lifecycleOptions?.targetHref ?? window.location.href;
|
|
593
|
+
const routeManifestLoad = loadRouteManifest();
|
|
594
|
+
if (routeManifestLoad !== null && !await routeManifestLoad) {
|
|
595
|
+
if (isCurrentNavigation(startedNavigationId)) {
|
|
596
|
+
performHardNavigation(targetHref);
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
notifyDiscardedServerActionRevalidation(lifecycleOptions);
|
|
600
|
+
return resolveSameUrlActionReturnValue(returnValue);
|
|
601
|
+
}
|
|
545
602
|
const { approvedCommit, decision, pending, trace: _navigationTrace } = await resolveAndClassifyNavigationCommit({
|
|
546
603
|
activeNavigationId,
|
|
547
604
|
currentState,
|
|
@@ -582,6 +639,9 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
582
639
|
syncHistoryStatePreviousNextUrl(approvedRevalidationCommit.previousNextUrl, approvedRevalidationCommit.action.bfcacheIds);
|
|
583
640
|
} else notifyDiscardedServerActionRevalidation(lifecycleOptions);
|
|
584
641
|
} else if (decision.disposition === "no-commit") notifyDiscardedServerActionRevalidation(lifecycleOptions);
|
|
642
|
+
return resolveSameUrlActionReturnValue(returnValue);
|
|
643
|
+
}
|
|
644
|
+
async function resolveSameUrlActionReturnValue(returnValue) {
|
|
585
645
|
if (returnValue) {
|
|
586
646
|
if (!returnValue.ok) throw await returnValue.data;
|
|
587
647
|
return returnValue.data;
|
|
@@ -609,6 +669,7 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
609
669
|
waitForBrowserRouterStateReady,
|
|
610
670
|
attachBrowserRouterState,
|
|
611
671
|
beginPendingBrowserRouterState,
|
|
672
|
+
abandonPendingBrowserRouterState,
|
|
612
673
|
finalizeNavigation,
|
|
613
674
|
discardPendingNavigation,
|
|
614
675
|
flushCommittingNavigationUrl,
|
|
@@ -620,8 +681,9 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
620
681
|
beginNavigationRenderCommit,
|
|
621
682
|
commitNavigationRender,
|
|
622
683
|
clearCommittedNavigationFailureTargets,
|
|
623
|
-
NavigationCommitSignal
|
|
684
|
+
NavigationCommitSignal,
|
|
685
|
+
NavigationHistoryCommit
|
|
624
686
|
};
|
|
625
687
|
}
|
|
626
688
|
//#endregion
|
|
627
|
-
export { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch, createSnapshotPathAndSearch };
|
|
689
|
+
export { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch, createSnapshotPathAndSearch, navigateDocumentDirectly };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
1
|
+
import { formatRscRequestPath, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
2
2
|
import { peekPrefetchResponseForNavigation } from "../shims/navigation.js";
|
|
3
3
|
//#region src/server/app-browser-prefetch-response.ts
|
|
4
4
|
function peekSettledPrefetchResponseForNavigation(options) {
|
|
@@ -25,7 +25,7 @@ function isSameOriginBrowserRscUrl(url, origin) {
|
|
|
25
25
|
function canonicalizeBrowserRscResponseUrl(responseUrl, origin) {
|
|
26
26
|
try {
|
|
27
27
|
const parsed = new URL(responseUrl, origin);
|
|
28
|
-
if (parsed.origin === new URL(origin).origin) return
|
|
28
|
+
if (parsed.origin === new URL(origin).origin) return formatRscRequestPath(parsed);
|
|
29
29
|
} catch {}
|
|
30
30
|
return responseUrl;
|
|
31
31
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BrowserRouteManifest } from "../routing/browser-route-manifest.js";
|
|
2
2
|
import { CacheEntryReuseProof } from "./cache-proof.js";
|
|
3
3
|
import { AppElements, AppElementsInterception, AppElementsSlotBinding, LayoutFlags } from "./app-elements-wire.js";
|
|
4
4
|
import "./app-elements.js";
|
|
@@ -130,7 +130,7 @@ export declare function resolvePendingNavigationCommitDispositionDecision(option
|
|
|
130
130
|
activeNavigationId: number;
|
|
131
131
|
currentState: AppRouterState;
|
|
132
132
|
pending: PendingNavigationCommit;
|
|
133
|
-
routeManifest?:
|
|
133
|
+
routeManifest?: BrowserRouteManifest | null;
|
|
134
134
|
startedNavigationId: number;
|
|
135
135
|
targetHref?: string;
|
|
136
136
|
}): PendingNavigationCommitDispositionDecision;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
2
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
3
2
|
import { VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } from "./app-rsc-vary.js";
|
|
4
3
|
import { NEXT_ACTION_HEADER, RSC_ACTION_HEADER } from "./headers.js";
|
|
4
|
+
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
5
5
|
import { normalizePath } from "./normalize-path.js";
|
|
6
6
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
7
7
|
import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
2
1
|
import { addBasePathToPathname, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
3
3
|
import { normalizePath } from "./normalize-path.js";
|
|
4
4
|
import { APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_SLOT_BINDINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
5
5
|
import "./app-elements.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BrowserRouteManifest } from "../routing/browser-route-manifest.js";
|
|
2
2
|
import { AppElements } from "./app-elements-wire.js";
|
|
3
3
|
import "./app-elements.js";
|
|
4
4
|
import { NavigationTrace } from "./navigation-trace.js";
|
|
@@ -52,14 +52,14 @@ export declare function applyApprovedVisibleCommit(state: AppRouterState, commit
|
|
|
52
52
|
export declare function approveHmrVisibleCommit(options: {
|
|
53
53
|
currentState: AppRouterState;
|
|
54
54
|
pending: PendingNavigationCommit;
|
|
55
|
-
routeManifest?:
|
|
55
|
+
routeManifest?: BrowserRouteManifest | null;
|
|
56
56
|
targetHref: string;
|
|
57
57
|
}): CommitApproval;
|
|
58
58
|
export declare function approvePendingNavigationCommit(options: {
|
|
59
59
|
activeNavigationId: number;
|
|
60
60
|
currentState: AppRouterState;
|
|
61
61
|
pending: PendingNavigationCommit;
|
|
62
|
-
routeManifest?:
|
|
62
|
+
routeManifest?: BrowserRouteManifest | null;
|
|
63
63
|
startedNavigationId: number;
|
|
64
64
|
targetHref: string;
|
|
65
65
|
}): CommitApproval;
|
|
@@ -74,7 +74,7 @@ export declare function resolveAndClassifyNavigationCommit(options: {
|
|
|
74
74
|
payloadOrigin: AppNavigationPayloadOrigin;
|
|
75
75
|
previousNextUrl?: string | null;
|
|
76
76
|
renderId: number;
|
|
77
|
-
routeManifest?:
|
|
77
|
+
routeManifest?: BrowserRouteManifest | null;
|
|
78
78
|
startedNavigationId: number;
|
|
79
79
|
targetHref: string;
|
|
80
80
|
type: "navigate" | "replace" | "traverse";
|
|
@@ -9,5 +9,28 @@ type ClientReferencePreloaderOptions = {
|
|
|
9
9
|
type ClientReferencePreloader = {
|
|
10
10
|
preload: (referenceIds?: Iterable<string>) => Promise<void>;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* The client references each App Router route preloads before SSR, generated
|
|
14
|
+
* by plugins/rsc-client-reference-loaders.ts from the RSC build's module graph.
|
|
15
|
+
* Each list holds indices into `references`, or for routes into `files`.
|
|
16
|
+
*/
|
|
17
|
+
export type RouteClientReferences = {
|
|
18
|
+
/** Client reference keys. */
|
|
19
|
+
references: readonly string[];
|
|
20
|
+
/** References any render may use, whatever its route. */
|
|
21
|
+
always: readonly number[];
|
|
22
|
+
/** The references each route file reaches. */
|
|
23
|
+
files: readonly (readonly number[])[];
|
|
24
|
+
/** Each route pattern's files. */
|
|
25
|
+
routes: Readonly<Record<string, readonly number[]>>;
|
|
26
|
+
/** The files of a render without a route, such as a route-miss 404. */
|
|
27
|
+
routeless: readonly number[];
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* The client references a render of `routePattern` preloads, or of no route
|
|
31
|
+
* when it is null. Undefined, meaning every reference, without a plan or a
|
|
32
|
+
* route to look up, or for a pattern the plan doesn't know.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveRouteClientReferences(plan: RouteClientReferences | null, routePattern: string | null | undefined): string[] | undefined;
|
|
12
35
|
export declare function createClientReferencePreloader(options: ClientReferencePreloaderOptions): ClientReferencePreloader;
|
|
13
36
|
//#endregion
|
|
@@ -1,27 +1,50 @@
|
|
|
1
|
+
import { shareIsolatePromise } from "./isolate-shared-promise.js";
|
|
1
2
|
//#region src/server/app-client-reference-preloader.ts
|
|
2
3
|
const resolvedPreload = Promise.resolve();
|
|
4
|
+
/**
|
|
5
|
+
* The client references a render of `routePattern` preloads, or of no route
|
|
6
|
+
* when it is null. Undefined, meaning every reference, without a plan or a
|
|
7
|
+
* route to look up, or for a pattern the plan doesn't know.
|
|
8
|
+
*/
|
|
9
|
+
function resolveRouteClientReferences(plan, routePattern) {
|
|
10
|
+
if (!plan || routePattern === void 0) return void 0;
|
|
11
|
+
let files;
|
|
12
|
+
if (routePattern === null) files = plan.routeless;
|
|
13
|
+
else if (Object.hasOwn(plan.routes, routePattern)) files = plan.routes[routePattern];
|
|
14
|
+
else return;
|
|
15
|
+
const indices = new Set(plan.always);
|
|
16
|
+
for (const file of files) for (const index of plan.files[file]) indices.add(index);
|
|
17
|
+
return Array.from(indices, (index) => plan.references[index]);
|
|
18
|
+
}
|
|
3
19
|
function createClientReferencePreloader(options) {
|
|
4
20
|
let allReferencesPreloaded = false;
|
|
5
21
|
let allReferencesPreloadPromise = null;
|
|
6
22
|
const preloadedReferences = /* @__PURE__ */ new Set();
|
|
7
23
|
const referencePreloadPromises = /* @__PURE__ */ new Map();
|
|
8
24
|
function preloadReference(id, clientRequire) {
|
|
9
|
-
if (preloadedReferences.has(id)) return resolvedPreload;
|
|
10
25
|
const existing = referencePreloadPromises.get(id);
|
|
11
26
|
if (existing) return existing;
|
|
12
|
-
const
|
|
27
|
+
const loading = clientRequire(id);
|
|
28
|
+
const preloadPromise = shareIsolatePromise(loading.then((value) => {
|
|
29
|
+
loading.status = "fulfilled";
|
|
30
|
+
loading.value = value;
|
|
31
|
+
}, (error) => {
|
|
32
|
+
loading.status = "rejected";
|
|
33
|
+
loading.reason = error;
|
|
34
|
+
throw error;
|
|
35
|
+
}).catch((error) => {
|
|
13
36
|
options.onPreloadError?.(id, error);
|
|
14
37
|
}).then(() => {
|
|
15
38
|
preloadedReferences.add(id);
|
|
16
39
|
}).finally(() => {
|
|
17
40
|
referencePreloadPromises.delete(id);
|
|
18
|
-
});
|
|
41
|
+
}));
|
|
19
42
|
referencePreloadPromises.set(id, preloadPromise);
|
|
20
43
|
return preloadPromise;
|
|
21
44
|
}
|
|
22
45
|
function preloadReferenceSet(referenceIds, refs, clientRequire) {
|
|
23
46
|
const pending = [];
|
|
24
|
-
for (const id of referenceIds) if (Object.hasOwn(refs, id)) pending.push(preloadReference(id, clientRequire));
|
|
47
|
+
for (const id of referenceIds) if (Object.hasOwn(refs, id) && !preloadedReferences.has(id)) pending.push(preloadReference(id, clientRequire));
|
|
25
48
|
if (pending.length === 0) return resolvedPreload;
|
|
26
49
|
return Promise.all(pending).then(() => {});
|
|
27
50
|
}
|
|
@@ -32,13 +55,13 @@ function createClientReferencePreloader(options) {
|
|
|
32
55
|
if (referenceIds) return preloadReferenceSet(referenceIds, refs, clientRequire);
|
|
33
56
|
if (allReferencesPreloaded) return resolvedPreload;
|
|
34
57
|
if (allReferencesPreloadPromise) return allReferencesPreloadPromise;
|
|
35
|
-
allReferencesPreloadPromise = preloadReferenceSet(Object.keys(refs), refs, clientRequire).then(() => {
|
|
58
|
+
allReferencesPreloadPromise = shareIsolatePromise(preloadReferenceSet(Object.keys(refs), refs, clientRequire).then(() => {
|
|
36
59
|
allReferencesPreloaded = true;
|
|
37
60
|
}).finally(() => {
|
|
38
61
|
allReferencesPreloadPromise = null;
|
|
39
|
-
});
|
|
62
|
+
}));
|
|
40
63
|
return allReferencesPreloadPromise;
|
|
41
64
|
} };
|
|
42
65
|
}
|
|
43
66
|
//#endregion
|
|
44
|
-
export { createClientReferencePreloader };
|
|
67
|
+
export { createClientReferencePreloader, resolveRouteClientReferences };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { runOutsideRequestScopes } from "../shims/internal/als-registry.js";
|
|
2
|
+
import { shareIsolatePromise } from "./isolate-shared-promise.js";
|
|
2
3
|
import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
|
|
3
4
|
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
4
5
|
import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
|
|
@@ -17,7 +18,7 @@ function createAppFallbackRenderer(options) {
|
|
|
17
18
|
let globalNotFoundModulePromise = null;
|
|
18
19
|
function resolveGlobalNotFoundModule() {
|
|
19
20
|
if (!loadGlobalNotFoundModule) return null;
|
|
20
|
-
if (globalNotFoundModulePromise === null) globalNotFoundModulePromise = runOutsideRequestScopes(() => Promise.resolve().then(loadGlobalNotFoundModule));
|
|
21
|
+
if (globalNotFoundModulePromise === null) globalNotFoundModulePromise = shareIsolatePromise(runOutsideRequestScopes(() => Promise.resolve().then(loadGlobalNotFoundModule)));
|
|
21
22
|
return globalNotFoundModulePromise;
|
|
22
23
|
}
|
|
23
24
|
return {
|
|
@@ -50,6 +50,12 @@ export type ApplyAppMiddlewareResult = {
|
|
|
50
50
|
search: string | null;
|
|
51
51
|
} | {
|
|
52
52
|
kind: "response";
|
|
53
|
+
/**
|
|
54
|
+
* True when `response` proxies a middleware external rewrite. It carries
|
|
55
|
+
* middleware's headers, and the caller still stages next.config headers
|
|
56
|
+
* beneath them.
|
|
57
|
+
*/
|
|
58
|
+
externalRewrite?: boolean;
|
|
53
59
|
/** Present on real middleware results; optional for older generated callers. */
|
|
54
60
|
matched?: boolean;
|
|
55
61
|
/** True when this pathname can match middleware for some request context. */
|
|
@@ -6,7 +6,7 @@ import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
|
6
6
|
import { cloneRequestWithHeaders, processMiddlewareHeaders } from "./request-pipeline.js";
|
|
7
7
|
import { executeMiddleware } from "./middleware-runtime.js";
|
|
8
8
|
import { applyMiddlewareRequestHeaders, setHeadersContext } from "../shims/headers.js";
|
|
9
|
-
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
9
|
+
import { mergeMiddlewareResponseHeaders, withExternalRewriteResponseHeaders } from "./middleware-response-headers.js";
|
|
10
10
|
import { setNavigationContext } from "../shims/navigation-context-accessors.js";
|
|
11
11
|
//#region src/server/app-middleware.ts
|
|
12
12
|
const FLIGHT_HEADER_SET = new Set(FLIGHT_HEADERS);
|
|
@@ -92,19 +92,15 @@ async function proxyExternalMiddlewareRewrite(request, rewriteUrl, context) {
|
|
|
92
92
|
const proxyResponse = await proxyExternalRequest(proxyRequest, rewriteUrl);
|
|
93
93
|
const headers = new Headers(proxyResponse.headers);
|
|
94
94
|
processMiddlewareHeaders(headers);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
statusText: proxyResponse.statusText,
|
|
98
|
-
headers
|
|
99
|
-
});
|
|
100
|
-
const middlewareHeaders = new Headers(context.headers);
|
|
95
|
+
const stagedHeaders = new Headers();
|
|
96
|
+
const middlewareHeaders = new Headers(context.headers ?? void 0);
|
|
101
97
|
processMiddlewareHeaders(middlewareHeaders);
|
|
102
|
-
mergeMiddlewareResponseHeaders(
|
|
103
|
-
return new Response(proxyResponse.body, {
|
|
98
|
+
mergeMiddlewareResponseHeaders(stagedHeaders, middlewareHeaders);
|
|
99
|
+
return withExternalRewriteResponseHeaders(new Response(proxyResponse.body, {
|
|
104
100
|
status: proxyResponse.status,
|
|
105
101
|
statusText: proxyResponse.statusText,
|
|
106
102
|
headers
|
|
107
|
-
});
|
|
103
|
+
}), stagedHeaders, middlewareHeaders.getSetCookie());
|
|
108
104
|
}
|
|
109
105
|
function validationResponseWithMiddlewareHeaders(response, context) {
|
|
110
106
|
if (!context.headers) return response;
|
|
@@ -171,6 +167,7 @@ async function applyAppMiddleware(options) {
|
|
|
171
167
|
const externalRequest = options.externalRewriteRequest ?? options.request;
|
|
172
168
|
return {
|
|
173
169
|
kind: "response",
|
|
170
|
+
externalRewrite: true,
|
|
174
171
|
matched,
|
|
175
172
|
pathnameEligible,
|
|
176
173
|
response: await proxyExternalMiddlewareRewrite(externalRequest, forwarded.rewriteUrl, options.context)
|
|
@@ -248,6 +245,7 @@ async function applyAppMiddleware(options) {
|
|
|
248
245
|
const externalRequest = options.externalRewriteRequest ?? options.request;
|
|
249
246
|
return {
|
|
250
247
|
kind: "response",
|
|
248
|
+
externalRewrite: true,
|
|
251
249
|
matched,
|
|
252
250
|
pathnameEligible,
|
|
253
251
|
response: await proxyExternalMiddlewareRewrite(externalRequest, result.rewriteUrl, options.context)
|