vinext 1.0.0-beta.1 → 1.0.0-beta.2
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 +4 -1
- package/dist/build/client-build-config.js +1 -0
- package/dist/build/report.d.ts +8 -1
- package/dist/build/report.js +12 -2
- package/dist/check.js +15 -2
- package/dist/cli.js +3 -2
- package/dist/config/config-matchers.d.ts +13 -37
- package/dist/config/config-matchers.js +31 -121
- package/dist/config/next-config.d.ts +3 -2
- package/dist/config/next-config.js +3 -1
- package/dist/config/request-context.d.ts +14 -0
- package/dist/config/request-context.js +26 -0
- package/dist/entries/app-rsc-entry.js +27 -9
- package/dist/entries/app-rsc-manifest.js +17 -0
- package/dist/entries/pages-server-entry.js +3 -2
- package/dist/index.js +82 -58
- package/dist/init.d.ts +6 -4
- package/dist/init.js +20 -22
- package/dist/plugins/og-assets.js +1 -1
- package/dist/routing/app-route-graph.d.ts +13 -5
- package/dist/routing/app-route-graph.js +59 -13
- package/dist/routing/app-router.js +12 -6
- package/dist/routing/file-matcher.d.ts +11 -22
- package/dist/routing/file-matcher.js +21 -33
- package/dist/routing/pages-router.js +23 -29
- package/dist/routing/route-matching.d.ts +14 -1
- package/dist/routing/route-matching.js +13 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +7 -4
- package/dist/routing/route-trie.d.ts +5 -1
- package/dist/routing/route-trie.js +5 -2
- package/dist/server/app-browser-entry.js +7 -6
- package/dist/server/app-browser-history-controller.d.ts +1 -1
- package/dist/server/app-browser-history-controller.js +3 -3
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-fallback-renderer.d.ts +3 -0
- package/dist/server/app-fallback-renderer.js +4 -2
- package/dist/server/app-middleware.js +2 -1
- package/dist/server/app-page-boundary-render.d.ts +12 -1
- package/dist/server/app-page-boundary-render.js +84 -2
- package/dist/server/app-page-cache-finalizer.d.ts +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-dispatch.d.ts +11 -2
- package/dist/server/app-page-dispatch.js +14 -17
- package/dist/server/app-page-element-builder.d.ts +7 -2
- package/dist/server/app-page-element-builder.js +112 -27
- package/dist/server/app-page-head.d.ts +54 -2
- package/dist/server/app-page-head.js +164 -78
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
- package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
- package/dist/server/app-page-render.d.ts +2 -2
- package/dist/server/app-page-render.js +1 -1
- package/dist/server/app-page-request.d.ts +12 -0
- package/dist/server/app-page-request.js +133 -13
- package/dist/server/app-page-route-wiring.d.ts +9 -0
- package/dist/server/app-page-route-wiring.js +43 -3
- package/dist/server/app-post-middleware-context.d.ts +1 -1
- package/dist/server/app-post-middleware-context.js +1 -1
- package/dist/server/app-route-handler-dispatch.js +31 -17
- package/dist/server/app-route-handler-execution.d.ts +6 -1
- package/dist/server/app-route-handler-execution.js +42 -16
- package/dist/server/app-route-handler-policy.d.ts +2 -0
- package/dist/server/app-route-handler-policy.js +3 -3
- package/dist/server/app-route-module-loader.d.ts +3 -1
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-rsc-cache-busting.d.ts +1 -1
- package/dist/server/app-rsc-errors.d.ts +1 -1
- package/dist/server/app-rsc-errors.js +12 -2
- package/dist/server/app-rsc-handler.d.ts +10 -5
- package/dist/server/app-rsc-handler.js +52 -24
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +8 -2
- package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
- package/dist/server/app-rsc-response-finalizer.js +5 -11
- package/dist/server/app-rsc-route-matching.d.ts +20 -0
- package/dist/server/app-rsc-route-matching.js +87 -11
- package/dist/server/app-segment-config.js +13 -3
- package/dist/server/app-server-action-execution.d.ts +3 -1
- package/dist/server/app-server-action-execution.js +9 -7
- package/dist/server/app-ssr-entry.js +2 -2
- package/dist/server/app-ssr-stream.d.ts +1 -7
- package/dist/server/app-ssr-stream.js +2 -10
- package/dist/server/config-headers.d.ts +24 -0
- package/dist/server/config-headers.js +52 -0
- package/dist/server/dev-initial-server-error.d.ts +1 -1
- package/dist/server/dev-server.js +29 -13
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/middleware-matcher-pattern.d.ts +22 -0
- package/dist/server/middleware-matcher-pattern.js +219 -0
- package/dist/server/middleware-matcher.d.ts +2 -7
- package/dist/server/middleware-matcher.js +13 -60
- package/dist/server/middleware-path-to-regexp.d.ts +14 -0
- package/dist/server/middleware-path-to-regexp.js +228 -0
- package/dist/server/middleware-runtime.js +4 -3
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +2 -1
- package/dist/server/pages-data-route.d.ts +11 -1
- package/dist/server/pages-data-route.js +16 -1
- package/dist/server/pages-get-initial-props.d.ts +15 -2
- package/dist/server/pages-get-initial-props.js +16 -6
- package/dist/server/pages-page-data.d.ts +3 -1
- package/dist/server/pages-page-data.js +16 -7
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +16 -17
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-readiness.d.ts +3 -3
- package/dist/server/pages-request-pipeline.d.ts +1 -0
- package/dist/server/pages-request-pipeline.js +25 -11
- package/dist/server/pages-router-entry.js +6 -0
- package/dist/server/prerender-route-params.js +2 -2
- package/dist/server/prod-server.d.ts +1 -4
- package/dist/server/prod-server.js +36 -23
- package/dist/server/request-pipeline.d.ts +15 -29
- package/dist/server/request-pipeline.js +24 -59
- package/dist/server/rsc-stream-hints.js +122 -18
- package/dist/shims/app.d.ts +1 -1
- package/dist/shims/cache-request-state.d.ts +27 -1
- package/dist/shims/cache-request-state.js +60 -1
- package/dist/shims/cache-runtime.d.ts +12 -1
- package/dist/shims/cache-runtime.js +22 -7
- package/dist/shims/cache.d.ts +5 -5
- package/dist/shims/cache.js +26 -10
- package/dist/shims/document.d.ts +42 -83
- package/dist/shims/document.js +62 -53
- package/dist/shims/dynamic.d.ts +5 -25
- package/dist/shims/dynamic.js +29 -8
- package/dist/shims/error.d.ts +1 -1
- package/dist/shims/error.js +1 -1
- package/dist/shims/fetch-cache.js +12 -3
- package/dist/shims/font-google-base.d.ts +11 -4
- package/dist/shims/font-local.d.ts +10 -3
- package/dist/shims/head.d.ts +13 -2
- package/dist/shims/head.js +3 -3
- package/dist/shims/headers.d.ts +28 -31
- package/dist/shims/headers.js +109 -49
- package/dist/shims/image.d.ts +27 -37
- package/dist/shims/image.js +21 -14
- package/dist/shims/internal/cookie-serialize.d.ts +3 -1
- package/dist/shims/internal/cookie-serialize.js +3 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
- package/dist/shims/internal/utils.d.ts +3 -3
- package/dist/shims/legacy-image.d.ts +3 -37
- package/dist/shims/legacy-image.js +6 -16
- package/dist/shims/link.d.ts +15 -22
- package/dist/shims/link.js +20 -11
- package/dist/shims/navigation-context-state.d.ts +1 -1
- package/dist/shims/navigation.d.ts +7 -3
- package/dist/shims/navigation.js +24 -13
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/next-shims-augmentations.d.ts +1 -0
- package/dist/shims/next-shims-public.d.ts +1 -0
- package/dist/shims/public-shim-map.json.js +103 -0
- package/dist/shims/readonly-url-search-params.d.ts +3 -3
- package/dist/shims/readonly-url-search-params.js +3 -3
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/router.d.ts +55 -21
- package/dist/shims/router.js +162 -37
- package/dist/shims/script.d.ts +6 -10
- package/dist/shims/script.js +6 -3
- package/dist/shims/server.d.ts +45 -22
- package/dist/shims/server.js +44 -5
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/url-safety.d.ts +1 -1
- package/dist/shims/url-safety.js +2 -2
- package/dist/typegen.d.ts +8 -2
- package/dist/typegen.js +76 -15
- package/dist/utils/domain-locale.d.ts +2 -2
- package/dist/utils/external-url.d.ts +5 -0
- package/dist/utils/external-url.js +7 -0
- package/dist/utils/regex-safety.d.ts +8 -0
- package/dist/utils/regex-safety.js +737 -0
- package/package.json +13 -2
|
@@ -16,16 +16,15 @@ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscR
|
|
|
16
16
|
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
17
17
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
18
18
|
import "../client/instrumentation-client.js";
|
|
19
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
20
|
+
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
|
|
21
|
+
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
19
22
|
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
20
23
|
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
21
24
|
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
22
25
|
import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
|
|
23
26
|
import { navigationPlanner } from "./navigation-planner.js";
|
|
24
|
-
import {
|
|
25
|
-
import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
26
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
27
|
-
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
|
|
28
|
-
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
27
|
+
import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, preloadHybridClientRouteOwner, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveLoadedHybridClientRewriteHref, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
29
28
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
30
29
|
import { COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, isCompleteAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl } from "./app-browser-state.js";
|
|
31
30
|
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
@@ -43,6 +42,7 @@ import { createRoot, hydrateRoot } from "react-dom/client";
|
|
|
43
42
|
import { createFromFetch, createFromReadableStream, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
44
43
|
import { hasServerActions, loadServerActionClient } from "virtual:vinext-app-capabilities";
|
|
45
44
|
//#region src/server/app-browser-entry.ts
|
|
45
|
+
const HAS_CLIENT_REWRITES = process.env.__VINEXT_HAS_CLIENT_REWRITES !== "false";
|
|
46
46
|
function toActionType(kind) {
|
|
47
47
|
return kind === "traverse" ? "traverse" : "navigate";
|
|
48
48
|
}
|
|
@@ -738,6 +738,7 @@ async function main() {
|
|
|
738
738
|
if (!claimInitialAppRouterBootstrap()) return;
|
|
739
739
|
if (hasServerActions) registerServerActionCallback();
|
|
740
740
|
installAppNavigationFailureListeners();
|
|
741
|
+
if (HAS_CLIENT_REWRITES) await preloadHybridClientRouteOwner();
|
|
741
742
|
let devErrorOverlay = null;
|
|
742
743
|
if (import.meta.env.DEV) {
|
|
743
744
|
devErrorOverlay = await import("../client/dev-error-overlay.js");
|
|
@@ -892,7 +893,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
892
893
|
mountedSlotsHeader
|
|
893
894
|
});
|
|
894
895
|
const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
|
|
895
|
-
const rewrittenNavigationHref = navigationKind === "navigate" ?
|
|
896
|
+
const rewrittenNavigationHref = navigationKind === "navigate" && HAS_CLIENT_REWRITES ? resolveLoadedHybridClientRewriteHref(currentHref, __basePath) : null;
|
|
896
897
|
const additionalPrefetchRscUrls = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [await createRscRequestUrl(rewrittenNavigationHref, requestHeaders)] : [];
|
|
897
898
|
const visitedResponseCandidate = shouldBypassNavigationCache ? {
|
|
898
899
|
cacheKey: AppElementsWire.encodeCacheKey(rscUrl, requestInterceptionContext),
|
|
@@ -18,7 +18,7 @@ type AppBrowserHistoryControllerDeps = {
|
|
|
18
18
|
readHistoryState: () => unknown; /** Reads `window.location.href`. Injected so the controller stays unit-testable. */
|
|
19
19
|
readCurrentHref: () => string; /** Wraps `pushHistoryStateWithoutNotify(state, "", href)`. */
|
|
20
20
|
pushHistoryState: (state: unknown, href: string) => void; /** Wraps `replaceHistoryStateWithoutNotify(state, "", href)`. */
|
|
21
|
-
replaceHistoryState: (state: unknown, href
|
|
21
|
+
replaceHistoryState: (state: unknown, href?: string) => void;
|
|
22
22
|
readVisibleNavigationMetadata: () => VisibleNavigationMetadata | null;
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
@@ -158,9 +158,9 @@ var AppBrowserHistoryController = class {
|
|
|
158
158
|
bfcacheVersion: bfcacheIds === void 0 ? void 0 : this.#restorableClientState.currentBfcacheVersion,
|
|
159
159
|
previousNextUrl
|
|
160
160
|
});
|
|
161
|
-
this.#replaceHistoryState(nextHistoryState
|
|
161
|
+
this.#replaceHistoryState(nextHistoryState);
|
|
162
162
|
if (this.#isHistoryStateNavigationMetadataInSync(this.#readHistoryState(), previousNextUrl, bfcacheIds)) return;
|
|
163
|
-
this.#replaceHistoryState(nextHistoryState
|
|
163
|
+
this.#replaceHistoryState(nextHistoryState);
|
|
164
164
|
}
|
|
165
165
|
#isHistoryStateNavigationMetadataInSync(state, previousNextUrl, bfcacheIds) {
|
|
166
166
|
return readHistoryStatePreviousNextUrl(state) === previousNextUrl && (bfcacheIds === void 0 || areBfcacheIdMapsEqual(readHistoryStateBfcacheIds(state), bfcacheIds) && this.#restorableClientState.isCurrentBfcacheVersion(state));
|
|
@@ -179,7 +179,7 @@ var AppBrowserHistoryController = class {
|
|
|
179
179
|
bfcacheVersion: this.#restorableClientState.currentBfcacheVersion,
|
|
180
180
|
previousNextUrl: options.previousNextUrl,
|
|
181
181
|
traversalIndex: this.#currentHistoryTraversalIndex
|
|
182
|
-
})
|
|
182
|
+
}));
|
|
183
183
|
}
|
|
184
184
|
/**
|
|
185
185
|
* Resolves a restorable snapshot candidate for the given history entry and
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
|
|
3
3
|
import { claimAppRouterScrollIntentForCommit, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
4
|
-
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
5
4
|
import { resolveServerActionOperationLane, shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
|
|
5
|
+
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
6
6
|
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit } from "./app-browser-state.js";
|
|
7
7
|
import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
|
|
8
8
|
import { startTransition, useInsertionEffect, useLayoutEffect } from "react";
|
|
@@ -6,12 +6,12 @@ import { AppElementsWire } from "./app-elements-wire.js";
|
|
|
6
6
|
import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
|
|
7
7
|
import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
|
|
8
8
|
import { createCacheEntryReuseProof } from "./cache-proof.js";
|
|
9
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
9
10
|
import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
|
|
10
11
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
11
12
|
import { verifyOperationTokenForCommit } from "./operation-token.js";
|
|
12
13
|
import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
|
|
13
14
|
import { createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
14
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
15
15
|
//#region src/server/app-browser-state.ts
|
|
16
16
|
const COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "committed-cache" };
|
|
17
17
|
const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
2
2
|
import "./app-elements.js";
|
|
3
3
|
import { mergeElements } from "../shims/slot.js";
|
|
4
|
-
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
5
4
|
import { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
5
|
+
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
6
6
|
import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
|
|
7
7
|
//#region src/server/app-browser-visible-commit.ts
|
|
8
8
|
const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
|
|
@@ -5,6 +5,7 @@ import { AppPageParams } from "./app-page-boundary.js";
|
|
|
5
5
|
import { AppPageFontPreload } from "./app-page-execution.js";
|
|
6
6
|
import { AppPageMiddlewareContext } from "./app-page-response.js";
|
|
7
7
|
import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
|
|
8
|
+
import { AppPageInterceptOptions } from "./app-page-element-builder.js";
|
|
8
9
|
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
9
10
|
import { AppPageBoundaryRoute } from "./app-page-boundary-render.js";
|
|
10
11
|
import { ReactNode } from "react";
|
|
@@ -81,6 +82,7 @@ type AppFallbackRendererCallContext = {
|
|
|
81
82
|
* render path. Defaults to `false` when no route is matched.
|
|
82
83
|
*/
|
|
83
84
|
isEdgeRuntime?: boolean;
|
|
85
|
+
routePathname?: string;
|
|
84
86
|
sourcePageSegments?: readonly string[] | null;
|
|
85
87
|
};
|
|
86
88
|
type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
|
|
@@ -88,6 +90,7 @@ type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
|
|
|
88
90
|
renderHttpAccessFallback: (route: AppPageBoundaryRoute<TModule> | null, statusCode: number, isRscRequest: boolean, request: Request, opts: {
|
|
89
91
|
boundaryComponent?: AppPageComponent | null;
|
|
90
92
|
boundaryModule?: TModule | null;
|
|
93
|
+
intercept?: AppPageInterceptOptions<TModule> | null;
|
|
91
94
|
layouts?: readonly (TModule | null | undefined)[] | null;
|
|
92
95
|
matchedParams?: AppPageParams;
|
|
93
96
|
}, scriptNonce: string | undefined, middlewareContext: AppPageMiddlewareContext, callContext?: AppFallbackRendererCallContext) => Promise<Response | null>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
|
|
2
1
|
import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
|
|
2
|
+
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
3
|
+
import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
|
|
3
4
|
import { DEFAULT_GLOBAL_NOT_FOUND_MODULE } from "./default-global-not-found-module.js";
|
|
4
5
|
import { DEFAULT_NOT_FOUND_MODULE } from "./default-not-found-module.js";
|
|
5
|
-
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
6
6
|
//#region src/server/app-fallback-renderer.ts
|
|
7
7
|
const EMPTY_MW_CTX = {
|
|
8
8
|
headers: null,
|
|
@@ -84,6 +84,7 @@ function createAppFallbackRenderer(options) {
|
|
|
84
84
|
getAndClearPendingCookies,
|
|
85
85
|
getNavigationContext,
|
|
86
86
|
globalErrorModule: effectiveGlobalErrorModule,
|
|
87
|
+
intercept: opts?.intercept ?? null,
|
|
87
88
|
isEdgeRuntime: callContext?.isEdgeRuntime,
|
|
88
89
|
isRscRequest,
|
|
89
90
|
layoutModules: useGlobalNotFound ? [] : opts?.layouts ?? null,
|
|
@@ -100,6 +101,7 @@ function createAppFallbackRenderer(options) {
|
|
|
100
101
|
rootNotFoundModule: routeMissRootNotFoundModule,
|
|
101
102
|
rootUnauthorizedModule,
|
|
102
103
|
route: useGlobalNotFound ? null : route,
|
|
104
|
+
routePathname: callContext?.routePathname,
|
|
103
105
|
renderToReadableStream: rscRenderer,
|
|
104
106
|
scriptNonce,
|
|
105
107
|
serveStreamingMetadata,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VINEXT_MW_CTX_HEADER } from "../utils/protocol-headers.js";
|
|
2
2
|
import { FLIGHT_HEADERS } from "./headers.js";
|
|
3
3
|
import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
|
|
4
|
-
import { isExternalUrl
|
|
4
|
+
import { isExternalUrl } from "../utils/external-url.js";
|
|
5
5
|
import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
6
6
|
import { cloneRequestWithHeaders, processMiddlewareHeaders } from "./request-pipeline.js";
|
|
7
7
|
import { executeMiddleware } from "./middleware-runtime.js";
|
|
@@ -58,6 +58,7 @@ async function proxyExternalMiddlewareRewrite(request, rewriteUrl, context) {
|
|
|
58
58
|
const proxyRequest = requestWithMiddlewareRequestHeaders(request, context.requestHeaders ?? context.headers);
|
|
59
59
|
setHeadersContext(null);
|
|
60
60
|
setNavigationContext(null);
|
|
61
|
+
const { proxyExternalRequest } = await import("../config/config-matchers.js");
|
|
61
62
|
const proxyResponse = await proxyExternalRequest(proxyRequest, rewriteUrl);
|
|
62
63
|
const headers = new Headers(proxyResponse.headers);
|
|
63
64
|
processMiddlewareHeaders(headers);
|
|
@@ -5,6 +5,8 @@ import { AppPageParams } from "./app-page-boundary.js";
|
|
|
5
5
|
import { AppPageFontPreload } from "./app-page-execution.js";
|
|
6
6
|
import { AppPageMiddlewareContext } from "./app-page-response.js";
|
|
7
7
|
import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
|
|
8
|
+
import { AppPageRouteWiringRoute } from "./app-page-route-wiring.js";
|
|
9
|
+
import { AppPageInterceptOptions } from "./app-page-element-builder.js";
|
|
8
10
|
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
9
11
|
import { ComponentType, ReactNode } from "react";
|
|
10
12
|
|
|
@@ -19,13 +21,20 @@ type AppPageBoundaryRoute<TModule extends AppPageModule = AppPageModule> = {
|
|
|
19
21
|
errorPaths?: readonly TModule[] | null;
|
|
20
22
|
errors?: readonly (TModule | null | undefined)[] | null;
|
|
21
23
|
forbidden?: TModule | null;
|
|
24
|
+
forbiddenTreePosition?: number | null;
|
|
25
|
+
forbiddens?: readonly (TModule | null | undefined)[] | null;
|
|
22
26
|
layoutTreePositions?: readonly number[] | null;
|
|
23
27
|
layouts?: readonly (TModule | null | undefined)[];
|
|
24
28
|
notFound?: TModule | null;
|
|
29
|
+
notFounds?: readonly (TModule | null | undefined)[] | null;
|
|
30
|
+
notFoundTreePosition?: number | null;
|
|
25
31
|
params?: AppPageParams;
|
|
26
32
|
pattern?: string;
|
|
27
33
|
routeSegments?: readonly string[];
|
|
34
|
+
slots?: AppPageRouteWiringRoute<TModule>["slots"];
|
|
28
35
|
unauthorized?: TModule | null;
|
|
36
|
+
unauthorizedTreePosition?: number | null;
|
|
37
|
+
unauthorizeds?: readonly (TModule | null | undefined)[] | null;
|
|
29
38
|
};
|
|
30
39
|
type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
31
40
|
applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
|
|
@@ -70,11 +79,13 @@ type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageM
|
|
|
70
79
|
type RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
71
80
|
boundaryComponent?: AppPageComponent | null;
|
|
72
81
|
boundaryModule?: TModule | null;
|
|
82
|
+
intercept?: AppPageInterceptOptions<TModule> | null;
|
|
73
83
|
layoutModules?: readonly (TModule | null | undefined)[] | null;
|
|
74
84
|
matchedParams: AppPageParams;
|
|
75
85
|
rootForbiddenModule?: TModule | null;
|
|
76
86
|
rootNotFoundModule?: TModule | null;
|
|
77
|
-
rootUnauthorizedModule?: TModule | null;
|
|
87
|
+
rootUnauthorizedModule?: TModule | null; /** Normalized, basePath-free application pathname used for route matching. */
|
|
88
|
+
routePathname?: string;
|
|
78
89
|
route?: AppPageBoundaryRoute<TModule> | null;
|
|
79
90
|
/**
|
|
80
91
|
* When true, the resolved boundary is rendered without wrapping it in the
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stripBasePath } from "../utils/base-path.js";
|
|
1
2
|
import { NEVER_CACHE_CONTROL } from "./cache-control.js";
|
|
2
3
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
3
4
|
import "./app-elements.js";
|
|
@@ -6,12 +7,17 @@ import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
|
6
7
|
import { ErrorBoundary, GlobalErrorBoundary, SerializedErrorBoundary } from "../shims/error-boundary.js";
|
|
7
8
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
8
9
|
import { MetadataHead, ViewportHead } from "../shims/metadata.js";
|
|
10
|
+
import { resolveAppPageBranchParams, resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
11
|
+
import { stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
9
12
|
import { buildRscRedirectFlightStream } from "./app-rsc-redirect-flight.js";
|
|
10
13
|
import { bufferAppPageBinaryStream, buildAppPageSpecialErrorResponse, resolveAppPageSpecialError } from "./app-page-execution.js";
|
|
11
|
-
import { resolveAppPageHead } from "./app-page-head.js";
|
|
14
|
+
import { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from "./app-page-head.js";
|
|
12
15
|
import { createAppPageLayoutEntries, createAppPageSourcePage } from "./app-page-route-wiring.js";
|
|
13
16
|
import { buildClientHookErrorMessage } from "../shims/client-hook-error.js";
|
|
17
|
+
import { resolveHttpAccessFallbackMetadata, resolveHttpAccessFallbackViewport } from "./app-page-http-access-fallback-metadata.js";
|
|
18
|
+
import "./app-rsc-route-matching.js";
|
|
14
19
|
import { renderAppPageBoundaryResponse, resolveAppPageErrorBoundary, resolveAppPageHttpAccessBoundaryModule, wrapAppPageBoundaryElement } from "./app-page-boundary.js";
|
|
20
|
+
import { resolveSlotParamOverrides } from "./app-page-element-builder.js";
|
|
15
21
|
import { createAppPageFontData, createAppPageRscErrorTracker, renderAppPageHtmlResponse } from "./app-page-stream.js";
|
|
16
22
|
import { Fragment, createElement } from "react";
|
|
17
23
|
//#region src/server/app-page-boundary-render.ts
|
|
@@ -19,6 +25,16 @@ const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
|
|
|
19
25
|
function getDefaultExport(module) {
|
|
20
26
|
return module?.default ?? null;
|
|
21
27
|
}
|
|
28
|
+
function resolveHttpAccessBoundaryTreePosition(route, boundaryModule, statusCode) {
|
|
29
|
+
if (!route || !boundaryModule) return null;
|
|
30
|
+
const routeBoundary = statusCode === 403 ? route.forbidden : statusCode === 401 ? route.unauthorized : route.notFound;
|
|
31
|
+
const layoutBoundaries = statusCode === 403 ? route.forbiddens : statusCode === 401 ? route.unauthorizeds : route.notFounds;
|
|
32
|
+
if (boundaryModule === routeBoundary && statusCode === 404) return route.notFoundTreePosition ?? null;
|
|
33
|
+
if (boundaryModule === routeBoundary && statusCode === 403) return route.forbiddenTreePosition ?? null;
|
|
34
|
+
if (boundaryModule === routeBoundary && statusCode === 401) return route.unauthorizedTreePosition ?? null;
|
|
35
|
+
for (let index = (layoutBoundaries?.length ?? 0) - 1; index >= 0; index--) if (layoutBoundaries?.[index] === boundaryModule) return route.layoutTreePositions?.[index] ?? null;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
22
38
|
function wrapRenderedBoundaryElement(options) {
|
|
23
39
|
return wrapAppPageBoundaryElement({
|
|
24
40
|
element: options.element,
|
|
@@ -194,10 +210,76 @@ async function renderAppPageHttpAccessFallback(options) {
|
|
|
194
210
|
if (!boundaryComponent) return null;
|
|
195
211
|
const layoutModules = options.layoutModules ?? options.route?.layouts ?? options.rootLayouts;
|
|
196
212
|
const pathname = new URL(options.requestUrl).pathname;
|
|
213
|
+
const routePathname = options.routePathname ?? stripRscSuffix(stripBasePath(pathname, options.basePath ?? ""));
|
|
197
214
|
const routeSegments = resolveHttpAccessFallbackHeadRouteSegments(options.route, layoutModules);
|
|
215
|
+
const fallbackRouteSegments = routeSegments ?? [];
|
|
198
216
|
let head;
|
|
199
217
|
try {
|
|
200
|
-
|
|
218
|
+
if ([
|
|
219
|
+
401,
|
|
220
|
+
403,
|
|
221
|
+
404
|
|
222
|
+
].includes(options.statusCode)) {
|
|
223
|
+
const boundaryTreePosition = resolveHttpAccessBoundaryTreePosition(options.route, boundaryModule, options.statusCode);
|
|
224
|
+
const boundaryParams = boundaryTreePosition == null ? {} : resolveAppPageSegmentParams(fallbackRouteSegments, boundaryTreePosition, options.matchedParams);
|
|
225
|
+
const intercept = options.intercept;
|
|
226
|
+
const isSiblingIntercept = intercept?.interceptSlotKey === "__vinext_page_intercept" && intercept.interceptPage != null;
|
|
227
|
+
const effectiveParams = isSiblingIntercept ? intercept.interceptParams ?? options.matchedParams : options.matchedParams;
|
|
228
|
+
const slotParams = resolveSlotParamOverrides({ slots: options.route?.slots ?? null }, routePathname);
|
|
229
|
+
const parallelBranches = resolveActiveParallelRouteHeadInputs({
|
|
230
|
+
interceptBranchSegments: intercept?.interceptBranchSegments ?? null,
|
|
231
|
+
interceptLayouts: intercept?.interceptLayouts ?? null,
|
|
232
|
+
interceptLayoutSegments: intercept?.interceptLayoutSegments ?? null,
|
|
233
|
+
interceptNotFoundBranchSegments: intercept?.interceptNotFoundBranchSegments ?? null,
|
|
234
|
+
interceptNotFound: intercept?.interceptNotFound ?? null,
|
|
235
|
+
interceptNotFoundTreePosition: intercept?.interceptNotFoundTreePosition ?? null,
|
|
236
|
+
interceptPage: intercept?.interceptPage ?? null,
|
|
237
|
+
interceptParams: intercept?.interceptParams ?? null,
|
|
238
|
+
interceptSlotKey: intercept?.interceptSlotKey ?? null,
|
|
239
|
+
interceptSourcePageSegments: intercept?.interceptSourcePageSegments ?? null,
|
|
240
|
+
layoutTreePositions: options.route?.layoutTreePositions,
|
|
241
|
+
params: options.matchedParams,
|
|
242
|
+
routeSegments: fallbackRouteSegments,
|
|
243
|
+
slotParams,
|
|
244
|
+
slots: options.route?.slots ?? null
|
|
245
|
+
});
|
|
246
|
+
const primaryParallelBranch = isSiblingIntercept ? {
|
|
247
|
+
head: {
|
|
248
|
+
layoutModules: intercept?.interceptLayouts ?? [],
|
|
249
|
+
layoutParams: (intercept?.interceptLayoutSegments ?? []).map((segments) => resolveAppPageBranchParams(intercept?.interceptBranchSegments ?? segments, segments.length, effectiveParams, segments)),
|
|
250
|
+
pageModule: intercept?.interceptPage ?? null,
|
|
251
|
+
params: effectiveParams,
|
|
252
|
+
routeSegments: intercept?.interceptSourcePageSegments ?? fallbackRouteSegments
|
|
253
|
+
},
|
|
254
|
+
...intercept?.interceptNotFound ? {
|
|
255
|
+
notFoundModule: intercept.interceptNotFound,
|
|
256
|
+
notFoundParams: resolveAppPageBranchParams(intercept.interceptNotFoundBranchSegments ?? intercept.interceptBranchSegments ?? fallbackRouteSegments, intercept.interceptNotFoundTreePosition ?? 0, effectiveParams)
|
|
257
|
+
} : {},
|
|
258
|
+
ownerTreePosition: fallbackRouteSegments.length
|
|
259
|
+
} : null;
|
|
260
|
+
const fallbackHeadOptions = {
|
|
261
|
+
boundaryModule,
|
|
262
|
+
boundaryParams,
|
|
263
|
+
branchNotFoundConventions: options.statusCode === 404,
|
|
264
|
+
layoutModules,
|
|
265
|
+
layoutTreePositions: resolveHttpAccessFallbackHeadLayoutTreePositions(options.route, layoutModules),
|
|
266
|
+
parallelBranches,
|
|
267
|
+
params: options.matchedParams,
|
|
268
|
+
primaryParallelBranch,
|
|
269
|
+
routeSegments
|
|
270
|
+
};
|
|
271
|
+
const [metadata, viewport] = await Promise.all([resolveHttpAccessFallbackMetadata({
|
|
272
|
+
applyFileBasedMetadata: options.applyFileBasedMetadata,
|
|
273
|
+
basePath: options.basePath ?? "",
|
|
274
|
+
...fallbackHeadOptions,
|
|
275
|
+
metadataRoutes: options.metadataRoutes,
|
|
276
|
+
routePath: options.route?.pattern ?? pathname
|
|
277
|
+
}), resolveHttpAccessFallbackViewport(fallbackHeadOptions)]);
|
|
278
|
+
head = {
|
|
279
|
+
metadata,
|
|
280
|
+
viewport
|
|
281
|
+
};
|
|
282
|
+
} else head = await resolveAppPageHead({
|
|
201
283
|
applyFileBasedMetadata: options.applyFileBasedMetadata,
|
|
202
284
|
basePath: options.basePath ?? "",
|
|
203
285
|
layoutModules,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RenderObservation } from "./cache-proof.js";
|
|
2
|
-
import { CachedAppPageValue } from "../shims/cache-handler.js";
|
|
3
2
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
3
|
+
import { CachedAppPageValue } from "../shims/cache-handler.js";
|
|
4
4
|
import { AppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
5
5
|
|
|
6
6
|
//#region src/server/app-page-cache-finalizer.d.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RenderObservation } from "./cache-proof.js";
|
|
2
|
-
import { CacheControlMetadata, CachedAppPageValue } from "../shims/cache-handler.js";
|
|
3
2
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
3
|
+
import { CacheControlMetadata, CachedAppPageValue } from "../shims/cache-handler.js";
|
|
4
4
|
import { finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, scheduleAppPageRscCacheWrite } from "./app-page-cache-finalizer.js";
|
|
5
5
|
import { ISRCacheEntry } from "./isr-cache.js";
|
|
6
6
|
|
|
@@ -4,11 +4,11 @@ import { AppOutgoingElements } from "./app-elements-wire.js";
|
|
|
4
4
|
import { NavigationContext } from "../shims/navigation-context-state.js";
|
|
5
5
|
import { AppPageFontPreload, LayoutClassificationOptions } from "./app-page-execution.js";
|
|
6
6
|
import { AppPageMiddlewareContext } from "./app-page-response.js";
|
|
7
|
+
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
8
|
+
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
7
9
|
import { RootParams } from "../shims/root-params.js";
|
|
8
10
|
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
9
|
-
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
10
11
|
import { CachedAppPageValue } from "../shims/cache-handler.js";
|
|
11
|
-
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
12
12
|
import { ISRCacheEntry } from "./isr-cache.js";
|
|
13
13
|
import { PprFallbackShellState } from "../shims/ppr-fallback-shell.js";
|
|
14
14
|
import { FetchCacheMode } from "../shims/fetch-cache.js";
|
|
@@ -36,6 +36,9 @@ type AppPageDispatchIntercept<TPage = unknown> = {
|
|
|
36
36
|
interceptLayouts?: readonly unknown[] | null;
|
|
37
37
|
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
38
38
|
interceptBranchSegments?: readonly string[] | null;
|
|
39
|
+
interceptNotFoundBranchSegments?: readonly string[] | null;
|
|
40
|
+
notFound?: unknown;
|
|
41
|
+
notFoundTreePosition?: number | null;
|
|
39
42
|
matchedParams: AppPageParams;
|
|
40
43
|
sourceMatchedParams?: AppPageParams;
|
|
41
44
|
page: TPage;
|
|
@@ -49,6 +52,9 @@ type AppPageDispatchInterceptOptions<TPage = unknown> = {
|
|
|
49
52
|
interceptLayouts?: readonly unknown[] | null;
|
|
50
53
|
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
51
54
|
interceptBranchSegments?: readonly string[] | null;
|
|
55
|
+
interceptNotFoundBranchSegments?: readonly string[] | null;
|
|
56
|
+
interceptNotFound?: unknown;
|
|
57
|
+
interceptNotFoundTreePosition?: number | null;
|
|
52
58
|
interceptPage: TPage;
|
|
53
59
|
interceptParams: AppPageParams;
|
|
54
60
|
interceptSlotId?: string | null;
|
|
@@ -73,6 +79,7 @@ type AppPageDispatchRoute = {
|
|
|
73
79
|
error?: AppPageModule | null;
|
|
74
80
|
errors?: readonly (AppPageModule | null | undefined)[];
|
|
75
81
|
forbidden?: AppPageModule | null;
|
|
82
|
+
forbiddenTreePosition?: number | null;
|
|
76
83
|
forbiddens?: readonly (AppPageModule | null | undefined)[];
|
|
77
84
|
isDynamic: boolean;
|
|
78
85
|
layouts: readonly AppPageModule[];
|
|
@@ -85,6 +92,7 @@ type AppPageDispatchRoute = {
|
|
|
85
92
|
routeSegments: readonly string[];
|
|
86
93
|
slots?: Readonly<Record<string, AppPageDispatchSlot>>;
|
|
87
94
|
unauthorized?: AppPageModule | null;
|
|
95
|
+
unauthorizedTreePosition?: number | null;
|
|
88
96
|
unauthorizeds?: readonly (AppPageModule | null | undefined)[];
|
|
89
97
|
};
|
|
90
98
|
type AppPagePprRuntime<TRoute extends AppPageDispatchRoute> = {
|
|
@@ -185,6 +193,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
185
193
|
renderHttpAccessFallbackPage: (statusCode: number, opts: {
|
|
186
194
|
boundaryComponent?: unknown;
|
|
187
195
|
boundaryModule?: AppPageModule | null;
|
|
196
|
+
intercept?: AppPageDispatchInterceptOptions | null;
|
|
188
197
|
layouts?: readonly AppPageModule[];
|
|
189
198
|
matchedParams: AppPageParams;
|
|
190
199
|
}, middlewareContext: AppPageMiddlewareContext | null) => Promise<Response | null>;
|
|
@@ -4,7 +4,7 @@ import "../utils/protocol-headers.js";
|
|
|
4
4
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
5
5
|
import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL } from "./app-rsc-render-mode.js";
|
|
6
6
|
import "./app-elements.js";
|
|
7
|
-
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest,
|
|
7
|
+
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, peekDynamicUsage, peekRenderRequestApiUsage, runWithIsolatedDynamicUsage, setHeadersContext } from "../shims/headers.js";
|
|
8
8
|
import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
9
9
|
import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground } from "../shims/fetch-cache.js";
|
|
10
10
|
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
|
|
@@ -16,10 +16,10 @@ import { createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
|
16
16
|
import { consumeAppPageRenderObservationState, discardAppPageRenderState } from "./app-page-render-observation.js";
|
|
17
17
|
import { resolveAppPageParentHttpAccessBoundary, resolveAppPageParentHttpAccessBoundaryModule } from "./app-page-boundary.js";
|
|
18
18
|
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
19
|
+
import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
|
|
19
20
|
import { createAppLayoutParamAccessTracker, isAppLayoutObservationUnsafeForStaticReuse } from "./app-layout-param-observation.js";
|
|
20
21
|
import { buildAppPageTags } from "./implicit-tags.js";
|
|
21
22
|
import { resolveAppPageMethodResponse } from "./app-page-method.js";
|
|
22
|
-
import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
|
|
23
23
|
import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
|
|
24
24
|
import { renderAppPageLifecycle } from "./app-page-render.js";
|
|
25
25
|
//#region src/server/app-page-dispatch.ts
|
|
@@ -140,6 +140,9 @@ function toInterceptOptions(interceptionContext, intercept) {
|
|
|
140
140
|
interceptLayouts: intercept.interceptLayouts,
|
|
141
141
|
interceptLayoutSegments: intercept.interceptLayoutSegments,
|
|
142
142
|
interceptBranchSegments: intercept.interceptBranchSegments,
|
|
143
|
+
interceptNotFoundBranchSegments: intercept.interceptNotFoundBranchSegments,
|
|
144
|
+
interceptNotFound: intercept.notFound,
|
|
145
|
+
interceptNotFoundTreePosition: intercept.notFoundTreePosition,
|
|
143
146
|
interceptPage: intercept.page,
|
|
144
147
|
interceptParams: intercept.matchedParams,
|
|
145
148
|
interceptSlotId: intercept.slotId ?? null,
|
|
@@ -318,7 +321,7 @@ async function dispatchAppPageInner(options) {
|
|
|
318
321
|
});
|
|
319
322
|
if (cachedPageResponse) return cachedPageResponse;
|
|
320
323
|
}
|
|
321
|
-
if (options.skipStaticParamsValidation !== true) {
|
|
324
|
+
if (options.skipStaticParamsValidation !== true && !(options.isProduction && isForceDynamic)) {
|
|
322
325
|
const dynamicParamsResponse = await validateAppPageDynamicParams({
|
|
323
326
|
clearRequestContext: options.clearRequestContext,
|
|
324
327
|
enforceStaticParamsOnly: options.dynamicParamsConfig === false,
|
|
@@ -419,7 +422,7 @@ async function dispatchAppPageInner(options) {
|
|
|
419
422
|
return options.renderErrorBoundaryPage(buildError);
|
|
420
423
|
},
|
|
421
424
|
renderSpecialError(specialError) {
|
|
422
|
-
return renderPageSpecialError(options, specialError, serveStreamingMetadata);
|
|
425
|
+
return renderPageSpecialError(options, specialError, serveStreamingMetadata, interceptResult.interceptOpts);
|
|
423
426
|
},
|
|
424
427
|
resolveSpecialError: resolveAppPageSpecialError
|
|
425
428
|
});
|
|
@@ -535,16 +538,7 @@ async function dispatchAppPageInner(options) {
|
|
|
535
538
|
return isAppLayoutObservationUnsafeForStaticReuse(layoutParamAccess.getLayoutObservation(layoutId));
|
|
536
539
|
},
|
|
537
540
|
async runWithIsolatedDynamicScope(fn) {
|
|
538
|
-
|
|
539
|
-
try {
|
|
540
|
-
return {
|
|
541
|
-
result: await fn(),
|
|
542
|
-
dynamicDetected: consumeDynamicUsage()
|
|
543
|
-
};
|
|
544
|
-
} finally {
|
|
545
|
-
consumeDynamicUsage();
|
|
546
|
-
if (priorDynamic) markDynamicUsage();
|
|
547
|
-
}
|
|
541
|
+
return runWithIsolatedDynamicUsage(fn);
|
|
548
542
|
}
|
|
549
543
|
},
|
|
550
544
|
dynamicStaleTimeSeconds: options.dynamicStaleTimeSeconds,
|
|
@@ -558,7 +552,7 @@ async function dispatchAppPageInner(options) {
|
|
|
558
552
|
return renderLayoutSpecialError(options, specialError, layoutIndex, serveStreamingMetadata);
|
|
559
553
|
},
|
|
560
554
|
renderPageSpecialError(specialError) {
|
|
561
|
-
return renderPageSpecialError(options, specialError, serveStreamingMetadata);
|
|
555
|
+
return renderPageSpecialError(options, specialError, serveStreamingMetadata, interceptResult.interceptOpts);
|
|
562
556
|
},
|
|
563
557
|
renderToReadableStream: options.renderToReadableStream,
|
|
564
558
|
hasCustomGlobalError: options.hasCustomGlobalError,
|
|
@@ -611,7 +605,7 @@ async function renderLayoutSpecialError(options, specialError, layoutIndex, serv
|
|
|
611
605
|
specialError
|
|
612
606
|
});
|
|
613
607
|
}
|
|
614
|
-
async function renderPageSpecialError(options, specialError, serveStreamingMetadata) {
|
|
608
|
+
async function renderPageSpecialError(options, specialError, serveStreamingMetadata, intercept) {
|
|
615
609
|
return buildAppPageSpecialErrorResponse({
|
|
616
610
|
basePath: options.basePath,
|
|
617
611
|
buildRscRedirectFlightStream: (rscOptions) => buildRscRedirectFlightStream({
|
|
@@ -638,7 +632,10 @@ async function renderPageSpecialError(options, specialError, serveStreamingMetad
|
|
|
638
632
|
statusCode
|
|
639
633
|
});
|
|
640
634
|
const useLayoutAlignedBoundary = boundaryLayoutIndex !== null && (routeBoundaryModule === null || routeBoundaryModule === parentBoundaryModule);
|
|
641
|
-
const fallbackOptions = {
|
|
635
|
+
const fallbackOptions = {
|
|
636
|
+
intercept,
|
|
637
|
+
matchedParams: options.params
|
|
638
|
+
};
|
|
642
639
|
if (useLayoutAlignedBoundary && boundaryLayoutIndex !== null) {
|
|
643
640
|
fallbackOptions.layouts = options.route.layouts.slice(0, boundaryLayoutIndex + 1);
|
|
644
641
|
if (parentBoundaryModule) {
|
|
@@ -22,6 +22,9 @@ type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
|
22
22
|
interceptLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
23
23
|
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
24
24
|
interceptBranchSegments?: readonly string[] | null;
|
|
25
|
+
interceptNotFoundBranchSegments?: readonly string[] | null;
|
|
26
|
+
interceptNotFound?: TModule | null;
|
|
27
|
+
interceptNotFoundTreePosition?: number | null;
|
|
25
28
|
interceptPage?: TModule | null;
|
|
26
29
|
interceptParams?: AppPageParams | null;
|
|
27
30
|
interceptSlotId?: string | null;
|
|
@@ -38,7 +41,8 @@ type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {
|
|
|
38
41
|
renderMode?: AppRscRenderMode; /** Observe page `searchParams` access for cache-safety classification. */
|
|
39
42
|
observePageSearchParamsAccess?: boolean; /** Observe page metadata `searchParams` access for cache-safety classification. */
|
|
40
43
|
observeMetadataSearchParamsAccess?: boolean; /** Whether generated metadata may stream into the response body. */
|
|
41
|
-
serveStreamingMetadata?: boolean;
|
|
44
|
+
serveStreamingMetadata?: boolean; /** Whether streamed render errors must be sanitized for client transport. */
|
|
45
|
+
isProduction?: boolean;
|
|
42
46
|
};
|
|
43
47
|
type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {
|
|
44
48
|
applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
|
|
@@ -97,6 +101,7 @@ type AppPageNavigationParamInterceptOptions = {
|
|
|
97
101
|
*/
|
|
98
102
|
declare function buildPageElements<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements>;
|
|
99
103
|
declare function resolveInterceptedSlotSegments(sourcePageSegments: readonly string[] | null | undefined, slotKey: string): readonly string[] | null;
|
|
104
|
+
declare function resolveSlotParamOverrides(route: AppPageNavigationParamRoute, routePath: string): Readonly<Record<string, AppPageParams>> | null;
|
|
100
105
|
declare function resolveAppPageNavigationParams(route: AppPageNavigationParamRoute, routeParams: AppPageParams, routePath: string, opts?: AppPageNavigationParamInterceptOptions | null): AppPageParams;
|
|
101
106
|
//#endregion
|
|
102
|
-
export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams, resolveInterceptedSlotSegments };
|
|
107
|
+
export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams, resolveInterceptedSlotSegments, resolveSlotParamOverrides };
|