vinext 0.1.0 → 0.1.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/dist/build/assets-ignore.d.ts +32 -0
- package/dist/build/assets-ignore.js +48 -0
- package/dist/build/client-build-config.d.ts +27 -1
- package/dist/build/client-build-config.js +58 -1
- package/dist/cli.js +2 -0
- package/dist/client/navigation-runtime.d.ts +8 -0
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/client/vinext-next-data.d.ts +2 -1
- package/dist/config/config-matchers.d.ts +20 -1
- package/dist/config/config-matchers.js +35 -1
- package/dist/config/next-config.d.ts +16 -3
- package/dist/config/next-config.js +30 -2
- package/dist/deploy.js +40 -304
- package/dist/entries/app-rsc-entry.d.ts +8 -2
- package/dist/entries/app-rsc-entry.js +54 -4
- package/dist/entries/app-rsc-manifest.js +20 -2
- package/dist/entries/pages-server-entry.js +9 -1
- package/dist/index.js +162 -217
- package/dist/plugins/postcss.js +18 -14
- package/dist/plugins/require-context.d.ts +6 -0
- package/dist/plugins/require-context.js +184 -0
- package/dist/routing/app-route-graph.d.ts +12 -1
- package/dist/routing/app-route-graph.js +137 -5
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +16 -1
- package/dist/server/api-handler.js +4 -0
- package/dist/server/app-browser-entry.js +84 -39
- package/dist/server/app-browser-interception-context.d.ts +2 -1
- package/dist/server/app-browser-interception-context.js +15 -2
- package/dist/server/app-browser-navigation-controller.d.ts +11 -1
- package/dist/server/app-browser-navigation-controller.js +77 -1
- package/dist/server/app-browser-popstate.d.ts +12 -3
- package/dist/server/app-browser-popstate.js +19 -4
- package/dist/server/app-browser-state.d.ts +3 -0
- package/dist/server/app-browser-state.js +6 -3
- package/dist/server/app-browser-visible-commit.js +9 -7
- package/dist/server/app-history-state.d.ts +45 -1
- package/dist/server/app-history-state.js +109 -1
- package/dist/server/app-page-boundary-render.js +41 -19
- package/dist/server/app-page-dispatch.d.ts +6 -0
- package/dist/server/app-page-dispatch.js +3 -1
- package/dist/server/app-page-element-builder.d.ts +1 -0
- package/dist/server/app-page-element-builder.js +22 -10
- package/dist/server/app-page-render.d.ts +6 -0
- package/dist/server/app-page-render.js +5 -3
- package/dist/server/app-page-request.d.ts +8 -6
- package/dist/server/app-page-request.js +12 -9
- package/dist/server/app-page-response.d.ts +2 -2
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.js +2 -1
- package/dist/server/app-page-stream.d.ts +37 -2
- package/dist/server/app-page-stream.js +36 -3
- package/dist/server/app-pages-bridge.d.ts +16 -0
- package/dist/server/app-pages-bridge.js +23 -3
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +2 -0
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-runtime.d.ts +1 -0
- package/dist/server/app-route-handler-runtime.js +3 -2
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +4 -3
- package/dist/server/app-rsc-route-matching.d.ts +20 -1
- package/dist/server/app-rsc-route-matching.js +29 -4
- package/dist/server/app-server-action-execution.d.ts +11 -1
- package/dist/server/app-server-action-execution.js +68 -10
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +17 -1
- package/dist/server/dev-server.d.ts +1 -1
- package/dist/server/dev-server.js +54 -31
- package/dist/server/isr-cache.d.ts +37 -1
- package/dist/server/isr-cache.js +85 -1
- package/dist/server/navigation-planner.js +5 -3
- package/dist/server/navigation-trace.d.ts +1 -1
- package/dist/server/pages-node-compat.d.ts +2 -0
- package/dist/server/pages-node-compat.js +4 -0
- package/dist/server/pages-page-data.d.ts +10 -7
- package/dist/server/pages-page-data.js +4 -2
- package/dist/server/pages-page-handler.d.ts +9 -2
- package/dist/server/pages-page-handler.js +29 -16
- package/dist/server/pages-page-response.d.ts +11 -2
- package/dist/server/pages-page-response.js +8 -1
- package/dist/server/pages-readiness.d.ts +36 -0
- package/dist/server/pages-readiness.js +21 -0
- package/dist/server/pages-request-pipeline.d.ts +99 -0
- package/dist/server/pages-request-pipeline.js +209 -0
- package/dist/server/pages-revalidate.d.ts +15 -0
- package/dist/server/pages-revalidate.js +19 -0
- package/dist/server/prod-server.d.ts +6 -2
- package/dist/server/prod-server.js +101 -217
- package/dist/server/socket-error-backstop.d.ts +19 -1
- package/dist/server/socket-error-backstop.js +77 -4
- package/dist/shims/app-router-scroll.js +22 -4
- package/dist/shims/cache-runtime.js +31 -1
- package/dist/shims/error-boundary.d.ts +21 -11
- package/dist/shims/error-boundary.js +8 -1
- package/dist/shims/fetch-cache.d.ts +14 -1
- package/dist/shims/fetch-cache.js +18 -1
- package/dist/shims/hash-scroll.d.ts +1 -0
- package/dist/shims/hash-scroll.js +3 -1
- package/dist/shims/internal/link-status-registry.d.ts +43 -0
- package/dist/shims/internal/link-status-registry.js +42 -0
- package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
- package/dist/shims/internal/route-pattern-for-warning.js +40 -0
- package/dist/shims/internal/utils.d.ts +1 -0
- package/dist/shims/link.js +20 -6
- package/dist/shims/navigation.d.ts +2 -2
- package/dist/shims/navigation.js +63 -7
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js +2 -0
- package/dist/shims/router.d.ts +6 -3
- package/dist/shims/router.js +128 -21
- package/dist/utils/client-build-manifest.d.ts +8 -1
- package/dist/utils/client-build-manifest.js +30 -5
- package/dist/utils/client-entry-manifest.d.ts +11 -0
- package/dist/utils/client-entry-manifest.js +29 -0
- package/package.json +5 -1
|
@@ -99,7 +99,8 @@ function createBfcacheSegmentStateKeyMap(options) {
|
|
|
99
99
|
return stateKeys;
|
|
100
100
|
}
|
|
101
101
|
function createNextBfcacheIdMap(options) {
|
|
102
|
-
|
|
102
|
+
const current = options.reuseCurrent === false ? {} : options.current;
|
|
103
|
+
for (const value of Object.values(current)) rememberBfcacheId(value);
|
|
103
104
|
for (const value of Object.values(options.restored ?? {})) rememberBfcacheId(value);
|
|
104
105
|
const currentMetadata = readAppElementsMetadata(options.currentElements);
|
|
105
106
|
const nextMetadata = readAppElementsMetadata(options.elements);
|
|
@@ -113,7 +114,7 @@ function createNextBfcacheIdMap(options) {
|
|
|
113
114
|
}) === createBfcacheSegmentIdentity(id, {
|
|
114
115
|
metadata: nextMetadata,
|
|
115
116
|
pathname: nextPathname
|
|
116
|
-
}) ?
|
|
117
|
+
}) ? current[id] : void 0;
|
|
117
118
|
const value = options.restored?.[id] ?? currentValue ?? mintBfcacheId();
|
|
118
119
|
ids[id] = value;
|
|
119
120
|
rememberBfcacheId(value);
|
|
@@ -396,7 +397,8 @@ async function createPendingNavigationCommit(options) {
|
|
|
396
397
|
currentPathname: options.currentState.navigationSnapshot.pathname,
|
|
397
398
|
elements,
|
|
398
399
|
nextPathname: options.navigationSnapshot.pathname,
|
|
399
|
-
restored: options.restoredBfcacheIds
|
|
400
|
+
restored: options.restoredBfcacheIds,
|
|
401
|
+
reuseCurrent: options.reuseCurrentBfcacheIds
|
|
400
402
|
}),
|
|
401
403
|
...cacheEntryReuseProof ? { cacheEntryReuseProof } : {},
|
|
402
404
|
elements,
|
|
@@ -414,6 +416,7 @@ async function createPendingNavigationCommit(options) {
|
|
|
414
416
|
previousNextUrl,
|
|
415
417
|
renderId: options.renderId,
|
|
416
418
|
rootLayoutTreePath: metadata.rootLayoutTreePath,
|
|
419
|
+
reuseCurrentBfcacheIds: options.reuseCurrentBfcacheIds ?? true,
|
|
417
420
|
routeId: metadata.routeId,
|
|
418
421
|
skippedLayoutIds: metadata.skippedLayoutIds,
|
|
419
422
|
type: options.type
|
|
@@ -56,29 +56,31 @@ function reduceApprovedVisibleCommitState(state, commit) {
|
|
|
56
56
|
switch (action.type) {
|
|
57
57
|
case "traverse":
|
|
58
58
|
case "navigate": {
|
|
59
|
+
const preserveElementIds = action.reuseCurrentBfcacheIds ? commit.decision.preserveElementIds : [];
|
|
60
|
+
const preservePreviousSlotIds = action.reuseCurrentBfcacheIds ? commit.decision.preservePreviousSlotIds : [];
|
|
59
61
|
const mergedElements = mergeElements(state.elements, action.elements, {
|
|
60
|
-
clearAbsentSlots: action.type === "traverse",
|
|
61
|
-
preserveAbsentSlots: commit.decision.preserveAbsentSlots,
|
|
62
|
-
preserveElementIds
|
|
63
|
-
preservePreviousSlotIds
|
|
62
|
+
clearAbsentSlots: action.type === "traverse" || !action.reuseCurrentBfcacheIds,
|
|
63
|
+
preserveAbsentSlots: action.reuseCurrentBfcacheIds && commit.decision.preserveAbsentSlots,
|
|
64
|
+
preserveElementIds,
|
|
65
|
+
preservePreviousSlotIds
|
|
64
66
|
});
|
|
65
67
|
return commitVisibleRouterState(state, {
|
|
66
68
|
bfcacheIds: preserveBfcacheIdsForMergedElements({
|
|
67
69
|
elements: mergedElements,
|
|
68
70
|
next: action.bfcacheIds,
|
|
69
|
-
previous: state.bfcacheIds
|
|
71
|
+
previous: action.reuseCurrentBfcacheIds ? state.bfcacheIds : {}
|
|
70
72
|
}),
|
|
71
73
|
elements: mergedElements,
|
|
72
74
|
interception: action.interception,
|
|
73
75
|
interceptionContext: action.interceptionContext,
|
|
74
|
-
layoutFlags: mergeLayoutFlags(state.layoutFlags, action.layoutFlags,
|
|
76
|
+
layoutFlags: mergeLayoutFlags(state.layoutFlags, action.layoutFlags, preserveElementIds),
|
|
75
77
|
layoutIds: action.layoutIds,
|
|
76
78
|
navigationSnapshot: action.navigationSnapshot,
|
|
77
79
|
previousNextUrl: action.previousNextUrl,
|
|
78
80
|
renderId: action.renderId,
|
|
79
81
|
rootLayoutTreePath: action.rootLayoutTreePath,
|
|
80
82
|
routeId: action.routeId,
|
|
81
|
-
slotBindings: mergeSlotBindings(state.slotBindings, action.slotBindings, action.layoutIds,
|
|
83
|
+
slotBindings: mergeSlotBindings(state.slotBindings, action.slotBindings, action.layoutIds, preservePreviousSlotIds)
|
|
82
84
|
}, action.operation);
|
|
83
85
|
}
|
|
84
86
|
case "replace": return commitVisibleRouterState(state, {
|
|
@@ -10,6 +10,50 @@ type HistoryTraversalIntent = {
|
|
|
10
10
|
historyState: unknown;
|
|
11
11
|
targetHistoryIndex: number | null;
|
|
12
12
|
};
|
|
13
|
+
type HistoryStateSnapshotRestoreDecision<TState> = {
|
|
14
|
+
kind: "restore";
|
|
15
|
+
state: TState;
|
|
16
|
+
targetHistoryIndex: number;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "skip";
|
|
19
|
+
reason: "guarded" | "missing-history-index" | "missing-snapshot" | "stale-bfcache-version";
|
|
20
|
+
targetHistoryIndex: number | null;
|
|
21
|
+
};
|
|
22
|
+
declare class HistoryStateSnapshotCache<TState> {
|
|
23
|
+
#private;
|
|
24
|
+
constructor(options: {
|
|
25
|
+
maxEntries: number;
|
|
26
|
+
});
|
|
27
|
+
clear(): void;
|
|
28
|
+
remember(options: {
|
|
29
|
+
bfcacheVersion: number;
|
|
30
|
+
historyIndex: number | null;
|
|
31
|
+
state: TState;
|
|
32
|
+
}): void;
|
|
33
|
+
resolveRestore(options: {
|
|
34
|
+
currentBfcacheVersion: number;
|
|
35
|
+
guarded: boolean;
|
|
36
|
+
historyState: unknown;
|
|
37
|
+
}): HistoryStateSnapshotRestoreDecision<TState>;
|
|
38
|
+
}
|
|
39
|
+
declare class RestorableClientStateController<TState> {
|
|
40
|
+
#private;
|
|
41
|
+
constructor(options: {
|
|
42
|
+
initialHistoryState: unknown;
|
|
43
|
+
maxHistoryStateSnapshots: number;
|
|
44
|
+
});
|
|
45
|
+
get currentBfcacheVersion(): number;
|
|
46
|
+
beginCacheInvalidationGuard(): () => void;
|
|
47
|
+
isCacheInvalidationGuarded(): boolean;
|
|
48
|
+
isCurrentBfcacheVersion(historyState: unknown): boolean;
|
|
49
|
+
readCurrentBfcacheVersionHistoryIds(historyState: unknown): BfcacheIdMap | null;
|
|
50
|
+
invalidateClientState(): void;
|
|
51
|
+
rememberHistoryStateSnapshot(options: {
|
|
52
|
+
historyIndex: number | null;
|
|
53
|
+
state: TState;
|
|
54
|
+
}): void;
|
|
55
|
+
resolveHistoryStateSnapshotRestore(historyState: unknown): HistoryStateSnapshotRestoreDecision<TState>;
|
|
56
|
+
}
|
|
13
57
|
declare function createHistoryStateWithPreviousNextUrl(state: unknown, previousNextUrl: string | null): HistoryStateRecord | null;
|
|
14
58
|
declare function createHistoryStateWithNavigationMetadata(state: unknown, metadata: {
|
|
15
59
|
bfcacheIds?: BfcacheIdMap | null;
|
|
@@ -39,4 +83,4 @@ declare function resolveHistoryTraversalIntent(options: {
|
|
|
39
83
|
historyState: unknown;
|
|
40
84
|
}): HistoryTraversalIntent;
|
|
41
85
|
//#endregion
|
|
42
|
-
export { BfcacheIdMap, HistoryTraversalIntent, createExternalHistoryStatePreservingMetadata, createHashOnlyHistoryStatePreservingNavigationMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isBfcacheSegmentId, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent };
|
|
86
|
+
export { BfcacheIdMap, HistoryStateSnapshotCache, HistoryTraversalIntent, RestorableClientStateController, createExternalHistoryStatePreservingMetadata, createHashOnlyHistoryStatePreservingNavigationMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isBfcacheSegmentId, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent };
|
|
@@ -6,6 +6,114 @@ const VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY = "__vinext_previousNextUrl";
|
|
|
6
6
|
const VINEXT_HISTORY_INDEX_HISTORY_STATE_KEY = "__vinext_historyIndex";
|
|
7
7
|
const VINEXT_BFCACHE_IDS_HISTORY_STATE_KEY = "__vinext_bfcacheIds";
|
|
8
8
|
const VINEXT_BFCACHE_VERSION_HISTORY_STATE_KEY = "__vinext_bfcacheVersion";
|
|
9
|
+
var HistoryStateSnapshotCache = class {
|
|
10
|
+
#maxEntries;
|
|
11
|
+
#snapshots = /* @__PURE__ */ new Map();
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.#maxEntries = options.maxEntries;
|
|
14
|
+
}
|
|
15
|
+
clear() {
|
|
16
|
+
this.#snapshots.clear();
|
|
17
|
+
}
|
|
18
|
+
remember(options) {
|
|
19
|
+
if (options.historyIndex === null) return;
|
|
20
|
+
this.#snapshots.delete(options.historyIndex);
|
|
21
|
+
this.#snapshots.set(options.historyIndex, {
|
|
22
|
+
bfcacheVersion: options.bfcacheVersion,
|
|
23
|
+
state: options.state
|
|
24
|
+
});
|
|
25
|
+
if (this.#snapshots.size <= this.#maxEntries) return;
|
|
26
|
+
const oldestIndex = this.#snapshots.keys().next().value;
|
|
27
|
+
if (typeof oldestIndex === "number") this.#snapshots.delete(oldestIndex);
|
|
28
|
+
}
|
|
29
|
+
resolveRestore(options) {
|
|
30
|
+
const targetHistoryIndex = readHistoryStateTraversalIndex(options.historyState);
|
|
31
|
+
if (targetHistoryIndex === null) return {
|
|
32
|
+
kind: "skip",
|
|
33
|
+
reason: "missing-history-index",
|
|
34
|
+
targetHistoryIndex
|
|
35
|
+
};
|
|
36
|
+
const snapshot = this.#snapshots.get(targetHistoryIndex);
|
|
37
|
+
if (!snapshot) return {
|
|
38
|
+
kind: "skip",
|
|
39
|
+
reason: "missing-snapshot",
|
|
40
|
+
targetHistoryIndex
|
|
41
|
+
};
|
|
42
|
+
if (options.guarded) return {
|
|
43
|
+
kind: "skip",
|
|
44
|
+
reason: "guarded",
|
|
45
|
+
targetHistoryIndex
|
|
46
|
+
};
|
|
47
|
+
if (snapshot.bfcacheVersion !== options.currentBfcacheVersion) {
|
|
48
|
+
this.#snapshots.delete(targetHistoryIndex);
|
|
49
|
+
return {
|
|
50
|
+
kind: "skip",
|
|
51
|
+
reason: "stale-bfcache-version",
|
|
52
|
+
targetHistoryIndex
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
kind: "restore",
|
|
57
|
+
state: snapshot.state,
|
|
58
|
+
targetHistoryIndex
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var RestorableClientStateController = class {
|
|
63
|
+
#currentBfcacheVersion;
|
|
64
|
+
#pendingCacheInvalidationGuards = 0;
|
|
65
|
+
#snapshots;
|
|
66
|
+
constructor(options) {
|
|
67
|
+
const initialHistoryBfcacheVersion = readHistoryStateBfcacheVersion(options.initialHistoryState);
|
|
68
|
+
this.#currentBfcacheVersion = initialHistoryBfcacheVersion === null ? 0 : initialHistoryBfcacheVersion + 1;
|
|
69
|
+
this.#snapshots = new HistoryStateSnapshotCache({ maxEntries: options.maxHistoryStateSnapshots });
|
|
70
|
+
}
|
|
71
|
+
get currentBfcacheVersion() {
|
|
72
|
+
return this.#currentBfcacheVersion;
|
|
73
|
+
}
|
|
74
|
+
beginCacheInvalidationGuard() {
|
|
75
|
+
this.#pendingCacheInvalidationGuards += 1;
|
|
76
|
+
let released = false;
|
|
77
|
+
return () => {
|
|
78
|
+
if (released) return;
|
|
79
|
+
released = true;
|
|
80
|
+
this.#pendingCacheInvalidationGuards = Math.max(0, this.#pendingCacheInvalidationGuards - 1);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
isCacheInvalidationGuarded() {
|
|
84
|
+
return this.#pendingCacheInvalidationGuards > 0;
|
|
85
|
+
}
|
|
86
|
+
isCurrentBfcacheVersion(historyState) {
|
|
87
|
+
return isHistoryStateBfcacheVersionCurrent(historyState, this.#currentBfcacheVersion);
|
|
88
|
+
}
|
|
89
|
+
readCurrentBfcacheVersionHistoryIds(historyState) {
|
|
90
|
+
if (this.isCacheInvalidationGuarded()) return null;
|
|
91
|
+
const ids = readHistoryStateBfcacheIds(historyState);
|
|
92
|
+
if (ids === null) return null;
|
|
93
|
+
return this.isCurrentBfcacheVersion(historyState) ? ids : null;
|
|
94
|
+
}
|
|
95
|
+
#invalidateBfcacheIds() {
|
|
96
|
+
this.#currentBfcacheVersion += 1;
|
|
97
|
+
}
|
|
98
|
+
invalidateClientState() {
|
|
99
|
+
this.#snapshots.clear();
|
|
100
|
+
this.#invalidateBfcacheIds();
|
|
101
|
+
}
|
|
102
|
+
rememberHistoryStateSnapshot(options) {
|
|
103
|
+
this.#snapshots.remember({
|
|
104
|
+
bfcacheVersion: this.#currentBfcacheVersion,
|
|
105
|
+
historyIndex: options.historyIndex,
|
|
106
|
+
state: options.state
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
resolveHistoryStateSnapshotRestore(historyState) {
|
|
110
|
+
return this.#snapshots.resolveRestore({
|
|
111
|
+
currentBfcacheVersion: this.#currentBfcacheVersion,
|
|
112
|
+
guarded: this.isCacheInvalidationGuarded(),
|
|
113
|
+
historyState
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
9
117
|
function cloneHistoryState(state) {
|
|
10
118
|
if (!state || typeof state !== "object") return {};
|
|
11
119
|
const nextState = {};
|
|
@@ -112,4 +220,4 @@ function resolveHistoryTraversalIntent(options) {
|
|
|
112
220
|
};
|
|
113
221
|
}
|
|
114
222
|
//#endregion
|
|
115
|
-
export { createExternalHistoryStatePreservingMetadata, createHashOnlyHistoryStatePreservingNavigationMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isBfcacheSegmentId, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent };
|
|
223
|
+
export { HistoryStateSnapshotCache, RestorableClientStateController, createExternalHistoryStatePreservingMetadata, createHashOnlyHistoryStatePreservingNavigationMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isBfcacheSegmentId, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent };
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
2
2
|
import "./app-elements.js";
|
|
3
|
-
import {
|
|
3
|
+
import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
4
|
+
import { ErrorBoundary, GlobalErrorBoundary } from "../shims/error-boundary.js";
|
|
4
5
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
5
6
|
import { MetadataHead, ViewportHead } from "../shims/metadata.js";
|
|
7
|
+
import { resolveAppPageSpecialError } from "./app-page-execution.js";
|
|
6
8
|
import { resolveAppPageHead } from "./app-page-head.js";
|
|
7
9
|
import { createAppPageLayoutEntries } from "./app-page-route-wiring.js";
|
|
8
10
|
import { buildClientHookErrorMessage } from "../shims/client-hook-error.js";
|
|
11
|
+
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
9
12
|
import { renderAppPageBoundaryResponse, resolveAppPageErrorBoundary, resolveAppPageHttpAccessBoundaryModule, wrapAppPageBoundaryElement } from "./app-page-boundary.js";
|
|
10
13
|
import { createAppPageFontData, renderAppPageHtmlResponse } from "./app-page-stream.js";
|
|
11
14
|
import { Fragment, createElement } from "react";
|
|
12
15
|
//#region src/server/app-page-boundary-render.ts
|
|
16
|
+
const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
|
|
13
17
|
function getDefaultExport(module) {
|
|
14
18
|
return module?.default ?? null;
|
|
15
19
|
}
|
|
@@ -25,9 +29,12 @@ function wrapRenderedBoundaryElement(options) {
|
|
|
25
29
|
makeThenableParams: options.makeThenableParams,
|
|
26
30
|
matchedParams: options.matchedParams,
|
|
27
31
|
renderErrorBoundary(GlobalErrorComponent, children) {
|
|
28
|
-
return createElement(
|
|
29
|
-
fallback:
|
|
30
|
-
children
|
|
32
|
+
return createElement(GlobalErrorBoundary, {
|
|
33
|
+
fallback: DEFAULT_GLOBAL_ERROR_COMPONENT,
|
|
34
|
+
children: createElement(ErrorBoundary, {
|
|
35
|
+
fallback: GlobalErrorComponent,
|
|
36
|
+
children
|
|
37
|
+
})
|
|
31
38
|
});
|
|
32
39
|
},
|
|
33
40
|
renderLayout(LayoutComponent, children, asyncParams) {
|
|
@@ -233,22 +240,28 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
233
240
|
} catch (error) {
|
|
234
241
|
console.error(`[vinext] App page error boundary head resolution failed for ${options.route?.pattern ?? pathname}:`, error);
|
|
235
242
|
}
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
243
|
+
const buildElement = (BoundaryComponent) => {
|
|
244
|
+
const boundaryElement = createElement(BoundaryComponent, { error: errorObject });
|
|
245
|
+
return wrapRenderedBoundaryElement({
|
|
246
|
+
element: createElement(Fragment, null, ...headElements, errorBoundary.isGlobalError ? createElement(GlobalErrorBoundary, {
|
|
247
|
+
fallback: DEFAULT_GLOBAL_ERROR_COMPONENT,
|
|
248
|
+
children: boundaryElement
|
|
249
|
+
}) : boundaryElement),
|
|
250
|
+
globalErrorModule: options.globalErrorModule,
|
|
251
|
+
includeGlobalErrorBoundary: !errorBoundary.isGlobalError,
|
|
252
|
+
isRscRequest: options.isRscRequest,
|
|
253
|
+
layoutModules,
|
|
254
|
+
layoutTreePositions: options.route?.layoutTreePositions,
|
|
255
|
+
makeThenableParams: options.makeThenableParams,
|
|
256
|
+
matchedParams,
|
|
257
|
+
resolveChildSegments: options.resolveChildSegments,
|
|
258
|
+
routeSegments: options.route?.routeSegments,
|
|
259
|
+
skipLayoutWrapping: errorBoundary.isGlobalError
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
const renderWith = (BoundaryComponent) => renderAppPageBoundaryElementResponse({
|
|
250
263
|
...options,
|
|
251
|
-
element,
|
|
264
|
+
element: buildElement(BoundaryComponent),
|
|
252
265
|
initialDevServerError: rawError,
|
|
253
266
|
layoutModules,
|
|
254
267
|
navigationParams: matchedParams,
|
|
@@ -256,6 +269,15 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
256
269
|
routePattern: options.route?.pattern,
|
|
257
270
|
status: 200
|
|
258
271
|
});
|
|
272
|
+
try {
|
|
273
|
+
return await renderWith(errorBoundary.component);
|
|
274
|
+
} catch (renderError) {
|
|
275
|
+
if (errorBoundary.isGlobalError && !isNavigationSignalError(renderError) && !resolveAppPageSpecialError(renderError)) {
|
|
276
|
+
console.error(`[vinext] global-error.tsx threw while rendering for ${options.route?.pattern ?? pathname}; falling back to the built-in default global-error:`, renderError);
|
|
277
|
+
return renderWith(DEFAULT_GLOBAL_ERROR_COMPONENT);
|
|
278
|
+
}
|
|
279
|
+
throw renderError;
|
|
280
|
+
}
|
|
259
281
|
}
|
|
260
282
|
const _clientHookPattern = /\b(useState|useEffect|useReducer|useRef|useContext|useLayoutEffect|useInsertionEffect|useSyncExternalStore|useTransition|useImperativeHandle|useDeferredValue|useActionState|useOptimistic|useEffectEvent)\b.*is not a function/;
|
|
261
283
|
function rewriteClientHookError(error) {
|
|
@@ -78,6 +78,12 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
78
78
|
* SSR head. Undefined or empty disables emission entirely.
|
|
79
79
|
*/
|
|
80
80
|
clientTraceMetadata?: readonly string[];
|
|
81
|
+
/**
|
|
82
|
+
* Maximum total length (in characters) of the preload `Link` header emitted
|
|
83
|
+
* during SSR. `0` disables emission. From `reactMaxHeadersLength` in
|
|
84
|
+
* `next.config`. Undefined falls back to the React default downstream.
|
|
85
|
+
*/
|
|
86
|
+
reactMaxHeadersLength?: number;
|
|
81
87
|
buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker) => Promise<AppPageElement>;
|
|
82
88
|
clientReuseManifest?: ClientReuseManifestParseResult;
|
|
83
89
|
cleanPathname: string;
|
|
@@ -217,7 +217,7 @@ async function dispatchAppPageInner(options) {
|
|
|
217
217
|
expireSeconds: options.expireSeconds,
|
|
218
218
|
revalidateSeconds: currentRevalidateSeconds ?? 0,
|
|
219
219
|
renderFreshPageForCache: async () => {
|
|
220
|
-
const revalidationTarget = resolveAppPageInterceptionRerenderTarget({
|
|
220
|
+
const revalidationTarget = await resolveAppPageInterceptionRerenderTarget({
|
|
221
221
|
cleanPathname: options.cleanPathname,
|
|
222
222
|
currentParams: options.params,
|
|
223
223
|
currentRoute: route,
|
|
@@ -256,6 +256,7 @@ async function dispatchAppPageInner(options) {
|
|
|
256
256
|
}, {
|
|
257
257
|
basePath: options.basePath,
|
|
258
258
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
259
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
259
260
|
rootParams: options.rootParams,
|
|
260
261
|
waitForAllReady: true,
|
|
261
262
|
...revalidatedRscCapture.sideStream ? {
|
|
@@ -390,6 +391,7 @@ async function dispatchAppPageInner(options) {
|
|
|
390
391
|
return renderAppPageLifecycle({
|
|
391
392
|
basePath: options.basePath,
|
|
392
393
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
394
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
393
395
|
cleanPathname: options.cleanPathname,
|
|
394
396
|
clearRequestContext: options.clearRequestContext,
|
|
395
397
|
consumeDynamicUsage,
|
|
@@ -37,6 +37,7 @@ type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TEr
|
|
|
37
37
|
route: AppPageBuildRoute<TModule, TErrorModule>;
|
|
38
38
|
params: AppPageParams;
|
|
39
39
|
routePath: string;
|
|
40
|
+
displayPathname?: string;
|
|
40
41
|
pageRequest: AppPagePageRequest<TModule>; /** Root-level global-error.tsx module. Present when the app defines this file. */
|
|
41
42
|
globalErrorModule?: TErrorModule | null; /** Root-level not-found.tsx module. Present when the app defines this file. */
|
|
42
43
|
rootNotFoundModule?: TModule | null; /** Root-level forbidden.tsx module. Present when the app defines this file. */
|
|
@@ -9,6 +9,7 @@ import { makeObservedAppPageSearchParamsThenable } from "./app-page-search-param
|
|
|
9
9
|
import { buildAppPageElements, createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
10
10
|
import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
|
|
11
11
|
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
12
|
+
import "./app-rsc-route-matching.js";
|
|
12
13
|
import { createElement } from "react";
|
|
13
14
|
//#region src/server/app-page-element-builder.ts
|
|
14
15
|
/**
|
|
@@ -28,18 +29,21 @@ import { createElement } from "react";
|
|
|
28
29
|
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
|
|
29
30
|
*/
|
|
30
31
|
async function buildPageElements(options) {
|
|
31
|
-
const { route, params, routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
|
|
32
|
+
const { route, params, routePath, displayPathname = routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
|
|
32
33
|
const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION } = pageRequest;
|
|
33
34
|
const pageModule = route.page;
|
|
34
|
-
const
|
|
35
|
+
const isSiblingIntercept = opts?.interceptSlotKey === "__vinext_page_intercept" && !!opts?.interceptPage;
|
|
36
|
+
const effectivePageModule = isSiblingIntercept ? opts.interceptPage : pageModule;
|
|
37
|
+
const EffectivePageComponent = effectivePageModule?.default;
|
|
38
|
+
const effectiveParams = isSiblingIntercept ? opts.interceptParams ?? params : params;
|
|
35
39
|
const hasPageModule = !!pageModule;
|
|
36
40
|
const renderIdentity = createAppPageRenderIdentity({
|
|
37
|
-
displayPathname
|
|
41
|
+
displayPathname,
|
|
38
42
|
interceptionContext: opts?.interceptionContext ?? null,
|
|
39
43
|
interceptSourceMatchedUrl: opts?.interceptSourceMatchedUrl ?? null,
|
|
40
|
-
interceptSlotId: opts?.interceptSlotId ?? null
|
|
44
|
+
interceptSlotId: isSiblingIntercept ? null : opts?.interceptSlotId ?? null
|
|
41
45
|
});
|
|
42
|
-
if (hasPageModule && !
|
|
46
|
+
if ((hasPageModule || isSiblingIntercept) && !EffectivePageComponent) {
|
|
43
47
|
let noExportRootLayout = null;
|
|
44
48
|
const noExportLayoutIds = route.ids?.layouts ?? route.layouts.map((_, index) => AppElementsWire.encodeLayoutId(createAppPageTreePath(route.routeSegments, route.layoutTreePositions?.[index] ?? 0)));
|
|
45
49
|
if (route.layouts?.length > 0) {
|
|
@@ -62,7 +66,7 @@ async function buildPageElements(options) {
|
|
|
62
66
|
layoutModules: route.layouts,
|
|
63
67
|
layoutTreePositions: route.layoutTreePositions,
|
|
64
68
|
metadataRoutes,
|
|
65
|
-
pageModule:
|
|
69
|
+
pageModule: effectivePageModule ?? null,
|
|
66
70
|
parallelRoutes: resolveActiveParallelRouteHeadInputs({
|
|
67
71
|
interceptLayouts: opts?.interceptLayouts ?? null,
|
|
68
72
|
interceptPage: opts?.interceptPage ?? null,
|
|
@@ -72,12 +76,12 @@ async function buildPageElements(options) {
|
|
|
72
76
|
routeSegments: route.routeSegments ?? [],
|
|
73
77
|
slots: route.slots ?? null
|
|
74
78
|
}),
|
|
75
|
-
params,
|
|
79
|
+
params: effectiveParams,
|
|
76
80
|
routePath: route.pattern,
|
|
77
81
|
routeSegments: route.routeSegments ?? null,
|
|
78
82
|
searchParams
|
|
79
83
|
});
|
|
80
|
-
const pageProps = { params: makeThenableParams(
|
|
84
|
+
const pageProps = { params: makeThenableParams(effectiveParams) };
|
|
81
85
|
let pageSearchParamsThenable;
|
|
82
86
|
if (searchParams) {
|
|
83
87
|
pageSearchParamsThenable = !shouldSuppressLoadingBoundaries(renderMode) && Boolean(route.loading?.default) ? makeObservedAppPageSearchParamsThenable(pageSearchParams) : makeThenableParams(pageSearchParams);
|
|
@@ -86,8 +90,16 @@ async function buildPageElements(options) {
|
|
|
86
90
|
const mountedSlotIds = mountedSlotsHeader ? new Set(mountedSlotsHeader.split(" ")) : null;
|
|
87
91
|
const slotOverrides = buildSlotOverrides(route, params, routePath, opts);
|
|
88
92
|
const metadataPlacement = hasDynamicMetadata && shouldServeStreamingMetadata(pageRequest.request.headers.get("user-agent") ?? "", options.htmlLimitedBots) ? "body" : "head";
|
|
93
|
+
let siblingInterceptElement = isSiblingIntercept && EffectivePageComponent ? createElement(EffectivePageComponent, pageProps) : null;
|
|
94
|
+
if (isSiblingIntercept && siblingInterceptElement !== null && opts?.interceptLayouts?.length) {
|
|
95
|
+
const siblingThenableParams = makeThenableParams(effectiveParams);
|
|
96
|
+
for (let i = opts.interceptLayouts.length - 1; i >= 0; i--) {
|
|
97
|
+
const LayoutComponent = opts.interceptLayouts[i]?.default;
|
|
98
|
+
if (LayoutComponent) siblingInterceptElement = createElement(LayoutComponent, { params: siblingThenableParams }, siblingInterceptElement);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
89
101
|
return buildAppPageElements({
|
|
90
|
-
element:
|
|
102
|
+
element: isSiblingIntercept ? siblingInterceptElement : EffectivePageComponent ? createElement(EffectivePageComponent, pageProps) : null,
|
|
91
103
|
globalErrorModule: globalErrorModule ?? DEFAULT_GLOBAL_ERROR_MODULE,
|
|
92
104
|
isRscRequest,
|
|
93
105
|
layoutParamAccess: options.layoutParamAccess,
|
|
@@ -125,7 +137,7 @@ async function buildPageElements(options) {
|
|
|
125
137
|
*/
|
|
126
138
|
function buildSlotOverrides(route, routeParams, routePath, opts) {
|
|
127
139
|
const overrides = {};
|
|
128
|
-
if (opts && opts.interceptSlotKey && opts.interceptPage) overrides[opts.interceptSlotKey] = {
|
|
140
|
+
if (opts && opts.interceptSlotKey && opts.interceptPage && opts.interceptSlotKey !== "__vinext_page_intercept") overrides[opts.interceptSlotKey] = {
|
|
129
141
|
layoutModules: opts.interceptLayouts || null,
|
|
130
142
|
pageModule: opts.interceptPage,
|
|
131
143
|
params: opts.interceptParams || routeParams
|
|
@@ -28,6 +28,12 @@ type RenderAppPageLifecycleOptions = {
|
|
|
28
28
|
* Undefined or empty disables emission.
|
|
29
29
|
*/
|
|
30
30
|
clientTraceMetadata?: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Maximum total length (in characters) of the preload `Link` header emitted
|
|
33
|
+
* during SSR. `0` disables emission. From `reactMaxHeadersLength` in
|
|
34
|
+
* `next.config`.
|
|
35
|
+
*/
|
|
36
|
+
reactMaxHeadersLength?: number;
|
|
31
37
|
cleanPathname: string;
|
|
32
38
|
clearRequestContext: () => void;
|
|
33
39
|
consumeDynamicUsage: () => boolean;
|
|
@@ -10,7 +10,7 @@ import { DEFAULT_CACHE_VARIANT_BUDGET, buildCacheVariantWithRouteBudget, buildRe
|
|
|
10
10
|
import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
11
11
|
import { finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse } from "./app-page-cache.js";
|
|
12
12
|
import { createStaticLayoutClientReuseArtifactCompatibility, createStaticLayoutClientReusePayloadHash, createStaticLayoutClientReuseRouteId } from "./static-layout-client-reuse-proof.js";
|
|
13
|
-
import { createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery, shouldRerenderAppPageWithGlobalError } from "./app-page-stream.js";
|
|
13
|
+
import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery, shouldRerenderAppPageWithGlobalError } from "./app-page-stream.js";
|
|
14
14
|
import { getStaticLayoutObservationSkipRejection } from "./app-layout-param-observation.js";
|
|
15
15
|
import { hasDigest } from "./app-rsc-errors.js";
|
|
16
16
|
import { createClientReuseSkipTransportPlan, crossCheckClientReuseManifestEntryWithCache } from "./skip-cache-proof.js";
|
|
@@ -418,6 +418,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
418
418
|
navigationContext: options.getNavigationContext(),
|
|
419
419
|
basePath: options.basePath,
|
|
420
420
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
421
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
421
422
|
rootParams: options.rootParams,
|
|
422
423
|
formState: options.formState ?? null,
|
|
423
424
|
rscStream: rscForResponse,
|
|
@@ -435,6 +436,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
435
436
|
if (htmlRender.response) return htmlRender.response;
|
|
436
437
|
let htmlStream = htmlRender.htmlStream;
|
|
437
438
|
if (!htmlStream) throw new Error("[vinext] Expected an HTML stream when no fallback response was returned");
|
|
439
|
+
const linkHeader = buildAppPageLinkHeader(htmlRender.linkHeader, fontLinkHeader, options.reactMaxHeadersLength);
|
|
438
440
|
if (options.isPrerender === true) await htmlRender.metadataReady;
|
|
439
441
|
if (options.hasLoadingBoundary) {
|
|
440
442
|
const captured = rscErrorTracker.getCapturedSpecialError();
|
|
@@ -491,7 +493,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
491
493
|
if (htmlResponsePolicy.shouldWriteToCache || shouldSpeculativelyWriteCache) {
|
|
492
494
|
const isrResponse = buildAppPageHtmlResponse(safeHtmlStream, {
|
|
493
495
|
draftCookie,
|
|
494
|
-
|
|
496
|
+
linkHeader,
|
|
495
497
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
496
498
|
middlewareContext: options.middlewareContext,
|
|
497
499
|
policy: htmlResponsePolicy,
|
|
@@ -551,7 +553,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
551
553
|
}
|
|
552
554
|
return buildAppPageHtmlResponse(safeHtmlStream, {
|
|
553
555
|
draftCookie,
|
|
554
|
-
|
|
556
|
+
linkHeader,
|
|
555
557
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
556
558
|
middlewareContext: options.middlewareContext,
|
|
557
559
|
policy: htmlResponsePolicy,
|
|
@@ -6,6 +6,7 @@ type AppPageParams = Record<string, string | string[]>;
|
|
|
6
6
|
type GenerateStaticParams = (args: {
|
|
7
7
|
params: AppPageParams;
|
|
8
8
|
}) => unknown;
|
|
9
|
+
type Awaitable<T> = T | Promise<T>;
|
|
9
10
|
type GenerateStaticParamsModule = {
|
|
10
11
|
generateStaticParams?: GenerateStaticParams | null;
|
|
11
12
|
};
|
|
@@ -39,6 +40,7 @@ type BuildAppPageElementResult<TElement> = {
|
|
|
39
40
|
type AppPageInterceptMatch<TPage = unknown> = {
|
|
40
41
|
matchedParams: AppPageParams;
|
|
41
42
|
page: TPage;
|
|
43
|
+
__pageLoader?: (() => Promise<TPage>) | null;
|
|
42
44
|
slotId?: string | null;
|
|
43
45
|
slotKey: string;
|
|
44
46
|
sourceRouteIndex: number;
|
|
@@ -48,7 +50,7 @@ type ResolveAppPageInterceptMatchOptions<TRoute, TPage, TInterceptOpts> = {
|
|
|
48
50
|
currentRoute: TRoute;
|
|
49
51
|
findIntercept: (pathname: string) => AppPageInterceptMatch<TPage> | null;
|
|
50
52
|
getRouteParamNames: (route: TRoute) => readonly string[];
|
|
51
|
-
getSourceRoute: (sourceRouteIndex: number) => TRoute | undefined
|
|
53
|
+
getSourceRoute: (sourceRouteIndex: number) => Awaitable<TRoute | undefined>;
|
|
52
54
|
isRscRequest: boolean;
|
|
53
55
|
toInterceptOpts: (intercept: AppPageInterceptMatch<TPage>) => TInterceptOpts;
|
|
54
56
|
};
|
|
@@ -64,7 +66,7 @@ type ResolveAppPageInterceptionRerenderTargetOptions<TRoute, TPage, TInterceptOp
|
|
|
64
66
|
currentRoute: TRoute;
|
|
65
67
|
findIntercept: (pathname: string) => AppPageInterceptMatch<TPage> | null;
|
|
66
68
|
getRouteParamNames: (route: TRoute) => readonly string[];
|
|
67
|
-
getSourceRoute: (sourceRouteIndex: number) => TRoute | undefined
|
|
69
|
+
getSourceRoute: (sourceRouteIndex: number) => Awaitable<TRoute | undefined>;
|
|
68
70
|
isRscRequest: boolean;
|
|
69
71
|
toInterceptOpts: (intercept: AppPageInterceptMatch<TPage>) => TInterceptOpts;
|
|
70
72
|
};
|
|
@@ -82,7 +84,7 @@ type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
|
|
|
82
84
|
currentRoute: TRoute;
|
|
83
85
|
findIntercept: (pathname: string) => AppPageInterceptMatch<TPage> | null;
|
|
84
86
|
getRouteParamNames: (route: TRoute) => readonly string[];
|
|
85
|
-
getSourceRoute: (sourceRouteIndex: number) => TRoute | undefined
|
|
87
|
+
getSourceRoute: (sourceRouteIndex: number) => Awaitable<TRoute | undefined>;
|
|
86
88
|
isRscRequest: boolean;
|
|
87
89
|
layoutParamAccess?: AppLayoutParamAccessTracker;
|
|
88
90
|
renderInterceptResponse: (route: TRoute, element: TElement) => Promise<Response> | Response;
|
|
@@ -116,9 +118,9 @@ declare function validateAppPageDynamicParams(options: ValidateAppPageDynamicPar
|
|
|
116
118
|
* `setNavigationContext` + element build + Response wrap) and the server-action
|
|
117
119
|
* POST path (entries/app-rsc-entry.ts), which runs its own response pipeline.
|
|
118
120
|
*/
|
|
119
|
-
declare function resolveAppPageInterceptMatch<TRoute, TPage, TInterceptOpts>(options: ResolveAppPageInterceptMatchOptions<TRoute, TPage, TInterceptOpts>): ResolveAppPageInterceptMatchResult<TRoute, TInterceptOpts> | null
|
|
120
|
-
declare function resolveAppPageInterceptionRerenderTarget<TRoute, TPage, TInterceptOpts>(options: ResolveAppPageInterceptionRerenderTargetOptions<TRoute, TPage, TInterceptOpts>): ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts
|
|
121
|
-
declare function resolveAppPageActionRerenderTarget<TRoute, TPage, TInterceptOpts>(options: ResolveAppPageActionRerenderTargetOptions<TRoute, TPage, TInterceptOpts>): ResolveAppPageActionRerenderTargetResult<TRoute, TInterceptOpts
|
|
121
|
+
declare function resolveAppPageInterceptMatch<TRoute, TPage, TInterceptOpts>(options: ResolveAppPageInterceptMatchOptions<TRoute, TPage, TInterceptOpts>): Promise<ResolveAppPageInterceptMatchResult<TRoute, TInterceptOpts> | null>;
|
|
122
|
+
declare function resolveAppPageInterceptionRerenderTarget<TRoute, TPage, TInterceptOpts>(options: ResolveAppPageInterceptionRerenderTargetOptions<TRoute, TPage, TInterceptOpts>): Promise<ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts>>;
|
|
123
|
+
declare function resolveAppPageActionRerenderTarget<TRoute, TPage, TInterceptOpts>(options: ResolveAppPageActionRerenderTargetOptions<TRoute, TPage, TInterceptOpts>): Promise<ResolveAppPageActionRerenderTargetResult<TRoute, TInterceptOpts>>;
|
|
122
124
|
declare function resolveAppPageIntercept<TRoute, TPage, TInterceptOpts, TElement>(options: ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement>): Promise<ResolveAppPageInterceptResult<TInterceptOpts>>;
|
|
123
125
|
declare function buildAppPageElement<TElement>(options: BuildAppPageElementOptions<TElement>): Promise<BuildAppPageElementResult<TElement>>;
|
|
124
126
|
//#endregion
|