vinext 0.1.5 → 0.1.6
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 +2 -2
- package/dist/build/google-fonts/find-font-files-in-css.d.ts +16 -0
- package/dist/build/google-fonts/find-font-files-in-css.js +28 -0
- package/dist/build/report.d.ts +1 -2
- package/dist/build/report.js +2 -11
- package/dist/build/run-prerender.js +1 -1
- package/dist/check.js +3 -3
- package/dist/client/pages-router-link-navigation.d.ts +10 -0
- package/dist/client/pages-router-link-navigation.js +3 -3
- package/dist/deploy.js +3 -3
- package/dist/entries/app-rsc-entry.js +1 -0
- package/dist/entries/app-rsc-manifest.js +76 -46
- package/dist/entries/pages-server-entry.js +1 -0
- package/dist/index.js +69 -54
- package/dist/init.d.ts +5 -4
- package/dist/init.js +27 -8
- package/dist/plugins/fonts.js +3 -1
- package/dist/plugins/middleware-export-validation.d.ts +5 -0
- package/dist/plugins/middleware-export-validation.js +36 -0
- package/dist/plugins/og-asset-ownership.d.ts +27 -0
- package/dist/plugins/og-asset-ownership.js +285 -0
- package/dist/plugins/og-assets.js +22 -4
- package/dist/server/accept-encoding.d.ts +29 -0
- package/dist/server/accept-encoding.js +95 -0
- package/dist/server/app-browser-entry.js +8 -5
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-rsc-redirect.d.ts +2 -1
- package/dist/server/app-browser-rsc-redirect.js +8 -1
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-middleware.d.ts +1 -0
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-page-dispatch.d.ts +2 -2
- package/dist/server/app-page-head.js +2 -2
- package/dist/server/app-page-request.d.ts +7 -0
- package/dist/server/app-page-request.js +19 -1
- package/dist/server/app-prerender-endpoints.d.ts +3 -3
- package/dist/server/app-prerender-endpoints.js +3 -4
- package/dist/server/app-route-module-loader.d.ts +62 -14
- package/dist/server/app-route-module-loader.js +61 -10
- package/dist/server/app-rsc-handler.d.ts +7 -6
- package/dist/server/app-rsc-handler.js +31 -26
- package/dist/server/app-rsc-route-matching.d.ts +9 -0
- package/dist/server/app-rsc-route-matching.js +13 -0
- package/dist/server/app-ssr-entry.js +2 -2
- package/dist/server/headers.d.ts +5 -1
- package/dist/server/headers.js +5 -1
- package/dist/server/metadata-route-response.d.ts +3 -3
- package/dist/server/middleware-runtime.d.ts +2 -1
- package/dist/server/middleware-runtime.js +19 -8
- package/dist/server/middleware.d.ts +2 -2
- package/dist/server/middleware.js +26 -11
- package/dist/server/pages-request-pipeline.d.ts +3 -1
- package/dist/server/pages-request-pipeline.js +4 -2
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +85 -72
- package/dist/shims/font-google-base.d.ts +1 -0
- package/dist/shims/font-google-base.js +6 -21
- package/dist/shims/internal/interpolate-as.d.ts +25 -0
- package/dist/shims/internal/interpolate-as.js +196 -0
- package/dist/shims/link.js +24 -1
- package/dist/shims/navigation.js +1 -1
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/router.d.ts +1 -3
- package/dist/shims/router.js +62 -18
- package/dist/typegen.js +2 -10
- package/dist/utils/project.d.ts +7 -1
- package/dist/utils/project.js +16 -2
- package/package.json +3 -3
|
@@ -18,14 +18,15 @@ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscR
|
|
|
18
18
|
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
19
19
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
20
20
|
import "../client/instrumentation-client.js";
|
|
21
|
-
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
22
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
23
|
-
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
|
|
24
|
-
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
25
21
|
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
22
|
+
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
26
23
|
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
24
|
+
import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
|
|
27
25
|
import { navigationPlanner } from "./navigation-planner.js";
|
|
28
26
|
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, getClientNavigationRenderContext, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
27
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
28
|
+
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
|
|
29
|
+
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
29
30
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
30
31
|
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
|
|
31
32
|
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
@@ -1032,6 +1033,8 @@ function bootstrapHydration(rscStream) {
|
|
|
1032
1033
|
}
|
|
1033
1034
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1034
1035
|
const navContentType = navResponse.headers.get("content-type") ?? "";
|
|
1036
|
+
const streamedRedirectTarget = navResponse.headers.get(VINEXT_RSC_REDIRECT_HEADER);
|
|
1037
|
+
if (blockDangerousStreamedRscRedirect(navResponse, streamedRedirectTarget)) return;
|
|
1035
1038
|
const liveFetchDecision = navigationPlanner.classifyRscFetchResult({
|
|
1036
1039
|
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
1037
1040
|
compatibilityIdHeader: navResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
|
|
@@ -1045,7 +1048,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1045
1048
|
responseOk: navResponse.ok,
|
|
1046
1049
|
responseUrl: navResponseUrl ?? navResponse.url,
|
|
1047
1050
|
source: "live",
|
|
1048
|
-
streamedRedirectTarget
|
|
1051
|
+
streamedRedirectTarget
|
|
1049
1052
|
});
|
|
1050
1053
|
if (liveFetchDecision.kind === "hardNavigate") {
|
|
1051
1054
|
if (liveFetchDecision.discardBody) navResponse.body?.cancel().catch(() => {});
|
|
@@ -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 { shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
|
|
5
4
|
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
5
|
+
import { shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.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";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//#region src/server/app-browser-rsc-redirect.d.ts
|
|
2
|
+
declare function blockDangerousStreamedRscRedirect(response: Response, streamedRedirectTarget: string | null): boolean;
|
|
2
3
|
type RscRedirectHistoryUpdateMode = "push" | "replace" | undefined;
|
|
3
4
|
type RscRedirectLifecycleDecision = {
|
|
4
5
|
href: string;
|
|
@@ -34,4 +35,4 @@ declare function resolveStreamedRscRedirectLifecycleHop(options: {
|
|
|
34
35
|
streamedRedirectTarget: string;
|
|
35
36
|
}): RscRedirectLifecycleDecision;
|
|
36
37
|
//#endregion
|
|
37
|
-
export { resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop };
|
|
38
|
+
export { blockDangerousStreamedRscRedirect, resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop };
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { isDangerousScheme, reportBlockedDangerousNavigation } from "../shims/url-safety.js";
|
|
1
2
|
import { resolveHardNavigationTargetFromRscResponse, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
2
3
|
//#region src/server/app-browser-rsc-redirect.ts
|
|
3
4
|
const MAX_RSC_REDIRECT_DEPTH = 10;
|
|
5
|
+
function blockDangerousStreamedRscRedirect(response, streamedRedirectTarget) {
|
|
6
|
+
if (streamedRedirectTarget === null || !isDangerousScheme(streamedRedirectTarget)) return false;
|
|
7
|
+
response.body?.cancel().catch(() => {});
|
|
8
|
+
reportBlockedDangerousNavigation();
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
4
11
|
function toVisibleAppHref(href, origin) {
|
|
5
12
|
const url = new URL(href, origin);
|
|
6
13
|
stripRscCacheBustingSearchParam(url);
|
|
@@ -54,4 +61,4 @@ function resolveStreamedRscRedirectLifecycleHop(options) {
|
|
|
54
61
|
});
|
|
55
62
|
}
|
|
56
63
|
//#endregion
|
|
57
|
-
export { resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop };
|
|
64
|
+
export { blockDangerousStreamedRscRedirect, resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop };
|
|
@@ -7,11 +7,11 @@ 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
9
|
import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
|
|
10
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
11
10
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
12
11
|
import { verifyOperationTokenForCommit } from "./operation-token.js";
|
|
13
12
|
import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
|
|
14
13
|
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 FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
|
|
17
17
|
const VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "visited-cache" };
|
|
@@ -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 { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
5
4
|
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
5
|
+
import { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.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");
|
|
@@ -117,6 +117,7 @@ async function applyAppMiddleware(options) {
|
|
|
117
117
|
const result = await executeMiddleware({
|
|
118
118
|
basePath: options.basePath,
|
|
119
119
|
hadBasePath: true,
|
|
120
|
+
filePath: options.filePath,
|
|
120
121
|
i18nConfig: options.i18nConfig,
|
|
121
122
|
isDataRequest: options.isDataRequest,
|
|
122
123
|
isProxy: options.isProxy,
|
|
@@ -31,7 +31,7 @@ type AppPageBackgroundRegenerationErrorContext = {
|
|
|
31
31
|
};
|
|
32
32
|
type AppPageBackgroundRegenerator = (key: string, renderFn: () => Promise<void>, errorContext?: AppPageBackgroundRegenerationErrorContext) => void;
|
|
33
33
|
type AppPageDispatchIntercept<TPage = unknown> = {
|
|
34
|
-
interceptLayouts?: readonly
|
|
34
|
+
interceptLayouts?: readonly unknown[] | null;
|
|
35
35
|
matchedParams: AppPageParams;
|
|
36
36
|
page: TPage;
|
|
37
37
|
slotId?: string | null;
|
|
@@ -41,7 +41,7 @@ type AppPageDispatchIntercept<TPage = unknown> = {
|
|
|
41
41
|
};
|
|
42
42
|
type AppPageDispatchInterceptOptions<TPage = unknown> = {
|
|
43
43
|
interceptionContext: string | null;
|
|
44
|
-
interceptLayouts?: readonly
|
|
44
|
+
interceptLayouts?: readonly unknown[] | null;
|
|
45
45
|
interceptPage: TPage;
|
|
46
46
|
interceptParams: AppPageParams;
|
|
47
47
|
interceptSlotId?: string | null;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
2
2
|
import { mergeMetadataEntries, mergeViewport, postProcessMetadata, resolveModuleMetadata as resolveModuleMetadata$1, resolveModuleViewport } from "../shims/metadata.js";
|
|
3
3
|
import { resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
4
|
-
import { applyFileBasedMetadata } from "./file-based-metadata.js";
|
|
5
4
|
import { tagAppPageMetadataError } from "./app-page-execution.js";
|
|
6
5
|
//#region src/server/app-page-head.ts
|
|
7
6
|
/**
|
|
@@ -206,7 +205,8 @@ async function resolveAppPageHeadInner(options) {
|
|
|
206
205
|
const metadataSources = createMetadataSources(layoutMetadataResults, routeSegments, layoutSourcePositions, pageMetadata, Boolean(options.pageModule));
|
|
207
206
|
metadataSources.push(...parallelMetadataSources);
|
|
208
207
|
let metadata = resolvedMetadataBase;
|
|
209
|
-
try {
|
|
208
|
+
if (options.metadataRoutes.length > 0) try {
|
|
209
|
+
const { applyFileBasedMetadata } = await import("./file-based-metadata.js");
|
|
210
210
|
metadata = await applyFileBasedMetadata(resolvedMetadataBase, options.routePath, options.params, options.metadataRoutes, {
|
|
211
211
|
routeSegments,
|
|
212
212
|
metadataSources,
|
|
@@ -39,9 +39,16 @@ type BuildAppPageElementResult<TElement> = {
|
|
|
39
39
|
response: Response | null;
|
|
40
40
|
};
|
|
41
41
|
type AppPageInterceptMatch<TPage = unknown> = {
|
|
42
|
+
interceptLayouts?: readonly unknown[] | null;
|
|
43
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
42
44
|
matchedParams: AppPageParams;
|
|
43
45
|
page: TPage;
|
|
44
46
|
__pageLoader?: (() => Promise<TPage>) | null;
|
|
47
|
+
__loadState?: {
|
|
48
|
+
page: TPage;
|
|
49
|
+
pageLoading: Promise<TPage> | null;
|
|
50
|
+
interceptLayoutsLoading: Promise<readonly unknown[]> | null;
|
|
51
|
+
};
|
|
45
52
|
slotId?: string | null;
|
|
46
53
|
slotKey: string;
|
|
47
54
|
sourceRouteIndex: number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
2
2
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
3
3
|
import { getAppPageSegmentParamName } from "./app-page-params.js";
|
|
4
|
+
import { loadAppInterceptLayouts } from "./app-route-module-loader.js";
|
|
4
5
|
//#region src/server/app-page-request.ts
|
|
5
6
|
function pickRouteParams(matchedParams, routeParamNames) {
|
|
6
7
|
const params = {};
|
|
@@ -104,7 +105,24 @@ async function resolveAppPageInterceptState(options) {
|
|
|
104
105
|
if (!options.isRscRequest) return { kind: "none" };
|
|
105
106
|
const intercept = options.findIntercept(options.cleanPathname);
|
|
106
107
|
if (!intercept) return { kind: "none" };
|
|
107
|
-
|
|
108
|
+
const loadState = intercept.__loadState;
|
|
109
|
+
if (loadState?.page != null) intercept.page = loadState.page;
|
|
110
|
+
if (intercept.__pageLoader && intercept.page == null) {
|
|
111
|
+
const loading = loadState?.pageLoading ?? intercept.__pageLoader().then((page) => {
|
|
112
|
+
intercept.page = page;
|
|
113
|
+
if (loadState) {
|
|
114
|
+
loadState.page = page;
|
|
115
|
+
loadState.pageLoading = null;
|
|
116
|
+
}
|
|
117
|
+
return page;
|
|
118
|
+
}).catch((error) => {
|
|
119
|
+
if (loadState) loadState.pageLoading = null;
|
|
120
|
+
throw error;
|
|
121
|
+
});
|
|
122
|
+
if (loadState) loadState.pageLoading = loading;
|
|
123
|
+
await loading;
|
|
124
|
+
}
|
|
125
|
+
if (intercept.__loadInterceptLayouts) await loadAppInterceptLayouts(intercept);
|
|
108
126
|
const sourceRoute = await options.getSourceRoute(intercept.sourceRouteIndex);
|
|
109
127
|
if (!sourceRoute) return { kind: "none" };
|
|
110
128
|
if (sourceRoute === options.currentRoute) return {
|
|
@@ -5,14 +5,14 @@ type GenerateStaticParams = (args: {
|
|
|
5
5
|
params: RootParams;
|
|
6
6
|
}) => unknown;
|
|
7
7
|
type AppPrerenderStaticParamsMap = Record<string, GenerateStaticParams | null | undefined>;
|
|
8
|
-
type
|
|
8
|
+
type AppPrerenderRootParamNamesMap = Record<string, readonly string[] | undefined>;
|
|
9
9
|
type HandleAppPrerenderEndpointOptions = {
|
|
10
10
|
isPrerenderEnabled?: () => boolean;
|
|
11
11
|
loadPagesRoutes?: () => Promise<unknown>;
|
|
12
12
|
pathname: string;
|
|
13
|
-
rootParamNamesByPattern?:
|
|
13
|
+
rootParamNamesByPattern?: AppPrerenderRootParamNamesMap;
|
|
14
14
|
staticParamsMap: AppPrerenderStaticParamsMap;
|
|
15
15
|
};
|
|
16
16
|
declare function handleAppPrerenderEndpoint(request: Request, options: HandleAppPrerenderEndpointOptions): Promise<Response | null>;
|
|
17
17
|
//#endregion
|
|
18
|
-
export { handleAppPrerenderEndpoint };
|
|
18
|
+
export { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap, handleAppPrerenderEndpoint };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import "./headers.js";
|
|
1
2
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
2
3
|
import { callAppPrerenderStaticParams } from "./app-prerender-static-params.js";
|
|
3
4
|
//#region src/server/app-prerender-endpoints.ts
|
|
4
|
-
const STATIC_PARAMS_ENDPOINT = "/__vinext/prerender/static-params";
|
|
5
|
-
const PAGES_STATIC_PATHS_ENDPOINT = "/__vinext/prerender/pages-static-paths";
|
|
6
5
|
const JSON_HEADERS = { "content-type": "application/json" };
|
|
7
6
|
async function handleAppPrerenderEndpoint(request, options) {
|
|
8
|
-
if (options.pathname ===
|
|
9
|
-
if (options.pathname ===
|
|
7
|
+
if (options.pathname === "/__vinext/prerender/static-params") return handleStaticParamsEndpoint(request, options);
|
|
8
|
+
if (options.pathname === "/__vinext/prerender/pages-static-paths") {
|
|
10
9
|
if (!options.loadPagesRoutes) return null;
|
|
11
10
|
return handlePagesStaticPathsEndpoint(request, options);
|
|
12
11
|
}
|
|
@@ -10,34 +10,82 @@
|
|
|
10
10
|
* module at Worker startup. Only the module(s) for the matched route are
|
|
11
11
|
* evaluated, on demand.
|
|
12
12
|
*
|
|
13
|
-
* `ensureAppRouteModulesLoaded` resolves a route's lazy thunks and populates
|
|
14
|
-
* synchronous
|
|
15
|
-
*
|
|
13
|
+
* `ensureAppRouteModulesLoaded` resolves a route's lazy thunks and populates
|
|
14
|
+
* the synchronous module fields that the rest of the request pipeline reads
|
|
15
|
+
* directly (`page`, `routeHandler`, layouts, templates, boundaries, and
|
|
16
|
+
* parallel-slot modules). It is:
|
|
16
17
|
*
|
|
17
18
|
* - idempotent: once a route is loaded it returns immediately;
|
|
18
19
|
* - dedup'd: concurrent calls for the same route share one in-flight promise,
|
|
19
20
|
* so a burst of requests to the same route triggers a single import.
|
|
20
21
|
*
|
|
21
|
-
* Callers must `await` it before any synchronous read of
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* Callers must `await` it before any synchronous read of route modules
|
|
23
|
+
* (segment config, fetch-cache mode, runtime resolution, dispatch branch,
|
|
24
|
+
* element building, etc.).
|
|
24
25
|
*/
|
|
25
26
|
type LazyModuleThunk = () => Promise<unknown>;
|
|
27
|
+
type LazyModuleLoaderArray = readonly (LazyModuleThunk | null | undefined)[];
|
|
28
|
+
type LazyLoadableIntercept = {
|
|
29
|
+
interceptLayouts?: readonly unknown[] | null;
|
|
30
|
+
__loadInterceptLayouts?: LazyModuleLoaderArray | null;
|
|
31
|
+
__loadState?: {
|
|
32
|
+
interceptLayoutsLoading: Promise<readonly unknown[]> | null;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
type LazyLoadableSlot = {
|
|
36
|
+
page?: unknown;
|
|
37
|
+
default?: unknown;
|
|
38
|
+
layout?: unknown;
|
|
39
|
+
loading?: unknown;
|
|
40
|
+
error?: unknown;
|
|
41
|
+
__loadPage?: LazyModuleThunk | null;
|
|
42
|
+
__loadDefault?: LazyModuleThunk | null;
|
|
43
|
+
__loadLayout?: LazyModuleThunk | null;
|
|
44
|
+
__loadLoading?: LazyModuleThunk | null;
|
|
45
|
+
__loadError?: LazyModuleThunk | null; /** Hydrated only after an intercept matches, not with the slot's base modules. */
|
|
46
|
+
intercepts?: LazyLoadableIntercept[];
|
|
47
|
+
};
|
|
26
48
|
type LazyLoadableRoute = {
|
|
27
49
|
page?: unknown;
|
|
28
|
-
routeHandler?: unknown;
|
|
50
|
+
routeHandler?: unknown;
|
|
51
|
+
layouts?: unknown[];
|
|
52
|
+
templates?: unknown[];
|
|
53
|
+
errors?: unknown[];
|
|
54
|
+
errorPaths?: unknown[];
|
|
55
|
+
notFounds?: unknown[];
|
|
56
|
+
forbiddens?: unknown[];
|
|
57
|
+
unauthorizeds?: unknown[];
|
|
58
|
+
loading?: unknown;
|
|
59
|
+
error?: unknown;
|
|
60
|
+
notFound?: unknown;
|
|
61
|
+
forbidden?: unknown;
|
|
62
|
+
unauthorized?: unknown;
|
|
63
|
+
slots?: Record<string, LazyLoadableSlot>;
|
|
64
|
+
siblingIntercepts?: LazyLoadableIntercept[]; /** Lazy loader for the page module; `null`/absent when the page is eager. */
|
|
29
65
|
__loadPage?: LazyModuleThunk | null; /** Lazy loader for the route-handler module; `null`/absent when none. */
|
|
30
|
-
__loadRouteHandler?: LazyModuleThunk | null;
|
|
66
|
+
__loadRouteHandler?: LazyModuleThunk | null;
|
|
67
|
+
__loadLayouts?: LazyModuleLoaderArray | null;
|
|
68
|
+
__loadTemplates?: LazyModuleLoaderArray | null;
|
|
69
|
+
__loadErrors?: LazyModuleLoaderArray | null;
|
|
70
|
+
__loadErrorPaths?: LazyModuleLoaderArray | null;
|
|
71
|
+
__loadNotFounds?: LazyModuleLoaderArray | null;
|
|
72
|
+
__loadForbiddens?: LazyModuleLoaderArray | null;
|
|
73
|
+
__loadUnauthorizeds?: LazyModuleLoaderArray | null;
|
|
74
|
+
__loadLoading?: LazyModuleThunk | null;
|
|
75
|
+
__loadError?: LazyModuleThunk | null;
|
|
76
|
+
__loadNotFound?: LazyModuleThunk | null;
|
|
77
|
+
__loadForbidden?: LazyModuleThunk | null;
|
|
78
|
+
__loadUnauthorized?: LazyModuleThunk | null; /** Set once the route's lazy module fields have been resolved. */
|
|
31
79
|
__loaded?: boolean; /** In-flight hydration promise, used to dedup concurrent loads. */
|
|
32
80
|
__loading?: Promise<unknown> | null;
|
|
33
81
|
};
|
|
82
|
+
declare function loadAppInterceptLayouts(intercept: LazyLoadableIntercept): Promise<readonly unknown[]>;
|
|
34
83
|
/**
|
|
35
|
-
* Resolve a route's lazy
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* routes that have no lazy thunks.
|
|
84
|
+
* Resolve a route's lazy modules and assign them onto the route's synchronous
|
|
85
|
+
* module fields. Returns the same route reference (synchronously when already
|
|
86
|
+
* loaded, otherwise after the in-flight import resolves). Safe to call on
|
|
87
|
+
* `null`/`undefined` routes and on eager routes that have no lazy thunks.
|
|
40
88
|
*/
|
|
41
89
|
declare function ensureAppRouteModulesLoaded<TRoute extends LazyLoadableRoute>(route: TRoute | null | undefined): TRoute | Promise<TRoute>;
|
|
42
90
|
//#endregion
|
|
43
|
-
export { LazyLoadableRoute, ensureAppRouteModulesLoaded };
|
|
91
|
+
export { LazyLoadableRoute, ensureAppRouteModulesLoaded, loadAppInterceptLayouts };
|
|
@@ -1,23 +1,74 @@
|
|
|
1
1
|
//#region src/server/app-route-module-loader.ts
|
|
2
|
+
function pushFieldLoad(loads, target, field, loader) {
|
|
3
|
+
if (!loader || target[field] != null) return;
|
|
4
|
+
loads.push(loader().then((module) => {
|
|
5
|
+
target[field] = module;
|
|
6
|
+
}));
|
|
7
|
+
}
|
|
8
|
+
function pushArrayLoads(loads, target, loaders) {
|
|
9
|
+
if (!target || !loaders) return;
|
|
10
|
+
const slots = target;
|
|
11
|
+
for (const [index, loader] of loaders.entries()) {
|
|
12
|
+
if (index >= slots.length || !loader || slots[index] != null) continue;
|
|
13
|
+
loads.push(loader().then((module) => {
|
|
14
|
+
slots[index] = module;
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function loadAppInterceptLayouts(intercept) {
|
|
19
|
+
const loadState = intercept.__loadState;
|
|
20
|
+
if (loadState?.interceptLayoutsLoading) return loadState.interceptLayoutsLoading;
|
|
21
|
+
const loads = [];
|
|
22
|
+
pushArrayLoads(loads, intercept.interceptLayouts, intercept.__loadInterceptLayouts);
|
|
23
|
+
if (loads.length === 0) return Promise.resolve(intercept.interceptLayouts ?? []);
|
|
24
|
+
const loading = Promise.all(loads).then(() => {
|
|
25
|
+
if (loadState) loadState.interceptLayoutsLoading = null;
|
|
26
|
+
return intercept.interceptLayouts ?? [];
|
|
27
|
+
}).catch((error) => {
|
|
28
|
+
if (loadState) loadState.interceptLayoutsLoading = null;
|
|
29
|
+
throw error;
|
|
30
|
+
});
|
|
31
|
+
if (loadState) loadState.interceptLayoutsLoading = loading;
|
|
32
|
+
return loading;
|
|
33
|
+
}
|
|
2
34
|
/**
|
|
3
|
-
* Resolve a route's lazy
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* routes that have no lazy thunks.
|
|
35
|
+
* Resolve a route's lazy modules and assign them onto the route's synchronous
|
|
36
|
+
* module fields. Returns the same route reference (synchronously when already
|
|
37
|
+
* loaded, otherwise after the in-flight import resolves). Safe to call on
|
|
38
|
+
* `null`/`undefined` routes and on eager routes that have no lazy thunks.
|
|
8
39
|
*/
|
|
9
40
|
function ensureAppRouteModulesLoaded(route) {
|
|
10
41
|
if (!route || route.__loaded) return route;
|
|
11
42
|
if (route.__loading) return route.__loading;
|
|
12
43
|
const loadPage = route.__loadPage;
|
|
13
44
|
const loadRouteHandler = route.__loadRouteHandler;
|
|
14
|
-
|
|
45
|
+
const loads = [];
|
|
46
|
+
pushFieldLoad(loads, route, "page", loadPage);
|
|
47
|
+
pushFieldLoad(loads, route, "routeHandler", loadRouteHandler);
|
|
48
|
+
pushFieldLoad(loads, route, "loading", route.__loadLoading);
|
|
49
|
+
pushFieldLoad(loads, route, "error", route.__loadError);
|
|
50
|
+
pushFieldLoad(loads, route, "notFound", route.__loadNotFound);
|
|
51
|
+
pushFieldLoad(loads, route, "forbidden", route.__loadForbidden);
|
|
52
|
+
pushFieldLoad(loads, route, "unauthorized", route.__loadUnauthorized);
|
|
53
|
+
pushArrayLoads(loads, route.layouts, route.__loadLayouts);
|
|
54
|
+
pushArrayLoads(loads, route.templates, route.__loadTemplates);
|
|
55
|
+
pushArrayLoads(loads, route.errors, route.__loadErrors);
|
|
56
|
+
pushArrayLoads(loads, route.errorPaths, route.__loadErrorPaths);
|
|
57
|
+
pushArrayLoads(loads, route.notFounds, route.__loadNotFounds);
|
|
58
|
+
pushArrayLoads(loads, route.forbiddens, route.__loadForbiddens);
|
|
59
|
+
pushArrayLoads(loads, route.unauthorizeds, route.__loadUnauthorizeds);
|
|
60
|
+
for (const slot of Object.values(route.slots ?? {})) {
|
|
61
|
+
pushFieldLoad(loads, slot, "page", slot.__loadPage);
|
|
62
|
+
pushFieldLoad(loads, slot, "default", slot.__loadDefault);
|
|
63
|
+
pushFieldLoad(loads, slot, "layout", slot.__loadLayout);
|
|
64
|
+
pushFieldLoad(loads, slot, "loading", slot.__loadLoading);
|
|
65
|
+
pushFieldLoad(loads, slot, "error", slot.__loadError);
|
|
66
|
+
}
|
|
67
|
+
if (loads.length === 0) {
|
|
15
68
|
route.__loaded = true;
|
|
16
69
|
return route;
|
|
17
70
|
}
|
|
18
|
-
const loading = Promise.all(
|
|
19
|
-
if (loadPage) route.page = pageModule;
|
|
20
|
-
if (loadRouteHandler) route.routeHandler = routeHandlerModule;
|
|
71
|
+
const loading = Promise.all(loads).then(() => {
|
|
21
72
|
route.__loaded = true;
|
|
22
73
|
route.__loading = null;
|
|
23
74
|
return route;
|
|
@@ -29,4 +80,4 @@ function ensureAppRouteModulesLoaded(route) {
|
|
|
29
80
|
return loading;
|
|
30
81
|
}
|
|
31
82
|
//#endregion
|
|
32
|
-
export { ensureAppRouteModulesLoaded };
|
|
83
|
+
export { ensureAppRouteModulesLoaded, loadAppInterceptLayouts };
|
|
@@ -5,16 +5,16 @@ import { RootParams } from "../shims/root-params.js";
|
|
|
5
5
|
import { MiddlewareModule } from "./middleware-runtime.js";
|
|
6
6
|
import { AppMiddlewareContext } from "./app-middleware.js";
|
|
7
7
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap } from "./app-prerender-endpoints.js";
|
|
9
|
+
import { MetadataRouteMakeThenableParams, MetadataRuntimeRoute } from "./metadata-route-response.js";
|
|
10
10
|
import { ReactFormState } from "react-dom/client";
|
|
11
11
|
|
|
12
12
|
//#region src/server/app-rsc-handler.d.ts
|
|
13
13
|
type AppPageParams = Record<string, string | string[]>;
|
|
14
|
-
type MetadataRoutes =
|
|
15
|
-
type MakeThenableParams =
|
|
16
|
-
type StaticParamsMap =
|
|
17
|
-
type RootParamNamesMap =
|
|
14
|
+
type MetadataRoutes = readonly MetadataRuntimeRoute[];
|
|
15
|
+
type MakeThenableParams = MetadataRouteMakeThenableParams;
|
|
16
|
+
type StaticParamsMap = AppPrerenderStaticParamsMap;
|
|
17
|
+
type RootParamNamesMap = AppPrerenderRootParamNamesMap;
|
|
18
18
|
type AppRscMiddlewareContext = AppMiddlewareContext;
|
|
19
19
|
type AppRscHandlerRoute = {
|
|
20
20
|
isDynamic: boolean;
|
|
@@ -183,6 +183,7 @@ type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
|
|
|
183
183
|
makeThenableParams: MakeThenableParams;
|
|
184
184
|
matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;
|
|
185
185
|
metadataRoutes: MetadataRoutes;
|
|
186
|
+
middlewareFilePath: string | null;
|
|
186
187
|
middlewareModule: MiddlewareModule | null;
|
|
187
188
|
publicFiles: ReadonlySet<string>;
|
|
188
189
|
renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;
|
|
@@ -17,14 +17,12 @@ import "./app-page-response.js";
|
|
|
17
17
|
import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
|
|
18
18
|
import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
19
19
|
import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
|
|
20
|
+
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
20
21
|
import { flattenErrorCauses } from "../utils/error-cause.js";
|
|
21
22
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
22
23
|
import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
|
|
23
|
-
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
24
|
-
import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
|
|
25
24
|
import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
|
|
26
25
|
import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
|
|
27
|
-
import { handleMetadataRouteRequest } from "./metadata-route-response.js";
|
|
28
26
|
import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
|
|
29
27
|
//#region src/server/app-rsc-handler.ts
|
|
30
28
|
const STATIC_METADATA_CONFIG_HEADER_OVERRIDES = new Set(["cache-control"]);
|
|
@@ -125,16 +123,19 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
125
123
|
basePath: options.basePath,
|
|
126
124
|
hadBasePath: true
|
|
127
125
|
};
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
126
|
+
if (pathname === "/__vinext/prerender/static-params" || pathname === "/__vinext/prerender/pages-static-paths") {
|
|
127
|
+
const { handleAppPrerenderEndpoint } = await import("./app-prerender-endpoints.js");
|
|
128
|
+
const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {
|
|
129
|
+
isPrerenderEnabled() {
|
|
130
|
+
return process.env.VINEXT_PRERENDER === "1";
|
|
131
|
+
},
|
|
132
|
+
loadPagesRoutes: options.loadPrerenderPagesRoutes,
|
|
133
|
+
pathname,
|
|
134
|
+
rootParamNamesByPattern: options.rootParamNamesByPattern,
|
|
135
|
+
staticParamsMap: options.staticParamsMap
|
|
136
|
+
});
|
|
137
|
+
if (prerenderEndpointResponse) return prerenderEndpointResponse;
|
|
138
|
+
}
|
|
138
139
|
const trailingSlashRedirect = normalizeTrailingSlash(pathname, options.basePath, options.trailingSlash, url.search);
|
|
139
140
|
if (trailingSlashRedirect) return trailingSlashRedirect;
|
|
140
141
|
const matchPathname = (p) => normalizeDefaultLocalePathname(p, options.i18nConfig, { hostname: url.hostname });
|
|
@@ -170,6 +171,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
170
171
|
basePath: options.basePath,
|
|
171
172
|
cleanPathname,
|
|
172
173
|
context: middlewareContext,
|
|
174
|
+
filePath: options.middlewareFilePath ?? void 0,
|
|
173
175
|
i18nConfig: options.i18nConfig,
|
|
174
176
|
isDataRequest,
|
|
175
177
|
isProxy: options.isMiddlewareProxy,
|
|
@@ -209,20 +211,23 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
209
211
|
if (!imageRedirect) return new Response("Invalid image optimization parameters", { status: 400 });
|
|
210
212
|
return Response.redirect(new URL(imageRedirect, url.origin).href, 302);
|
|
211
213
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
applyConfigHeadersToResponse(metadataRouteResponse.headers, {
|
|
219
|
-
basePathState,
|
|
220
|
-
configHeaders: options.configHeaders,
|
|
221
|
-
overwriteExisting: STATIC_METADATA_CONFIG_HEADER_OVERRIDES,
|
|
222
|
-
pathname: matchPathname(cleanPathname),
|
|
223
|
-
requestContext: preMiddlewareRequestContext
|
|
214
|
+
if (options.metadataRoutes.length > 0) {
|
|
215
|
+
const { handleMetadataRouteRequest } = await import("./metadata-route-response.js");
|
|
216
|
+
const metadataRouteResponse = await handleMetadataRouteRequest({
|
|
217
|
+
metadataRoutes: options.metadataRoutes,
|
|
218
|
+
cleanPathname,
|
|
219
|
+
makeThenableParams: options.makeThenableParams
|
|
224
220
|
});
|
|
225
|
-
|
|
221
|
+
if (metadataRouteResponse) {
|
|
222
|
+
applyConfigHeadersToResponse(metadataRouteResponse.headers, {
|
|
223
|
+
basePathState,
|
|
224
|
+
configHeaders: options.configHeaders,
|
|
225
|
+
overwriteExisting: STATIC_METADATA_CONFIG_HEADER_OVERRIDES,
|
|
226
|
+
pathname: matchPathname(cleanPathname),
|
|
227
|
+
requestContext: preMiddlewareRequestContext
|
|
228
|
+
});
|
|
229
|
+
return applyMiddlewareContextToResponse(metadataRouteResponse, middlewareContext);
|
|
230
|
+
}
|
|
226
231
|
}
|
|
227
232
|
const publicFileResponse = resolvePublicFileRoute({
|
|
228
233
|
cleanPathname,
|
|
@@ -31,6 +31,7 @@ type AppRscInterceptForMatching = {
|
|
|
31
31
|
sourceMatchPattern?: string;
|
|
32
32
|
sourcePageSegments?: readonly string[];
|
|
33
33
|
interceptLayouts: readonly unknown[];
|
|
34
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
34
35
|
page: unknown;
|
|
35
36
|
__pageLoader?: (() => Promise<unknown>) | null;
|
|
36
37
|
params: readonly string[];
|
|
@@ -45,6 +46,7 @@ type AppRscSiblingInterceptForMatching = {
|
|
|
45
46
|
sourcePageSegments?: readonly string[];
|
|
46
47
|
slotId: string | null;
|
|
47
48
|
interceptLayouts: readonly unknown[];
|
|
49
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
48
50
|
page: unknown;
|
|
49
51
|
__pageLoader?: (() => Promise<unknown>) | null;
|
|
50
52
|
params: readonly string[];
|
|
@@ -58,6 +60,11 @@ type AppRscRouteForMatching = {
|
|
|
58
60
|
type AppRscInterceptMatch = AppRscInterceptLookupEntry & {
|
|
59
61
|
matchedParams: AppRscRouteParams;
|
|
60
62
|
};
|
|
63
|
+
type AppRscInterceptLoadState = {
|
|
64
|
+
page: unknown;
|
|
65
|
+
pageLoading: Promise<unknown> | null;
|
|
66
|
+
interceptLayoutsLoading: Promise<readonly unknown[]> | null;
|
|
67
|
+
};
|
|
61
68
|
type AppRscInterceptLookupEntry = {
|
|
62
69
|
sourceRouteIndex: number;
|
|
63
70
|
slotKey: string;
|
|
@@ -67,8 +74,10 @@ type AppRscInterceptLookupEntry = {
|
|
|
67
74
|
sourceMatchPatternParts: string[] | null;
|
|
68
75
|
sourcePageSegments: readonly string[] | null;
|
|
69
76
|
interceptLayouts: readonly unknown[];
|
|
77
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
70
78
|
page: unknown;
|
|
71
79
|
__pageLoader?: (() => Promise<unknown>) | null;
|
|
80
|
+
__loadState: AppRscInterceptLoadState;
|
|
72
81
|
params: readonly string[];
|
|
73
82
|
slotId: string | null;
|
|
74
83
|
};
|
|
@@ -39,6 +39,7 @@ function createAppRscRouteMatcher(routes) {
|
|
|
39
39
|
const sourceParams = matchedSourceParams ?? createRouteParams();
|
|
40
40
|
return {
|
|
41
41
|
...entry,
|
|
42
|
+
page: entry.__loadState.page,
|
|
42
43
|
sourceRouteIndex: concreteSourceRouteIndex,
|
|
43
44
|
matchedParams: mergeMatchedParams(sourceParams, params)
|
|
44
45
|
};
|
|
@@ -84,8 +85,14 @@ function createInterceptLookup(routes) {
|
|
|
84
85
|
sourceMatchPatternParts,
|
|
85
86
|
sourcePageSegments: intercept.sourcePageSegments ?? null,
|
|
86
87
|
interceptLayouts: intercept.interceptLayouts,
|
|
88
|
+
__loadInterceptLayouts: intercept.__loadInterceptLayouts,
|
|
87
89
|
page: intercept.page,
|
|
88
90
|
__pageLoader: intercept.__pageLoader,
|
|
91
|
+
__loadState: {
|
|
92
|
+
page: intercept.page,
|
|
93
|
+
pageLoading: null,
|
|
94
|
+
interceptLayoutsLoading: null
|
|
95
|
+
},
|
|
89
96
|
params: intercept.params
|
|
90
97
|
});
|
|
91
98
|
}
|
|
@@ -103,8 +110,14 @@ function createInterceptLookup(routes) {
|
|
|
103
110
|
sourceMatchPatternParts,
|
|
104
111
|
sourcePageSegments: intercept.sourcePageSegments ?? null,
|
|
105
112
|
interceptLayouts: intercept.interceptLayouts,
|
|
113
|
+
__loadInterceptLayouts: intercept.__loadInterceptLayouts,
|
|
106
114
|
page: intercept.page,
|
|
107
115
|
__pageLoader: intercept.__pageLoader,
|
|
116
|
+
__loadState: {
|
|
117
|
+
page: intercept.page,
|
|
118
|
+
pageLoading: null,
|
|
119
|
+
interceptLayoutsLoading: null
|
|
120
|
+
},
|
|
108
121
|
params: intercept.params
|
|
109
122
|
});
|
|
110
123
|
}
|