vinext 0.1.7 → 0.2.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 +51 -30
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- package/dist/build/layout-classification.js +1 -1
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +13 -6
- package/dist/build/report.d.ts +13 -2
- package/dist/build/report.js +99 -2
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +10 -1
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- package/dist/cli-args.d.ts +1 -2
- package/dist/cli-args.js +1 -1
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +113 -97
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/client/navigation-runtime.d.ts +2 -0
- package/dist/client/navigation-runtime.js +3 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/config/config-matchers.js +14 -10
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +47 -1
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +89 -15
- package/dist/entries/app-rsc-manifest.js +10 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +16 -1
- package/dist/entries/pages-server-entry.js +6 -2
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +59 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +211 -118
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +839 -0
- package/dist/init-platform.d.ts +40 -0
- package/dist/init-platform.js +195 -0
- package/dist/init.d.ts +16 -38
- package/dist/init.js +208 -97
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
- package/dist/packages/cloudflare/src/deploy-config.js +150 -0
- package/dist/packages/cloudflare/src/deploy-help.js +55 -0
- package/dist/packages/cloudflare/src/deploy.js +276 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.d.ts +27 -1
- package/dist/plugins/ast-utils.js +32 -1
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +29 -4
- package/dist/routing/app-route-graph.js +182 -40
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +8 -0
- package/dist/routing/file-matcher.js +10 -1
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/api-handler.js +9 -14
- package/dist/server/app-browser-action-result.d.ts +4 -1
- package/dist/server/app-browser-action-result.js +8 -1
- package/dist/server/app-browser-entry.js +194 -190
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +60 -31
- package/dist/server/app-browser-server-action-client.d.ts +32 -0
- package/dist/server/app-browser-server-action-client.js +127 -0
- package/dist/server/app-browser-state.d.ts +11 -1
- package/dist/server/app-browser-state.js +25 -8
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +43 -25
- package/dist/server/app-elements-wire.d.ts +9 -2
- package/dist/server/app-elements-wire.js +8 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +4 -3
- package/dist/server/app-fallback-renderer.d.ts +5 -2
- package/dist/server/app-fallback-renderer.js +15 -7
- package/dist/server/app-hydration-cache-publication.d.ts +11 -0
- package/dist/server/app-hydration-cache-publication.js +43 -0
- package/dist/server/app-middleware.d.ts +4 -3
- package/dist/server/app-middleware.js +8 -3
- package/dist/server/app-optimistic-routing.js +11 -4
- package/dist/server/app-page-boundary-render.d.ts +3 -0
- package/dist/server/app-page-boundary-render.js +14 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +10 -3
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +5 -2
- package/dist/server/app-page-dispatch.d.ts +33 -4
- package/dist/server/app-page-dispatch.js +63 -90
- package/dist/server/app-page-element-builder.d.ts +9 -2
- package/dist/server/app-page-element-builder.js +114 -23
- package/dist/server/app-page-head.d.ts +16 -1
- package/dist/server/app-page-head.js +44 -22
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-ppr-runtime.d.ts +7 -0
- package/dist/server/app-page-ppr-runtime.js +70 -0
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +6 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +26 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +92 -15
- package/dist/server/app-page-route-wiring.d.ts +14 -2
- package/dist/server/app-page-route-wiring.js +61 -25
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- package/dist/server/app-page-segment-state.d.ts +2 -1
- package/dist/server/app-page-segment-state.js +3 -1
- package/dist/server/app-page-stream.d.ts +5 -0
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
- package/dist/server/app-route-handler-dispatch.js +1 -0
- package/dist/server/app-route-handler-execution.js +7 -2
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.js +16 -8
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.d.ts +3 -1
- package/dist/server/app-rsc-handler.js +67 -39
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +6 -3
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +12 -0
- package/dist/server/app-segment-config.js +91 -5
- package/dist/server/app-server-action-execution.d.ts +5 -0
- package/dist/server/app-server-action-execution.js +94 -33
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +19 -8
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -1
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-route-files.js +4 -0
- package/dist/server/dev-server.js +19 -18
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/fetch-handler.d.ts +2 -0
- package/dist/server/fetch-handler.js +18 -0
- package/dist/server/headers.d.ts +5 -15
- package/dist/server/headers.js +4 -15
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/implicit-tags.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -2
- package/dist/server/metadata-routes.d.ts +3 -1
- package/dist/server/metadata-routes.js +12 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-node-compat.d.ts +8 -1
- package/dist/server/pages-node-compat.js +32 -4
- package/dist/server/pages-page-data.d.ts +24 -1
- package/dist/server/pages-page-data.js +45 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +19 -12
- package/dist/server/pages-page-response.d.ts +7 -0
- package/dist/server/pages-page-response.js +4 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- package/dist/server/pages-router-entry.d.ts +30 -0
- package/dist/server/pages-router-entry.js +108 -0
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +48 -26
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +9 -1
- package/dist/shims/headers.js +31 -6
- package/dist/shims/image.js +75 -14
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
- package/dist/shims/internal/pages-data-target.d.ts +10 -9
- package/dist/shims/internal/pages-data-target.js +91 -12
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/layout-segment-context.d.ts +4 -1
- package/dist/shims/layout-segment-context.js +18 -4
- package/dist/shims/link.js +70 -37
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.d.ts +5 -1
- package/dist/shims/navigation.js +45 -10
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +5 -7
- package/dist/shims/router.js +374 -94
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/typegen.js +6 -5
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +2 -2
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +52 -2
- package/dist/utils/project.js +230 -5
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +53 -4
- package/dist/deploy.d.ts +0 -190
- package/dist/deploy.js +0 -1033
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { getLayoutSegmentContext } from "./navigation-context-state.js";
|
|
3
3
|
import "./navigation-server.js";
|
|
4
|
-
import { createElement } from "react";
|
|
4
|
+
import { createElement, useEffect, useRef } from "react";
|
|
5
5
|
//#region src/shims/layout-segment-context.tsx
|
|
6
6
|
/**
|
|
7
7
|
* Layout segment context provider.
|
|
@@ -19,6 +19,14 @@ import { createElement } from "react";
|
|
|
19
19
|
* The context is shared with navigation.ts via getLayoutSegmentContext()
|
|
20
20
|
* to avoid creating separate contexts in different modules.
|
|
21
21
|
*/
|
|
22
|
+
const committedSegmentMapsByProviderId = /* @__PURE__ */ new Map();
|
|
23
|
+
function mergeLayoutSegmentMap(previous, next) {
|
|
24
|
+
if (!previous) return next;
|
|
25
|
+
return {
|
|
26
|
+
...previous,
|
|
27
|
+
...next
|
|
28
|
+
};
|
|
29
|
+
}
|
|
22
30
|
/**
|
|
23
31
|
* Wraps children with the layout segment context.
|
|
24
32
|
*
|
|
@@ -30,10 +38,16 @@ import { createElement } from "react";
|
|
|
30
38
|
* Components inside the provider call useSelectedLayoutSegments(parallelRoutesKey)
|
|
31
39
|
* to read the segments for a specific parallel route.
|
|
32
40
|
*/
|
|
33
|
-
function LayoutSegmentProvider({ segmentMap, children }) {
|
|
41
|
+
function LayoutSegmentProvider({ providerId, segmentMap, children }) {
|
|
42
|
+
const previousSegmentMap = useRef(null);
|
|
34
43
|
const ctx = getLayoutSegmentContext();
|
|
44
|
+
const mergedSegmentMap = mergeLayoutSegmentMap(previousSegmentMap.current ?? (providerId ? committedSegmentMapsByProviderId.get(providerId) ?? null : null), segmentMap);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
previousSegmentMap.current = mergedSegmentMap;
|
|
47
|
+
if (providerId) committedSegmentMapsByProviderId.set(providerId, mergedSegmentMap);
|
|
48
|
+
}, [mergedSegmentMap, providerId]);
|
|
35
49
|
if (!ctx) return children;
|
|
36
|
-
return createElement(ctx.Provider, { value:
|
|
50
|
+
return createElement(ctx.Provider, { value: mergedSegmentMap }, children);
|
|
37
51
|
}
|
|
38
52
|
//#endregion
|
|
39
|
-
export { LayoutSegmentProvider };
|
|
53
|
+
export { LayoutSegmentProvider, mergeLayoutSegmentMap };
|
package/dist/shims/link.js
CHANGED
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { stripBasePath } from "../utils/base-path.js";
|
|
3
3
|
import { createRouteTrieCache, matchRouteWithTrie } from "../routing/route-matching.js";
|
|
4
|
-
import { VINEXT_MOUNTED_SLOTS_HEADER } from "../server/headers.js";
|
|
5
4
|
import { isDangerousScheme, reportBlockedDangerousNavigation } from "./url-safety.js";
|
|
6
|
-
import { AppElementsWire } from "../server/app-elements-wire.js";
|
|
7
|
-
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "../server/app-rsc-render-mode.js";
|
|
8
|
-
import "../server/app-elements.js";
|
|
9
5
|
import { addLocalePrefix, getDomainLocaleUrl } from "../utils/domain-locale.js";
|
|
10
|
-
import { prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
11
|
-
import { appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
12
|
-
import { resolveHybridClientRouteOwner } from "./internal/hybrid-client-route-owner.js";
|
|
6
|
+
import { getPagesMiddlewareDataHref, prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
13
7
|
import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
|
|
14
8
|
import { isAbsoluteOrProtocolRelativeUrl, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
9
|
+
import { appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
15
10
|
import { interpolateDynamicRouteHref } from "./internal/interpolate-as.js";
|
|
16
11
|
import { getCurrentBrowserLocale } from "./client-locale.js";
|
|
17
12
|
import { getCurrentRoutePathnameForWarning } from "./internal/route-pattern-for-warning.js";
|
|
18
|
-
import {
|
|
13
|
+
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
19
14
|
import { getNavigationRuntime, hasAppNavigationRuntime, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
20
15
|
import { navigatePagesRouterLinkWithFallback, resolvePagesRouterQueryOnlyHref } from "../client/pages-router-link-navigation.js";
|
|
21
|
-
import { getMountedSlotsHeader, getPrefetchCache, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, navigateClientSide, prefetchRscResponse } from "./navigation.js";
|
|
22
16
|
import { getI18nContext } from "./i18n-context.js";
|
|
23
17
|
import { canLinkIntentPrefetch, canLinkPrefetch, getLinkPrefetchHref } from "./link-prefetch.js";
|
|
24
18
|
import { clearLinkForCurrentNavigation, notifyLinkNavigationStart, setLinkForCurrentNavigation } from "./internal/link-status-registry.js";
|
|
@@ -32,6 +26,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
32
26
|
* On click, prevents full page reload and triggers client-side
|
|
33
27
|
* page swap via the router's navigation system.
|
|
34
28
|
*/
|
|
29
|
+
const HAS_PAGES_ROUTER = process.env.__VINEXT_HAS_PAGES_ROUTER !== "false";
|
|
35
30
|
const LinkStatusContext = createContext({ pending: false });
|
|
36
31
|
/**
|
|
37
32
|
* useLinkStatus returns the pending state of the enclosing <Link>.
|
|
@@ -58,6 +53,7 @@ function resolveHref(href) {
|
|
|
58
53
|
return url;
|
|
59
54
|
}
|
|
60
55
|
function resolvePagesQueryOnlyHref(href) {
|
|
56
|
+
if (!HAS_PAGES_ROUTER) return href;
|
|
61
57
|
if (!href.startsWith("?") || typeof window === "undefined") return href;
|
|
62
58
|
const pagesRouter = window.next?.appDir === true ? void 0 : window.next?.router;
|
|
63
59
|
return resolvePagesRouterQueryOnlyHref(href, {
|
|
@@ -70,6 +66,11 @@ function resolvePagesQueryOnlyHref(href) {
|
|
|
70
66
|
function resolvePagesLinkNavigationHref(href, locale) {
|
|
71
67
|
return normalizePathTrailingSlash(applyLocaleToHref(resolvePagesQueryOnlyHref(href), locale), __trailingSlash);
|
|
72
68
|
}
|
|
69
|
+
function applyPagesNavigationFallback(href, replace) {
|
|
70
|
+
if (replace) window.history.replaceState({}, "", href);
|
|
71
|
+
else window.history.pushState({}, "", href);
|
|
72
|
+
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
73
|
+
}
|
|
73
74
|
/**
|
|
74
75
|
* Collapse repeated forward-slashes (and convert backslashes to forward-slashes)
|
|
75
76
|
* in the path portion of a URL, preserving any query string.
|
|
@@ -183,12 +184,13 @@ function resolveAutoAppRoutePrefetch(href) {
|
|
|
183
184
|
*
|
|
184
185
|
* For App Router (RSC): fetches the .rsc payload in the background and
|
|
185
186
|
* stores it in an in-memory cache for instant use during navigation.
|
|
186
|
-
* For Pages Router:
|
|
187
|
+
* For Pages Router: warms the page chunk, prefetches data only for SSG pages,
|
|
188
|
+
* and falls back to a document prefetch hint when no page loader matches.
|
|
187
189
|
*
|
|
188
190
|
* Uses `requestIdleCallback` (or `setTimeout` fallback) to avoid blocking
|
|
189
191
|
* the main thread during initial page load.
|
|
190
192
|
*/
|
|
191
|
-
function prefetchUrl(href, mode, priority = "low") {
|
|
193
|
+
function prefetchUrl(href, mode, priority = "low", pagesRouteHref) {
|
|
192
194
|
if (typeof window === "undefined") return;
|
|
193
195
|
const prefetchHref = getLinkPrefetchHref({
|
|
194
196
|
href,
|
|
@@ -197,6 +199,11 @@ function prefetchUrl(href, mode, priority = "low") {
|
|
|
197
199
|
});
|
|
198
200
|
if (prefetchHref == null) return;
|
|
199
201
|
const fullHref = toBrowserNavigationHref(prefetchHref, window.location.href, __basePath);
|
|
202
|
+
const fullRouteHref = toBrowserNavigationHref(pagesRouteHref === void 0 ? prefetchHref : getLinkPrefetchHref({
|
|
203
|
+
href: pagesRouteHref,
|
|
204
|
+
basePath: __basePath,
|
|
205
|
+
currentOrigin: window.location.origin
|
|
206
|
+
}) ?? prefetchHref, window.location.href, __basePath);
|
|
200
207
|
const target = new URL(fullHref, window.location.href);
|
|
201
208
|
if (target.origin === window.location.origin && target.pathname === window.location.pathname && target.search === window.location.search) return;
|
|
202
209
|
(priority === "high" ? (fn) => {
|
|
@@ -204,6 +211,18 @@ function prefetchUrl(href, mode, priority = "low") {
|
|
|
204
211
|
} : window.requestIdleCallback ?? ((fn) => setTimeout(fn, 100)))(() => {
|
|
205
212
|
(async () => {
|
|
206
213
|
if (hasAppNavigationRuntime()) {
|
|
214
|
+
if (isBotUserAgent(window.navigator?.userAgent ?? "")) return;
|
|
215
|
+
const [navigation, { AppElementsWire }, rscCacheBusting, { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL }, headersModule, { resolveHybridClientRouteOwner }] = await Promise.all([
|
|
216
|
+
import("./navigation.js"),
|
|
217
|
+
import("../server/app-elements.js"),
|
|
218
|
+
import("../server/app-rsc-cache-busting.js"),
|
|
219
|
+
import("../server/app-rsc-render-mode.js"),
|
|
220
|
+
import("../server/headers.js"),
|
|
221
|
+
import("./internal/hybrid-client-route-owner.js")
|
|
222
|
+
]);
|
|
223
|
+
const { getPrefetchInterceptionContext, getPrefetchCache, getPrefetchedUrls, getMountedSlotsHeader, hasPrefetchCacheEntryForNavigation, prefetchRscResponse, PREFETCH_CACHE_TTL } = navigation;
|
|
224
|
+
const { createRscRequestHeaders, createRscRequestUrl } = rscCacheBusting;
|
|
225
|
+
const { NEXT_ROUTER_PREFETCH_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } = headersModule;
|
|
207
226
|
const hybridOwner = resolveHybridClientRouteOwner(prefetchHref, __basePath);
|
|
208
227
|
if (hybridOwner === "pages" || hybridOwner === "document") return;
|
|
209
228
|
const autoPrefetch = mode === "auto" ? resolveAutoAppRoutePrefetch(prefetchHref) : {
|
|
@@ -221,6 +240,7 @@ function prefetchUrl(href, mode, priority = "low") {
|
|
|
221
240
|
renderMode: isOptimisticRouteShellPrefetch ? APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL : void 0
|
|
222
241
|
});
|
|
223
242
|
if (mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);
|
|
243
|
+
if (isOptimisticRouteShellPrefetch) headers.set(NEXT_ROUTER_PREFETCH_HEADER, "1");
|
|
224
244
|
const rscUrl = await createRscRequestUrl(fullHref, headers);
|
|
225
245
|
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
226
246
|
const prefetched = getPrefetchedUrls();
|
|
@@ -259,13 +279,19 @@ function prefetchUrl(href, mode, priority = "low") {
|
|
|
259
279
|
purpose: "prefetch"
|
|
260
280
|
}), interceptionContext, mountedSlotsHeader, void 0, {
|
|
261
281
|
cacheForNavigation: autoPrefetch.cacheForNavigation,
|
|
282
|
+
fallbackTtlMs: PREFETCH_CACHE_TTL,
|
|
262
283
|
optimisticRouteShell: isOptimisticRouteShellPrefetch
|
|
263
284
|
});
|
|
264
|
-
} else if (window.__NEXT_DATA__) {
|
|
265
|
-
const dataTarget = resolvePagesDataNavigationTarget(
|
|
266
|
-
if (dataTarget)
|
|
267
|
-
|
|
268
|
-
|
|
285
|
+
} else if (HAS_PAGES_ROUTER && window.__NEXT_DATA__) {
|
|
286
|
+
const dataTarget = resolvePagesDataNavigationTarget(fullRouteHref, __basePath);
|
|
287
|
+
if (dataTarget) {
|
|
288
|
+
const middlewareDataHref = fullRouteHref === fullHref ? dataTarget.middlewareDataHref : getPagesMiddlewareDataHref(fullHref, __basePath) ?? void 0;
|
|
289
|
+
prefetchPagesData({
|
|
290
|
+
...dataTarget,
|
|
291
|
+
middlewareDataHref
|
|
292
|
+
});
|
|
293
|
+
} else {
|
|
294
|
+
await markAppRouteDetectedOnPrefetch(fullHref, __basePath);
|
|
269
295
|
const link = document.createElement("link");
|
|
270
296
|
link.rel = "prefetch";
|
|
271
297
|
link.href = fullHref;
|
|
@@ -278,8 +304,10 @@ function prefetchUrl(href, mode, priority = "low") {
|
|
|
278
304
|
});
|
|
279
305
|
});
|
|
280
306
|
}
|
|
281
|
-
function promotePrefetchEntriesForNavigation(href) {
|
|
307
|
+
async function promotePrefetchEntriesForNavigation(href) {
|
|
282
308
|
if (typeof window === "undefined") return;
|
|
309
|
+
if (!hasAppNavigationRuntime()) return;
|
|
310
|
+
const [{ getPrefetchCache }, { stripRscCacheBustingSearchParam, stripRscSuffix }] = await Promise.all([import("./navigation.js"), import("../server/app-rsc-cache-busting.js")]);
|
|
283
311
|
let target;
|
|
284
312
|
try {
|
|
285
313
|
target = new URL(toBrowserNavigationHref(href, window.location.href, __basePath), window.location.href);
|
|
@@ -311,7 +339,7 @@ function setVisibleLinkPrefetch(instance, isVisible) {
|
|
|
311
339
|
if (isVisible) {
|
|
312
340
|
visibleLinkPrefetches.add(instance);
|
|
313
341
|
if (instance.routerMode === "pages" && instance.viewportPrefetched) return;
|
|
314
|
-
prefetchUrl(instance.href, instance.mode, "low");
|
|
342
|
+
prefetchUrl(instance.href, instance.mode, "low", instance.pagesRouteHref);
|
|
315
343
|
instance.viewportPrefetched = true;
|
|
316
344
|
} else visibleLinkPrefetches.delete(instance);
|
|
317
345
|
}
|
|
@@ -320,7 +348,7 @@ function registerVisibleLinkPing() {
|
|
|
320
348
|
registerNavigationRuntimeFunctions({ pingVisibleLinks: pingVisibleLinkPrefetches });
|
|
321
349
|
}
|
|
322
350
|
function pingVisibleLinkPrefetches() {
|
|
323
|
-
for (const instance of visibleLinkPrefetches) if (instance.isVisible && instance.routerMode === "app") prefetchUrl(instance.href, instance.mode, "low");
|
|
351
|
+
for (const instance of visibleLinkPrefetches) if (instance.isVisible && instance.routerMode === "app") prefetchUrl(instance.href, instance.mode, "low", instance.pagesRouteHref);
|
|
324
352
|
}
|
|
325
353
|
function getSharedObserver() {
|
|
326
354
|
if (typeof window === "undefined" || typeof IntersectionObserver === "undefined") return null;
|
|
@@ -415,10 +443,11 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
415
443
|
let children = childrenProp;
|
|
416
444
|
if (legacyBehavior && (typeof childrenProp === "string" || typeof childrenProp === "number")) children = React.createElement("a", null, childrenProp);
|
|
417
445
|
const rawResolvedHref = as ?? resolveHref(href);
|
|
418
|
-
const routeHrefRaw = resolveConcreteRouteHref(href, as) ?? (typeof href === "string" ? href : resolveHref(href));
|
|
446
|
+
const routeHrefRaw = (HAS_PAGES_ROUTER ? resolveConcreteRouteHref(href, as) : null) ?? (typeof href === "string" ? href : resolveHref(href));
|
|
419
447
|
const resolvedHref = typeof rawResolvedHref === "string" ? warnAndNormalizeRepeatedSlashesInHref(rawResolvedHref) : rawResolvedHref;
|
|
420
448
|
const isDangerous = typeof resolvedHref === "string" && isDangerousScheme(resolvedHref);
|
|
421
449
|
const normalizedHref = normalizePathTrailingSlash(applyLocaleToHref(isDangerous ? "/" : resolvedHref, locale), __trailingSlash);
|
|
450
|
+
const normalizedRouteHref = HAS_PAGES_ROUTER && typeof as === "string" && typeof routeHrefRaw === "string" && as !== routeHrefRaw ? normalizePathTrailingSlash(applyLocaleToHref(isDangerous ? "/" : routeHrefRaw, locale), __trailingSlash) : normalizedHref;
|
|
422
451
|
const fullHref = normalizePathTrailingSlash(withBasePath(normalizedHref, __basePath), __trailingSlash);
|
|
423
452
|
const [pending, setPending] = useState(false);
|
|
424
453
|
const mountedRef = useRef(true);
|
|
@@ -463,6 +492,11 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
463
492
|
href: hrefToPrefetch,
|
|
464
493
|
isVisible: false,
|
|
465
494
|
mode: prefetchMode,
|
|
495
|
+
pagesRouteHref: normalizedRouteHref === normalizedHref ? void 0 : getLinkPrefetchHref({
|
|
496
|
+
href: normalizedRouteHref,
|
|
497
|
+
basePath: __basePath,
|
|
498
|
+
currentOrigin: window.location.origin
|
|
499
|
+
}) ?? void 0,
|
|
466
500
|
routerMode: getLinkPrefetchRouterMode(),
|
|
467
501
|
viewportPrefetched: false
|
|
468
502
|
};
|
|
@@ -476,7 +510,8 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
476
510
|
}, [
|
|
477
511
|
shouldViewportPrefetch,
|
|
478
512
|
prefetchMode,
|
|
479
|
-
normalizedHref
|
|
513
|
+
normalizedHref,
|
|
514
|
+
normalizedRouteHref
|
|
480
515
|
]);
|
|
481
516
|
const prefetchOnIntent = useCallback(() => {
|
|
482
517
|
if (!canLinkIntentPrefetch({
|
|
@@ -491,12 +526,13 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
491
526
|
if (instance) instance.mode = "full";
|
|
492
527
|
promotePrefetchEntriesForNavigation(normalizedHref);
|
|
493
528
|
}
|
|
494
|
-
prefetchUrl(normalizedHref, intentMode, "high");
|
|
529
|
+
prefetchUrl(normalizedHref, intentMode, "high", normalizedRouteHref === normalizedHref ? void 0 : normalizedRouteHref);
|
|
495
530
|
}, [
|
|
496
531
|
prefetchProp,
|
|
497
532
|
isDangerous,
|
|
498
533
|
prefetchMode,
|
|
499
534
|
normalizedHref,
|
|
535
|
+
normalizedRouteHref,
|
|
500
536
|
unstable_dynamicOnHover
|
|
501
537
|
]);
|
|
502
538
|
const handleMouseEnter = useCallback((e) => {
|
|
@@ -527,8 +563,8 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
527
563
|
}
|
|
528
564
|
e.preventDefault();
|
|
529
565
|
const hasAppNavigationRuntime = Boolean(getNavigationRuntime()?.functions.navigate);
|
|
530
|
-
const pagesNavigateHref = resolvedHref.startsWith("?") ? resolvePagesLinkNavigationHref(resolvedHref, locale) : navigateHref;
|
|
531
|
-
const pagesAsForLink = typeof as === "string" && typeof routeHrefRaw === "string" && as !== routeHrefRaw ? pagesNavigateHref : void 0;
|
|
566
|
+
const pagesNavigateHref = HAS_PAGES_ROUTER && resolvedHref.startsWith("?") ? resolvePagesLinkNavigationHref(resolvedHref, locale) : navigateHref;
|
|
567
|
+
const pagesAsForLink = HAS_PAGES_ROUTER && typeof as === "string" && typeof routeHrefRaw === "string" && as !== routeHrefRaw ? pagesNavigateHref : void 0;
|
|
532
568
|
const pagesHrefForLink = pagesAsForLink === void 0 ? pagesNavigateHref : routeHrefRaw;
|
|
533
569
|
const absoluteFullHref = toBrowserNavigationHref(hasAppNavigationRuntime ? navigateHref : pagesNavigateHref, window.location.href, __basePath);
|
|
534
570
|
if (onNavigate) try {
|
|
@@ -546,12 +582,14 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
546
582
|
onNavigate(navEvent);
|
|
547
583
|
if (navEvent.defaultPrevented) return;
|
|
548
584
|
} catch {}
|
|
549
|
-
|
|
585
|
+
const hybridOwner = HAS_PAGES_ROUTER && hasAppNavigationRuntime ? (await import("./internal/hybrid-client-route-owner.js")).resolveHybridClientRouteOwner(navigateHref, __basePath) : null;
|
|
586
|
+
if (HAS_PAGES_ROUTER && hasAppNavigationRuntime && ["pages", "document"].includes(hybridOwner ?? "")) {
|
|
550
587
|
if (replace) window.location.replace(absoluteFullHref);
|
|
551
588
|
else window.location.assign(absoluteFullHref);
|
|
552
589
|
return;
|
|
553
590
|
}
|
|
554
591
|
if (hasAppNavigationRuntime) {
|
|
592
|
+
const { navigateClientSide } = await import("./navigation.js");
|
|
555
593
|
const setter = setPendingRef.current;
|
|
556
594
|
if (setter) setLinkForCurrentNavigation(setter);
|
|
557
595
|
setPending(true);
|
|
@@ -562,11 +600,11 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
562
600
|
});
|
|
563
601
|
});
|
|
564
602
|
return;
|
|
565
|
-
} else {
|
|
603
|
+
} else if (HAS_PAGES_ROUTER) {
|
|
566
604
|
const Router = window.next?.appDir === true ? void 0 : window.next?.router;
|
|
567
605
|
await navigatePagesRouterLinkWithFallback({
|
|
568
606
|
router: Router && "reload" in Router ? Router : void 0,
|
|
569
|
-
loadRouter: async () => (await import("next/router
|
|
607
|
+
loadRouter: async () => (await import("next/router")).default,
|
|
570
608
|
navigation: {
|
|
571
609
|
href: pagesHrefForLink,
|
|
572
610
|
as: pagesAsForLink,
|
|
@@ -576,13 +614,10 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
576
614
|
locale,
|
|
577
615
|
interpolateDynamicRoute: resolvedHref.startsWith("?")
|
|
578
616
|
},
|
|
579
|
-
fallback: () =>
|
|
580
|
-
if (replace) window.history.replaceState({}, "", absoluteFullHref);
|
|
581
|
-
else window.history.pushState({}, "", absoluteFullHref);
|
|
582
|
-
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
583
|
-
}
|
|
617
|
+
fallback: () => applyPagesNavigationFallback(absoluteFullHref, replace)
|
|
584
618
|
});
|
|
585
|
-
}
|
|
619
|
+
} else if (replace) window.location.replace(absoluteFullHref);
|
|
620
|
+
else window.location.assign(absoluteFullHref);
|
|
586
621
|
};
|
|
587
622
|
const anchorProps = restWithoutLocale;
|
|
588
623
|
const linkStatusValue = React.useMemo(() => ({ pending }), [pending]);
|
|
@@ -647,7 +682,7 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
647
682
|
onClick: (event) => {
|
|
648
683
|
if (childOnClick) childOnClick(event);
|
|
649
684
|
if (event.defaultPrevented) return;
|
|
650
|
-
handleClick(event, { skipLinkOnClick: true });
|
|
685
|
+
return handleClick(event, { skipLinkOnClick: true });
|
|
651
686
|
},
|
|
652
687
|
onMouseEnter: (event) => {
|
|
653
688
|
if (childOnMouseEnter) childOnMouseEnter(event);
|
|
@@ -669,9 +704,7 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
669
704
|
children: /* @__PURE__ */ jsx("a", {
|
|
670
705
|
ref: setRefs,
|
|
671
706
|
href: fullHref,
|
|
672
|
-
onClick:
|
|
673
|
-
handleClick(event);
|
|
674
|
-
},
|
|
707
|
+
onClick: handleClick,
|
|
675
708
|
onMouseEnter: handleMouseEnter,
|
|
676
709
|
onTouchStart: handleTouchStart,
|
|
677
710
|
...anchorProps,
|
package/dist/shims/metadata.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ThenableParamsObserver } from "./thenable-params.js";
|
|
1
2
|
import React from "react";
|
|
2
3
|
|
|
3
4
|
//#region src/shims/metadata.d.ts
|
|
@@ -18,7 +19,7 @@ type Viewport = {
|
|
|
18
19
|
* Resolve viewport config from a module. Handles both static `viewport` export
|
|
19
20
|
* and async `generateViewport()` function.
|
|
20
21
|
*/
|
|
21
|
-
declare function resolveModuleViewport(mod: Record<string, unknown>, params: Record<string, string | string[]
|
|
22
|
+
declare function resolveModuleViewport(mod: Record<string, unknown>, params: Record<string, string | string[]>, searchParams?: Record<string, string | string[]>, searchParamsObserver?: ThenableParamsObserver): Promise<Viewport | null>;
|
|
22
23
|
/**
|
|
23
24
|
* Merge viewport configs from multiple sources (layouts + page).
|
|
24
25
|
* Later entries override earlier ones.
|
|
@@ -267,7 +268,7 @@ declare function mergeMetadataEntries(entries: readonly MetadataMergeEntry[]): M
|
|
|
267
268
|
* resolution approach. If not provided, defaults to a promise that resolves
|
|
268
269
|
* to an empty object (so `await parent` never throws).
|
|
269
270
|
*/
|
|
270
|
-
declare function resolveModuleMetadata(mod: Record<string, unknown>, params?: Record<string, string | string[]>, searchParams?: Record<string, string | string[]>, parent?: Promise<Metadata
|
|
271
|
+
declare function resolveModuleMetadata(mod: Record<string, unknown>, params?: Record<string, string | string[]>, searchParams?: Record<string, string | string[]>, parent?: Promise<Metadata>, searchParamsObserver?: ThenableParamsObserver): Promise<Metadata | null>;
|
|
271
272
|
type MetadataHeadProps = {
|
|
272
273
|
metadata: Metadata;
|
|
273
274
|
pathname?: string;
|
package/dist/shims/metadata.js
CHANGED
|
@@ -13,10 +13,14 @@ import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
|
13
13
|
* Resolve viewport config from a module. Handles both static `viewport` export
|
|
14
14
|
* and async `generateViewport()` function.
|
|
15
15
|
*/
|
|
16
|
-
async function resolveModuleViewport(mod, params) {
|
|
16
|
+
async function resolveModuleViewport(mod, params, searchParams, searchParamsObserver) {
|
|
17
17
|
if (typeof mod.generateViewport === "function") {
|
|
18
18
|
const asyncParams = makeThenableParams(params);
|
|
19
|
-
|
|
19
|
+
const props = searchParams === void 0 ? { params: asyncParams } : {
|
|
20
|
+
params: asyncParams,
|
|
21
|
+
searchParams: makeThenableParams(searchParams, searchParamsObserver)
|
|
22
|
+
};
|
|
23
|
+
return await mod.generateViewport(props);
|
|
20
24
|
}
|
|
21
25
|
if (mod.viewport && typeof mod.viewport === "object") return mod.viewport;
|
|
22
26
|
return null;
|
|
@@ -213,12 +217,12 @@ function mergeMetadataEntries(entries) {
|
|
|
213
217
|
* resolution approach. If not provided, defaults to a promise that resolves
|
|
214
218
|
* to an empty object (so `await parent` never throws).
|
|
215
219
|
*/
|
|
216
|
-
async function resolveModuleMetadata(mod, params = {}, searchParams, parent = Promise.resolve({})) {
|
|
220
|
+
async function resolveModuleMetadata(mod, params = {}, searchParams, parent = Promise.resolve({}), searchParamsObserver) {
|
|
217
221
|
if (typeof mod.generateMetadata === "function") {
|
|
218
222
|
const asyncParams = makeThenableParams(params);
|
|
219
223
|
const props = searchParams === void 0 ? { params: asyncParams } : {
|
|
220
224
|
params: asyncParams,
|
|
221
|
-
searchParams: makeThenableParams(searchParams)
|
|
225
|
+
searchParams: makeThenableParams(searchParams, searchParamsObserver)
|
|
222
226
|
};
|
|
223
227
|
return await (mod.generateMetadata.length >= 2 ? mod.generateMetadata(props, parent) : mod.generateMetadata(props));
|
|
224
228
|
}
|
|
@@ -12,6 +12,7 @@ import * as React$1 from "react";
|
|
|
12
12
|
declare const __basePath: string;
|
|
13
13
|
/** Maximum number of entries in the RSC prefetch cache. */
|
|
14
14
|
declare const MAX_PREFETCH_CACHE_SIZE = 50;
|
|
15
|
+
declare const DYNAMIC_NAVIGATION_CACHE_TTL: number;
|
|
15
16
|
declare const PREFETCH_CACHE_TTL: number;
|
|
16
17
|
/** A buffered RSC response stored as an ArrayBuffer for replay. */
|
|
17
18
|
type CachedRscResponse = {
|
|
@@ -57,6 +58,8 @@ declare function hasPrefetchCacheEntryForNavigation(rscUrl: string, interception
|
|
|
57
58
|
notifyInvalidation?: boolean;
|
|
58
59
|
}): boolean;
|
|
59
60
|
declare function invalidatePrefetchCache(): void;
|
|
61
|
+
declare function seedPrefetchResponseSnapshot(rscUrl: string, snapshot: CachedRscResponse, interceptionContext?: string | null, mountedSlotsHeader?: string | null, fallbackTtlMs?: number): void;
|
|
62
|
+
declare function deletePrefetchResponseSnapshot(rscUrl: string, snapshot: CachedRscResponse, interceptionContext?: string | null): void;
|
|
60
63
|
/**
|
|
61
64
|
* Store a prefetched RSC response in the cache by snapshotting it to an
|
|
62
65
|
* ArrayBuffer. The snapshot completes asynchronously; during that window
|
|
@@ -105,6 +108,7 @@ declare function restoreRscResponse(cached: CachedRscResponse, copy?: boolean):
|
|
|
105
108
|
*/
|
|
106
109
|
declare function prefetchRscResponse(rscUrl: string, fetchPromise: Promise<Response>, interceptionContext?: string | null, mountedSlotsHeader?: string | null, options?: PrefetchOptions, behavior?: {
|
|
107
110
|
cacheForNavigation?: boolean;
|
|
111
|
+
fallbackTtlMs?: number;
|
|
108
112
|
optimisticRouteShell?: boolean;
|
|
109
113
|
}): void;
|
|
110
114
|
/**
|
|
@@ -283,4 +287,4 @@ declare function useSelectedLayoutSegments(parallelRoutesKey?: string): string[]
|
|
|
283
287
|
*/
|
|
284
288
|
declare function useServerInsertedHTML(callback: () => unknown): void;
|
|
285
289
|
//#endregion
|
|
286
|
-
export { BailoutToCSRError, CachedRscResponse, ClientNavigationRenderSnapshot, DynamicServerError, GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, type NavigationContext, type NavigationStateAccessors, PREFETCH_CACHE_TTL, PrefetchCacheEntry, PrefetchOptions, ReadonlyURLSearchParams, RedirectType, type 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 };
|
|
290
|
+
export { BailoutToCSRError, CachedRscResponse, ClientNavigationRenderSnapshot, DYNAMIC_NAVIGATION_CACHE_TTL, DynamicServerError, GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, type NavigationContext, type NavigationStateAccessors, PREFETCH_CACHE_TTL, PrefetchCacheEntry, PrefetchOptions, ReadonlyURLSearchParams, RedirectType, type SegmentMap, ServerInsertedHTMLContext, UnrecognizedActionError, __basePath, _registerStateAccessors, activateNavigationSnapshot, appRouterInstance, applyAppRouterScrollFallback, clearPendingPathname, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, deletePrefetchResponseSnapshot, 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, seedPrefetchResponseSnapshot, 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
|
@@ -5,11 +5,11 @@ import { AppElementsWire } from "../server/app-elements-wire.js";
|
|
|
5
5
|
import "../server/app-elements.js";
|
|
6
6
|
import { markPprFallbackShellDynamicBoundary } from "./ppr-fallback-shell.js";
|
|
7
7
|
import { AppRouterContext } from "./internal/app-router-context.js";
|
|
8
|
-
import { resolveHybridClientRouteOwner } from "./internal/hybrid-client-route-owner.js";
|
|
9
8
|
import { isAbsoluteOrProtocolRelativeUrl, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
10
9
|
import { retryScrollTo, scrollToHashTarget } from "./hash-scroll.js";
|
|
11
10
|
import { GLOBAL_ACCESSORS_KEY, ServerInsertedHTMLContext, _registerStateAccessors, clearClientHydrationContext, clearServerInsertedHTML, flushServerInsertedHTML, getBfcacheIdMapContext, getBfcacheSegmentIdContext, getLayoutSegmentContext, getNavigationContext, registerServerInsertedHTMLCallback, renderServerInsertedHTML, setNavigationContext } from "./navigation-context-state.js";
|
|
12
11
|
import { BailoutToCSRError, DynamicServerError, HTTP_ERROR_FALLBACK_ERROR_CODE, RedirectType, decodeRedirectError, forbidden, getAccessFallbackHTTPStatus, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, notFound, permanentRedirect, redirect, unauthorized, unstable_rethrow } from "./navigation-errors.js";
|
|
12
|
+
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
13
13
|
import { clearAppNavigationFailureTarget, stageAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
|
|
14
14
|
import { beginAppRouterScrollIntent, clearAppRouterScrollIntent, consumeAppRouterScrollIntent, getPendingAppRouterScrollIntent } from "./app-router-scroll-state.js";
|
|
15
15
|
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscRequestUrl, stripRscCacheBustingSearchParam } from "../server/app-rsc-cache-busting.js";
|
|
@@ -22,6 +22,7 @@ import { hasPendingAppRouterPageRedirect } from "../server/app-browser-mpa-navig
|
|
|
22
22
|
import { navigationPlanner } from "../server/navigation-planner.js";
|
|
23
23
|
import { ReadonlyURLSearchParams } from "./readonly-url-search-params.js";
|
|
24
24
|
import { getPagesNavigationContext } from "./internal/pages-router-accessor.js";
|
|
25
|
+
import { resolveHybridClientRouteOwner } from "./internal/hybrid-client-route-owner.js";
|
|
25
26
|
import { UnrecognizedActionError, unstable_isUnrecognizedActionError } from "./unrecognized-action-error.js";
|
|
26
27
|
import * as React$1 from "react";
|
|
27
28
|
//#region src/shims/navigation.ts
|
|
@@ -41,7 +42,7 @@ function useChildSegments(parallelRoutesKey = "children") {
|
|
|
41
42
|
const ctx = getLayoutSegmentContext();
|
|
42
43
|
if (!ctx) return [];
|
|
43
44
|
try {
|
|
44
|
-
return React$1.useContext(ctx)[parallelRoutesKey] ?? [];
|
|
45
|
+
return (React$1.useContext(ctx)[parallelRoutesKey] ?? []).filter((segment) => !segment.startsWith("__PAGE__"));
|
|
45
46
|
} catch {
|
|
46
47
|
return [];
|
|
47
48
|
}
|
|
@@ -69,14 +70,15 @@ const MAX_PREFETCH_CACHE_SIZE = 50;
|
|
|
69
70
|
* has not set `experimental.staleTimes`, Next.js' 300s default applies
|
|
70
71
|
* (see `resolveStaleTimes` in `config/next-config.ts`).
|
|
71
72
|
*/
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
if (raw === void 0 || raw === "") return 3e4;
|
|
73
|
+
function resolveClientRouterStaleTime(raw, fallbackMs) {
|
|
74
|
+
if (raw === void 0 || raw === "") return fallbackMs;
|
|
75
75
|
const seconds = Number(raw);
|
|
76
|
-
if (!Number.isFinite(seconds) || seconds < 0) return
|
|
76
|
+
if (!Number.isFinite(seconds) || seconds < 0) return fallbackMs;
|
|
77
77
|
return seconds * 1e3;
|
|
78
78
|
}
|
|
79
|
-
const
|
|
79
|
+
const DYNAMIC_NAVIGATION_CACHE_TTL = resolveClientRouterStaleTime(process.env.__NEXT_CLIENT_ROUTER_DYNAMIC_STALETIME, 3e4);
|
|
80
|
+
const PREFETCH_CACHE_TTL = resolveClientRouterStaleTime(process.env.__NEXT_CLIENT_ROUTER_STATIC_STALETIME, 3e4);
|
|
81
|
+
const MIN_PREFETCH_STALE_TIME_MS = 3e4;
|
|
80
82
|
function getCurrentInterceptionContext() {
|
|
81
83
|
if (isServer) return null;
|
|
82
84
|
return stripBasePath(window.location.pathname, __basePath);
|
|
@@ -135,6 +137,12 @@ function resolveCachedRscResponseExpiresAt(timestamp, cached, fallbackTtlMs) {
|
|
|
135
137
|
if (isCacheExpiresAt(cached.expiresAt)) return cached.expiresAt;
|
|
136
138
|
return timestamp + resolveCachedRscResponseTtlMs(cached, fallbackTtlMs);
|
|
137
139
|
}
|
|
140
|
+
function resolvePrefetchedRscResponseExpiresAt(timestamp, cached, fallbackTtlMs) {
|
|
141
|
+
if (isCacheExpiresAt(cached.expiresAt)) return cached.expiresAt;
|
|
142
|
+
const seconds = cached.dynamicStaleTimeSeconds;
|
|
143
|
+
if (!isDynamicStaleTimeSeconds(seconds)) return timestamp + Math.max(fallbackTtlMs, MIN_PREFETCH_STALE_TIME_MS);
|
|
144
|
+
return timestamp + Math.max(seconds * 1e3, MIN_PREFETCH_STALE_TIME_MS);
|
|
145
|
+
}
|
|
138
146
|
function resolvePrefetchCacheEntryExpiresAt(entry) {
|
|
139
147
|
if (entry.expiresAt !== void 0) return entry.expiresAt;
|
|
140
148
|
if (entry.snapshot) return resolveCachedRscResponseExpiresAt(entry.timestamp, entry.snapshot, PREFETCH_CACHE_TTL);
|
|
@@ -282,6 +290,32 @@ function invalidatePrefetchCache() {
|
|
|
282
290
|
prefetched.clear();
|
|
283
291
|
if (!isServer) getNavigationRuntime()?.functions.pingVisibleLinks?.();
|
|
284
292
|
}
|
|
293
|
+
function seedPrefetchResponseSnapshot(rscUrl, snapshot, interceptionContext = null, mountedSlotsHeader = null, fallbackTtlMs = DYNAMIC_NAVIGATION_CACHE_TTL) {
|
|
294
|
+
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
295
|
+
const cache = getPrefetchCache();
|
|
296
|
+
const existing = cache.get(cacheKey);
|
|
297
|
+
if (existing) deletePrefetchCacheEntry(cache, getPrefetchedUrls(), cacheKey, existing, false);
|
|
298
|
+
evictPrefetchCacheIfNeeded();
|
|
299
|
+
const timestamp = Date.now();
|
|
300
|
+
const entry = {
|
|
301
|
+
cacheForNavigation: true,
|
|
302
|
+
expiresAt: resolveCachedRscResponseExpiresAt(timestamp, snapshot, fallbackTtlMs),
|
|
303
|
+
mountedSlotsHeader,
|
|
304
|
+
outcome: "cache-seeded",
|
|
305
|
+
snapshot,
|
|
306
|
+
timestamp
|
|
307
|
+
};
|
|
308
|
+
cache.set(cacheKey, entry);
|
|
309
|
+
getPrefetchedUrls().add(cacheKey);
|
|
310
|
+
schedulePrefetchInvalidation(cacheKey, entry);
|
|
311
|
+
}
|
|
312
|
+
function deletePrefetchResponseSnapshot(rscUrl, snapshot, interceptionContext = null) {
|
|
313
|
+
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
314
|
+
const cache = getPrefetchCache();
|
|
315
|
+
const entry = cache.get(cacheKey);
|
|
316
|
+
if (entry?.snapshot !== snapshot) return;
|
|
317
|
+
deletePrefetchCacheEntry(cache, getPrefetchedUrls(), cacheKey, entry, false);
|
|
318
|
+
}
|
|
285
319
|
/**
|
|
286
320
|
* Store a prefetched RSC response in the cache by snapshotting it to an
|
|
287
321
|
* ArrayBuffer. The snapshot completes asynchronously; during that window
|
|
@@ -390,7 +424,7 @@ function prefetchRscResponse(rscUrl, fetchPromise, interceptionContext = null, m
|
|
|
390
424
|
entry.pending = fetchPromise.then(async (response) => {
|
|
391
425
|
if (response.ok) {
|
|
392
426
|
entry.snapshot = await snapshotRscResponse(response);
|
|
393
|
-
entry.expiresAt =
|
|
427
|
+
entry.expiresAt = resolvePrefetchedRscResponseExpiresAt(entry.timestamp, entry.snapshot, behavior.fallbackTtlMs ?? PREFETCH_CACHE_TTL);
|
|
394
428
|
} else deletePrefetchCacheEntry(cache, prefetched, cacheKey, entry, false);
|
|
395
429
|
}).catch(() => {
|
|
396
430
|
deletePrefetchCacheEntry(cache, prefetched, cacheKey, entry, false);
|
|
@@ -772,7 +806,7 @@ function commitClientNavigationState(navId, options) {
|
|
|
772
806
|
if (isServer) return;
|
|
773
807
|
const state = getClientNavigationState();
|
|
774
808
|
if (!state) return;
|
|
775
|
-
if ((navId !== void 0
|
|
809
|
+
if ((options?.releaseSnapshot ?? navId !== void 0) && state.navigationSnapshotActiveCount > 0) state.navigationSnapshotActiveCount -= 1;
|
|
776
810
|
const urlChanged = syncCommittedUrlStateFromLocation();
|
|
777
811
|
let paramsChanged = false;
|
|
778
812
|
if (state.pendingClientParams !== null && state.pendingClientParamsJson !== null) {
|
|
@@ -1033,6 +1067,7 @@ const _appRouter = {
|
|
|
1033
1067
|
prefetch(href, options) {
|
|
1034
1068
|
assertSafeNavigationUrl(href);
|
|
1035
1069
|
if (isServer) return;
|
|
1070
|
+
if (isBotUserAgent(window.navigator?.userAgent ?? "")) return;
|
|
1036
1071
|
try {
|
|
1037
1072
|
new URL(withBasePath(href, __basePath), window.location.href);
|
|
1038
1073
|
} catch {
|
|
@@ -1203,4 +1238,4 @@ if (!isServer) {
|
|
|
1203
1238
|
}
|
|
1204
1239
|
}
|
|
1205
1240
|
//#endregion
|
|
1206
|
-
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 };
|
|
1241
|
+
export { BailoutToCSRError, DYNAMIC_NAVIGATION_CACHE_TTL, 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, deletePrefetchResponseSnapshot, 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, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, storePrefetchResponse, unauthorized, unstable_isUnrecognizedActionError, unstable_rethrow, useClientNavigationRenderSnapshot, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { GLOBAL_ACCESSORS_KEY, ServerInsertedHTMLContext, _registerStateAccessors, clearServerInsertedHTML, flushServerInsertedHTML, getLayoutSegmentContext, getNavigationContext, renderServerInsertedHTML, setNavigationContext } from "./navigation-context-state.js";
|
|
2
2
|
import { BailoutToCSRError, DynamicServerError, HTTP_ERROR_FALLBACK_ERROR_CODE, RedirectType, forbidden, getAccessFallbackHTTPStatus, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, notFound, permanentRedirect, redirect, unauthorized, unstable_rethrow } from "./navigation-errors.js";
|
|
3
3
|
import "./navigation-server.js";
|
|
4
|
-
import { throwClientHookError } from "./client-hook-error.js";
|
|
5
4
|
import { ReadonlyURLSearchParams } from "./readonly-url-search-params.js";
|
|
5
|
+
import { throwClientHookError } from "./client-hook-error.js";
|
|
6
6
|
//#region src/shims/navigation.react-server.ts
|
|
7
7
|
function usePathname() {
|
|
8
8
|
throwClientHookError("usePathname()");
|
|
@@ -3,10 +3,24 @@ type RootParams = Record<string, string | string[] | undefined>;
|
|
|
3
3
|
type RootParamsState = {
|
|
4
4
|
rootParams: RootParams | null;
|
|
5
5
|
};
|
|
6
|
+
type RootParamsUsage = {
|
|
7
|
+
kind: "route";
|
|
8
|
+
} | {
|
|
9
|
+
kind: "server-action";
|
|
10
|
+
} | {
|
|
11
|
+
kind: "route-handler";
|
|
12
|
+
routePattern: string;
|
|
13
|
+
};
|
|
14
|
+
type RootParamsUsageController = {
|
|
15
|
+
transitionToRender(): void;
|
|
16
|
+
};
|
|
6
17
|
declare function pickRootParams(params: RootParams, rootParamNames: readonly string[] | null | undefined): RootParams;
|
|
7
18
|
declare function setRootParams(params: RootParams | null): void;
|
|
8
19
|
declare function getRootParam(name: string): Promise<string | string[] | undefined>;
|
|
20
|
+
declare function runWithRootParamsUsage<T>(usage: RootParamsUsage, fn: () => Promise<T>, controller?: RootParamsUsageController): Promise<T>;
|
|
21
|
+
declare function runWithRootParamsUsage<T>(usage: RootParamsUsage, fn: () => T | Promise<T>, controller?: RootParamsUsageController): T | Promise<T>;
|
|
22
|
+
declare function createRootParamsUsageController(): RootParamsUsageController;
|
|
9
23
|
declare function runWithRootParamsScope<T>(params: RootParams, fn: () => Promise<T>): Promise<T>;
|
|
10
24
|
declare function runWithRootParamsScope<T>(params: RootParams, fn: () => T | Promise<T>): T | Promise<T>;
|
|
11
25
|
//#endregion
|
|
12
|
-
export { RootParams, RootParamsState, getRootParam, pickRootParams, runWithRootParamsScope, setRootParams };
|
|
26
|
+
export { RootParams, RootParamsState, RootParamsUsage, RootParamsUsageController, createRootParamsUsageController, getRootParam, pickRootParams, runWithRootParamsScope, runWithRootParamsUsage, setRootParams };
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { getOrCreateAls } from "./internal/als-registry.js";
|
|
2
2
|
import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
|
|
3
3
|
//#region src/shims/root-params.ts
|
|
4
|
+
function createRootParamsUsageError(message) {
|
|
5
|
+
return new Error(message);
|
|
6
|
+
}
|
|
4
7
|
const _FALLBACK_KEY = Symbol.for("vinext.rootParams.fallback");
|
|
5
8
|
const _g = globalThis;
|
|
6
9
|
const _als = getOrCreateAls("vinext.rootParams.als");
|
|
10
|
+
const _usageAls = getOrCreateAls("vinext.rootParams.usage.als");
|
|
7
11
|
const _fallbackState = _g[_FALLBACK_KEY] ??= { rootParams: null };
|
|
8
12
|
function getState() {
|
|
9
13
|
if (isInsideUnifiedScope()) return getRequestContext();
|
|
@@ -18,8 +22,24 @@ function setRootParams(params) {
|
|
|
18
22
|
getState().rootParams = params;
|
|
19
23
|
}
|
|
20
24
|
function getRootParam(name) {
|
|
25
|
+
const usage = _usageAls.getStore();
|
|
26
|
+
if (usage?.kind === "server-action" && usage.phase === "active") throw createRootParamsUsageError(`\`import('next/root-params').${name}()\` was used inside a Server Action. This is not supported. Functions from 'next/root-params' can only be called in the context of a route.`);
|
|
27
|
+
if (usage?.kind === "route-handler" && usage.phase === "active") throw createRootParamsUsageError(`Route ${usage.routePattern} used \`import('next/root-params').${name}()\` inside a Route Handler. Support for this API in Route Handlers is planned for a future version of Next.js.`);
|
|
21
28
|
return Promise.resolve(getState().rootParams?.[name]);
|
|
22
29
|
}
|
|
30
|
+
function runWithRootParamsUsage(usage, fn, controller) {
|
|
31
|
+
const state = {
|
|
32
|
+
...usage,
|
|
33
|
+
phase: "active"
|
|
34
|
+
};
|
|
35
|
+
if (controller) controller.transitionToRender = () => {
|
|
36
|
+
if (usage.kind === "server-action") state.phase = "render";
|
|
37
|
+
};
|
|
38
|
+
return _usageAls.run(state, fn);
|
|
39
|
+
}
|
|
40
|
+
function createRootParamsUsageController() {
|
|
41
|
+
return { transitionToRender() {} };
|
|
42
|
+
}
|
|
23
43
|
function runWithRootParamsScope(params, fn) {
|
|
24
44
|
if (isInsideUnifiedScope()) return runWithUnifiedStateMutation((ctx) => {
|
|
25
45
|
ctx.rootParams = params;
|
|
@@ -27,4 +47,4 @@ function runWithRootParamsScope(params, fn) {
|
|
|
27
47
|
else return _als.run({ rootParams: params }, fn);
|
|
28
48
|
}
|
|
29
49
|
//#endregion
|
|
30
|
-
export { getRootParam, pickRootParams, runWithRootParamsScope, setRootParams };
|
|
50
|
+
export { createRootParamsUsageController, getRootParam, pickRootParams, runWithRootParamsScope, runWithRootParamsUsage, setRootParams };
|