vinext 1.4.0 → 1.4.1
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 +20 -20
- package/dist/build/prerender.js +3 -2
- package/dist/check.js +3 -6
- package/dist/client/dev-error-overlay-store.d.ts +1 -0
- package/dist/client/dev-error-overlay.d.ts +2 -0
- package/dist/client/dev-error-overlay.js +19 -3
- package/dist/config/config-matchers.js +2 -0
- package/dist/config/destination-params.d.ts +2 -1
- package/dist/config/destination-params.js +52 -2
- package/dist/config/next-config.d.ts +6 -0
- package/dist/config/next-config.js +18 -3
- package/dist/entries/app-rsc-entry.js +0 -1
- package/dist/entries/pages-server-entry.js +3 -1
- package/dist/index.js +29 -20
- package/dist/plugins/strip-server-exports.js +2 -1
- package/dist/server/api-handler.js +2 -1
- package/dist/server/app-browser-entry.js +7 -3
- package/dist/server/app-browser-rsc-redirect.js +3 -3
- package/dist/server/app-browser-server-action-client.js +2 -2
- package/dist/server/app-browser-visible-commit.js +2 -2
- package/dist/server/app-optimistic-routing.js +2 -3
- package/dist/server/app-page-boundary-render.js +5 -10
- package/dist/server/app-page-dispatch.d.ts +0 -1
- package/dist/server/app-page-dispatch.js +0 -1
- package/dist/server/app-page-element-builder.js +3 -3
- package/dist/server/app-page-execution.js +9 -6
- package/dist/server/app-page-render.d.ts +0 -1
- package/dist/server/app-page-render.js +14 -14
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.js +22 -5
- package/dist/server/app-page-stream.d.ts +10 -8
- package/dist/server/app-page-stream.js +2 -1
- package/dist/server/app-request-stage-independent-entry.js +1 -1
- package/dist/server/app-route-handler-execution.js +3 -2
- package/dist/server/app-route-handler-runtime.d.ts +1 -1
- package/dist/server/app-route-handler-runtime.js +11 -7
- package/dist/server/app-router-entry.js +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +10 -10
- package/dist/server/app-rsc-cache-busting.js +27 -68
- package/dist/server/app-rsc-error-handler.js +1 -1
- package/dist/server/app-rsc-errors.js +4 -1
- package/dist/server/app-rsc-handler.js +53 -62
- package/dist/server/app-rsc-request-normalization.d.ts +10 -12
- package/dist/server/app-rsc-request-normalization.js +11 -14
- package/dist/server/app-rsc-response-stage.js +4 -12
- package/dist/server/app-server-action-execution.js +8 -4
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +13 -8
- package/dist/server/app-worker-stages.d.ts +12 -3
- package/dist/server/app-worker-stages.js +37 -4
- package/dist/server/bfcache-identity.d.ts +7 -0
- package/dist/server/bfcache-identity.js +10 -1
- package/dist/server/cacheability-manifest.js +1 -2
- package/dist/server/dev-origin-check.d.ts +2 -1
- package/dist/server/dev-origin-check.js +2 -1
- package/dist/server/dev-server.js +2 -1
- package/dist/server/image-optimization.d.ts +5 -0
- package/dist/server/image-optimization.js +6 -1
- package/dist/server/isr-cache.js +4 -1
- package/dist/server/metadata-route-response.js +1 -1
- package/dist/server/middleware-matcher.js +19 -6
- package/dist/server/middleware-runtime.js +6 -2
- package/dist/server/multi-stage.d.ts +7 -3
- package/dist/server/pages-node-compat.d.ts +1 -1
- package/dist/server/pages-node-compat.js +2 -0
- package/dist/server/pages-page-data.js +2 -1
- package/dist/server/pages-page-handler.js +17 -6
- package/dist/server/pages-page-response.d.ts +9 -0
- package/dist/server/pages-page-response.js +18 -4
- package/dist/server/pages-request-stage-entry.js +24 -4
- package/dist/server/pages-router-entry.js +3 -2
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +42 -8
- package/dist/server/request-error-log.d.ts +9 -0
- package/dist/server/request-error-log.js +13 -0
- package/dist/server/request-pipeline.d.ts +9 -4
- package/dist/server/request-pipeline.js +23 -15
- package/dist/server/rsc-completion-metadata.js +3 -0
- package/dist/server/static-file-cache.d.ts +9 -0
- package/dist/server/static-file-cache.js +13 -2
- package/dist/shims/cache-request-state.d.ts +6 -6
- package/dist/shims/cache-request-state.js +6 -36
- package/dist/shims/cache-runtime.d.ts +3 -1
- package/dist/shims/cache-runtime.js +77 -47
- package/dist/shims/cache.d.ts +10 -5
- package/dist/shims/cache.js +35 -22
- package/dist/shims/client-hook-error.d.ts +2 -0
- package/dist/shims/client-hook-error.js +16 -1
- package/dist/shims/fetch-cache.js +6 -2
- package/dist/shims/headers.d.ts +2 -1
- package/dist/shims/headers.js +5 -3
- package/dist/shims/internal/cache-context-accessor.d.ts +1 -1
- package/dist/shims/link.js +5 -10
- package/dist/shims/navigation.js +2 -3
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/slot.d.ts +6 -2
- package/dist/shims/slot.js +10 -3
- package/dist/shims/unified-request-context.d.ts +6 -0
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/utils/cache-life-profiles.d.ts +33 -0
- package/dist/utils/cache-life-profiles.js +111 -0
- package/dist/utils/middleware-request-headers.d.ts +14 -3
- package/dist/utils/middleware-request-headers.js +54 -7
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { stripBasePath } from "../utils/base-path.js";
|
|
|
3
3
|
import { decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
4
4
|
import { extractRawRoutePatternParams, matchRoutePattern } from "../routing/route-pattern.js";
|
|
5
5
|
import { buildOptimisticRouteTrie, matchOptimisticRouteTrie } from "../routing/optimistic-route-trie.js";
|
|
6
|
-
import { stripRscCacheBustingSearchParam
|
|
6
|
+
import { stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
7
7
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
8
8
|
import "./app-elements.js";
|
|
9
9
|
import { createNestedBfcacheSlotSegmentId, deriveBfcacheSegmentIdentity, isNestedBfcacheSlotSegmentId } from "./bfcache-identity.js";
|
|
@@ -36,8 +36,7 @@ function hrefToRouteParts(href, basePath) {
|
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
38
|
stripRscCacheBustingSearchParam(url);
|
|
39
|
-
const
|
|
40
|
-
const appPathname = stripBasePath(withoutRscSuffix, basePath);
|
|
39
|
+
const appPathname = stripBasePath(url.pathname, basePath);
|
|
41
40
|
const pathname = appPathname === "" ? "/" : appPathname;
|
|
42
41
|
return {
|
|
43
42
|
normalized: splitPathnameForRouteMatch(pathname),
|
|
@@ -3,13 +3,12 @@ import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
|
3
3
|
import { NEVER_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
|
|
4
4
|
import { isRenderDynamicLatched, isStaticGenerationAccessError } from "../shims/internal/headers-state.js";
|
|
5
5
|
import { copyLinkHeaderProvenance } from "./app-response-header-provenance.js";
|
|
6
|
-
import { stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
7
6
|
import { createArtifactCompatibilityEnvelope } from "./artifact-compatibility.js";
|
|
8
7
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
9
8
|
import "./app-elements.js";
|
|
10
9
|
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
11
10
|
import { ErrorBoundary, GlobalErrorBoundary, SerializedErrorBoundary } from "../shims/error-boundary.js";
|
|
12
|
-
import {
|
|
11
|
+
import { rewriteClientHookError } from "../shims/client-hook-error.js";
|
|
13
12
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
14
13
|
import { withUseCacheLayoutMarker } from "../shims/internal/app-page-props-cache-key.js";
|
|
15
14
|
import { MetadataHead, ViewportHead } from "../shims/metadata.js";
|
|
@@ -258,7 +257,7 @@ async function renderAppPageHttpAccessFallback(options) {
|
|
|
258
257
|
if (!boundaryComponent) return null;
|
|
259
258
|
const layoutModules = options.layoutModules ?? options.route?.layouts ?? options.rootLayouts;
|
|
260
259
|
const pathname = new URL(options.requestUrl).pathname;
|
|
261
|
-
const routePathname = options.routePathname ??
|
|
260
|
+
const routePathname = options.routePathname ?? stripBasePath(pathname, options.basePath ?? "");
|
|
262
261
|
const headBoundaryModule = options.headBoundaryModule ?? boundaryModule;
|
|
263
262
|
const headLayoutModules = options.headLayoutModules ?? layoutModules;
|
|
264
263
|
const routeSegments = resolveHttpAccessFallbackHeadRouteSegments(options.route, headLayoutModules);
|
|
@@ -612,6 +611,7 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
612
611
|
skipLayoutWrapping: errorBoundary.isGlobalError
|
|
613
612
|
});
|
|
614
613
|
};
|
|
614
|
+
const isErrorStatus = errorBoundary.isGlobalError || !options.isRscRequest;
|
|
615
615
|
const renderWith = async (BoundaryComponent) => {
|
|
616
616
|
const response = await renderAppPageBoundaryElementResponse({
|
|
617
617
|
...options,
|
|
@@ -621,9 +621,9 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
621
621
|
navigationParams: matchedParams,
|
|
622
622
|
route: options.route,
|
|
623
623
|
routePattern: options.route?.pattern,
|
|
624
|
-
status:
|
|
624
|
+
status: isErrorStatus ? 500 : 200
|
|
625
625
|
});
|
|
626
|
-
if (
|
|
626
|
+
if (isErrorStatus) applyCdnResponseHeaders(response.headers, { cacheControl: NEVER_CACHE_CONTROL });
|
|
627
627
|
return response;
|
|
628
628
|
};
|
|
629
629
|
try {
|
|
@@ -636,10 +636,5 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
636
636
|
throw renderError;
|
|
637
637
|
}
|
|
638
638
|
}
|
|
639
|
-
const _clientHookPattern = /\b(useState|useEffect|useReducer|useRef|useContext|useLayoutEffect|useInsertionEffect|useSyncExternalStore|useTransition|useImperativeHandle|useDeferredValue|useActionState|useOptimistic|useEffectEvent)\b.*is not a function/;
|
|
640
|
-
function rewriteClientHookError(error) {
|
|
641
|
-
const match = error.message.match(_clientHookPattern);
|
|
642
|
-
if (match) error.message = buildClientHookErrorMessage(`${match[1]}()`);
|
|
643
|
-
}
|
|
644
639
|
//#endregion
|
|
645
640
|
export { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback };
|
|
@@ -200,7 +200,6 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
200
200
|
hasGenerateStaticParams: boolean;
|
|
201
201
|
/** Whether any segment of the route exports `generateStaticParams`. */
|
|
202
202
|
hasAnyGenerateStaticParams: boolean;
|
|
203
|
-
hasCustomGlobalError?: boolean;
|
|
204
203
|
hasPageDefaultExport: boolean;
|
|
205
204
|
hasPageModule: boolean;
|
|
206
205
|
handlerStart: number;
|
|
@@ -692,7 +692,6 @@ async function dispatchAppPageInner(options) {
|
|
|
692
692
|
return renderPageSpecialError(options, specialError, serveStreamingMetadata, interceptResult.interceptOpts, renderOptions?.isCacheCandidate === true, renderOptions?.caughtDocument, renderedRouteHead);
|
|
693
693
|
},
|
|
694
694
|
renderToReadableStream: options.renderToReadableStream,
|
|
695
|
-
hasCustomGlobalError: options.hasCustomGlobalError,
|
|
696
695
|
prerenderToReadableStream: options.prerenderToReadableStream,
|
|
697
696
|
routePattern: route.pattern,
|
|
698
697
|
scriptNonce: options.scriptNonce,
|
|
@@ -451,9 +451,9 @@ async function buildPageElements(options) {
|
|
|
451
451
|
* slot-scoped params, which `app-page-route-wiring` then hands to the
|
|
452
452
|
* slot page instead of the route's matched params.
|
|
453
453
|
*
|
|
454
|
-
* `routePath` is the already-normalized request pathname (basePath stripped
|
|
455
|
-
*
|
|
456
|
-
*
|
|
454
|
+
* `routePath` is the already-normalized request pathname (basePath stripped).
|
|
455
|
+
* Re-parsing `request.url` here would re-introduce the basePath and silently
|
|
456
|
+
* break the match for any app that configures one.
|
|
457
457
|
*/
|
|
458
458
|
function buildSlotOverrides(route, routeParams, routePath, opts, interceptMetadataOutlet) {
|
|
459
459
|
const overrides = {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER } from "./headers.js";
|
|
2
2
|
import { copyLinkHeaderProvenance, getFrameworkLinkHeader, markFrameworkLinkHeaders } from "./app-response-header-provenance.js";
|
|
3
3
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
4
|
-
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, createRscRedirectLocation } from "./app-rsc-cache-busting.js";
|
|
4
|
+
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, createRscRedirectLocation, toPathAbsolutePathname } from "./app-rsc-cache-busting.js";
|
|
5
5
|
import { isHTTPAccessFallbackError, isThrownNavigationError } from "../shims/navigation-errors.js";
|
|
6
6
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
7
7
|
import { parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
@@ -298,9 +298,11 @@ function toHeaderSafeUrlReference(location) {
|
|
|
298
298
|
* header-safe, so a protocol-relative or scheme-relative target still resolves
|
|
299
299
|
* against the page each client fetched. A relative target resolves against the
|
|
300
300
|
* request's path to a path-only form, which the client resolves against its
|
|
301
|
-
* own origin
|
|
302
|
-
*
|
|
303
|
-
*
|
|
301
|
+
* own origin; a resolved pathname that begins with "//" keeps a "/." prefix
|
|
302
|
+
* so that form stays a path rather than naming another host. Resolving
|
|
303
|
+
* against two placeholder origins tells these apart the way the URL parser
|
|
304
|
+
* does, never depends on the request's origin, and cannot mistake an absolute
|
|
305
|
+
* target naming one placeholder for a relative one.
|
|
304
306
|
*/
|
|
305
307
|
function resolveRedirectTargets(location, requestUrl) {
|
|
306
308
|
try {
|
|
@@ -310,9 +312,10 @@ function resolveRedirectTargets(location, requestUrl) {
|
|
|
310
312
|
headerUrl: toHeaderSafeUrlReference(location)
|
|
311
313
|
};
|
|
312
314
|
const { pathname, search, hash } = first.resolved;
|
|
315
|
+
const target = `${toPathAbsolutePathname(pathname)}${search}${hash}`;
|
|
313
316
|
return {
|
|
314
|
-
digestUrl:
|
|
315
|
-
headerUrl:
|
|
317
|
+
digestUrl: target,
|
|
318
|
+
headerUrl: target
|
|
316
319
|
};
|
|
317
320
|
} catch {
|
|
318
321
|
return {
|
|
@@ -72,7 +72,6 @@ type RenderAppPageLifecycleOptionsBase = {
|
|
|
72
72
|
peekRequestCacheLife?: () => AppPageRequestCacheLife | null;
|
|
73
73
|
getDraftModeCookieHeader: () => string | null | undefined;
|
|
74
74
|
handlerStart: number;
|
|
75
|
-
hasCustomGlobalError?: boolean;
|
|
76
75
|
dynamicStaleTimeSeconds?: number;
|
|
77
76
|
isDynamicError: boolean;
|
|
78
77
|
isDraftMode: boolean;
|
|
@@ -13,6 +13,7 @@ import { isRenderDynamicLatched } from "../shims/internal/headers-state.js";
|
|
|
13
13
|
import { peekDynamicUsage } from "../shims/headers.js";
|
|
14
14
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
15
15
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
16
|
+
import { applyPrerenderCacheLifeHeader, applyPrerenderCacheTagsHeader } from "./prerender-cache-life-header.js";
|
|
16
17
|
import { copyLinkHeaderProvenance, getFrameworkLinkHeader } from "./app-response-header-provenance.js";
|
|
17
18
|
import { traceResponseStartWithCompletion } from "./response-start-tracing.js";
|
|
18
19
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
@@ -21,7 +22,6 @@ import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
|
21
22
|
import "./app-elements.js";
|
|
22
23
|
import { appendRscCompletionMetadata } from "./rsc-completion-metadata.js";
|
|
23
24
|
import { isBailoutToCSRError } from "../shims/navigation-errors.js";
|
|
24
|
-
import { applyPrerenderCacheLifeHeader, applyPrerenderCacheTagsHeader } from "./prerender-cache-life-header.js";
|
|
25
25
|
import { applyClientStaleTimeHeader, applyEdgeRuntimeHeader, buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy, resolveUncacheableCacheControl } from "./app-page-response.js";
|
|
26
26
|
import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageCaughtNotFoundBoundaries, resolveAppPageShellSpecialError, resolveAppPageSpecialError, resolveAppPageSpecialErrorStoredHeaders, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
27
27
|
import { getAppPageLayoutGate } from "./app-page-layout-gate.js";
|
|
@@ -230,7 +230,6 @@ async function prepareAppPageElement(options) {
|
|
|
230
230
|
}
|
|
231
231
|
async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
232
232
|
let dynamicUsageObserved = false;
|
|
233
|
-
let dynamicUsageFinalized = false;
|
|
234
233
|
const isCacheCandidateHtmlRender = options.isCacheCandidate === true && options.isPrerender !== true && !options.isRscRequest;
|
|
235
234
|
const readsRenderDynamicLatch = isCacheCandidateHtmlRender || !options.isRscRequest && options.pprFallbackShellSignal === void 0 && (options.isPrerender === true || isRouteCacheabilityEvaluation());
|
|
236
235
|
const readDynamicUsage = bindRequestContext(() => options.consumeDynamicUsage() || readsRenderDynamicLatch && isRenderDynamicLatched());
|
|
@@ -240,13 +239,6 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
240
239
|
if (!dynamicUsageObserved) dynamicUsageObserved = readDynamicUsage();
|
|
241
240
|
return dynamicUsageObserved;
|
|
242
241
|
};
|
|
243
|
-
const finalizeRenderDynamicUsage = () => {
|
|
244
|
-
if (!dynamicUsageFinalized) {
|
|
245
|
-
consumeRenderDynamicUsage();
|
|
246
|
-
dynamicUsageFinalized = true;
|
|
247
|
-
}
|
|
248
|
-
return dynamicUsageObserved;
|
|
249
|
-
};
|
|
250
242
|
const artifactCompatibility = createAppPageArtifactCompatibility(options.element, options.routePattern);
|
|
251
243
|
const rootBoundaryId = artifactCompatibility?.rootBoundaryId ?? null;
|
|
252
244
|
const renderEpoch = artifactCompatibility?.renderEpoch ?? null;
|
|
@@ -429,7 +421,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
429
421
|
const completionHeaders = new Headers(rscResponse.headers);
|
|
430
422
|
completionHeaders.set(VINEXT_RSC_COMPLETION_METADATA_HEADER, "1");
|
|
431
423
|
const completionResponse = dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true && !options.isForceStatic && rscResponse.body ? new Response(appendRscCompletionMetadata(rscResponse.body, () => {
|
|
432
|
-
if (!
|
|
424
|
+
if (!consumeRenderDynamicUsage()) return void 0;
|
|
433
425
|
const completedServerStaleTimeSeconds = resolveClientStaleTimeSeconds(options.peekRequestCacheLife?.());
|
|
434
426
|
if (shouldEmitDynamicStaleTime && completedServerStaleTimeSeconds === void 0) return;
|
|
435
427
|
return {
|
|
@@ -447,7 +439,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
447
439
|
bypassInterceptionContextCache: options.bypassInterceptionContextCache,
|
|
448
440
|
captureAdmittedDocument,
|
|
449
441
|
cleanPathname: options.cleanPathname,
|
|
450
|
-
consumeDynamicUsage:
|
|
442
|
+
consumeDynamicUsage: consumeRenderDynamicUsage,
|
|
451
443
|
consumeRenderObservationState,
|
|
452
444
|
createHtmlRenderObservation(input) {
|
|
453
445
|
return createAppPageRenderObservation({
|
|
@@ -630,6 +622,12 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
630
622
|
copyLinkHeaderProvenance(response.headers, prerenderResponse.headers);
|
|
631
623
|
return prerenderResponse;
|
|
632
624
|
};
|
|
625
|
+
const markPrerenderedDynamicShellSpecialError = (response, specialError) => {
|
|
626
|
+
if (options.isPrerender === true && response.status === specialError.statusCode && resolveEarlyResponseCacheControl(options) !== null && response.headers.get("cache-control")?.includes("no-store")) getRequestExecutionContext()?.recordPrerenderSpecialError?.({
|
|
627
|
+
headers: resolveAppPageSpecialErrorStoredHeaders(specialError, options.basePath) ?? {},
|
|
628
|
+
status: response.status
|
|
629
|
+
});
|
|
630
|
+
};
|
|
633
631
|
const finalizeShellSpecialErrorResponse = (response, specialError) => {
|
|
634
632
|
if (response.status !== specialError.statusCode) return applyIneligibleRouteCachePolicy(response, options);
|
|
635
633
|
const dynamicUsedDuringRender = consumeRenderDynamicUsage();
|
|
@@ -687,7 +685,6 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
687
685
|
capturedRscDataRef,
|
|
688
686
|
getInitialNavigationCacheMetadata: () => resolveInitialNavigationCacheMetadata(dynamicUsedDuringHtmlRender || peekDynamicUsage(), options.isPrerender === true ? requestCacheLifeForPrerender ?? options.peekRequestCacheLife?.() : options.peekRequestCacheLife?.()),
|
|
689
687
|
fontData,
|
|
690
|
-
hasCustomGlobalError: options.hasCustomGlobalError,
|
|
691
688
|
navigationContext: options.getNavigationContext(),
|
|
692
689
|
basePath: options.basePath,
|
|
693
690
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
@@ -701,7 +698,8 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
701
698
|
scriptNonce: options.scriptNonce,
|
|
702
699
|
sideStream: rscCapture.sideStream,
|
|
703
700
|
ssrHandler,
|
|
704
|
-
fallbackToErrorDocumentOnShellError: options.isPrerender === true && options.isSpeculativePrerender === true
|
|
701
|
+
fallbackToErrorDocumentOnShellError: !(options.isPrerender === true && options.isSpeculativePrerender === true),
|
|
702
|
+
isServerComponentError: rscErrorTracker.isCapturedError,
|
|
705
703
|
waitForAllReady: shouldWaitForAllReady,
|
|
706
704
|
isStaticGeneration: options.isPrerender === true,
|
|
707
705
|
isForceStatic: options.isForceStatic,
|
|
@@ -740,7 +738,9 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
740
738
|
if (htmlRender.response) {
|
|
741
739
|
if (shellSpecialError && options.isProduction && options.isPrerender !== true && resolveEarlyResponseCacheControl(options) === null) return finalizeShellSpecialErrorResponse(htmlRender.response, shellSpecialError);
|
|
742
740
|
if (shellSpecialError && prerenderedSpecialError) return finalizePrerenderedShellSpecialErrorResponse(htmlRender.response, shellSpecialError, prerenderedSpecialError);
|
|
743
|
-
|
|
741
|
+
const response = applyIneligibleRouteCachePolicy(htmlRender.response, options);
|
|
742
|
+
if (shellSpecialError) markPrerenderedDynamicShellSpecialError(response, shellSpecialError);
|
|
743
|
+
return response;
|
|
744
744
|
}
|
|
745
745
|
let htmlStream = htmlRender.htmlStream;
|
|
746
746
|
if (!htmlStream) throw new Error("[vinext] Expected an HTML stream when no fallback response was returned");
|
|
@@ -2,10 +2,10 @@ import { VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-v
|
|
|
2
2
|
import { NEXT_CACHE_TAGS_HEADER, NEXT_ROUTER_STALE_TIME_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_STALE_TIME_PENDING_HEADER, VINEXT_TIMING_HEADER } from "./headers.js";
|
|
3
3
|
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, STATIC_CACHE_CONTROL, buildRevalidateCacheControl } from "./cache-control.js";
|
|
4
4
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
5
|
+
import { applyPrerenderCacheLifeHeader } from "./prerender-cache-life-header.js";
|
|
5
6
|
import { markFrameworkLinkHeaders } from "./app-response-header-provenance.js";
|
|
6
7
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
7
8
|
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
|
|
8
|
-
import { applyPrerenderCacheLifeHeader } from "./prerender-cache-life-header.js";
|
|
9
9
|
//#region src/server/app-page-response.ts
|
|
10
10
|
function applyTimingHeader(headers, timing) {
|
|
11
11
|
if (!timing) return;
|
|
@@ -3,6 +3,7 @@ import { fnv1a64 } from "../utils/hash.js";
|
|
|
3
3
|
import { createInlineScriptTag, escapeHtmlAttr } from "./html.js";
|
|
4
4
|
import { APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
5
5
|
import { APP_PREFETCH_LOADING_SHELL_MARKER_KEY, APP_STREAMING_METADATA_BODY_ID_PREFIX } from "./app-elements.js";
|
|
6
|
+
import { createBfcacheChildSegmentStateKey } from "./bfcache-identity.js";
|
|
6
7
|
import { AppRouterScrollTarget } from "../shims/app-router-scroll.js";
|
|
7
8
|
import { hashMountedLayoutIdentity } from "./app-mounted-layouts.js";
|
|
8
9
|
import { BfcacheChildrenBoundary, BfcacheSegmentBoundary, Children as Children$1, ParallelSlot, Slot } from "../shims/slot.js";
|
|
@@ -876,8 +877,20 @@ function buildAppPageElements(options) {
|
|
|
876
877
|
fallback: pageErrorComponent,
|
|
877
878
|
children: routeChildren
|
|
878
879
|
});
|
|
879
|
-
const
|
|
880
|
-
|
|
880
|
+
const firstLayoutWithElementTreePosition = layoutEntries.find((entry) => getDefaultExport(entry.layoutModule) !== null)?.treePosition;
|
|
881
|
+
const keepsSegmentLevelLists = String(process.env.__NEXT_CACHE_COMPONENTS) === "true" && firstLayoutWithElementTreePosition !== void 0 && !options.route.childrenSlot && options.semanticPageIdentity === void 0;
|
|
882
|
+
const spineTreePositions = keepsSegmentLevelLists ? Array.from(/* @__PURE__ */ new Set([...orderedTreePositions, ...Array.from({ length: Math.max(0, routeSegments.length - firstLayoutWithElementTreePosition) }, (_, offset) => firstLayoutWithElementTreePosition + 1 + offset)])).sort((left, right) => left - right) : orderedTreePositions;
|
|
883
|
+
const renderedTreePositions = isPrefetchLoadingShell ? spineTreePositions.filter(includesPrefetchTreePosition) : spineTreePositions;
|
|
884
|
+
const firstLayoutBelowShell = keepsSegmentLevelLists && isPrefetchLoadingShell ? layoutEntries.find((entry) => !includesPrefetchTreePosition(entry.treePosition) && getDefaultExport(entry.layoutModule) !== null) : void 0;
|
|
885
|
+
let childSegmentElementId = firstLayoutBelowShell?.id ?? pageElementId;
|
|
886
|
+
let childSegmentTreePosition = firstLayoutBelowShell?.treePosition ?? routeSegments.length + 1;
|
|
887
|
+
const retainChildSegment = (treePosition, children) => treePosition === childSegmentTreePosition - 1 ? /* @__PURE__ */ jsx(BfcacheChildrenBoundary, {
|
|
888
|
+
id: childSegmentElementId,
|
|
889
|
+
children
|
|
890
|
+
}) : /* @__PURE__ */ jsx(BfcacheChildrenBoundary, {
|
|
891
|
+
stateKey: createBfcacheChildSegmentStateKey(resolveAppPageTemplateStateKey(routeSegments, treePosition, options.matchedParams)),
|
|
892
|
+
children
|
|
893
|
+
});
|
|
881
894
|
for (let index = renderedTreePositions.length - 1; index >= 0; index--) {
|
|
882
895
|
const treePosition = renderedTreePositions[index];
|
|
883
896
|
const segmentResetKey = resolveRouteSegmentResetKey(treePosition);
|
|
@@ -927,11 +940,12 @@ function buildAppPageElements(options) {
|
|
|
927
940
|
children: segmentChildren
|
|
928
941
|
}, String(process.env.__NEXT_CACHE_COMPONENTS) === "true" ? void 0 : templateStateKey);
|
|
929
942
|
}
|
|
943
|
+
const layoutHasElement = layoutEntry !== void 0 && getDefaultExport(layoutEntry.layoutModule) !== null;
|
|
944
|
+
if (keepsSegmentLevelLists && !layoutHasElement && treePosition > firstLayoutWithElementTreePosition && treePosition < childSegmentTreePosition) segmentChildren = retainChildSegment(treePosition, segmentChildren);
|
|
930
945
|
if (!layoutEntry) {
|
|
931
946
|
routeChildren = segmentChildren;
|
|
932
947
|
continue;
|
|
933
948
|
}
|
|
934
|
-
const layoutHasElement = getDefaultExport(layoutEntry.layoutModule) !== null;
|
|
935
949
|
const layoutIndex = layoutIndicesByTreePosition.get(treePosition) ?? -1;
|
|
936
950
|
const segmentMap = { children: resolveAppPageLayoutSegmentProviderSegments(options.route.childrenRouteSegments ?? routeSegments, layoutEntry.treePosition, options.matchedParams) };
|
|
937
951
|
for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {
|
|
@@ -949,13 +963,16 @@ function buildAppPageElements(options) {
|
|
|
949
963
|
children: layoutHasElement ? /* @__PURE__ */ jsx(Slot, {
|
|
950
964
|
id: layoutEntry.id,
|
|
951
965
|
parallelSlots: createAppPageParallelSlotEntries(layoutIndex, layoutEntries, options.route, getEffectiveSlotParams, resolveSlotOverride),
|
|
952
|
-
children: /* @__PURE__ */ jsx(BfcacheChildrenBoundary, {
|
|
966
|
+
children: keepsSegmentLevelLists ? retainChildSegment(treePosition, segmentChildren) : /* @__PURE__ */ jsx(BfcacheChildrenBoundary, {
|
|
953
967
|
id: childSegmentElementId,
|
|
954
968
|
children: segmentChildren
|
|
955
969
|
})
|
|
956
970
|
}) : segmentChildren
|
|
957
971
|
});
|
|
958
|
-
if (layoutHasElement)
|
|
972
|
+
if (layoutHasElement) {
|
|
973
|
+
childSegmentElementId = layoutEntry.id;
|
|
974
|
+
childSegmentTreePosition = treePosition;
|
|
975
|
+
}
|
|
959
976
|
}
|
|
960
977
|
const globalErrorComponent = getErrorBoundaryExport(options.globalErrorModule);
|
|
961
978
|
routeChildren = /* @__PURE__ */ jsx(GlobalErrorBoundary, {
|
|
@@ -96,10 +96,13 @@ export type AppPageSsrHandler = {
|
|
|
96
96
|
/** Mirror inline Flight chunks into Next.js's `self.__next_f` transport, or start
|
|
97
97
|
* mirroring once a function returns true. */
|
|
98
98
|
mirrorNextFlight?: boolean | (() => boolean);
|
|
99
|
-
/** When true,
|
|
100
|
-
*
|
|
101
|
-
*
|
|
99
|
+
/** When true, a shell render error other than a redirect, HTTP access
|
|
100
|
+
* fallback or bail-out resolves to the default `__next_error__`
|
|
101
|
+
* error-document shell (with the original flight payload and
|
|
102
|
+
* bootstrap) instead of rejecting. See handleSsr. */
|
|
102
103
|
fallbackToErrorDocumentOnShellError?: boolean;
|
|
104
|
+
/** Whether the RSC render threw the given shell error. See handleSsr. */
|
|
105
|
+
isServerComponentError?: (error: unknown) => boolean;
|
|
103
106
|
/** The parallel slot not-found boundaries that catch a shell error. See handleSsr. */
|
|
104
107
|
resolveCaughtNotFoundBoundaries?: (error: unknown) => readonly string[] | null;
|
|
105
108
|
dynamicStaleTimeSeconds?: number;
|
|
@@ -153,8 +156,11 @@ type RenderAppPageHtmlStreamOptions = {
|
|
|
153
156
|
isForceStatic?: boolean;
|
|
154
157
|
/** Production render that may be stored under a query-free key. */
|
|
155
158
|
isCacheCandidate?: boolean;
|
|
156
|
-
/**
|
|
159
|
+
/** Whether handleSsr answers a shell error with the error document. Off by
|
|
160
|
+
* default: a boundary render that fails keeps rejecting. */
|
|
157
161
|
fallbackToErrorDocumentOnShellError?: boolean;
|
|
162
|
+
/** Whether the RSC render threw the given shell error. See handleSsr. */
|
|
163
|
+
isServerComponentError?: (error: unknown) => boolean;
|
|
158
164
|
/** The parallel slot not-found boundaries that catch a shell error. See handleSsr. */
|
|
159
165
|
resolveCaughtNotFoundBoundaries?: (error: unknown) => readonly string[] | null;
|
|
160
166
|
/** Dev-only: original server error to surface in the browser overlay. */
|
|
@@ -164,10 +170,6 @@ type RenderAppPageHtmlStreamOptions = {
|
|
|
164
170
|
/** Mirror inline Flight chunks into Next.js's `self.__next_f` transport, or start
|
|
165
171
|
* mirroring once a function returns true. */
|
|
166
172
|
mirrorNextFlight?: boolean | (() => boolean);
|
|
167
|
-
/** True when the app supplies a custom global-error.tsx. Disables the
|
|
168
|
-
* default error-document shell fallback so SSR shell errors keep driving
|
|
169
|
-
* the server-rendered global-error boundary re-render. */
|
|
170
|
-
hasCustomGlobalError?: boolean;
|
|
171
173
|
};
|
|
172
174
|
type RenderAppPageHtmlResponseOptions = {
|
|
173
175
|
clearRequestContext: () => void;
|
|
@@ -86,7 +86,8 @@ async function renderAppPageHtmlStream(options) {
|
|
|
86
86
|
initialDevServerError: options.initialDevServerError,
|
|
87
87
|
onSsrError: options.onSsrError,
|
|
88
88
|
mirrorNextFlight: options.mirrorNextFlight,
|
|
89
|
-
fallbackToErrorDocumentOnShellError: options.fallbackToErrorDocumentOnShellError
|
|
89
|
+
fallbackToErrorDocumentOnShellError: options.fallbackToErrorDocumentOnShellError,
|
|
90
|
+
isServerComponentError: options.isServerComponentError,
|
|
90
91
|
resolveCaughtNotFoundBoundaries: options.resolveCaughtNotFoundBoundaries,
|
|
91
92
|
dynamicStaleTimeSeconds: options.dynamicStaleTimeSeconds,
|
|
92
93
|
getInitialNavigationCacheMetadata: options.getInitialNavigationCacheMetadata
|
|
@@ -32,7 +32,7 @@ function handleRequestStage(request, env, ctx, dispatchResponseStage) {
|
|
|
32
32
|
callback: () => handleRequest(request, env, ctx, dispatchResponseStage, ctx?.assets).then((response) => applyCdnResponseIdentityHeaders(response, originalRequest)),
|
|
33
33
|
getStatus: (response) => response?.status,
|
|
34
34
|
headers: request.headers,
|
|
35
|
-
isRsc:
|
|
35
|
+
isRsc: request.headers.get("RSC") === "1",
|
|
36
36
|
method: request.method,
|
|
37
37
|
target: url.pathname + url.search
|
|
38
38
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isFullyBufferedBody } from "./fully-buffered-response.js";
|
|
2
2
|
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
3
3
|
import { frameworkTracer } from "./tracer.js";
|
|
4
|
+
import { logRequestError } from "./request-error-log.js";
|
|
4
5
|
import { getRouteCacheabilityCaptureOptions, getRouteCacheabilityDynamicReason, isRouteCacheabilityEvaluation, markRouteCacheabilityExplicitResponsePolicy, markRouteCacheabilityResponseBodyComplete, recordRouteCacheability } from "../shims/cacheability-classification.js";
|
|
5
6
|
import { NEVER_CACHE_CONTROL, applyCdnResponseHeaders, hasCdnResponsePolicy, hasExplicitNonCacheableResponsePolicy } from "./cache-control.js";
|
|
6
7
|
import { buildAppRouteMissIsrCacheControl } from "./isr-decision.js";
|
|
@@ -117,7 +118,7 @@ async function runAppRouteHandler(options) {
|
|
|
117
118
|
onDynamicAccess() {
|
|
118
119
|
options.markDynamicUsage();
|
|
119
120
|
},
|
|
120
|
-
requestMode: options.dynamicConfig === "force-static" || options.dynamicConfig === "error" ? options.dynamicConfig : "auto",
|
|
121
|
+
requestMode: options.dynamicConfig === "force-dynamic" || options.dynamicConfig === "force-static" || options.dynamicConfig === "error" ? options.dynamicConfig : "auto",
|
|
121
122
|
signal: options.requestSignal,
|
|
122
123
|
staticGenerationErrorMessage(expression) {
|
|
123
124
|
return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);
|
|
@@ -339,7 +340,7 @@ async function executeAppRouteHandlerImpl(options) {
|
|
|
339
340
|
}), options.middlewareContext, middlewareMergeOptions), shouldApplyDraftPolicy);
|
|
340
341
|
return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(new Response(null, { status: specialError.statusCode }), options.middlewareContext, middlewareMergeOptions), shouldApplyDraftPolicy);
|
|
341
342
|
}
|
|
342
|
-
|
|
343
|
+
logRequestError("[vinext] Route handler error:", error);
|
|
343
344
|
await options.reportRequestError(error, {
|
|
344
345
|
path: options.cleanPathname,
|
|
345
346
|
method: options.request.method,
|
|
@@ -21,7 +21,7 @@ type NextUrlDynamicAccess = "nextUrl.search" | "nextUrl.searchParams" | "nextUrl
|
|
|
21
21
|
type HostDerivedNextUrlDynamicAccess = "nextUrl.protocol" | "nextUrl.username" | "nextUrl.password" | "nextUrl.host" | "nextUrl.hostname" | "nextUrl.port" | DomainLocaleNextUrlDynamicAccess;
|
|
22
22
|
type DomainLocaleNextUrlDynamicAccess = "nextUrl.locale" | "nextUrl.defaultLocale" | "nextUrl.domainLocale";
|
|
23
23
|
type AppRouteDynamicRequestAccess = RequestDynamicAccess | NextUrlDynamicAccess;
|
|
24
|
-
type AppRouteRequestMode = "auto" | "force-static" | "error";
|
|
24
|
+
type AppRouteRequestMode = "auto" | "force-dynamic" | "force-static" | "error";
|
|
25
25
|
type TrackedAppRouteRequestOptions = {
|
|
26
26
|
basePath?: string;
|
|
27
27
|
i18n?: NextI18nConfig | null;
|
|
@@ -2,6 +2,7 @@ import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-r
|
|
|
2
2
|
import { addBasePathToPathname } from "../utils/base-path.js";
|
|
3
3
|
import { cloneRequestWithHeaders, cloneRequestWithUrl } from "./request-pipeline.js";
|
|
4
4
|
import { NextRequest, RequestCookies, sealRequestCookies, sealRequestHeaders } from "../shims/server.js";
|
|
5
|
+
import { throwIfInsideCacheScope } from "../shims/internal/headers-state.js";
|
|
5
6
|
import { BUILT_IN_REQUEST_PROPERTIES } from "./app-route-request-built-ins.js";
|
|
6
7
|
//#region src/server/app-route-handler-runtime.ts
|
|
7
8
|
const BUILT_IN_REQUEST_PROPERTY_MAP = new Map(BUILT_IN_REQUEST_PROPERTIES.map((property) => [property.key, property]));
|
|
@@ -150,7 +151,8 @@ function createTrackedAppRouteRequest(request, options = {}) {
|
|
|
150
151
|
let didAccessDynamicRequest = false;
|
|
151
152
|
const requestMode = options.requestMode ?? "auto";
|
|
152
153
|
const nextConfig = buildNextConfig(options);
|
|
153
|
-
const markDynamicAccess = (access) => {
|
|
154
|
+
const markDynamicAccess = (access, trackedByNext) => {
|
|
155
|
+
if (trackedByNext && requestMode !== "force-dynamic") throwIfInsideCacheScope(access);
|
|
154
156
|
didAccessDynamicRequest = true;
|
|
155
157
|
options.onDynamicAccess?.(access);
|
|
156
158
|
};
|
|
@@ -184,7 +186,7 @@ function createTrackedAppRouteRequest(request, options = {}) {
|
|
|
184
186
|
const wrapNextUrl = (nextUrl) => {
|
|
185
187
|
return new Proxy(nextUrl, { get(target, prop) {
|
|
186
188
|
if (isNextDynamicNextUrlProperty(prop) || isHostDerivedNextUrlProperty(prop)) {
|
|
187
|
-
markDynamicAccess(`nextUrl.${String(prop)}
|
|
189
|
+
markDynamicAccess(`nextUrl.${String(prop)}`, isNextDynamicNextUrlProperty(prop));
|
|
188
190
|
return bindMethodIfNeeded(Reflect.get(target, prop, target), target);
|
|
189
191
|
}
|
|
190
192
|
if (prop === "clone") return () => wrapNextUrl(target.clone());
|
|
@@ -252,7 +254,7 @@ function createTrackedAppRouteRequest(request, options = {}) {
|
|
|
252
254
|
const accessCf = (read, forceStaticValue) => {
|
|
253
255
|
if (requestMode === "force-static") return forceStaticValue;
|
|
254
256
|
if (requestMode === "error") return throwStaticGenerationError("request.cf");
|
|
255
|
-
markDynamicAccess("request.cf");
|
|
257
|
+
markDynamicAccess("request.cf", false);
|
|
256
258
|
return read();
|
|
257
259
|
};
|
|
258
260
|
const controlledCfGetter = () => accessCf(sourceCfAccessor ? () => Reflect.apply(sourceCfAccessor, requestWithOverrides, []) : () => rawCfMetadata, void 0);
|
|
@@ -354,17 +356,19 @@ function createTrackedAppRouteRequest(request, options = {}) {
|
|
|
354
356
|
return proxiedNextUrl;
|
|
355
357
|
case "headers":
|
|
356
358
|
case "cookies":
|
|
357
|
-
case "ip":
|
|
358
|
-
case "geo":
|
|
359
359
|
case "url":
|
|
360
360
|
case "body":
|
|
361
361
|
case "blob":
|
|
362
|
-
case "bytes":
|
|
363
362
|
case "json":
|
|
364
363
|
case "text":
|
|
365
364
|
case "arrayBuffer":
|
|
366
365
|
case "formData":
|
|
367
|
-
markDynamicAccess(`request.${String(prop)}
|
|
366
|
+
markDynamicAccess(`request.${String(prop)}`, true);
|
|
367
|
+
return bindMethodIfNeeded(Reflect.get(target, prop, target), target);
|
|
368
|
+
case "ip":
|
|
369
|
+
case "geo":
|
|
370
|
+
case "bytes":
|
|
371
|
+
markDynamicAccess(`request.${String(prop)}`, false);
|
|
368
372
|
return bindMethodIfNeeded(Reflect.get(target, prop, target), target);
|
|
369
373
|
case "clone": return cloneTrackedRequest;
|
|
370
374
|
default: return getTrackedRequestProperty(target, prop, receiver);
|
|
@@ -37,7 +37,7 @@ var app_router_entry_default = {
|
|
|
37
37
|
callback: async () => applyCdnResponseIdentityHeaders(await handleRequest(request, env, ctx), request),
|
|
38
38
|
getStatus: (response) => response?.status,
|
|
39
39
|
headers: request.headers,
|
|
40
|
-
isRsc:
|
|
40
|
+
isRsc: request.headers.get("RSC") === "1",
|
|
41
41
|
method: request.method,
|
|
42
42
|
target: url.pathname + url.search
|
|
43
43
|
});
|
|
@@ -68,11 +68,6 @@ export declare function stripRscCacheBustingSearchParam(url: URL): void;
|
|
|
68
68
|
* are dropped. Other requests keep no `_rsc`, because it selects nothing there.
|
|
69
69
|
*/
|
|
70
70
|
export declare function keepOnlyValidatedRscCacheBustingSearchParam(url: URL, isRscRequest: boolean): void;
|
|
71
|
-
/**
|
|
72
|
-
* Remove a trailing `.rsc` suffix from a pathname. Returns the pathname
|
|
73
|
-
* unchanged when the suffix is absent.
|
|
74
|
-
*/
|
|
75
|
-
export declare function stripRscSuffix(pathname: string): string;
|
|
76
71
|
export declare function createCanonicalRscRequestHeaders(deploymentId?: string | null | undefined): Headers;
|
|
77
72
|
/** Headers for the deterministic loading-boundary prefetch representation. */
|
|
78
73
|
export declare function createCanonicalLoadingShellRscRequestHeaders(deploymentId?: string | null | undefined): Headers;
|
|
@@ -96,13 +91,18 @@ export declare function canonicalizeLoadingShellRscRequestHeaders(headers: Heade
|
|
|
96
91
|
* appended to the base instead of resolved against it.
|
|
97
92
|
*/
|
|
98
93
|
export declare function parseRscRequestPath(href: string): URL;
|
|
94
|
+
/**
|
|
95
|
+
* A pathname as the start of a path-absolute reference. One that begins with
|
|
96
|
+
* "//" would serialize as a protocol-relative URL naming another host, so it
|
|
97
|
+
* keeps a "/." prefix, as the WHATWG URL serializer does. URL resolution drops
|
|
98
|
+
* the dot segment, so the reference still targets the same pathname on the
|
|
99
|
+
* origin it is resolved against.
|
|
100
|
+
*/
|
|
101
|
+
export declare function toPathAbsolutePathname(pathname: string): string;
|
|
99
102
|
/**
|
|
100
103
|
* Serialize the path-absolute reference callers fetch against the app origin.
|
|
101
|
-
* A pathname
|
|
102
|
-
*
|
|
103
|
-
* WHATWG URL serializer does. URL resolution drops the dot segment, so the
|
|
104
|
-
* request still targets the same pathname on the app origin, as Next.js's
|
|
105
|
-
* full-URL fetch does.
|
|
104
|
+
* A "//" pathname keeps its "/." prefix so the request still targets the same
|
|
105
|
+
* pathname on the app origin, as Next.js's full-URL fetch does.
|
|
106
106
|
*/
|
|
107
107
|
export declare function formatRscRequestPath(url: URL): string;
|
|
108
108
|
export declare function createRscRequestUrl(href: string, headers: Headers): Promise<string>;
|