vinext 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +41 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.js +73 -14
- package/dist/config/next-config.d.ts +46 -4
- package/dist/config/next-config.js +147 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +180 -99
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +64 -5
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +53 -8
- package/dist/entries/pages-server-entry.js +41 -5
- package/dist/index.js +200 -62
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/optimize-imports.d.ts +2 -1
- package/dist/plugins/optimize-imports.js +11 -9
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/routing/app-route-graph.d.ts +2 -1
- package/dist/routing/app-route-graph.js +44 -14
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +22 -1
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +19 -10
- package/dist/server/app-browser-entry.js +167 -90
- package/dist/server/app-browser-error.d.ts +10 -6
- package/dist/server/app-browser-error.js +43 -8
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +4 -2
- package/dist/server/app-browser-navigation-controller.js +23 -2
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -0
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-optimistic-routing.js +2 -2
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +27 -14
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +62 -1
- package/dist/server/app-page-dispatch.d.ts +26 -0
- package/dist/server/app-page-dispatch.js +149 -92
- package/dist/server/app-page-element-builder.d.ts +1 -0
- package/dist/server/app-page-element-builder.js +5 -2
- package/dist/server/app-page-execution.d.ts +6 -1
- package/dist/server/app-page-execution.js +21 -1
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +12 -1
- package/dist/server/app-page-render.js +42 -4
- package/dist/server/app-page-request.d.ts +2 -0
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +14 -5
- package/dist/server/app-page-stream.d.ts +15 -3
- package/dist/server/app-page-stream.js +11 -5
- package/dist/server/app-pages-bridge.d.ts +18 -0
- package/dist/server/app-pages-bridge.js +22 -5
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +25 -0
- package/dist/server/app-rsc-handler.js +154 -54
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +2 -0
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +42 -13
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +83 -10
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +244 -51
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/navigation-planner.d.ts +133 -30
- package/dist/server/navigation-planner.js +114 -0
- package/dist/server/navigation-trace.d.ts +8 -1
- package/dist/server/navigation-trace.js +8 -1
- package/dist/server/pages-api-route.d.ts +6 -0
- package/dist/server/pages-api-route.js +13 -2
- package/dist/server/pages-asset-tags.d.ts +2 -1
- package/dist/server/pages-asset-tags.js +6 -2
- package/dist/server/pages-data-route.d.ts +8 -1
- package/dist/server/pages-data-route.js +11 -2
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-node-compat.js +2 -2
- package/dist/server/pages-page-data.d.ts +11 -2
- package/dist/server/pages-page-data.js +204 -33
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +59 -22
- package/dist/server/pages-page-response.d.ts +2 -1
- package/dist/server/pages-page-response.js +7 -4
- package/dist/server/pages-request-pipeline.d.ts +1 -0
- package/dist/server/pages-request-pipeline.js +73 -36
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.js +9 -3
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/cache-runtime.js +3 -2
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/dynamic-preload-chunks.js +6 -4
- package/dist/shims/error-boundary.d.ts +2 -0
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +3 -2
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +45 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/headers.js +29 -4
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.js +8 -17
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +12 -5
- package/dist/shims/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +61 -31
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +13 -2
- package/dist/shims/router.js +419 -128
- package/dist/shims/server.d.ts +16 -1
- package/dist/shims/server.js +44 -12
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +7 -1
- package/dist/utils/path.js +9 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getPagesNavigationContext } from "./pages-router-accessor.js";
|
|
2
|
+
import { getClientNavigationState, getNavigationContext, useClientNavigationRenderSnapshot } from "../navigation.js";
|
|
3
|
+
//#region src/shims/internal/navigation-untracked.ts
|
|
4
|
+
/**
|
|
5
|
+
* Internal navigation-untracked pathname hook.
|
|
6
|
+
*
|
|
7
|
+
* Used by `unstable_catchError` error boundaries to avoid subscribing to
|
|
8
|
+
* pathname changes. This is NOT part of the public `next/navigation` API.
|
|
9
|
+
*
|
|
10
|
+
* Ported from Next.js:
|
|
11
|
+
* https://github.com/vercel/next.js/blob/v16.2.6/packages/next/src/client/components/navigation-untracked.ts
|
|
12
|
+
*/
|
|
13
|
+
const isServer = typeof window === "undefined";
|
|
14
|
+
function getPathnameSnapshot() {
|
|
15
|
+
const pagesCtx = getPagesNavigationContext();
|
|
16
|
+
if (pagesCtx) return pagesCtx.pathname;
|
|
17
|
+
return getClientNavigationState()?.cachedPathname ?? "/";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns the current pathname without registering it as a tracked render
|
|
21
|
+
* dependency. Unlike `usePathname()`, this does not use `useSyncExternalStore`
|
|
22
|
+
* and therefore does not cause the component to re-render on navigation.
|
|
23
|
+
*
|
|
24
|
+
* Server: returns the pathname from context, or `"/"` when no navigation context
|
|
25
|
+
* is available (the client will hydrate with the real value). The `"/"` fallback
|
|
26
|
+
* deliberately matches vinext's `usePathname()` behavior rather than Next.js's
|
|
27
|
+
* null context default. Returns `null` only when the render is a missing-params
|
|
28
|
+
* shell — vinext does not yet implement fallback-route-param detection, so this
|
|
29
|
+
* path is not currently reachable.
|
|
30
|
+
*
|
|
31
|
+
* Client: prefers the render snapshot **only during an active navigation**
|
|
32
|
+
* transition (`navigationSnapshotActiveCount > 0`) so the hook returns the
|
|
33
|
+
* pending URL, not the stale committed one. After commit, falls back to the
|
|
34
|
+
* cached pathname so user `pushState`/`replaceState` calls are immediately
|
|
35
|
+
* reflected.
|
|
36
|
+
*
|
|
37
|
+
* Used by `unstable_catchError` error boundaries to avoid unnecessary re-renders.
|
|
38
|
+
*
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
function useUntrackedPathname() {
|
|
42
|
+
if (isServer) {
|
|
43
|
+
const ctx = getNavigationContext();
|
|
44
|
+
if (ctx) return ctx.pathname;
|
|
45
|
+
const pagesCtx = getPagesNavigationContext();
|
|
46
|
+
return pagesCtx ? pagesCtx.pathname : "/";
|
|
47
|
+
}
|
|
48
|
+
const renderSnapshot = useClientNavigationRenderSnapshot();
|
|
49
|
+
if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.pathname;
|
|
50
|
+
const pagesCtx = getPagesNavigationContext();
|
|
51
|
+
if (pagesCtx) return pagesCtx.pathname;
|
|
52
|
+
return getPathnameSnapshot();
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { useUntrackedPathname };
|
|
@@ -43,10 +43,15 @@ type PagesDataTarget = {
|
|
|
43
43
|
*/
|
|
44
44
|
declare function resolvePagesDataNavigationTarget(browserUrl: string, basePath: string): PagesDataTarget | null;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* Prefetch the data JSON and kick off the code-split loader so the chunk is
|
|
47
|
+
* warm by the time the user clicks.
|
|
48
48
|
*
|
|
49
49
|
* Used by both `Router.prefetch()` and `<Link>` hover/viewport prefetch. The
|
|
50
|
+
* JSON request uses `fetch()` rather than `<link rel="prefetch">` so it can
|
|
51
|
+
* carry Next.js's `x-deployment-id` skew-protection header. The in-flight
|
|
52
|
+
* request is shared with a racing navigation; after it settles, the browser's
|
|
53
|
+
* normal HTTP cache remains responsible for reuse.
|
|
54
|
+
*
|
|
50
55
|
* loader's returned Promise is intentionally discarded — `import()` caches the
|
|
51
56
|
* result, so a subsequent navigation re-invocation hits the cache without
|
|
52
57
|
* paying for a second round trip. Errors are swallowed: prefetch is
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { stripBasePath } from "../../utils/base-path.js";
|
|
2
2
|
import { getLocalePathPrefix } from "../../utils/domain-locale.js";
|
|
3
3
|
import { buildPagesDataHref, matchPagesPattern } from "./pages-data-url.js";
|
|
4
|
+
import { dedupedPagesDataFetch } from "./pages-data-fetch-dedup.js";
|
|
5
|
+
import { NEXT_DEPLOYMENT_ID_HEADER, getDeploymentId } from "../../utils/deployment-id.js";
|
|
4
6
|
//#region src/shims/internal/pages-data-target.ts
|
|
5
7
|
/**
|
|
6
8
|
* Shared decision helper for the Pages Router `/_next/data/<id>/<page>.json`
|
|
@@ -66,10 +68,15 @@ function resolvePagesDataNavigationTarget(browserUrl, basePath) {
|
|
|
66
68
|
};
|
|
67
69
|
}
|
|
68
70
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
+
* Prefetch the data JSON and kick off the code-split loader so the chunk is
|
|
72
|
+
* warm by the time the user clicks.
|
|
71
73
|
*
|
|
72
74
|
* Used by both `Router.prefetch()` and `<Link>` hover/viewport prefetch. The
|
|
75
|
+
* JSON request uses `fetch()` rather than `<link rel="prefetch">` so it can
|
|
76
|
+
* carry Next.js's `x-deployment-id` skew-protection header. The in-flight
|
|
77
|
+
* request is shared with a racing navigation; after it settles, the browser's
|
|
78
|
+
* normal HTTP cache remains responsible for reuse.
|
|
79
|
+
*
|
|
73
80
|
* loader's returned Promise is intentionally discarded — `import()` caches the
|
|
74
81
|
* result, so a subsequent navigation re-invocation hits the cache without
|
|
75
82
|
* paying for a second round trip. Errors are swallowed: prefetch is
|
|
@@ -77,12 +84,14 @@ function resolvePagesDataNavigationTarget(browserUrl, basePath) {
|
|
|
77
84
|
*/
|
|
78
85
|
function prefetchPagesData(target) {
|
|
79
86
|
if (typeof document === "undefined") return;
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
const headers = {
|
|
88
|
+
Accept: "application/json",
|
|
89
|
+
purpose: "prefetch",
|
|
90
|
+
"x-nextjs-data": "1"
|
|
91
|
+
};
|
|
92
|
+
const deploymentId = getDeploymentId();
|
|
93
|
+
if (deploymentId) headers[NEXT_DEPLOYMENT_ID_HEADER] = deploymentId;
|
|
94
|
+
dedupedPagesDataFetch(target.dataHref, { headers }).catch(() => {});
|
|
86
95
|
target.loader().catch(() => {});
|
|
87
96
|
}
|
|
88
97
|
//#endregion
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/shims/internal/pages-router-accessor.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared Pages Router navigation accessor.
|
|
4
|
+
*
|
|
5
|
+
* Both `next/navigation` (usePathname/useParams/useSearchParams) and the
|
|
6
|
+
* internal `useUntrackedPathname` read from the same global Symbol. Keeping
|
|
7
|
+
* the lookup in one place avoids the Symbol string and the error-handling
|
|
8
|
+
* shape from drifting across modules.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
type PagesNavigationContext = {
|
|
13
|
+
pathname: string | null;
|
|
14
|
+
searchParams: URLSearchParams;
|
|
15
|
+
params: Record<string, string | string[]> | null;
|
|
16
|
+
};
|
|
17
|
+
declare function getPagesNavigationContext(): PagesNavigationContext | null;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { PagesNavigationContext, getPagesNavigationContext };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/shims/internal/pages-router-accessor.ts
|
|
2
|
+
const PAGES_NAVIGATION_ACCESSOR_KEY = Symbol.for("vinext.navigation.pagesNavigationContextAccessor");
|
|
3
|
+
function getPagesNavigationContext() {
|
|
4
|
+
const accessor = globalThis[PAGES_NAVIGATION_ACCESSOR_KEY];
|
|
5
|
+
if (!accessor) return null;
|
|
6
|
+
try {
|
|
7
|
+
return accessor();
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { getPagesNavigationContext };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextRouter } from "../router.js";
|
|
2
|
+
import { Context } from "react";
|
|
2
3
|
|
|
3
4
|
//#region src/shims/internal/router-context.d.ts
|
|
4
|
-
declare const RouterContext:
|
|
5
|
+
declare const RouterContext: Context<NextRouter | null>;
|
|
5
6
|
//#endregion
|
|
6
7
|
export { RouterContext };
|
|
@@ -6,6 +6,8 @@ import { createContext } from "react";
|
|
|
6
6
|
* Used by: some testing utilities and older libraries.
|
|
7
7
|
* Provides the Pages Router context.
|
|
8
8
|
*/
|
|
9
|
-
const
|
|
9
|
+
const ROUTER_CONTEXT_KEY = Symbol.for("vinext.routerContext");
|
|
10
|
+
const globalState = globalThis;
|
|
11
|
+
const RouterContext = globalState[ROUTER_CONTEXT_KEY] ?? (globalState[ROUTER_CONTEXT_KEY] = createContext(null));
|
|
10
12
|
//#endregion
|
|
11
13
|
export { RouterContext };
|
package/dist/shims/link.js
CHANGED
|
@@ -8,9 +8,10 @@ import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "../server/app-rsc-re
|
|
|
8
8
|
import "../server/app-elements.js";
|
|
9
9
|
import { addLocalePrefix, getDomainLocaleUrl } from "../utils/domain-locale.js";
|
|
10
10
|
import { prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
11
|
-
import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
|
|
12
|
-
import { isAbsoluteOrProtocolRelativeUrl, normalizePathTrailingSlash, resolveRelativeHref, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
13
11
|
import { appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
12
|
+
import { resolveHybridClientRouteOwner } from "./internal/hybrid-client-route-owner.js";
|
|
13
|
+
import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
|
|
14
|
+
import { isAbsoluteOrProtocolRelativeUrl, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
14
15
|
import { getCurrentBrowserLocale } from "./client-locale.js";
|
|
15
16
|
import { getCurrentRoutePathnameForWarning } from "./internal/route-pattern-for-warning.js";
|
|
16
17
|
import { getNavigationRuntime, hasAppNavigationRuntime, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
@@ -122,7 +123,7 @@ function getLinkPrefetchRouterMode() {
|
|
|
122
123
|
}
|
|
123
124
|
function resolveMatchedAutoAppRoutePrefetch(route) {
|
|
124
125
|
return {
|
|
125
|
-
cacheForNavigation: !
|
|
126
|
+
cacheForNavigation: !route.canPrefetchLoadingShell,
|
|
126
127
|
prefetchShellFirst: !route.isDynamic,
|
|
127
128
|
shouldPrefetch: true
|
|
128
129
|
};
|
|
@@ -189,6 +190,8 @@ function prefetchUrl(href, mode, priority = "low") {
|
|
|
189
190
|
} : window.requestIdleCallback ?? ((fn) => setTimeout(fn, 100)))(() => {
|
|
190
191
|
(async () => {
|
|
191
192
|
if (hasAppNavigationRuntime()) {
|
|
193
|
+
const hybridOwner = resolveHybridClientRouteOwner(prefetchHref, __basePath);
|
|
194
|
+
if (hybridOwner === "pages" || hybridOwner === "document") return;
|
|
192
195
|
const autoPrefetch = mode === "auto" ? resolveAutoAppRoutePrefetch(prefetchHref) : {
|
|
193
196
|
cacheForNavigation: true,
|
|
194
197
|
prefetchShellFirst: true,
|
|
@@ -490,7 +493,6 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
490
493
|
navigateHref = localPath;
|
|
491
494
|
}
|
|
492
495
|
e.preventDefault();
|
|
493
|
-
const absoluteHref = resolveRelativeHref(navigateHref, window.location.href, __basePath);
|
|
494
496
|
const absoluteFullHref = toBrowserNavigationHref(navigateHref, window.location.href, __basePath);
|
|
495
497
|
if (onNavigate) try {
|
|
496
498
|
const navUrl = new URL(absoluteFullHref, window.location.origin);
|
|
@@ -507,6 +509,11 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
507
509
|
onNavigate(navEvent);
|
|
508
510
|
if (navEvent.defaultPrevented) return;
|
|
509
511
|
} catch {}
|
|
512
|
+
if (getNavigationRuntime()?.functions.navigate && ["pages", "document"].includes(resolveHybridClientRouteOwner(navigateHref, __basePath) ?? "")) {
|
|
513
|
+
if (replace) window.location.replace(absoluteFullHref);
|
|
514
|
+
else window.location.assign(absoluteFullHref);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
510
517
|
if (getNavigationRuntime()?.functions.navigate) {
|
|
511
518
|
const setter = setPendingRef.current;
|
|
512
519
|
if (setter) setLinkForCurrentNavigation(setter);
|
|
@@ -521,7 +528,7 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
521
528
|
} else try {
|
|
522
529
|
const Router = (await import("next/router.js")).default;
|
|
523
530
|
await navigatePagesRouterLink(Router, {
|
|
524
|
-
href:
|
|
531
|
+
href: navigateHref,
|
|
525
532
|
replace,
|
|
526
533
|
scroll,
|
|
527
534
|
shallow,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AppRouterScrollIntent } from "./app-router-scroll-state.js";
|
|
1
2
|
import { NavigationRuntimeVisibleCommitMode } from "../client/navigation-runtime.js";
|
|
2
3
|
import { AppRouterInstance, NavigateOptions, PrefetchOptions as PrefetchOptions$1 } from "./internal/app-router-context.js";
|
|
3
4
|
import { ReadonlyURLSearchParams } from "./readonly-url-search-params.js";
|
|
@@ -97,7 +98,9 @@ declare function getPrefetchedUrls(): Set<string>;
|
|
|
97
98
|
declare function resolveCachedRscResponseTtlMs(cached: Pick<CachedRscResponse, "dynamicStaleTimeSeconds">, fallbackTtlMs: number): number;
|
|
98
99
|
declare function resolveCachedRscResponseExpiresAt(timestamp: number, cached: Pick<CachedRscResponse, "dynamicStaleTimeSeconds" | "expiresAt">, fallbackTtlMs: number): number;
|
|
99
100
|
declare function resolvePrefetchCacheEntryMountedSlotsHeader(entry: PrefetchCacheEntry): string | null;
|
|
100
|
-
declare function hasPrefetchCacheEntryForNavigation(rscUrl: string, interceptionContext?: string | null, mountedSlotsHeader?: string | null
|
|
101
|
+
declare function hasPrefetchCacheEntryForNavigation(rscUrl: string, interceptionContext?: string | null, mountedSlotsHeader?: string | null, options?: {
|
|
102
|
+
notifyInvalidation?: boolean;
|
|
103
|
+
}): boolean;
|
|
101
104
|
declare function invalidatePrefetchCache(): void;
|
|
102
105
|
/**
|
|
103
106
|
* Store a prefetched RSC response in the cache by snapshotting it to an
|
|
@@ -205,6 +208,8 @@ type ClientNavigationRenderSnapshot = {
|
|
|
205
208
|
params: Record<string, string | string[]>;
|
|
206
209
|
};
|
|
207
210
|
declare function getClientNavigationRenderContext(): React$1.Context<ClientNavigationRenderSnapshot | null> | null;
|
|
211
|
+
/** @internal */
|
|
212
|
+
declare function useClientNavigationRenderSnapshot(): ClientNavigationRenderSnapshot | null;
|
|
208
213
|
declare function createClientNavigationRenderSnapshot(href: string, params: Record<string, string | string[]>): ClientNavigationRenderSnapshot;
|
|
209
214
|
declare function createSnapshotPathAndSearch(snapshot: ClientNavigationRenderSnapshot): string;
|
|
210
215
|
declare function setClientParams(params: Record<string, string | string[]>): void;
|
|
@@ -255,6 +260,7 @@ declare function replaceHistoryStateWithoutNotify(data: unknown, unused: string,
|
|
|
255
260
|
* history.replaceState interception (which would cause spurious re-renders).
|
|
256
261
|
*/
|
|
257
262
|
declare function saveScrollPosition(): void;
|
|
263
|
+
declare function applyAppRouterScrollFallback(intent: AppRouterScrollIntent): void;
|
|
258
264
|
/**
|
|
259
265
|
* Navigate to a URL, handling external URLs, hash-only changes, and RSC navigation.
|
|
260
266
|
*/
|
|
@@ -565,4 +571,4 @@ declare function isDynamicServerError(error: unknown): error is DynamicServerErr
|
|
|
565
571
|
*/
|
|
566
572
|
declare function unstable_rethrow(error: unknown): void;
|
|
567
573
|
//#endregion
|
|
568
|
-
export { BailoutToCSRError, CachedRscResponse, ClientNavigationRenderSnapshot, DynamicServerError, GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, NavigationContext, PREFETCH_CACHE_TTL, PrefetchCacheEntry, PrefetchOptions, ReadonlyURLSearchParams, RedirectType, SegmentMap, ServerInsertedHTMLContext, UnrecognizedActionError, __basePath, _registerStateAccessors, activateNavigationSnapshot, appRouterInstance, clearPendingPathname, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getBfcacheIdMapContext, getBfcacheSegmentIdContext, getClientNavigationRenderContext, getClientNavigationState, getClientParams, getCurrentInterceptionContext, getCurrentNextUrl, getLayoutSegmentContext, getMountedSlotsHeader, getNavigationContext, getPrefetchCache, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, navigateClientSide, notFound, permanentRedirect, prefetchRscResponse, pushHistoryStateWithoutNotify, redirect, renderServerInsertedHTML, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveCachedRscResponseExpiresAt, resolveCachedRscResponseTtlMs, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, storePrefetchResponse, unauthorized, unstable_isUnrecognizedActionError, unstable_rethrow, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
|
|
574
|
+
export { BailoutToCSRError, CachedRscResponse, ClientNavigationRenderSnapshot, DynamicServerError, GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, NavigationContext, PREFETCH_CACHE_TTL, PrefetchCacheEntry, PrefetchOptions, ReadonlyURLSearchParams, RedirectType, SegmentMap, ServerInsertedHTMLContext, UnrecognizedActionError, __basePath, _registerStateAccessors, activateNavigationSnapshot, appRouterInstance, applyAppRouterScrollFallback, clearPendingPathname, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getBfcacheIdMapContext, getBfcacheSegmentIdContext, getClientNavigationRenderContext, getClientNavigationState, getClientParams, getCurrentInterceptionContext, getCurrentNextUrl, getLayoutSegmentContext, getMountedSlotsHeader, getNavigationContext, getPrefetchCache, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, navigateClientSide, notFound, permanentRedirect, prefetchRscResponse, pushHistoryStateWithoutNotify, redirect, renderServerInsertedHTML, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveCachedRscResponseExpiresAt, resolveCachedRscResponseTtlMs, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, storePrefetchResponse, unauthorized, unstable_isUnrecognizedActionError, unstable_rethrow, useClientNavigationRenderSnapshot, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
|
package/dist/shims/navigation.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER } from "../server/headers.js";
|
|
3
3
|
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
4
|
+
import { markPprFallbackShellDynamicBoundary } from "./ppr-fallback-shell.js";
|
|
4
5
|
import { AppElementsWire } from "../server/app-elements-wire.js";
|
|
5
6
|
import "../server/app-elements.js";
|
|
6
7
|
import { AppRouterContext } from "./internal/app-router-context.js";
|
|
8
|
+
import { resolveHybridClientRouteOwner } from "./internal/hybrid-client-route-owner.js";
|
|
7
9
|
import { isAbsoluteOrProtocolRelativeUrl, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
8
10
|
import { retryScrollTo, scrollToHashTarget } from "./hash-scroll.js";
|
|
9
11
|
import { getNavigationRuntime, hasAppNavigationRuntime } from "../client/navigation-runtime.js";
|
|
10
12
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
13
|
+
import { clearAppNavigationFailureTarget, stageAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
|
|
11
14
|
import { PUBLIC_INITIAL_BFCACHE_ID } from "../server/app-bfcache-id.js";
|
|
12
15
|
import { resolveManifestNavigationInterceptionContext } from "../server/app-browser-interception-context.js";
|
|
13
16
|
import { createExternalHistoryStatePreservingMetadata, createHashOnlyHistoryStatePreservingNavigationMetadata } from "../server/app-history-state.js";
|
|
@@ -15,7 +18,8 @@ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscR
|
|
|
15
18
|
import { hasPendingAppRouterPageRedirect } from "../server/app-browser-mpa-navigation.js";
|
|
16
19
|
import { navigationPlanner } from "../server/navigation-planner.js";
|
|
17
20
|
import { ReadonlyURLSearchParams } from "./readonly-url-search-params.js";
|
|
18
|
-
import {
|
|
21
|
+
import { getPagesNavigationContext } from "./internal/pages-router-accessor.js";
|
|
22
|
+
import { beginAppRouterScrollIntent, clearAppRouterScrollIntent, consumeAppRouterScrollIntent, getPendingAppRouterScrollIntent } from "./app-router-scroll-state.js";
|
|
19
23
|
import { UnrecognizedActionError, unstable_isUnrecognizedActionError } from "./unrecognized-action-error.js";
|
|
20
24
|
import * as React$1 from "react";
|
|
21
25
|
//#region src/shims/navigation.ts
|
|
@@ -131,17 +135,7 @@ function _registerStateAccessors(accessors) {
|
|
|
131
135
|
_getInsertedHTMLCallbacks = accessors.getInsertedHTMLCallbacks;
|
|
132
136
|
_clearInsertedHTMLCallbacks = accessors.clearInsertedHTMLCallbacks;
|
|
133
137
|
}
|
|
134
|
-
const PAGES_NAVIGATION_ACCESSOR_KEY = Symbol.for("vinext.navigation.pagesNavigationContextAccessor");
|
|
135
138
|
const PAGES_NAVIGATION_NOTIFY_KEY = Symbol.for("vinext.navigation.pagesNavigationNotify");
|
|
136
|
-
function _getPagesNavigationContext() {
|
|
137
|
-
const accessor = globalThis[PAGES_NAVIGATION_ACCESSOR_KEY];
|
|
138
|
-
if (!accessor) return null;
|
|
139
|
-
try {
|
|
140
|
-
return accessor();
|
|
141
|
-
} catch {
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
139
|
/**
|
|
146
140
|
* Get the navigation context for the current SSR/RSC render.
|
|
147
141
|
* Reads from AsyncLocalStorage when available (concurrent-safe),
|
|
@@ -299,12 +293,12 @@ function findPrefetchCacheEntryForNavigation(rscUrl, interceptionContext, mounte
|
|
|
299
293
|
}
|
|
300
294
|
return null;
|
|
301
295
|
}
|
|
302
|
-
function hasPrefetchCacheEntryForNavigation(rscUrl, interceptionContext = null, mountedSlotsHeader = null) {
|
|
296
|
+
function hasPrefetchCacheEntryForNavigation(rscUrl, interceptionContext = null, mountedSlotsHeader = null, options = {}) {
|
|
303
297
|
const match = findPrefetchCacheEntryForNavigation(rscUrl, interceptionContext, mountedSlotsHeader);
|
|
304
298
|
if (match === null) return false;
|
|
305
299
|
if (match.entry.pending !== void 0) return true;
|
|
306
300
|
if (resolvePrefetchCacheEntryExpiresAt(match.entry) > Date.now()) return true;
|
|
307
|
-
deletePrefetchCacheEntry(getPrefetchCache(), getPrefetchedUrls(), match.cacheKey, match.entry, true);
|
|
301
|
+
deletePrefetchCacheEntry(getPrefetchCache(), getPrefetchedUrls(), match.cacheKey, match.entry, options.notifyInvalidation ?? true);
|
|
308
302
|
return false;
|
|
309
303
|
}
|
|
310
304
|
/**
|
|
@@ -617,7 +611,7 @@ function getReadonlyPagesSearchParams(searchParams) {
|
|
|
617
611
|
* be visible until the next commit.
|
|
618
612
|
*/
|
|
619
613
|
function getPathnameSnapshot() {
|
|
620
|
-
const pagesCtx =
|
|
614
|
+
const pagesCtx = getPagesNavigationContext();
|
|
621
615
|
if (pagesCtx) return pagesCtx.pathname;
|
|
622
616
|
return getClientNavigationState()?.cachedPathname ?? "/";
|
|
623
617
|
}
|
|
@@ -632,7 +626,7 @@ let _cachedEmptyClientSearchParams = null;
|
|
|
632
626
|
*/
|
|
633
627
|
function getSearchParamsSnapshot() {
|
|
634
628
|
if (_getServerContext()) return getServerSearchParamsSnapshot();
|
|
635
|
-
const pagesCtx =
|
|
629
|
+
const pagesCtx = getPagesNavigationContext();
|
|
636
630
|
if (pagesCtx) return getReadonlyPagesSearchParams(pagesCtx.searchParams);
|
|
637
631
|
const cached = getClientNavigationState()?.cachedReadonlySearchParams;
|
|
638
632
|
if (cached) return cached;
|
|
@@ -659,7 +653,7 @@ function syncCommittedUrlStateFromLocation() {
|
|
|
659
653
|
function getServerSearchParamsSnapshot() {
|
|
660
654
|
const ctx = _getServerContext();
|
|
661
655
|
if (!ctx) {
|
|
662
|
-
const pagesCtx =
|
|
656
|
+
const pagesCtx = getPagesNavigationContext();
|
|
663
657
|
if (pagesCtx) return getReadonlyPagesSearchParams(pagesCtx.searchParams);
|
|
664
658
|
if (_cachedEmptyServerSearchParams === null) _cachedEmptyServerSearchParams = new ReadonlyURLSearchParams();
|
|
665
659
|
return _cachedEmptyServerSearchParams;
|
|
@@ -698,6 +692,7 @@ function getClientNavigationRenderContext() {
|
|
|
698
692
|
if (!globalState[_CLIENT_NAV_RENDER_CTX_KEY]) globalState[_CLIENT_NAV_RENDER_CTX_KEY] = React$1.createContext(null);
|
|
699
693
|
return globalState[_CLIENT_NAV_RENDER_CTX_KEY] ?? null;
|
|
700
694
|
}
|
|
695
|
+
/** @internal */
|
|
701
696
|
function useClientNavigationRenderSnapshot() {
|
|
702
697
|
const ctx = getClientNavigationRenderContext();
|
|
703
698
|
if (!ctx || typeof React$1.useContext !== "function") return null;
|
|
@@ -783,14 +778,14 @@ function getClientParamsSnapshot() {
|
|
|
783
778
|
const state = getClientNavigationState();
|
|
784
779
|
const ctx = _getServerContext();
|
|
785
780
|
if (ctx) return ctx.params;
|
|
786
|
-
const pagesCtx =
|
|
781
|
+
const pagesCtx = getPagesNavigationContext();
|
|
787
782
|
if (pagesCtx) return pagesCtx.params;
|
|
788
783
|
return state?.clientParams ?? _EMPTY_PARAMS;
|
|
789
784
|
}
|
|
790
785
|
function getServerParamsSnapshot() {
|
|
791
786
|
const ctx = _getServerContext();
|
|
792
787
|
if (ctx) return ctx.params;
|
|
793
|
-
const pagesCtx =
|
|
788
|
+
const pagesCtx = getPagesNavigationContext();
|
|
794
789
|
if (pagesCtx) return pagesCtx.params;
|
|
795
790
|
return _EMPTY_PARAMS;
|
|
796
791
|
}
|
|
@@ -808,16 +803,17 @@ function subscribeToNavigation(cb) {
|
|
|
808
803
|
*/
|
|
809
804
|
function usePathname() {
|
|
810
805
|
if (isServer) {
|
|
806
|
+
markPprFallbackShellDynamicBoundary();
|
|
811
807
|
const ctx = _getServerContext();
|
|
812
808
|
if (ctx) return ctx.pathname;
|
|
813
|
-
const pagesCtx =
|
|
809
|
+
const pagesCtx = getPagesNavigationContext();
|
|
814
810
|
return pagesCtx ? pagesCtx.pathname : "/";
|
|
815
811
|
}
|
|
816
812
|
const renderSnapshot = useClientNavigationRenderSnapshot();
|
|
817
813
|
const pathname = React$1.useSyncExternalStore(subscribeToNavigation, getPathnameSnapshot, () => {
|
|
818
814
|
const ctx = _getServerContext();
|
|
819
815
|
if (ctx) return ctx.pathname;
|
|
820
|
-
const pagesCtx =
|
|
816
|
+
const pagesCtx = getPagesNavigationContext();
|
|
821
817
|
return pagesCtx ? pagesCtx.pathname : "/";
|
|
822
818
|
});
|
|
823
819
|
if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.pathname;
|
|
@@ -827,7 +823,10 @@ function usePathname() {
|
|
|
827
823
|
* Returns the current search params as a read-only URLSearchParams.
|
|
828
824
|
*/
|
|
829
825
|
function useSearchParams() {
|
|
830
|
-
if (isServer)
|
|
826
|
+
if (isServer) {
|
|
827
|
+
markPprFallbackShellDynamicBoundary();
|
|
828
|
+
return getServerSearchParamsSnapshot();
|
|
829
|
+
}
|
|
831
830
|
const renderSnapshot = useClientNavigationRenderSnapshot();
|
|
832
831
|
const searchParams = React$1.useSyncExternalStore(subscribeToNavigation, getSearchParamsSnapshot, getServerSearchParamsSnapshot);
|
|
833
832
|
if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.searchParams;
|
|
@@ -837,7 +836,10 @@ function useSearchParams() {
|
|
|
837
836
|
* Returns the dynamic params for the current route.
|
|
838
837
|
*/
|
|
839
838
|
function useParams() {
|
|
840
|
-
if (isServer)
|
|
839
|
+
if (isServer) {
|
|
840
|
+
markPprFallbackShellDynamicBoundary();
|
|
841
|
+
return getServerParamsSnapshot();
|
|
842
|
+
}
|
|
841
843
|
const renderSnapshot = useClientNavigationRenderSnapshot();
|
|
842
844
|
const params = React$1.useSyncExternalStore(subscribeToNavigation, getClientParamsSnapshot, getServerParamsSnapshot);
|
|
843
845
|
if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.params;
|
|
@@ -930,8 +932,17 @@ function applyAppRouterScrollFallback(intent) {
|
|
|
930
932
|
scrollToHashTarget(intent.hash);
|
|
931
933
|
return;
|
|
932
934
|
}
|
|
935
|
+
if (intent.targetHoistedInHead) return;
|
|
933
936
|
document.documentElement.scrollTop = 0;
|
|
934
937
|
}
|
|
938
|
+
function scheduleAppRouterScrollFallback(intent) {
|
|
939
|
+
queueMicrotask(() => {
|
|
940
|
+
const pendingIntent = getPendingAppRouterScrollIntent();
|
|
941
|
+
if (pendingIntent === null || pendingIntent.id !== intent.id) return;
|
|
942
|
+
const fallbackIntent = consumeAppRouterScrollIntent(intent);
|
|
943
|
+
if (fallbackIntent) applyAppRouterScrollFallback(fallbackIntent);
|
|
944
|
+
});
|
|
945
|
+
}
|
|
935
946
|
/**
|
|
936
947
|
* Restore scroll position from a history state object (used on popstate).
|
|
937
948
|
*
|
|
@@ -958,6 +969,15 @@ function restoreScrollPosition(state) {
|
|
|
958
969
|
}
|
|
959
970
|
}
|
|
960
971
|
/**
|
|
972
|
+
* Hard-navigate to a URL via `window.location`, preserving push/replace
|
|
973
|
+
* semantics. Used for URLs the App Router cannot serve (Pages-owned
|
|
974
|
+
* targets in a hybrid build) and for catch-all RSC failures.
|
|
975
|
+
*/
|
|
976
|
+
function hardNavigateTo(fullHref, mode) {
|
|
977
|
+
if (mode === "replace") window.location.replace(fullHref);
|
|
978
|
+
else window.location.assign(fullHref);
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
961
981
|
* Navigate to a URL, handling external URLs, hash-only changes, and RSC navigation.
|
|
962
982
|
*/
|
|
963
983
|
async function navigateClientSide(href, mode, scroll, programmaticTransition = false, visibleCommitMode = "transition") {
|
|
@@ -972,14 +992,23 @@ async function navigateClientSide(href, mode, scroll, programmaticTransition = f
|
|
|
972
992
|
await externalNavigate(href, mode);
|
|
973
993
|
return;
|
|
974
994
|
}
|
|
975
|
-
|
|
976
|
-
else window.location.assign(href);
|
|
995
|
+
hardNavigateTo(href, mode);
|
|
977
996
|
await new Promise(() => {});
|
|
978
997
|
return;
|
|
979
998
|
}
|
|
980
999
|
normalizedHref = localPath;
|
|
981
1000
|
}
|
|
1001
|
+
const hybridOwner = resolveHybridClientRouteOwner(normalizedHref, __basePath);
|
|
1002
|
+
if (hybridOwner === "pages" || hybridOwner === "document") {
|
|
1003
|
+
const fullHref = toBrowserNavigationHref(normalizedHref, window.location.href, __basePath);
|
|
1004
|
+
notifyAppRouterTransitionStart(fullHref, mode);
|
|
1005
|
+
if (mode === "push") saveScrollPosition();
|
|
1006
|
+
hardNavigateTo(fullHref, mode);
|
|
1007
|
+
await new Promise(() => {});
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
982
1010
|
const fullHref = toBrowserNavigationHref(normalizedHref, window.location.href, __basePath);
|
|
1011
|
+
stageAppNavigationFailureTarget(fullHref);
|
|
983
1012
|
notifyAppRouterTransitionStart(fullHref, mode);
|
|
984
1013
|
if (mode === "push") saveScrollPosition();
|
|
985
1014
|
const earlyIntent = navigationPlanner.classifyEarlyNavigationIntent({
|
|
@@ -990,7 +1019,9 @@ async function navigateClientSide(href, mode, scroll, programmaticTransition = f
|
|
|
990
1019
|
targetHref: fullHref
|
|
991
1020
|
});
|
|
992
1021
|
if (earlyIntent.kind === "sameDocumentScroll") {
|
|
1022
|
+
clearAppRouterScrollIntent();
|
|
993
1023
|
commitHashOnlyHistoryState(fullHref, earlyIntent.mode, earlyIntent.scroll);
|
|
1024
|
+
clearAppNavigationFailureTarget(fullHref);
|
|
994
1025
|
commitClientNavigationState();
|
|
995
1026
|
if (earlyIntent.scroll) scrollToHashTarget(earlyIntent.hash);
|
|
996
1027
|
return;
|
|
@@ -1001,8 +1032,7 @@ async function navigateClientSide(href, mode, scroll, programmaticTransition = f
|
|
|
1001
1032
|
await mpaNavigate(fullHref, mode);
|
|
1002
1033
|
return;
|
|
1003
1034
|
}
|
|
1004
|
-
|
|
1005
|
-
else window.location.assign(fullHref);
|
|
1035
|
+
hardNavigateTo(fullHref, mode);
|
|
1006
1036
|
await new Promise(() => {});
|
|
1007
1037
|
return;
|
|
1008
1038
|
}
|
|
@@ -1022,10 +1052,7 @@ async function navigateClientSide(href, mode, scroll, programmaticTransition = f
|
|
|
1022
1052
|
if (scrollIntent) consumeAppRouterScrollIntent(scrollIntent);
|
|
1023
1053
|
throw error;
|
|
1024
1054
|
}
|
|
1025
|
-
if (scrollIntent)
|
|
1026
|
-
const fallbackIntent = consumeAppRouterScrollIntent(scrollIntent);
|
|
1027
|
-
if (fallbackIntent) applyAppRouterScrollFallback(fallbackIntent);
|
|
1028
|
-
}
|
|
1055
|
+
if (scrollIntent) scheduleAppRouterScrollFallback(scrollIntent);
|
|
1029
1056
|
}
|
|
1030
1057
|
let scheduledAppRouterNavigationCount = 0;
|
|
1031
1058
|
function trackScheduledAppRouterNavigation() {
|
|
@@ -1117,6 +1144,8 @@ const _appRouter = {
|
|
|
1117
1144
|
if (localPath == null) return;
|
|
1118
1145
|
prefetchHref = localPath;
|
|
1119
1146
|
}
|
|
1147
|
+
const hybridOwner = resolveHybridClientRouteOwner(prefetchHref, __basePath);
|
|
1148
|
+
if (hybridOwner === "pages" || hybridOwner === "document") return;
|
|
1120
1149
|
const fullHref = toBrowserNavigationHref(prefetchHref, window.location.href, __basePath);
|
|
1121
1150
|
const interceptionContext = getPrefetchInterceptionContext(fullHref);
|
|
1122
1151
|
const mountedSlotsHeader = getMountedSlotsHeader();
|
|
@@ -1220,6 +1249,7 @@ function useSelectedLayoutSegment(parallelRoutesKey) {
|
|
|
1220
1249
|
* @param parallelRoutesKey - Which parallel route to read (default: "children")
|
|
1221
1250
|
*/
|
|
1222
1251
|
function useSelectedLayoutSegments(parallelRoutesKey) {
|
|
1252
|
+
if (isServer) markPprFallbackShellDynamicBoundary();
|
|
1223
1253
|
return useChildSegments(parallelRoutesKey);
|
|
1224
1254
|
}
|
|
1225
1255
|
/**
|
|
@@ -1602,4 +1632,4 @@ if (!isServer) {
|
|
|
1602
1632
|
}
|
|
1603
1633
|
}
|
|
1604
1634
|
//#endregion
|
|
1605
|
-
export { BailoutToCSRError, DynamicServerError, GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, PREFETCH_CACHE_TTL, ReadonlyURLSearchParams, RedirectType, ServerInsertedHTMLContext, UnrecognizedActionError, __basePath, _registerStateAccessors, activateNavigationSnapshot, appRouterInstance, clearPendingPathname, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getBfcacheIdMapContext, getBfcacheSegmentIdContext, getClientNavigationRenderContext, getClientNavigationState, getClientParams, getCurrentInterceptionContext, getCurrentNextUrl, getLayoutSegmentContext, getMountedSlotsHeader, getNavigationContext, getPrefetchCache, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, navigateClientSide, notFound, permanentRedirect, prefetchRscResponse, pushHistoryStateWithoutNotify, redirect, renderServerInsertedHTML, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveCachedRscResponseExpiresAt, resolveCachedRscResponseTtlMs, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, storePrefetchResponse, unauthorized, unstable_isUnrecognizedActionError, unstable_rethrow, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
|
|
1635
|
+
export { BailoutToCSRError, DynamicServerError, GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, PREFETCH_CACHE_TTL, ReadonlyURLSearchParams, RedirectType, ServerInsertedHTMLContext, UnrecognizedActionError, __basePath, _registerStateAccessors, activateNavigationSnapshot, appRouterInstance, applyAppRouterScrollFallback, clearPendingPathname, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getBfcacheIdMapContext, getBfcacheSegmentIdContext, getClientNavigationRenderContext, getClientNavigationState, getClientParams, getCurrentInterceptionContext, getCurrentNextUrl, getLayoutSegmentContext, getMountedSlotsHeader, getNavigationContext, getPrefetchCache, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, navigateClientSide, notFound, permanentRedirect, prefetchRscResponse, pushHistoryStateWithoutNotify, redirect, renderServerInsertedHTML, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveCachedRscResponseExpiresAt, resolveCachedRscResponseTtlMs, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, storePrefetchResponse, unauthorized, unstable_isUnrecognizedActionError, unstable_rethrow, useClientNavigationRenderSnapshot, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
//#region src/shims/ppr-fallback-shell.d.ts
|
|
2
2
|
type PprFallbackShellState = {
|
|
3
3
|
abortController: AbortController;
|
|
4
|
+
reactAbortController: AbortController;
|
|
4
5
|
cacheEpoch: number;
|
|
5
6
|
cacheReadyResolvers: Array<() => void>;
|
|
6
7
|
fallbackParamNames: ReadonlySet<string>;
|
|
7
8
|
hasDynamicBoundary: boolean;
|
|
9
|
+
isFinalRenderStarted: boolean;
|
|
8
10
|
isAbortScheduled: boolean;
|
|
9
11
|
pendingAbortCleanup: (() => void) | null;
|
|
10
12
|
pendingCacheReadyCleanup: (() => void) | null;
|
|
@@ -21,9 +23,11 @@ declare function runWithPprFallbackShellState<T>(state: PprFallbackShellState, f
|
|
|
21
23
|
declare function getPprFallbackShellState(): PprFallbackShellState | null;
|
|
22
24
|
declare function trackPprFallbackShellCacheTask<T>(fn: () => Promise<T>, cacheVariant: string): Promise<T>;
|
|
23
25
|
declare function createPprFallbackShellSuspensePromiseForState<T>(state: PprFallbackShellState, expression: string): Promise<T>;
|
|
26
|
+
declare function markPprFallbackShellDynamicBoundary(): void;
|
|
24
27
|
declare function createPprFallbackShellSuspensePromise<T>(expression: string): Promise<T> | null;
|
|
25
28
|
declare function waitForPprFallbackShellCacheReady(state: PprFallbackShellState): Promise<void>;
|
|
26
29
|
declare function preparePprFallbackShellFinalRender(state: PprFallbackShellState): void;
|
|
30
|
+
declare function beginPprFallbackShellFinalRender(state: PprFallbackShellState): void;
|
|
27
31
|
declare function isPprFallbackShellAbortError(error: unknown): boolean;
|
|
28
32
|
//#endregion
|
|
29
|
-
export { PprFallbackShellState, createPprFallbackShellState, createPprFallbackShellSuspensePromise, createPprFallbackShellSuspensePromiseForState, getPprFallbackShellState, isPprFallbackShellAbortError, preparePprFallbackShellFinalRender, runWithPprFallbackShellState, trackPprFallbackShellCacheTask, waitForPprFallbackShellCacheReady };
|
|
33
|
+
export { PprFallbackShellState, beginPprFallbackShellFinalRender, createPprFallbackShellState, createPprFallbackShellSuspensePromise, createPprFallbackShellSuspensePromiseForState, getPprFallbackShellState, isPprFallbackShellAbortError, markPprFallbackShellDynamicBoundary, preparePprFallbackShellFinalRender, runWithPprFallbackShellState, trackPprFallbackShellCacheTask, waitForPprFallbackShellCacheReady };
|