vinext 1.0.0-beta.2 → 1.0.0-beta.4
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 +6 -9
- package/dist/build/client-build-config.js +7 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +12 -2
- package/dist/check.js +4 -0
- package/dist/cli-args.d.ts +2 -1
- package/dist/cli-args.js +10 -0
- package/dist/cli.js +14 -8
- package/dist/client/navigation-runtime.d.ts +6 -0
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/config/config-matchers.js +4 -1
- package/dist/config/dotenv.d.ts +3 -4
- package/dist/config/dotenv.js +30 -22
- package/dist/config/next-config.d.ts +16 -5
- package/dist/config/next-config.js +7 -0
- package/dist/entries/app-browser-entry.d.ts +4 -10
- package/dist/entries/app-browser-entry.js +20 -4
- package/dist/entries/app-rsc-entry.js +21 -3
- package/dist/entries/app-rsc-manifest.js +19 -0
- package/dist/entries/pages-client-entry.js +0 -1
- package/dist/entries/pages-server-entry.js +13 -3
- package/dist/index.js +122 -49
- package/dist/init-cloudflare.d.ts +3 -1
- package/dist/init-cloudflare.js +59 -5
- package/dist/plugins/client-reference-dedup.js +7 -5
- package/dist/plugins/extensionless-dynamic-import.js +23 -18
- package/dist/plugins/ignore-dynamic-requests.js +3 -1
- package/dist/plugins/import-meta-url.js +17 -6
- package/dist/plugins/require-context.js +20 -15
- package/dist/plugins/sass.js +3 -4
- package/dist/plugins/transform-cache.d.ts +19 -0
- package/dist/plugins/transform-cache.js +36 -0
- package/dist/routing/app-route-graph.d.ts +14 -6
- package/dist/routing/app-route-graph.js +106 -16
- package/dist/server/api-handler.d.ts +2 -0
- package/dist/server/api-handler.js +7 -6
- package/dist/server/app-bfcache-identity.js +28 -2
- package/dist/server/app-browser-entry.js +175 -75
- package/dist/server/app-browser-navigation-controller.d.ts +23 -21
- package/dist/server/app-browser-navigation-controller.js +30 -5
- package/dist/server/app-browser-prefetch-response.d.ts +9 -0
- package/dist/server/app-browser-prefetch-response.js +32 -0
- package/dist/server/app-browser-state.d.ts +8 -3
- package/dist/server/app-browser-state.js +9 -3
- package/dist/server/app-page-cache-finalizer.js +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +16 -2
- package/dist/server/app-page-dispatch.d.ts +9 -1
- package/dist/server/app-page-dispatch.js +37 -8
- package/dist/server/app-page-element-builder.d.ts +4 -1
- package/dist/server/app-page-element-builder.js +34 -7
- package/dist/server/app-page-head.d.ts +3 -3
- package/dist/server/app-page-head.js +58 -13
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +2 -2
- package/dist/server/app-page-http-access-fallback-metadata.js +9 -1
- package/dist/server/app-page-probe.d.ts +4 -0
- package/dist/server/app-page-probe.js +6 -2
- package/dist/server/app-page-render.d.ts +1 -1
- package/dist/server/app-page-render.js +13 -3
- package/dist/server/app-page-request.d.ts +3 -1
- package/dist/server/app-page-request.js +4 -13
- package/dist/server/app-page-response.d.ts +2 -0
- package/dist/server/app-page-response.js +7 -2
- package/dist/server/app-page-route-wiring.d.ts +10 -2
- package/dist/server/app-page-route-wiring.js +269 -59
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +3 -1
- package/dist/server/app-route-handler-cache.js +4 -0
- package/dist/server/app-route-handler-dispatch.js +9 -3
- package/dist/server/app-route-handler-response.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +6 -0
- package/dist/server/app-route-module-loader.js +3 -0
- package/dist/server/app-router-entry.js +6 -3
- package/dist/server/app-rsc-cache-busting.d.ts +7 -0
- package/dist/server/app-rsc-cache-busting.js +6 -0
- package/dist/server/app-rsc-errors.js +10 -0
- package/dist/server/app-rsc-handler.d.ts +2 -0
- package/dist/server/app-rsc-handler.js +30 -13
- package/dist/server/app-rsc-render-mode.d.ts +3 -2
- package/dist/server/app-rsc-render-mode.js +4 -1
- package/dist/server/app-rsc-request-normalization.js +65 -4
- package/dist/server/app-rsc-route-matching.d.ts +9 -0
- package/dist/server/app-rsc-route-matching.js +6 -0
- package/dist/server/app-server-action-execution.d.ts +1 -1
- package/dist/server/app-ssr-entry.js +4 -4
- package/dist/server/app-visited-response-cache.d.ts +6 -1
- package/dist/server/app-visited-response-cache.js +49 -1
- package/dist/server/cache-control.d.ts +2 -2
- package/dist/server/cache-control.js +2 -1
- package/dist/server/dev-server.d.ts +3 -1
- package/dist/server/dev-server.js +204 -348
- package/dist/server/edge-api-runtime.d.ts +10 -1
- package/dist/server/edge-api-runtime.js +29 -1
- package/dist/server/headers.d.ts +4 -2
- package/dist/server/headers.js +6 -3
- package/dist/server/isr-cache.d.ts +10 -33
- package/dist/server/isr-cache.js +33 -43
- package/dist/server/isr-decision.d.ts +2 -2
- package/dist/server/pages-api-route.d.ts +4 -0
- package/dist/server/pages-api-route.js +6 -3
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +6 -4
- package/dist/server/pages-dev-hydration.js +0 -1
- package/dist/server/pages-document-asset-props.d.ts +26 -0
- package/dist/server/pages-document-asset-props.js +69 -0
- package/dist/server/pages-get-initial-props.d.ts +1 -1
- package/dist/server/pages-get-initial-props.js +1 -4
- package/dist/server/pages-i18n.js +64 -16
- package/dist/server/pages-node-compat.d.ts +2 -0
- package/dist/server/pages-node-compat.js +10 -6
- package/dist/server/pages-page-data.d.ts +61 -9
- package/dist/server/pages-page-data.js +334 -74
- package/dist/server/pages-page-handler.d.ts +6 -1
- package/dist/server/pages-page-handler.js +119 -20
- package/dist/server/pages-page-response.d.ts +7 -3
- package/dist/server/pages-page-response.js +41 -33
- package/dist/server/pages-request-pipeline.d.ts +7 -0
- package/dist/server/pages-request-pipeline.js +5 -1
- package/dist/server/pages-revalidate.d.ts +1 -1
- package/dist/server/pages-revalidate.js +54 -8
- package/dist/server/pages-router-entry.d.ts +1 -0
- package/dist/server/pages-router-entry.js +10 -4
- package/dist/server/prerender-manifest.d.ts +1 -0
- package/dist/server/prod-server.d.ts +2 -1
- package/dist/server/prod-server.js +38 -13
- package/dist/server/revalidation-host.d.ts +11 -0
- package/dist/server/revalidation-host.js +19 -0
- package/dist/server/seed-cache.js +1 -1
- package/dist/server/worker-revalidation-context.d.ts +13 -0
- package/dist/server/worker-revalidation-context.js +30 -0
- package/dist/shims/app-router-scroll-state.d.ts +2 -1
- package/dist/shims/app-router-scroll-state.js +7 -2
- package/dist/shims/cache-handler.d.ts +1 -1
- package/dist/shims/cache-handler.js +10 -7
- package/dist/shims/cache-runtime.d.ts +6 -0
- package/dist/shims/cache-runtime.js +4 -1
- package/dist/shims/cache.js +1 -1
- package/dist/shims/document.js +15 -2
- package/dist/shims/error.js +1 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-google-base.js +17 -8
- package/dist/shims/font-local.js +41 -10
- package/dist/shims/hash-scroll.d.ts +1 -1
- package/dist/shims/hash-scroll.js +2 -1
- package/dist/shims/headers.d.ts +10 -13
- package/dist/shims/headers.js +85 -36
- package/dist/shims/internal/cookie-serialize.d.ts +10 -9
- package/dist/shims/internal/cookie-serialize.js +9 -8
- package/dist/shims/internal/interpolate-as.d.ts +15 -1
- package/dist/shims/internal/interpolate-as.js +27 -2
- package/dist/shims/link.d.ts +2 -0
- package/dist/shims/link.js +77 -24
- package/dist/shims/metadata.d.ts +18 -34
- package/dist/shims/metadata.js +98 -56
- package/dist/shims/navigation.d.ts +18 -2
- package/dist/shims/navigation.js +70 -21
- package/dist/shims/request-context.d.ts +6 -2
- package/dist/shims/router.js +18 -7
- package/dist/shims/script.js +1 -1
- package/dist/shims/server.d.ts +7 -6
- package/dist/shims/server.js +156 -57
- package/dist/shims/slot.d.ts +2 -1
- package/dist/shims/slot.js +6 -2
- package/dist/shims/streamed-icons.d.ts +9 -0
- package/dist/shims/streamed-icons.js +33 -0
- package/dist/shims/unified-request-context.d.ts +21 -2
- package/dist/shims/unified-request-context.js +82 -1
- package/dist/utils/cache-control-metadata.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +5 -1
- package/dist/utils/html-limited-bots.js +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/package.json +1 -1
package/dist/shims/link.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
import { stripBasePath } from "../utils/base-path.js";
|
|
3
3
|
import { createRouteTrieCache, matchRouteWithTrie } from "../routing/route-matching.js";
|
|
4
4
|
import { isDangerousScheme, reportBlockedDangerousNavigation } from "./url-safety.js";
|
|
5
|
+
import { RouterContext } from "./internal/router-context.js";
|
|
5
6
|
import { addLocalePrefix, getDomainLocaleUrl } from "../utils/domain-locale.js";
|
|
6
7
|
import { getPagesMiddlewareDataHref, prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
7
8
|
import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
|
|
8
9
|
import { isAbsoluteOrProtocolRelativeUrl, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
9
10
|
import { appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
10
|
-
import { interpolateDynamicRouteHref } from "./internal/interpolate-as.js";
|
|
11
|
+
import { interpolateDynamicRouteHref, resolveDynamicRouteHref } from "./internal/interpolate-as.js";
|
|
11
12
|
import { getCurrentBrowserLocale } from "./client-locale.js";
|
|
12
13
|
import { getCurrentRoutePathnameForWarning } from "./internal/route-pattern-for-warning.js";
|
|
13
14
|
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
@@ -29,6 +30,22 @@ import { jsx } from "react/jsx-runtime";
|
|
|
29
30
|
*/
|
|
30
31
|
const HAS_PAGES_ROUTER = process.env.__VINEXT_HAS_PAGES_ROUTER !== "false";
|
|
31
32
|
const HAS_CLIENT_REWRITES = process.env.__VINEXT_HAS_CLIENT_REWRITES !== "false";
|
|
33
|
+
let loadedNavigationModule = null;
|
|
34
|
+
let navigationModulePromise = null;
|
|
35
|
+
let loadedHybridClientRouteOwnerModule = null;
|
|
36
|
+
let hybridClientRouteOwnerModulePromise = null;
|
|
37
|
+
function loadNavigationModule() {
|
|
38
|
+
return navigationModulePromise ??= import("./navigation.js").then((module) => {
|
|
39
|
+
loadedNavigationModule = module;
|
|
40
|
+
return module;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function loadHybridClientRouteOwnerModule() {
|
|
44
|
+
return hybridClientRouteOwnerModulePromise ??= import("./internal/hybrid-client-route-owner.js").then((module) => {
|
|
45
|
+
loadedHybridClientRouteOwnerModule = module;
|
|
46
|
+
return module;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
32
49
|
const LinkStatusContext = createContext({ pending: false });
|
|
33
50
|
/**
|
|
34
51
|
* useLinkStatus returns the pending state of the enclosing <Link>.
|
|
@@ -147,6 +164,8 @@ function getLinkPrefetchRouterMode() {
|
|
|
147
164
|
function resolveMatchedAutoAppRoutePrefetch(route) {
|
|
148
165
|
return {
|
|
149
166
|
cacheForNavigation: !route.canPrefetchLoadingShell && route.requiresDynamicNavigationRequest !== true,
|
|
167
|
+
fallbackTtl: "static",
|
|
168
|
+
minimumTtlMs: route.isDynamic ? 0 : void 0,
|
|
150
169
|
prefetchShellFirst: !route.isDynamic,
|
|
151
170
|
shouldPrefetch: true
|
|
152
171
|
};
|
|
@@ -163,24 +182,32 @@ function canAutoPrefetchFullAppRoute(href) {
|
|
|
163
182
|
function resolveAutoAppRoutePrefetch(href) {
|
|
164
183
|
if (typeof window === "undefined") return {
|
|
165
184
|
cacheForNavigation: false,
|
|
185
|
+
fallbackTtl: "static",
|
|
186
|
+
minimumTtlMs: void 0,
|
|
166
187
|
prefetchShellFirst: false,
|
|
167
188
|
shouldPrefetch: false
|
|
168
189
|
};
|
|
169
190
|
const routes = window.__VINEXT_LINK_PREFETCH_ROUTES__;
|
|
170
191
|
if (!routes) return {
|
|
171
192
|
cacheForNavigation: false,
|
|
193
|
+
fallbackTtl: "static",
|
|
194
|
+
minimumTtlMs: void 0,
|
|
172
195
|
prefetchShellFirst: false,
|
|
173
196
|
shouldPrefetch: false
|
|
174
197
|
};
|
|
175
198
|
const routeHref = toSameOriginRouteHref(href);
|
|
176
199
|
if (routeHref === null) return {
|
|
177
200
|
cacheForNavigation: false,
|
|
201
|
+
fallbackTtl: "static",
|
|
202
|
+
minimumTtlMs: void 0,
|
|
178
203
|
prefetchShellFirst: false,
|
|
179
204
|
shouldPrefetch: false
|
|
180
205
|
};
|
|
181
206
|
const match = matchRouteWithTrie(routeHref, routes, linkPrefetchRouteTrieCache);
|
|
182
207
|
if (!match) return {
|
|
183
208
|
cacheForNavigation: false,
|
|
209
|
+
fallbackTtl: "static",
|
|
210
|
+
minimumTtlMs: void 0,
|
|
184
211
|
prefetchShellFirst: false,
|
|
185
212
|
shouldPrefetch: false
|
|
186
213
|
};
|
|
@@ -195,6 +222,8 @@ function resolveAutoAppRoutePrefetch(href) {
|
|
|
195
222
|
function resolveFullAppRoutePrefetch() {
|
|
196
223
|
return {
|
|
197
224
|
cacheForNavigation: true,
|
|
225
|
+
fallbackTtl: "static",
|
|
226
|
+
minimumTtlMs: void 0,
|
|
198
227
|
prefetchShellFirst: true,
|
|
199
228
|
shouldPrefetch: true
|
|
200
229
|
};
|
|
@@ -228,27 +257,30 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
228
257
|
}) ?? prefetchHref, window.location.href, __basePath);
|
|
229
258
|
const target = new URL(fullHref, window.location.href);
|
|
230
259
|
if (target.origin === window.location.origin && target.pathname === window.location.pathname && target.search === window.location.search) return;
|
|
260
|
+
if (mode === "auto" && priority === "low" && target.origin === window.location.origin && target.pathname === window.location.pathname && target.search !== window.location.search && target.hash !== "") return;
|
|
231
261
|
const runPrefetch = () => {
|
|
232
262
|
(async () => {
|
|
233
263
|
if (hasAppNavigationRuntime()) {
|
|
234
264
|
if (isBotUserAgent(window.navigator?.userAgent ?? "")) return;
|
|
235
265
|
const [navigation, { AppElementsWire }, rscCacheBusting, { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL }, headersModule, hybridRouteOwner] = await Promise.all([
|
|
236
|
-
|
|
266
|
+
loadNavigationModule(),
|
|
237
267
|
import("../server/app-elements.js"),
|
|
238
268
|
import("../server/app-rsc-cache-busting.js"),
|
|
239
269
|
import("../server/app-rsc-render-mode.js"),
|
|
240
270
|
import("../server/headers.js"),
|
|
241
|
-
HAS_PAGES_ROUTER || HAS_CLIENT_REWRITES ?
|
|
271
|
+
HAS_PAGES_ROUTER || HAS_CLIENT_REWRITES ? loadHybridClientRouteOwnerModule() : null
|
|
242
272
|
]);
|
|
243
273
|
if (navigationEpoch !== linkPrefetchNavigationEpoch) return;
|
|
244
|
-
const { getPrefetchInterceptionContext, getPrefetchCache, getPrefetchedUrls, getMountedSlotsHeader, hasSearchAgnosticPrefetchShellForRoute, hasPrefetchCacheEntryForNavigation, peekPrefetchResponseForNavigation, prefetchRscResponse, restoreRscResponse, PREFETCH_CACHE_TTL } = navigation;
|
|
245
|
-
const {
|
|
274
|
+
const { getPrefetchInterceptionContext, getPrefetchCache, getPrefetchedUrls, getMountedSlotsHeader, createAppPrefetchRequestHeaders, discardLearningOnlyPrefetchCacheEntry, hasSearchAgnosticPrefetchShellForRoute, hasPrefetchCacheEntryForNavigation, peekPrefetchResponseForNavigation, prefetchRscResponse, DYNAMIC_NAVIGATION_CACHE_TTL, restoreRscResponse, PREFETCH_CACHE_TTL } = navigation;
|
|
275
|
+
const { createRscRequestUrl } = rscCacheBusting;
|
|
246
276
|
const { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } = headersModule;
|
|
247
277
|
const hybridOwner = HAS_PAGES_ROUTER ? hybridRouteOwner.resolveHybridClientRouteOwner(prefetchHref, __basePath) : null;
|
|
248
278
|
if (hybridOwner === "pages" || hybridOwner === "document") return;
|
|
249
279
|
const rewrittenPrefetchHref = HAS_CLIENT_REWRITES ? hybridRouteOwner.resolveHybridClientRewriteHref(fullHref, __basePath) : null;
|
|
250
280
|
const autoPrefetch = mode === "auto" ? resolveAutoAppRoutePrefetch(rewrittenPrefetchHref ?? prefetchHref) : mode === "full-after-shell" ? {
|
|
251
281
|
cacheForNavigation: true,
|
|
282
|
+
fallbackTtl: "static",
|
|
283
|
+
minimumTtlMs: void 0,
|
|
252
284
|
prefetchShellFirst: true,
|
|
253
285
|
shouldPrefetch: true
|
|
254
286
|
} : resolveFullAppRoutePrefetch();
|
|
@@ -258,15 +290,16 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
258
290
|
const isOptimisticRouteShellPrefetch = !autoPrefetch.cacheForNavigation;
|
|
259
291
|
const hasSearchParams = new URL(fullHref, window.location.href).search !== "";
|
|
260
292
|
const isAutomaticSearchParamShell = mode === "auto" && isOptimisticRouteShellPrefetch && hasSearchParams;
|
|
261
|
-
if (isOptimisticRouteShellPrefetch && interceptionContext !== null) return;
|
|
262
293
|
const hasSearchAgnosticShell = isAutomaticSearchParamShell && hasSearchAgnosticPrefetchShellForRoute(await createRscRequestUrl(fullHref, new Headers()), interceptionContext, mountedSlotsHeader);
|
|
263
|
-
const headers =
|
|
294
|
+
const headers = createAppPrefetchRequestHeaders({
|
|
264
295
|
interceptionContext,
|
|
296
|
+
fetchPriority: priority,
|
|
297
|
+
prefetchKind: mode === "full" ? "full" : "auto",
|
|
265
298
|
renderMode: isOptimisticRouteShellPrefetch ? hasSearchAgnosticShell ? APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL : isAutomaticSearchParamShell ? APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL : APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL : void 0
|
|
266
299
|
});
|
|
267
300
|
if (mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);
|
|
268
301
|
const shouldSendSegmentPrefetchHeaders = isOptimisticRouteShellPrefetch || mode === "auto";
|
|
269
|
-
if (__prefetchInlining && autoPrefetch.cacheForNavigation) {
|
|
302
|
+
if (__prefetchInlining && mode === "auto" && autoPrefetch.cacheForNavigation) {
|
|
270
303
|
headers.set(NEXT_ROUTER_PREFETCH_HEADER, "1");
|
|
271
304
|
headers.set(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, "/__PAGE__");
|
|
272
305
|
} else if (shouldSendSegmentPrefetchHeaders) {
|
|
@@ -277,10 +310,9 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
277
310
|
const additionalRscUrls = rewrittenPrefetchHref && rewrittenPrefetchHref !== fullHref ? [await createRscRequestUrl(rewrittenPrefetchHref, headers)] : [];
|
|
278
311
|
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
279
312
|
const prefetched = getPrefetchedUrls();
|
|
313
|
+
if (autoPrefetch.cacheForNavigation) discardLearningOnlyPrefetchCacheEntry(rscUrl, interceptionContext);
|
|
280
314
|
if (prefetched.has(cacheKey)) {
|
|
281
315
|
if (!autoPrefetch.cacheForNavigation) return;
|
|
282
|
-
const existing = getPrefetchCache().get(cacheKey);
|
|
283
|
-
if (existing?.cacheForNavigation === false) existing.cacheForNavigation = true;
|
|
284
316
|
}
|
|
285
317
|
const fetchFullRscPayload = () => scheduleAppPrefetchFetch(() => fetch(rscUrl, {
|
|
286
318
|
headers,
|
|
@@ -289,8 +321,9 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
289
321
|
purpose: "prefetch"
|
|
290
322
|
}), priority);
|
|
291
323
|
const fetchLoadingShellForReuse = async () => {
|
|
292
|
-
const shellHeaders =
|
|
324
|
+
const shellHeaders = createAppPrefetchRequestHeaders({
|
|
293
325
|
interceptionContext,
|
|
326
|
+
fetchPriority: priority,
|
|
294
327
|
renderMode: APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL
|
|
295
328
|
});
|
|
296
329
|
shellHeaders.set(NEXT_ROUTER_PREFETCH_HEADER, "1");
|
|
@@ -317,8 +350,9 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
317
350
|
await shellEntry?.pending?.catch(() => {});
|
|
318
351
|
};
|
|
319
352
|
const fetchAliasCacheHitProbe = async () => {
|
|
320
|
-
const probeHeaders =
|
|
353
|
+
const probeHeaders = createAppPrefetchRequestHeaders({
|
|
321
354
|
interceptionContext,
|
|
355
|
+
fetchPriority: priority,
|
|
322
356
|
renderMode: APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL
|
|
323
357
|
});
|
|
324
358
|
probeHeaders.set(NEXT_ROUTER_PREFETCH_HEADER, "1");
|
|
@@ -350,8 +384,9 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
350
384
|
await fetchLoadingShellForReuse();
|
|
351
385
|
return fetchFullRscPayload();
|
|
352
386
|
}
|
|
353
|
-
const shellHeaders =
|
|
387
|
+
const shellHeaders = createAppPrefetchRequestHeaders({
|
|
354
388
|
interceptionContext,
|
|
389
|
+
fetchPriority: priority,
|
|
355
390
|
renderMode: void 0
|
|
356
391
|
});
|
|
357
392
|
shellHeaders.set(NEXT_ROUTER_PREFETCH_HEADER, "1");
|
|
@@ -389,12 +424,18 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
389
424
|
purpose: "prefetch"
|
|
390
425
|
}), priority);
|
|
391
426
|
})() : fetchFullRscPayload();
|
|
392
|
-
if (mode === "full" && autoPrefetch.cacheForNavigation && autoPrefetch.prefetchShellFirst && mountedSlotsHeader === null && !gateViaExplicitSearchShell) fetchLoadingShellForReuse();
|
|
427
|
+
if (!__prefetchInlining && mode === "full" && autoPrefetch.cacheForNavigation && autoPrefetch.prefetchShellFirst && mountedSlotsHeader === null && !gateViaExplicitSearchShell) fetchLoadingShellForReuse();
|
|
393
428
|
prefetchRscResponse(rscUrl, fetchPromise, interceptionContext, mountedSlotsHeader, void 0, {
|
|
394
429
|
cacheForNavigation: autoPrefetch.cacheForNavigation,
|
|
395
|
-
fallbackTtlMs: PREFETCH_CACHE_TTL,
|
|
430
|
+
fallbackTtlMs: autoPrefetch.fallbackTtl === "dynamic" ? DYNAMIC_NAVIGATION_CACHE_TTL : PREFETCH_CACHE_TTL,
|
|
431
|
+
minimumTtlMs: autoPrefetch.minimumTtlMs,
|
|
396
432
|
optimisticRouteShell: isOptimisticRouteShellPrefetch,
|
|
397
433
|
prefetchKind: isOptimisticRouteShellPrefetch ? "loading-shell" : "navigation",
|
|
434
|
+
prepareSnapshot: autoPrefetch.cacheForNavigation ? async (snapshot) => {
|
|
435
|
+
const preparePrefetchResponse = getNavigationRuntime()?.functions.preparePrefetchResponse;
|
|
436
|
+
if (!preparePrefetchResponse) throw new Error("App Router prefetch preparation is unavailable");
|
|
437
|
+
return await preparePrefetchResponse(restoreRscResponse(snapshot));
|
|
438
|
+
} : void 0,
|
|
398
439
|
searchAgnosticShell: isAutomaticSearchParamShell && !hasSearchAgnosticShell
|
|
399
440
|
});
|
|
400
441
|
} else if (HAS_PAGES_ROUTER && window.__NEXT_DATA__) {
|
|
@@ -427,7 +468,7 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
427
468
|
async function promotePrefetchEntriesForNavigation(href) {
|
|
428
469
|
if (typeof window === "undefined") return;
|
|
429
470
|
if (!hasAppNavigationRuntime()) return;
|
|
430
|
-
const [{ getPrefetchCache }, { stripRscCacheBustingSearchParam, stripRscSuffix }] = await Promise.all([
|
|
471
|
+
const [{ getPrefetchCache }, { stripRscCacheBustingSearchParam, stripRscSuffix }] = await Promise.all([loadNavigationModule(), import("../server/app-rsc-cache-busting.js")]);
|
|
431
472
|
let target;
|
|
432
473
|
try {
|
|
433
474
|
target = new URL(toBrowserNavigationHref(href, window.location.href, __basePath), window.location.href);
|
|
@@ -581,17 +622,29 @@ function resolveConcreteRouteHref(href, as) {
|
|
|
581
622
|
return interpolateDynamicRouteHref(typeof href === "string" ? href : resolveHref(href), as, typeof href === "string" || !href.query || typeof href.query === "string" ? void 0 : href.query)?.href || null;
|
|
582
623
|
}
|
|
583
624
|
const Link = forwardRef(function Link({ href, as, replace = false, prefetch: prefetchProp, scroll = true, shallow = false, children: childrenProp, onClick, onMouseEnter, onTouchStart, onNavigate, unstable_dynamicOnHover = false, legacyBehavior = false, passHref = false, transitionTypes: _transitionTypes, ...rest }, forwardedRef) {
|
|
625
|
+
const pagesRouter = useContext(RouterContext);
|
|
584
626
|
const asHref = as === void 0 ? void 0 : resolveHref(as);
|
|
627
|
+
const hrefStr = resolveHref(href);
|
|
585
628
|
const { locale, ...restWithoutLocale } = rest;
|
|
586
629
|
let children = childrenProp;
|
|
587
630
|
if (legacyBehavior && (typeof childrenProp === "string" || typeof childrenProp === "number")) children = React.createElement("a", null, childrenProp);
|
|
588
|
-
const
|
|
589
|
-
const
|
|
590
|
-
const
|
|
631
|
+
const hrefForImplicitInterpolation = isAbsoluteOrProtocolRelativeUrl(hrefStr) ? hrefStr.startsWith("//") ? null : toSameOriginAppPath(hrefStr, __basePath) : hrefStr;
|
|
632
|
+
const implicitDynamicRouteHref = HAS_PAGES_ROUTER && pagesRouter !== null && asHref === void 0 && hrefForImplicitInterpolation !== null ? resolveDynamicRouteHref(hrefForImplicitInterpolation) : null;
|
|
633
|
+
const dynamicRouteHref = implicitDynamicRouteHref ? {
|
|
634
|
+
...implicitDynamicRouteHref,
|
|
635
|
+
href: hrefStr
|
|
636
|
+
} : null;
|
|
637
|
+
const pagesAsHref = asHref ?? dynamicRouteHref?.as;
|
|
638
|
+
const unresolvedHref = pagesAsHref ?? hrefStr;
|
|
639
|
+
const rawResolvedHref = typeof unresolvedHref === "string" && unresolvedHref.startsWith("#") && !getNavigationRuntime()?.functions.navigate ? resolvePagesQueryOnlyHref(unresolvedHref) : unresolvedHref;
|
|
640
|
+
const concreteRouteHref = HAS_PAGES_ROUTER ? resolveConcreteRouteHref(dynamicRouteHref ? hrefForImplicitInterpolation ?? href : href, pagesAsHref) : null;
|
|
641
|
+
const routeHrefRaw = dynamicRouteHref?.href ?? concreteRouteHref ?? hrefStr;
|
|
642
|
+
const prefetchRouteHrefRaw = concreteRouteHref ?? routeHrefRaw;
|
|
643
|
+
const hasPagesHrefAsPair = HAS_PAGES_ROUTER && typeof pagesAsHref === "string" && typeof routeHrefRaw === "string" && pagesAsHref !== routeHrefRaw;
|
|
591
644
|
const resolvedHref = typeof rawResolvedHref === "string" ? warnAndNormalizeRepeatedSlashesInHref(rawResolvedHref) : rawResolvedHref;
|
|
592
645
|
const isDangerous = typeof resolvedHref === "string" && isDangerousScheme(resolvedHref);
|
|
593
646
|
const normalizedHref = normalizePathTrailingSlash(applyLocaleToHref(isDangerous ? "/" : resolvedHref, locale), __trailingSlash);
|
|
594
|
-
const normalizedRouteHref =
|
|
647
|
+
const normalizedRouteHref = hasPagesHrefAsPair ? normalizePathTrailingSlash(applyLocaleToHref(isDangerous ? "/" : prefetchRouteHrefRaw, locale), __trailingSlash) : normalizedHref;
|
|
595
648
|
const fullHref = normalizePathTrailingSlash(withBasePath(normalizedHref, __basePath), __trailingSlash);
|
|
596
649
|
const [pending, setPending] = useState(false);
|
|
597
650
|
const mountedRef = useRef(true);
|
|
@@ -713,7 +766,7 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
713
766
|
e.preventDefault();
|
|
714
767
|
const hasAppNavigationRuntime = Boolean(getNavigationRuntime()?.functions.navigate);
|
|
715
768
|
const pagesNavigateHref = HAS_PAGES_ROUTER && resolvedHref.startsWith("?") ? resolvePagesLinkNavigationHref(resolvedHref, locale) : navigateHref;
|
|
716
|
-
const pagesAsForLink =
|
|
769
|
+
const pagesAsForLink = hasPagesHrefAsPair ? pagesNavigateHref : void 0;
|
|
717
770
|
const pagesHrefForLink = pagesAsForLink === void 0 ? pagesNavigateHref : routeHrefRaw;
|
|
718
771
|
const absoluteFullHref = toBrowserNavigationHref(hasAppNavigationRuntime ? navigateHref : pagesNavigateHref, window.location.href, __basePath);
|
|
719
772
|
if (onNavigate) try {
|
|
@@ -731,19 +784,19 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
731
784
|
onNavigate(navEvent);
|
|
732
785
|
if (navEvent.defaultPrevented) return;
|
|
733
786
|
} catch {}
|
|
734
|
-
const hybridOwner = HAS_PAGES_ROUTER && hasAppNavigationRuntime ?
|
|
787
|
+
const hybridOwner = (HAS_PAGES_ROUTER && hasAppNavigationRuntime ? loadedHybridClientRouteOwnerModule ?? await loadHybridClientRouteOwnerModule() : null)?.resolveHybridClientRouteOwner(navigateHref, __basePath);
|
|
735
788
|
if (HAS_PAGES_ROUTER && hasAppNavigationRuntime && ["pages", "document"].includes(hybridOwner ?? "")) {
|
|
736
789
|
if (replace) window.location.replace(absoluteFullHref);
|
|
737
790
|
else window.location.assign(absoluteFullHref);
|
|
738
791
|
return;
|
|
739
792
|
}
|
|
740
793
|
if (hasAppNavigationRuntime) {
|
|
741
|
-
const { navigateClientSide } = await
|
|
794
|
+
const { navigateClientSide } = loadedNavigationModule ?? await loadNavigationModule();
|
|
742
795
|
const setter = setPendingRef.current;
|
|
743
796
|
if (setter) setLinkForCurrentNavigation(setter);
|
|
744
797
|
setPending(true);
|
|
745
798
|
React.startTransition(() => {
|
|
746
|
-
navigateClientSide(navigateHref, replace ? "replace" : "push", scroll,
|
|
799
|
+
navigateClientSide(navigateHref, replace ? "replace" : "push", scroll, false).finally(() => {
|
|
747
800
|
if (mountedRef.current) setPending(false);
|
|
748
801
|
if (setter) clearLinkForCurrentNavigation(setter);
|
|
749
802
|
});
|
package/dist/shims/metadata.d.ts
CHANGED
|
@@ -1,31 +1,21 @@
|
|
|
1
1
|
import { ThenableParamsObserver } from "./thenable-params.js";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { ResolvedViewport as ResolvedViewport$1, Viewport as Viewport$1 } from "@vinext/types/next/upstream/dist/lib/metadata/types/metadata-interface";
|
|
3
4
|
|
|
4
5
|
//#region src/shims/metadata.d.ts
|
|
5
|
-
type Viewport =
|
|
6
|
-
|
|
7
|
-
height?: string | number; /** Initial scale */
|
|
8
|
-
initialScale?: number; /** Minimum scale */
|
|
9
|
-
minimumScale?: number; /** Maximum scale */
|
|
10
|
-
maximumScale?: number; /** Whether user can scale */
|
|
11
|
-
userScalable?: boolean; /** Theme color — single color or array of { media, color } */
|
|
12
|
-
themeColor?: string | Array<{
|
|
13
|
-
media?: string;
|
|
14
|
-
color: string;
|
|
15
|
-
}>; /** Color scheme: 'light' | 'dark' | 'light dark' | 'normal' */
|
|
16
|
-
colorScheme?: string;
|
|
17
|
-
};
|
|
6
|
+
type Viewport = Viewport$1;
|
|
7
|
+
type ResolvedViewport = ResolvedViewport$1;
|
|
18
8
|
/**
|
|
19
9
|
* Resolve viewport config from a module. Handles both static `viewport` export
|
|
20
10
|
* and async `generateViewport()` function.
|
|
21
11
|
*/
|
|
22
|
-
declare function resolveModuleViewport(mod: Record<string, unknown>, params
|
|
12
|
+
declare function resolveModuleViewport(mod: Record<string, unknown>, params?: Record<string, string | string[]>, searchParams?: Record<string, string | string[]>, parent?: Promise<ResolvedViewport>, searchParamsObserver?: ThenableParamsObserver): Promise<Viewport | null>;
|
|
23
13
|
/**
|
|
24
14
|
* Merge viewport configs from multiple sources (layouts + page).
|
|
25
15
|
* Later entries override earlier ones.
|
|
26
16
|
*/
|
|
27
|
-
declare const DEFAULT_VIEWPORT:
|
|
28
|
-
declare function mergeViewport(viewportList: Viewport[]):
|
|
17
|
+
declare const DEFAULT_VIEWPORT: ResolvedViewport;
|
|
18
|
+
declare function mergeViewport(viewportList: readonly Viewport[]): ResolvedViewport;
|
|
29
19
|
/**
|
|
30
20
|
* React component that renders viewport meta tags into <head>.
|
|
31
21
|
*/
|
|
@@ -191,28 +181,19 @@ type SocialImageDescriptor = {
|
|
|
191
181
|
};
|
|
192
182
|
type IconDescriptor = {
|
|
193
183
|
url: string | URL;
|
|
194
|
-
sizes?: string;
|
|
195
184
|
type?: string;
|
|
196
|
-
media?: string;
|
|
197
|
-
};
|
|
198
|
-
type AppleIconDescriptor = {
|
|
199
|
-
url: string | URL;
|
|
200
185
|
sizes?: string;
|
|
201
|
-
|
|
186
|
+
color?: string;
|
|
187
|
+
rel?: string;
|
|
188
|
+
media?: string;
|
|
189
|
+
fetchPriority?: "high" | "low" | "auto";
|
|
202
190
|
};
|
|
203
191
|
type IconInput = string | URL | IconDescriptor;
|
|
204
|
-
type AppleIconInput = string | URL | AppleIconDescriptor;
|
|
205
|
-
type OtherIconDescriptor = {
|
|
206
|
-
rel: string;
|
|
207
|
-
url: string | URL;
|
|
208
|
-
sizes?: string;
|
|
209
|
-
type?: string;
|
|
210
|
-
};
|
|
211
192
|
type IconsMap = {
|
|
212
193
|
icon?: IconInput | IconInput[];
|
|
213
|
-
shortcut?:
|
|
214
|
-
apple?:
|
|
215
|
-
other?:
|
|
194
|
+
shortcut?: IconInput | IconInput[];
|
|
195
|
+
apple?: IconInput | IconInput[];
|
|
196
|
+
other?: IconDescriptor | IconDescriptor[];
|
|
216
197
|
};
|
|
217
198
|
type IconsMetadata = IconInput | IconInput[] | IconsMap;
|
|
218
199
|
type MetadataMergeEntry = {
|
|
@@ -273,14 +254,17 @@ type MetadataHeadProps = {
|
|
|
273
254
|
metadata: Metadata;
|
|
274
255
|
pathname?: string;
|
|
275
256
|
trailingSlash?: boolean;
|
|
257
|
+
streamedIconKey?: string;
|
|
276
258
|
};
|
|
277
259
|
declare function renderMetadataToHtml(metadata: Metadata, pathname?: string, options?: {
|
|
278
260
|
trailingSlash?: boolean;
|
|
261
|
+
streamedIconKey?: string;
|
|
279
262
|
}): string;
|
|
280
263
|
declare function MetadataHead({
|
|
281
264
|
metadata,
|
|
282
265
|
pathname,
|
|
283
|
-
trailingSlash
|
|
266
|
+
trailingSlash,
|
|
267
|
+
streamedIconKey
|
|
284
268
|
}: MetadataHeadProps): React.JSX.Element;
|
|
285
269
|
//#endregion
|
|
286
|
-
export { DEFAULT_VIEWPORT, Metadata, MetadataHead, MetadataMergeEntry, Viewport, ViewportHead, mergeMetadata, mergeMetadataEntries, mergeViewport, postProcessMetadata, renderMetadataToHtml, resolveModuleMetadata, resolveModuleViewport };
|
|
270
|
+
export { DEFAULT_VIEWPORT, Metadata, MetadataHead, MetadataMergeEntry, ResolvedViewport, Viewport, ViewportHead, mergeMetadata, mergeMetadataEntries, mergeViewport, postProcessMetadata, renderMetadataToHtml, resolveModuleMetadata, resolveModuleViewport };
|
package/dist/shims/metadata.js
CHANGED
|
@@ -9,18 +9,20 @@ import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
|
9
9
|
* Handles `export const metadata` and `export async function generateMetadata()`.
|
|
10
10
|
* Resolves metadata from layouts and pages (pages override layouts).
|
|
11
11
|
*/
|
|
12
|
+
const USE_CACHE_FUNCTION_SYMBOL = Symbol.for("vinext.useCacheFunction");
|
|
13
|
+
const USE_CACHE_ACCEPTS_SECOND_ARGUMENT_SYMBOL = Symbol.for("vinext.useCacheAcceptsSecondArgument");
|
|
12
14
|
/**
|
|
13
15
|
* Resolve viewport config from a module. Handles both static `viewport` export
|
|
14
16
|
* and async `generateViewport()` function.
|
|
15
17
|
*/
|
|
16
|
-
async function resolveModuleViewport(mod, params, searchParams, searchParamsObserver) {
|
|
18
|
+
async function resolveModuleViewport(mod, params = {}, searchParams, parent = Promise.resolve(mergeViewport([])), searchParamsObserver) {
|
|
17
19
|
if (typeof mod.generateViewport === "function") {
|
|
18
20
|
const asyncParams = makeThenableParams(params);
|
|
19
21
|
const props = searchParams === void 0 ? { params: asyncParams } : {
|
|
20
22
|
params: asyncParams,
|
|
21
23
|
searchParams: makeThenableParams(searchParams, searchParamsObserver)
|
|
22
24
|
};
|
|
23
|
-
return await mod.generateViewport(props);
|
|
25
|
+
return await mod.generateViewport(props, parent);
|
|
24
26
|
}
|
|
25
27
|
if (mod.viewport && typeof mod.viewport === "object") return mod.viewport;
|
|
26
28
|
return null;
|
|
@@ -31,47 +33,92 @@ async function resolveModuleViewport(mod, params, searchParams, searchParamsObse
|
|
|
31
33
|
*/
|
|
32
34
|
const DEFAULT_VIEWPORT = {
|
|
33
35
|
width: "device-width",
|
|
34
|
-
initialScale: 1
|
|
36
|
+
initialScale: 1,
|
|
37
|
+
themeColor: null,
|
|
38
|
+
colorScheme: null
|
|
35
39
|
};
|
|
36
40
|
function mergeViewport(viewportList) {
|
|
37
41
|
const merged = { ...DEFAULT_VIEWPORT };
|
|
38
|
-
for (const
|
|
42
|
+
for (const viewport of viewportList) for (const viewportKey in viewport) switch (viewportKey) {
|
|
43
|
+
case "themeColor":
|
|
44
|
+
merged.themeColor = resolveThemeColor(viewport.themeColor);
|
|
45
|
+
break;
|
|
46
|
+
case "colorScheme":
|
|
47
|
+
merged.colorScheme = viewport.colorScheme || null;
|
|
48
|
+
break;
|
|
49
|
+
case "width":
|
|
50
|
+
merged.width = viewport.width;
|
|
51
|
+
break;
|
|
52
|
+
case "height":
|
|
53
|
+
merged.height = viewport.height;
|
|
54
|
+
break;
|
|
55
|
+
case "initialScale":
|
|
56
|
+
merged.initialScale = viewport.initialScale;
|
|
57
|
+
break;
|
|
58
|
+
case "minimumScale":
|
|
59
|
+
merged.minimumScale = viewport.minimumScale;
|
|
60
|
+
break;
|
|
61
|
+
case "maximumScale":
|
|
62
|
+
merged.maximumScale = viewport.maximumScale;
|
|
63
|
+
break;
|
|
64
|
+
case "userScalable":
|
|
65
|
+
merged.userScalable = viewport.userScalable;
|
|
66
|
+
break;
|
|
67
|
+
case "viewportFit":
|
|
68
|
+
merged.viewportFit = viewport.viewportFit;
|
|
69
|
+
break;
|
|
70
|
+
case "interactiveWidget":
|
|
71
|
+
merged.interactiveWidget = viewport.interactiveWidget;
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
}
|
|
39
75
|
return merged;
|
|
40
76
|
}
|
|
77
|
+
const VIEWPORT_META_NAMES = {
|
|
78
|
+
width: "width",
|
|
79
|
+
height: "height",
|
|
80
|
+
initialScale: "initial-scale",
|
|
81
|
+
minimumScale: "minimum-scale",
|
|
82
|
+
maximumScale: "maximum-scale",
|
|
83
|
+
userScalable: "user-scalable",
|
|
84
|
+
viewportFit: "viewport-fit",
|
|
85
|
+
interactiveWidget: "interactive-widget"
|
|
86
|
+
};
|
|
41
87
|
/**
|
|
42
88
|
* React component that renders viewport meta tags into <head>.
|
|
43
89
|
*/
|
|
44
90
|
function ViewportHead({ viewport }) {
|
|
91
|
+
const resolvedViewport = mergeViewport([viewport]);
|
|
45
92
|
const elements = [];
|
|
46
93
|
let key = 0;
|
|
47
94
|
const parts = [];
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (viewport.userScalable !== void 0) parts.push(`user-scalable=${viewport.userScalable ? "yes" : "no"}`);
|
|
95
|
+
for (const key of Object.keys(VIEWPORT_META_NAMES)) {
|
|
96
|
+
const value = resolvedViewport[key];
|
|
97
|
+
if (value == null) continue;
|
|
98
|
+
parts.push(`${VIEWPORT_META_NAMES[key]}=${key === "userScalable" ? value ? "yes" : "no" : value}`);
|
|
99
|
+
}
|
|
54
100
|
if (parts.length > 0) elements.push(/* @__PURE__ */ jsx("meta", {
|
|
55
101
|
name: "viewport",
|
|
56
102
|
content: parts.join(", ")
|
|
57
103
|
}, key++));
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
name: "theme-color",
|
|
65
|
-
content: entry.color,
|
|
66
|
-
...entry.media ? { media: entry.media } : {}
|
|
67
|
-
}, key++));
|
|
68
|
-
}
|
|
69
|
-
if (viewport.colorScheme) elements.push(/* @__PURE__ */ jsx("meta", {
|
|
104
|
+
if (resolvedViewport.themeColor) for (const entry of resolvedViewport.themeColor) elements.push(/* @__PURE__ */ jsx("meta", {
|
|
105
|
+
name: "theme-color",
|
|
106
|
+
content: entry.color,
|
|
107
|
+
...entry.media ? { media: entry.media } : {}
|
|
108
|
+
}, key++));
|
|
109
|
+
if (resolvedViewport.colorScheme) elements.push(/* @__PURE__ */ jsx("meta", {
|
|
70
110
|
name: "color-scheme",
|
|
71
|
-
content:
|
|
111
|
+
content: resolvedViewport.colorScheme
|
|
72
112
|
}, key++));
|
|
73
113
|
return /* @__PURE__ */ jsx(Fragment$1, { children: elements });
|
|
74
114
|
}
|
|
115
|
+
function resolveThemeColor(themeColor) {
|
|
116
|
+
if (!themeColor) return null;
|
|
117
|
+
return (Array.isArray(themeColor) ? themeColor : [themeColor]).map((descriptor) => typeof descriptor === "string" ? { color: descriptor } : {
|
|
118
|
+
color: descriptor.color,
|
|
119
|
+
media: descriptor.media
|
|
120
|
+
});
|
|
121
|
+
}
|
|
75
122
|
/**
|
|
76
123
|
* Merge metadata from multiple sources (layouts + page).
|
|
77
124
|
*
|
|
@@ -219,12 +266,15 @@ function mergeMetadataEntries(entries) {
|
|
|
219
266
|
*/
|
|
220
267
|
async function resolveModuleMetadata(mod, params = {}, searchParams, parent = Promise.resolve({}), searchParamsObserver) {
|
|
221
268
|
if (typeof mod.generateMetadata === "function") {
|
|
269
|
+
const generateMetadata = mod.generateMetadata;
|
|
222
270
|
const asyncParams = makeThenableParams(params);
|
|
223
271
|
const props = searchParams === void 0 ? { params: asyncParams } : {
|
|
224
272
|
params: asyncParams,
|
|
225
273
|
searchParams: makeThenableParams(searchParams, searchParamsObserver)
|
|
226
274
|
};
|
|
227
|
-
|
|
275
|
+
const isUseCacheFunction = Reflect.get(generateMetadata, USE_CACHE_FUNCTION_SYMBOL) === true;
|
|
276
|
+
const acceptsSecondArgument = Reflect.get(generateMetadata, USE_CACHE_ACCEPTS_SECOND_ARGUMENT_SYMBOL);
|
|
277
|
+
return await (!isUseCacheFunction || (typeof acceptsSecondArgument === "boolean" ? acceptsSecondArgument : generateMetadata.length >= 2) ? generateMetadata(props, parent) : generateMetadata(props));
|
|
228
278
|
}
|
|
229
279
|
if (mod.metadata && typeof mod.metadata === "object") return mod.metadata;
|
|
230
280
|
return null;
|
|
@@ -370,12 +420,15 @@ function renderMetadataElementToHtml(node) {
|
|
|
370
420
|
"content"
|
|
371
421
|
])}>`;
|
|
372
422
|
case "link": return `<link${renderMetadataAttributes(props, [
|
|
423
|
+
"data-vinext-streamed-icon",
|
|
373
424
|
"rel",
|
|
374
425
|
"href",
|
|
375
426
|
"hrefLang",
|
|
376
|
-
"media",
|
|
377
427
|
"type",
|
|
378
|
-
"sizes"
|
|
428
|
+
"sizes",
|
|
429
|
+
"color",
|
|
430
|
+
"media",
|
|
431
|
+
"fetchPriority"
|
|
379
432
|
])}>`;
|
|
380
433
|
default: return "";
|
|
381
434
|
}
|
|
@@ -384,10 +437,11 @@ function renderMetadataToHtml(metadata, pathname = "/", options) {
|
|
|
384
437
|
return renderMetadataElementToHtml(MetadataHead({
|
|
385
438
|
metadata,
|
|
386
439
|
pathname,
|
|
387
|
-
trailingSlash: options?.trailingSlash
|
|
440
|
+
trailingSlash: options?.trailingSlash,
|
|
441
|
+
streamedIconKey: options?.streamedIconKey
|
|
388
442
|
}));
|
|
389
443
|
}
|
|
390
|
-
function MetadataHead({ metadata, pathname = "/", trailingSlash }) {
|
|
444
|
+
function MetadataHead({ metadata, pathname = "/", trailingSlash, streamedIconKey }) {
|
|
391
445
|
const elements = [];
|
|
392
446
|
let key = 0;
|
|
393
447
|
const base = metadata.metadataBase;
|
|
@@ -675,35 +729,23 @@ function MetadataHead({ metadata, pathname = "/", trailingSlash }) {
|
|
|
675
729
|
}
|
|
676
730
|
if (metadata.icons) {
|
|
677
731
|
const iconEntries = isIconsMap(metadata.icons) ? normalizeUrlDescriptorEntries(metadata.icons.icon, (url) => ({ url })) : normalizeUrlDescriptorEntries(metadata.icons, (url) => ({ url }));
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
for (const
|
|
681
|
-
|
|
682
|
-
|
|
732
|
+
let streamedIconOrder = 0;
|
|
733
|
+
const appendIcons = (entries, defaultRel) => {
|
|
734
|
+
for (const { url, rel, type, sizes, color, media, fetchPriority } of entries) elements.push(/* @__PURE__ */ jsx("link", {
|
|
735
|
+
"data-vinext-streamed-icon": streamedIconKey ? `${streamedIconKey}:${streamedIconOrder++}` : void 0,
|
|
736
|
+
rel: rel || defaultRel,
|
|
737
|
+
href: stringifyUrl(url),
|
|
738
|
+
type,
|
|
739
|
+
sizes,
|
|
740
|
+
color,
|
|
741
|
+
media,
|
|
742
|
+
fetchPriority
|
|
683
743
|
}, key++));
|
|
684
|
-
}
|
|
685
|
-
if (
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
...i.type ? { type: i.type } : {},
|
|
690
|
-
...i.media ? { media: i.media } : {}
|
|
691
|
-
}, key++));
|
|
692
|
-
if (isIconsMap(metadata.icons) && metadata.icons.apple) for (const a of normalizeUrlDescriptorEntries(metadata.icons.apple, (url) => ({ url }))) elements.push(/* @__PURE__ */ jsx("link", {
|
|
693
|
-
rel: "apple-touch-icon",
|
|
694
|
-
href: stringifyUrl(a.url),
|
|
695
|
-
...a.sizes ? { sizes: a.sizes } : {},
|
|
696
|
-
...a.type ? { type: a.type } : {}
|
|
697
|
-
}, key++));
|
|
698
|
-
if (isIconsMap(metadata.icons) && metadata.icons.other) {
|
|
699
|
-
const others = Array.isArray(metadata.icons.other) ? metadata.icons.other : [metadata.icons.other];
|
|
700
|
-
for (const o of others) elements.push(/* @__PURE__ */ jsx("link", {
|
|
701
|
-
rel: o.rel,
|
|
702
|
-
href: stringifyUrl(o.url),
|
|
703
|
-
...o.sizes ? { sizes: o.sizes } : {},
|
|
704
|
-
...o.type ? { type: o.type } : {}
|
|
705
|
-
}, key++));
|
|
706
|
-
}
|
|
744
|
+
};
|
|
745
|
+
if (isIconsMap(metadata.icons) && metadata.icons.shortcut) appendIcons(normalizeUrlDescriptorEntries(metadata.icons.shortcut, (url) => ({ url })), "shortcut icon");
|
|
746
|
+
if (iconEntries.length > 0) appendIcons(iconEntries, "icon");
|
|
747
|
+
if (isIconsMap(metadata.icons) && metadata.icons.apple) appendIcons(normalizeUrlDescriptorEntries(metadata.icons.apple, (url) => ({ url })), "apple-touch-icon");
|
|
748
|
+
if (isIconsMap(metadata.icons) && metadata.icons.other) appendIcons(normalizeUrlDescriptorEntries(metadata.icons.other, (url) => ({ url })), "icon");
|
|
707
749
|
}
|
|
708
750
|
if (metadata.manifest) elements.push(/* @__PURE__ */ jsx("link", {
|
|
709
751
|
rel: "manifest",
|