vinext 1.0.0-beta.2 → 1.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -9
- package/dist/build/client-build-config.js +7 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +12 -2
- package/dist/check.js +4 -0
- package/dist/cli-args.d.ts +2 -1
- package/dist/cli-args.js +10 -0
- package/dist/cli.js +14 -8
- package/dist/client/navigation-runtime.d.ts +6 -0
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/config/config-matchers.js +4 -1
- package/dist/config/dotenv.d.ts +3 -4
- package/dist/config/dotenv.js +30 -22
- package/dist/config/next-config.d.ts +16 -5
- package/dist/config/next-config.js +7 -0
- package/dist/entries/app-browser-entry.d.ts +4 -10
- package/dist/entries/app-browser-entry.js +20 -4
- package/dist/entries/app-rsc-entry.js +21 -3
- package/dist/entries/app-rsc-manifest.js +19 -0
- package/dist/entries/pages-client-entry.js +0 -1
- package/dist/entries/pages-server-entry.js +13 -3
- package/dist/index.js +122 -49
- package/dist/init-cloudflare.d.ts +3 -1
- package/dist/init-cloudflare.js +59 -5
- package/dist/plugins/client-reference-dedup.js +7 -5
- package/dist/plugins/extensionless-dynamic-import.js +23 -18
- package/dist/plugins/ignore-dynamic-requests.js +3 -1
- package/dist/plugins/import-meta-url.js +17 -6
- package/dist/plugins/require-context.js +20 -15
- package/dist/plugins/sass.js +3 -4
- package/dist/plugins/transform-cache.d.ts +19 -0
- package/dist/plugins/transform-cache.js +36 -0
- package/dist/routing/app-route-graph.d.ts +14 -6
- package/dist/routing/app-route-graph.js +106 -16
- package/dist/server/api-handler.d.ts +2 -0
- package/dist/server/api-handler.js +7 -6
- package/dist/server/app-bfcache-identity.js +28 -2
- package/dist/server/app-browser-entry.js +175 -75
- package/dist/server/app-browser-navigation-controller.d.ts +23 -21
- package/dist/server/app-browser-navigation-controller.js +30 -5
- package/dist/server/app-browser-prefetch-response.d.ts +9 -0
- package/dist/server/app-browser-prefetch-response.js +32 -0
- package/dist/server/app-browser-state.d.ts +8 -3
- package/dist/server/app-browser-state.js +9 -3
- package/dist/server/app-page-cache-finalizer.js +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +16 -2
- package/dist/server/app-page-dispatch.d.ts +9 -1
- package/dist/server/app-page-dispatch.js +37 -8
- package/dist/server/app-page-element-builder.d.ts +4 -1
- package/dist/server/app-page-element-builder.js +34 -7
- package/dist/server/app-page-head.d.ts +3 -3
- package/dist/server/app-page-head.js +58 -13
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +2 -2
- package/dist/server/app-page-http-access-fallback-metadata.js +9 -1
- package/dist/server/app-page-probe.d.ts +4 -0
- package/dist/server/app-page-probe.js +6 -2
- package/dist/server/app-page-render.d.ts +1 -1
- package/dist/server/app-page-render.js +13 -3
- package/dist/server/app-page-request.d.ts +3 -1
- package/dist/server/app-page-request.js +4 -13
- package/dist/server/app-page-response.d.ts +2 -0
- package/dist/server/app-page-response.js +7 -2
- package/dist/server/app-page-route-wiring.d.ts +10 -2
- package/dist/server/app-page-route-wiring.js +269 -59
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +3 -1
- package/dist/server/app-route-handler-cache.js +4 -0
- package/dist/server/app-route-handler-dispatch.js +9 -3
- package/dist/server/app-route-handler-response.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +6 -0
- package/dist/server/app-route-module-loader.js +3 -0
- package/dist/server/app-router-entry.js +6 -3
- package/dist/server/app-rsc-cache-busting.d.ts +7 -0
- package/dist/server/app-rsc-cache-busting.js +6 -0
- package/dist/server/app-rsc-errors.js +10 -0
- package/dist/server/app-rsc-handler.d.ts +2 -0
- package/dist/server/app-rsc-handler.js +30 -13
- package/dist/server/app-rsc-render-mode.d.ts +3 -2
- package/dist/server/app-rsc-render-mode.js +4 -1
- package/dist/server/app-rsc-request-normalization.js +65 -4
- package/dist/server/app-rsc-route-matching.d.ts +9 -0
- package/dist/server/app-rsc-route-matching.js +6 -0
- package/dist/server/app-server-action-execution.d.ts +1 -1
- package/dist/server/app-ssr-entry.js +4 -4
- package/dist/server/app-visited-response-cache.d.ts +6 -1
- package/dist/server/app-visited-response-cache.js +49 -1
- package/dist/server/cache-control.d.ts +2 -2
- package/dist/server/cache-control.js +2 -1
- package/dist/server/dev-server.d.ts +3 -1
- package/dist/server/dev-server.js +204 -348
- package/dist/server/edge-api-runtime.d.ts +10 -1
- package/dist/server/edge-api-runtime.js +29 -1
- package/dist/server/headers.d.ts +4 -2
- package/dist/server/headers.js +6 -3
- package/dist/server/isr-cache.d.ts +10 -33
- package/dist/server/isr-cache.js +33 -43
- package/dist/server/isr-decision.d.ts +2 -2
- package/dist/server/pages-api-route.d.ts +4 -0
- package/dist/server/pages-api-route.js +6 -3
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +6 -4
- package/dist/server/pages-dev-hydration.js +0 -1
- package/dist/server/pages-document-asset-props.d.ts +26 -0
- package/dist/server/pages-document-asset-props.js +69 -0
- package/dist/server/pages-get-initial-props.d.ts +1 -1
- package/dist/server/pages-get-initial-props.js +1 -4
- package/dist/server/pages-i18n.js +64 -16
- package/dist/server/pages-node-compat.d.ts +2 -0
- package/dist/server/pages-node-compat.js +10 -6
- package/dist/server/pages-page-data.d.ts +61 -9
- package/dist/server/pages-page-data.js +334 -74
- package/dist/server/pages-page-handler.d.ts +6 -1
- package/dist/server/pages-page-handler.js +119 -20
- package/dist/server/pages-page-response.d.ts +7 -3
- package/dist/server/pages-page-response.js +41 -33
- package/dist/server/pages-request-pipeline.d.ts +7 -0
- package/dist/server/pages-request-pipeline.js +5 -1
- package/dist/server/pages-revalidate.d.ts +1 -1
- package/dist/server/pages-revalidate.js +54 -8
- package/dist/server/pages-router-entry.d.ts +1 -0
- package/dist/server/pages-router-entry.js +10 -4
- package/dist/server/prerender-manifest.d.ts +1 -0
- package/dist/server/prod-server.d.ts +2 -1
- package/dist/server/prod-server.js +38 -13
- package/dist/server/revalidation-host.d.ts +11 -0
- package/dist/server/revalidation-host.js +19 -0
- package/dist/server/seed-cache.js +1 -1
- package/dist/server/worker-revalidation-context.d.ts +13 -0
- package/dist/server/worker-revalidation-context.js +30 -0
- package/dist/shims/app-router-scroll-state.d.ts +2 -1
- package/dist/shims/app-router-scroll-state.js +7 -2
- package/dist/shims/cache-handler.d.ts +1 -1
- package/dist/shims/cache-handler.js +10 -7
- package/dist/shims/cache-runtime.d.ts +6 -0
- package/dist/shims/cache-runtime.js +4 -1
- package/dist/shims/cache.js +1 -1
- package/dist/shims/document.js +15 -2
- package/dist/shims/error.js +1 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-google-base.js +17 -8
- package/dist/shims/font-local.js +41 -10
- package/dist/shims/hash-scroll.d.ts +1 -1
- package/dist/shims/hash-scroll.js +2 -1
- package/dist/shims/headers.d.ts +10 -13
- package/dist/shims/headers.js +85 -36
- package/dist/shims/internal/cookie-serialize.d.ts +10 -9
- package/dist/shims/internal/cookie-serialize.js +9 -8
- package/dist/shims/internal/interpolate-as.d.ts +15 -1
- package/dist/shims/internal/interpolate-as.js +27 -2
- package/dist/shims/link.d.ts +2 -0
- package/dist/shims/link.js +77 -24
- package/dist/shims/metadata.d.ts +18 -34
- package/dist/shims/metadata.js +98 -56
- package/dist/shims/navigation.d.ts +18 -2
- package/dist/shims/navigation.js +70 -21
- package/dist/shims/request-context.d.ts +6 -2
- package/dist/shims/router.js +18 -7
- package/dist/shims/script.js +1 -1
- package/dist/shims/server.d.ts +7 -6
- package/dist/shims/server.js +156 -57
- package/dist/shims/slot.d.ts +2 -1
- package/dist/shims/slot.js +6 -2
- package/dist/shims/streamed-icons.d.ts +9 -0
- package/dist/shims/streamed-icons.js +33 -0
- package/dist/shims/unified-request-context.d.ts +21 -2
- package/dist/shims/unified-request-context.js +82 -1
- package/dist/utils/cache-control-metadata.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +5 -1
- package/dist/utils/html-limited-bots.js +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/package.json +1 -1
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { createAppRenderDependency, registerAppElementRenderDependencies, renderAfterAppDependencies, renderWithAppDependencyBarrier } from "./app-render-dependency.js";
|
|
2
|
-
import { APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
3
|
-
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "./app-rsc-render-mode.js";
|
|
2
|
+
import { APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
3
|
+
import { APP_RSC_RENDER_MODE_PREFETCH_EMPTY, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "./app-rsc-render-mode.js";
|
|
4
4
|
import { APP_PREFETCH_LOADING_SHELL_MARKER_KEY } from "./app-elements.js";
|
|
5
|
+
import { createInlineScriptTag, escapeHtmlAttr } from "./html.js";
|
|
5
6
|
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
6
7
|
import { ErrorBoundary, ForbiddenBoundary, GlobalErrorBoundary, NotFoundBoundary, RedirectBoundary, UnauthorizedBoundary } from "../shims/error-boundary.js";
|
|
7
8
|
import { AppRouterScrollTarget } from "../shims/app-router-scroll.js";
|
|
9
|
+
import DefaultNotFound from "../shims/default-not-found.js";
|
|
8
10
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
9
11
|
import { MetadataHead, ViewportHead, renderMetadataToHtml } from "../shims/metadata.js";
|
|
10
12
|
import { Children as Children$1, ParallelSlot, Slot } from "../shims/slot.js";
|
|
13
|
+
import { StreamedIconsInsertion } from "../shims/streamed-icons.js";
|
|
11
14
|
import { resolveAppPageBranchParams, resolveAppPageSegmentParamScopeKeys, resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
12
15
|
import { probeReactServerSubtree } from "./app-page-probe.js";
|
|
13
16
|
import { APP_PAGE_SEGMENT_KEY, resolveAppPageChildSegments, resolveAppPageRouteStateKey, resolveAppPageSegmentStateKey } from "./app-page-segment-state.js";
|
|
@@ -16,6 +19,7 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
|
16
19
|
//#region src/server/app-page-route-wiring.tsx
|
|
17
20
|
const APP_PAGE_LAYOUT_PROBE_CHILD = /* @__PURE__ */ jsx(Fragment, {});
|
|
18
21
|
const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
|
|
22
|
+
const DEFAULT_NOT_FOUND_COMPONENT = DefaultNotFound;
|
|
19
23
|
function resolveSlotLayoutParams(routeSegments, treePosition, params) {
|
|
20
24
|
return resolveAppPageBranchParams(routeSegments, treePosition, params);
|
|
21
25
|
}
|
|
@@ -108,6 +112,66 @@ function createAppPageErrorEntries(route) {
|
|
|
108
112
|
}];
|
|
109
113
|
});
|
|
110
114
|
}
|
|
115
|
+
function createAppPageLoadingEntries(route) {
|
|
116
|
+
return (route.loadings ?? []).flatMap((loadingModule, index) => {
|
|
117
|
+
if (!loadingModule) return [];
|
|
118
|
+
const treePosition = route.loadingTreePositions?.[index];
|
|
119
|
+
if (treePosition === void 0) return [];
|
|
120
|
+
return [{
|
|
121
|
+
loadingModule,
|
|
122
|
+
treePosition
|
|
123
|
+
}];
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function getPrefetchLoadingEntry(route) {
|
|
127
|
+
let rootEntry = null;
|
|
128
|
+
let firstNestedEntry = null;
|
|
129
|
+
for (const [index, loadingModule] of (route.loadings ?? []).entries()) {
|
|
130
|
+
if (!getDefaultExport(loadingModule)) continue;
|
|
131
|
+
const treePosition = route.loadingTreePositions?.[index];
|
|
132
|
+
if (treePosition === void 0) continue;
|
|
133
|
+
if (treePosition === 0) rootEntry ??= {
|
|
134
|
+
loadingModule,
|
|
135
|
+
treePosition
|
|
136
|
+
};
|
|
137
|
+
else if (firstNestedEntry === null || treePosition < firstNestedEntry.treePosition) firstNestedEntry = {
|
|
138
|
+
loadingModule,
|
|
139
|
+
treePosition
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (firstNestedEntry) return firstNestedEntry;
|
|
143
|
+
if (rootEntry) return rootEntry;
|
|
144
|
+
return getDefaultExport(route.loading) ? {
|
|
145
|
+
loadingModule: route.loading,
|
|
146
|
+
treePosition: route.routeSegments?.length ?? 0
|
|
147
|
+
} : null;
|
|
148
|
+
}
|
|
149
|
+
function createAppPageSlotLoadingEntries(slot, override) {
|
|
150
|
+
const entries = [];
|
|
151
|
+
const slotLoadingModules = (slot.loadings?.length ?? 0) > 0 ? slot.loadings : slot.loading ? [slot.loading] : [];
|
|
152
|
+
const slotLoadingTreePositions = (slot.loadingTreePositions?.length ?? 0) > 0 ? slot.loadingTreePositions : [0];
|
|
153
|
+
for (const [index, loadingModule] of slotLoadingModules.entries()) {
|
|
154
|
+
const treePosition = slotLoadingTreePositions[index];
|
|
155
|
+
if (!getDefaultExport(loadingModule) || treePosition === void 0) continue;
|
|
156
|
+
if (override && treePosition !== 0) continue;
|
|
157
|
+
entries.push({
|
|
158
|
+
loadingModule,
|
|
159
|
+
treePosition
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
for (const [index, loadingModule] of (override?.loadingModules ?? []).entries()) {
|
|
163
|
+
const treePosition = override?.loadingTreePositions?.[index];
|
|
164
|
+
if (!getDefaultExport(loadingModule) || treePosition === void 0) continue;
|
|
165
|
+
entries.push({
|
|
166
|
+
loadingModule,
|
|
167
|
+
treePosition
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return entries;
|
|
171
|
+
}
|
|
172
|
+
function getFirstLoadingEntry(entries) {
|
|
173
|
+
return entries.reduce((first, entry) => first === null || entry.treePosition < first.treePosition ? entry : first, null);
|
|
174
|
+
}
|
|
111
175
|
function createAppPageParallelSlotEntries(layoutIndex, layoutEntries, route, getEffectiveSlotParams, resolveSlotOverride) {
|
|
112
176
|
const parallelSlots = {};
|
|
113
177
|
for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {
|
|
@@ -140,6 +204,7 @@ function createAppPageSlotBindings(route, layoutEntries, resolveSlotOverride, op
|
|
|
140
204
|
if (route.childrenSlot) {
|
|
141
205
|
const ownerLayoutId = layoutEntries.find((layoutEntry) => layoutEntry.treePath === route.childrenSlot?.ownerTreePath)?.id;
|
|
142
206
|
bindings.push({
|
|
207
|
+
...route.childrenSlot.state === "active" ? { activeRouteId: options.routeId } : {},
|
|
143
208
|
ownerLayoutId: ownerLayoutId ?? null,
|
|
144
209
|
slotId: route.childrenSlot.id,
|
|
145
210
|
state: route.childrenSlot.state
|
|
@@ -172,16 +237,40 @@ function createAppPageRouteHead(metadata, viewport, pathname, metadataPlacement,
|
|
|
172
237
|
/* @__PURE__ */ jsx(ViewportHead, { viewport })
|
|
173
238
|
] });
|
|
174
239
|
}
|
|
175
|
-
function
|
|
240
|
+
function hasStreamedIcons(metadata) {
|
|
241
|
+
const icons = metadata.icons;
|
|
242
|
+
if (!icons) return false;
|
|
243
|
+
if (typeof icons === "string" || icons instanceof URL || Array.isArray(icons)) return !Array.isArray(icons) || icons.length > 0;
|
|
244
|
+
if ("url" in icons) return true;
|
|
245
|
+
return Boolean(icons.shortcut || icons.icon || icons.apple || icons.other);
|
|
246
|
+
}
|
|
247
|
+
function createStreamedIconKey(pathname, metadataHtml) {
|
|
248
|
+
let hash = 2166136261;
|
|
249
|
+
for (let index = 0; index < metadataHtml.length; index++) {
|
|
250
|
+
hash ^= metadataHtml.charCodeAt(index);
|
|
251
|
+
hash = Math.imul(hash, 16777619);
|
|
252
|
+
}
|
|
253
|
+
return `${pathname}:${(hash >>> 0).toString(36)}`;
|
|
254
|
+
}
|
|
255
|
+
const STREAMED_ICON_KEY_PLACEHOLDER = "vinext-pending-streamed-icon-key";
|
|
256
|
+
const REINSERT_STREAMED_ICONS_SCRIPT = `document.querySelectorAll('body link[rel="icon"], body link[rel="apple-touch-icon"]').forEach(el => document.head.appendChild(el));const a='data-vinext-streamed-icon',o=el=>{const m=el.getAttribute(a),i=m.lastIndexOf(':');return Number(m.slice(i+1))};[...document.querySelectorAll('link['+a+']')].sort((l,r)=>o(l)-o(r)).forEach(el=>document.head.appendChild(el))`;
|
|
257
|
+
function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement, trailingSlash, scriptNonce) {
|
|
176
258
|
if (!metadata || metadataPlacement !== "body") return null;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
259
|
+
const streamedIconKey = hasStreamedIcons(metadata) ? STREAMED_ICON_KEY_PLACEHOLDER : void 0;
|
|
260
|
+
const renderedMetadataHtml = renderMetadataToHtml(metadata, pathname, {
|
|
261
|
+
trailingSlash,
|
|
262
|
+
streamedIconKey
|
|
180
263
|
});
|
|
264
|
+
const metadataKey = streamedIconKey ? createStreamedIconKey(pathname, renderedMetadataHtml) : "";
|
|
265
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
266
|
+
hidden: true,
|
|
267
|
+
suppressHydrationWarning: true,
|
|
268
|
+
dangerouslySetInnerHTML: { __html: (streamedIconKey ? renderedMetadataHtml.replaceAll(`<link data-vinext-streamed-icon="${STREAMED_ICON_KEY_PLACEHOLDER}:`, `<link data-vinext-streamed-icon="${escapeHtmlAttr(metadataKey)}:`) : renderedMetadataHtml) + createInlineScriptTag(REINSERT_STREAMED_ICONS_SCRIPT, scriptNonce) }
|
|
269
|
+
}), /* @__PURE__ */ jsx(StreamedIconsInsertion, { metadataKey })] });
|
|
181
270
|
}
|
|
182
271
|
async function AppPageStreamingMetadata(props) {
|
|
183
272
|
try {
|
|
184
|
-
return createAppPageRouteBodyMetadata(await props.metadata, props.pathname, "body", props.trailingSlash);
|
|
273
|
+
return createAppPageRouteBodyMetadata(await props.metadata, props.pathname, "body", props.trailingSlash, props.scriptNonce);
|
|
185
274
|
} catch {
|
|
186
275
|
return null;
|
|
187
276
|
}
|
|
@@ -223,13 +312,27 @@ function buildAppPageElements(options) {
|
|
|
223
312
|
const streamingMetadataOutletId = options.streamingMetadataOutlet ? `__vinext_streaming_metadata_outlet:${routeId}` : null;
|
|
224
313
|
const layoutEntries = createAppPageLayoutEntries(options.route);
|
|
225
314
|
const templateEntries = createAppPageTemplateEntries(options.route);
|
|
315
|
+
const loadingEntries = createAppPageLoadingEntries(options.route);
|
|
226
316
|
const errorEntries = createAppPageErrorEntries(options.route);
|
|
317
|
+
const findNearestAncestorLoadingEntry = (treePosition) => {
|
|
318
|
+
for (let index = loadingEntries.length - 1; index >= 0; index--) if (loadingEntries[index].treePosition < treePosition) return loadingEntries[index];
|
|
319
|
+
};
|
|
320
|
+
const findNearestLoadingEntryAtOrAbove = (treePosition) => {
|
|
321
|
+
let nearest;
|
|
322
|
+
for (const entry of loadingEntries) if (entry.treePosition <= treePosition && (!nearest || entry.treePosition > nearest.treePosition)) nearest = entry;
|
|
323
|
+
return nearest;
|
|
324
|
+
};
|
|
325
|
+
const isPrefetchEmpty = renderMode === APP_RSC_RENDER_MODE_PREFETCH_EMPTY;
|
|
326
|
+
const isPrefetchLoadingShell = renderMode === APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL;
|
|
327
|
+
const prefetchLoadingEntry = isPrefetchLoadingShell ? getPrefetchLoadingEntry(options.route) : null;
|
|
227
328
|
const metadataPlacement = options.metadataPlacement ?? "head";
|
|
228
329
|
const layoutEntriesByTreePosition = /* @__PURE__ */ new Map();
|
|
229
330
|
const templateEntriesByTreePosition = /* @__PURE__ */ new Map();
|
|
331
|
+
const loadingEntriesByTreePosition = /* @__PURE__ */ new Map();
|
|
230
332
|
const errorEntriesByTreePosition = /* @__PURE__ */ new Map();
|
|
231
333
|
for (const layoutEntry of layoutEntries) layoutEntriesByTreePosition.set(layoutEntry.treePosition, layoutEntry);
|
|
232
334
|
for (const templateEntry of templateEntries) templateEntriesByTreePosition.set(templateEntry.treePosition, templateEntry);
|
|
335
|
+
for (const loadingEntry of loadingEntries) loadingEntriesByTreePosition.set(loadingEntry.treePosition, loadingEntry);
|
|
233
336
|
for (const errorEntry of errorEntries) errorEntriesByTreePosition.set(errorEntry.treePosition, errorEntry);
|
|
234
337
|
const layoutIndicesByTreePosition = /* @__PURE__ */ new Map();
|
|
235
338
|
for (let index = 0; index < layoutEntries.length; index++) layoutIndicesByTreePosition.set(layoutEntries[index].treePosition, index);
|
|
@@ -249,6 +352,7 @@ function buildAppPageElements(options) {
|
|
|
249
352
|
const orderedTreePositions = Array.from(/* @__PURE__ */ new Set([
|
|
250
353
|
...layoutEntries.map((entry) => entry.treePosition),
|
|
251
354
|
...templateEntries.map((entry) => entry.treePosition),
|
|
355
|
+
...loadingEntries.map((entry) => entry.treePosition),
|
|
252
356
|
...errorEntries.map((entry) => entry.treePosition)
|
|
253
357
|
])).sort((left, right) => left - right);
|
|
254
358
|
const resolveSlotOverride = (slotKey, slotName) => {
|
|
@@ -256,6 +360,11 @@ function buildAppPageElements(options) {
|
|
|
256
360
|
if (overrideByKey) return overrideByKey;
|
|
257
361
|
if (slotKey === slotName || (slotNameCounts.get(slotName) ?? 0) === 1) return options.slotOverrides?.[slotName];
|
|
258
362
|
};
|
|
363
|
+
const prefetchSlotLoadingEntries = isPrefetchLoadingShell ? Object.entries(options.route.slots ?? {}).flatMap(([slotKey, slot]) => {
|
|
364
|
+
return getFirstLoadingEntry(createAppPageSlotLoadingEntries(slot, resolveSlotOverride(slotKey, slot.name) ?? null)) ? [{ ownerTreePosition: slot.ownerTreePosition ?? 0 }] : [];
|
|
365
|
+
}) : [];
|
|
366
|
+
const prefetchCutoffTreePosition = isPrefetchLoadingShell ? prefetchLoadingEntry?.treePosition ?? prefetchSlotLoadingEntries.reduce((deepest, entry) => Math.max(deepest, entry.ownerTreePosition), 0) : null;
|
|
367
|
+
const includesPrefetchTreePosition = (treePosition) => prefetchCutoffTreePosition === null || treePosition <= prefetchCutoffTreePosition;
|
|
259
368
|
const elements = { ...AppElementsWire.createMetadataEntries({
|
|
260
369
|
interception: renderIdentity?.interception ?? options.interception ?? null,
|
|
261
370
|
interceptionContext,
|
|
@@ -266,18 +375,28 @@ function buildAppPageElements(options) {
|
|
|
266
375
|
slotBindings: createAppPageSlotBindings(options.route, layoutEntries, resolveSlotOverride, {
|
|
267
376
|
interception: renderIdentity?.interception ?? options.interception ?? null,
|
|
268
377
|
interceptionContext,
|
|
378
|
+
routeId,
|
|
269
379
|
routePath: options.routePath
|
|
270
380
|
})
|
|
271
381
|
}) };
|
|
382
|
+
if (isPrefetchEmpty) {
|
|
383
|
+
elements[APP_LAYOUT_IDS_KEY] = [];
|
|
384
|
+
elements[APP_ROOT_LAYOUT_KEY] = null;
|
|
385
|
+
elements[pageElementId] = null;
|
|
386
|
+
elements[routeId] = null;
|
|
387
|
+
return elements;
|
|
388
|
+
}
|
|
272
389
|
if (options.route.staticSiblings && options.route.staticSiblings.length > 0) elements[APP_STATIC_SIBLINGS_KEY] = options.route.staticSiblings;
|
|
273
390
|
if (options.streamingMetadata && streamingMetadataBodyId) elements[streamingMetadataBodyId] = /* @__PURE__ */ jsx(AppPageStreamingMetadata, {
|
|
274
391
|
metadata: options.streamingMetadataTags ?? options.streamingMetadata,
|
|
275
392
|
pathname: options.resolvedMetadataPathname ?? options.routePath,
|
|
393
|
+
scriptNonce: options.scriptNonce,
|
|
276
394
|
trailingSlash: options.trailingSlash
|
|
277
395
|
});
|
|
278
396
|
if (options.streamingMetadataOutlet && streamingMetadataOutletId) elements[streamingMetadataOutletId] = /* @__PURE__ */ jsx(AppPageMetadataOutlet, { metadata: options.streamingMetadataOutlet });
|
|
279
397
|
const getEffectiveSlotParams = (slotKey, slotName) => resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;
|
|
280
398
|
for (const treePosition of orderedTreePositions) {
|
|
399
|
+
if (isPrefetchLoadingShell && !includesPrefetchTreePosition(treePosition)) continue;
|
|
281
400
|
const layoutIndex = layoutIndicesByTreePosition.get(treePosition);
|
|
282
401
|
if (layoutIndex !== void 0) {
|
|
283
402
|
const layoutEntry = layoutEntries[layoutIndex];
|
|
@@ -298,19 +417,31 @@ function buildAppPageElements(options) {
|
|
|
298
417
|
pageDependencies.push(templateDependency);
|
|
299
418
|
}
|
|
300
419
|
const routeLoadingComponent = getDefaultExport(options.route.loading);
|
|
301
|
-
const
|
|
302
|
-
if (isPrefetchLoadingShell &&
|
|
420
|
+
const prefetchLoadingComponent = getDefaultExport(prefetchLoadingEntry?.loadingModule);
|
|
421
|
+
if (isPrefetchLoadingShell && (prefetchLoadingComponent !== null || prefetchSlotLoadingEntries.length > 0)) elements[APP_PREFETCH_LOADING_SHELL_MARKER_KEY] = "LoadingBoundary";
|
|
303
422
|
elements[pageElementId] = isPrefetchLoadingShell ? null : renderAfterAppDependencies(options.element, pageDependencies);
|
|
304
423
|
for (const templateEntry of templateEntries) {
|
|
424
|
+
if (isPrefetchLoadingShell && !includesPrefetchTreePosition(templateEntry.treePosition)) continue;
|
|
305
425
|
const templateComponent = getDefaultExport(templateEntry.templateModule);
|
|
306
426
|
if (!templateComponent) continue;
|
|
307
427
|
const TemplateComponent = templateComponent;
|
|
308
428
|
const templateDependency = templateDependenciesById.get(templateEntry.id);
|
|
309
|
-
|
|
429
|
+
let templateElement = templateDependency ? renderWithAppDependencyBarrier(/* @__PURE__ */ jsx(TemplateComponent, { children: /* @__PURE__ */ jsx(Children$1, {}) }), templateDependency) : /* @__PURE__ */ jsx(TemplateComponent, { children: /* @__PURE__ */ jsx(Children$1, {}) });
|
|
430
|
+
const ancestorLoadingEntry = findNearestAncestorLoadingEntry(templateEntry.treePosition);
|
|
431
|
+
const ancestorLoadingComponent = getDefaultExport(ancestorLoadingEntry?.loadingModule);
|
|
432
|
+
if (ancestorLoadingComponent && ancestorLoadingEntry) {
|
|
433
|
+
const AncestorLoadingComponent = ancestorLoadingComponent;
|
|
434
|
+
const loadingResetKey = resolveAppPageSegmentStateKey(routeSegments, ancestorLoadingEntry.treePosition, options.matchedParams);
|
|
435
|
+
templateElement = /* @__PURE__ */ jsx(Suspense, {
|
|
436
|
+
fallback: /* @__PURE__ */ jsx(AncestorLoadingComponent, {}),
|
|
437
|
+
children: templateElement
|
|
438
|
+
}, loadingResetKey || routeResetKey);
|
|
439
|
+
}
|
|
310
440
|
elements[templateEntry.id] = renderAfterAppDependencies(templateElement, templateDependenciesBeforeById.get(templateEntry.id) ?? []);
|
|
311
441
|
}
|
|
312
442
|
for (let index = 0; index < layoutEntries.length; index++) {
|
|
313
443
|
const layoutEntry = layoutEntries[index];
|
|
444
|
+
if (isPrefetchLoadingShell && !includesPrefetchTreePosition(layoutEntry.treePosition)) continue;
|
|
314
445
|
const layoutComponent = getDefaultExport(layoutEntry.layoutModule);
|
|
315
446
|
if (!layoutComponent) continue;
|
|
316
447
|
const layoutParams = resolveAppPageSegmentParams(options.route.routeSegments, layoutEntry.treePosition, options.matchedParams);
|
|
@@ -329,79 +460,147 @@ function buildAppPageElements(options) {
|
|
|
329
460
|
}
|
|
330
461
|
const LayoutComponent = layoutComponent;
|
|
331
462
|
const layoutDependency = layoutDependenciesByIndex.get(index);
|
|
332
|
-
|
|
463
|
+
let layoutElement = layoutDependency ? renderWithAppDependencyBarrier(/* @__PURE__ */ jsx(LayoutComponent, {
|
|
333
464
|
...layoutProps,
|
|
334
465
|
children: /* @__PURE__ */ jsx(Children$1, {})
|
|
335
466
|
}), layoutDependency) : /* @__PURE__ */ jsx(LayoutComponent, {
|
|
336
467
|
...layoutProps,
|
|
337
468
|
children: /* @__PURE__ */ jsx(Children$1, {})
|
|
338
469
|
});
|
|
470
|
+
const ancestorLoadingEntry = findNearestAncestorLoadingEntry(layoutEntry.treePosition);
|
|
471
|
+
const ancestorLoadingComponent = getDefaultExport(ancestorLoadingEntry?.loadingModule);
|
|
472
|
+
if (ancestorLoadingComponent && ancestorLoadingEntry) {
|
|
473
|
+
const AncestorLoadingComponent = ancestorLoadingComponent;
|
|
474
|
+
const loadingResetKey = resolveAppPageSegmentStateKey(routeSegments, ancestorLoadingEntry.treePosition, options.matchedParams);
|
|
475
|
+
layoutElement = /* @__PURE__ */ jsx(Suspense, {
|
|
476
|
+
fallback: /* @__PURE__ */ jsx(AncestorLoadingComponent, {}),
|
|
477
|
+
children: layoutElement
|
|
478
|
+
}, loadingResetKey || routeResetKey);
|
|
479
|
+
}
|
|
339
480
|
elements[layoutEntry.id] = renderAfterAppDependencies(layoutElement, layoutDependenciesBefore[index] ?? []);
|
|
340
481
|
}
|
|
341
482
|
for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {
|
|
342
483
|
const slotName = slot.name;
|
|
343
484
|
const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;
|
|
485
|
+
const targetTreePosition = layoutEntries[targetIndex]?.treePosition ?? 0;
|
|
486
|
+
const ownerTreePosition = slot.ownerTreePosition ?? targetTreePosition;
|
|
487
|
+
const isOwnedAtRoutePrefetchCutoff = isPrefetchLoadingShell && prefetchLoadingEntry !== null && ownerTreePosition === prefetchLoadingEntry.treePosition;
|
|
488
|
+
if (isPrefetchLoadingShell && (prefetchLoadingEntry ? ownerTreePosition > prefetchLoadingEntry.treePosition : !includesPrefetchTreePosition(targetTreePosition))) continue;
|
|
344
489
|
const slotId = resolveAppPageSlotId(slot, layoutEntries[targetIndex]?.treePath ?? "/");
|
|
345
490
|
const slotOverride = resolveSlotOverride(slotKey, slotName);
|
|
346
491
|
const slotParams = getEffectiveSlotParams(slotKey, slotName);
|
|
347
492
|
const slotRouteSegments = slotOverride?.routeSegments ?? slot.routeSegments ?? [];
|
|
348
493
|
const slotOwnerParams = resolveAppPageSegmentParams(options.route.routeSegments, layoutEntries[targetIndex]?.treePosition ?? 0, options.matchedParams);
|
|
349
494
|
const slotResetKey = resolveAppPageRouteStateKey(slotRouteSegments, slotParams);
|
|
495
|
+
const hasSlotTreeOverride = slotOverride?.pageModule != null || slotOverride?.layoutModules !== void 0;
|
|
496
|
+
const slotLoadingEntries = createAppPageSlotLoadingEntries(slot, hasSlotTreeOverride ? slotOverride ?? null : null);
|
|
497
|
+
const prefetchSlotLoadingEntry = isOwnedAtRoutePrefetchCutoff ? prefetchLoadingEntry : isPrefetchLoadingShell ? getFirstLoadingEntry(slotLoadingEntries) : null;
|
|
498
|
+
if (isPrefetchLoadingShell && prefetchSlotLoadingEntry === null) continue;
|
|
350
499
|
const overrideOrPageComponent = getDefaultExport(slotOverride?.pageModule) ?? getDefaultExport(slot.page);
|
|
351
500
|
const defaultComponent = getDefaultExport(slot.default);
|
|
352
501
|
if (!overrideOrPageComponent && defaultComponent && options.isRscRequest && options.mountedSlotIds?.has(slotId)) continue;
|
|
353
502
|
const slotComponent = overrideOrPageComponent ?? defaultComponent;
|
|
354
|
-
if (!slotComponent) {
|
|
503
|
+
if (!slotComponent && !isOwnedAtRoutePrefetchCutoff) {
|
|
355
504
|
elements[slotId] = AppElementsWire.unmatchedSlotValue;
|
|
356
505
|
continue;
|
|
357
506
|
}
|
|
358
|
-
|
|
359
|
-
if (
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
507
|
+
let slotElement;
|
|
508
|
+
if (prefetchSlotLoadingEntry) slotElement = /* @__PURE__ */ jsx(getDefaultExport(prefetchSlotLoadingEntry.loadingModule), {});
|
|
509
|
+
else {
|
|
510
|
+
const slotProps = { params: options.makeThenableParams(slotParams) };
|
|
511
|
+
if (options.searchParams !== void 0) slotProps.searchParams = options.searchParams;
|
|
512
|
+
if (slotOverride?.props) Object.assign(slotProps, slotOverride.props);
|
|
513
|
+
slotElement = options.createPageElement ? options.createPageElement(slotComponent, slotProps) : (() => {
|
|
514
|
+
return /* @__PURE__ */ jsx(slotComponent, { ...slotProps });
|
|
515
|
+
})();
|
|
516
|
+
if (overrideOrPageComponent) slotElement = /* @__PURE__ */ jsx(Fragment, { children: slotElement }, slotResetKey);
|
|
517
|
+
}
|
|
518
|
+
const branchSegments = slotOverride?.branchSegments ?? slotRouteSegments;
|
|
519
|
+
const branchLayouts = /* @__PURE__ */ new Map();
|
|
520
|
+
const addBranchLayout = (treePosition, entry) => {
|
|
521
|
+
const entries = branchLayouts.get(treePosition) ?? [];
|
|
522
|
+
entries.push(entry);
|
|
523
|
+
branchLayouts.set(treePosition, entries);
|
|
524
|
+
};
|
|
525
|
+
if (hasSlotTreeOverride) for (const [layoutIndex, layoutModule] of (slotOverride?.layoutModules ?? []).entries()) {
|
|
526
|
+
const component = getDefaultExport(layoutModule);
|
|
527
|
+
if (!component) continue;
|
|
528
|
+
const treePosition = slotOverride?.layoutSegments?.[layoutIndex]?.length ?? branchSegments.length;
|
|
529
|
+
addBranchLayout(treePosition, {
|
|
530
|
+
component,
|
|
531
|
+
params: resolveSlotLayoutParams(branchSegments, treePosition, slotParams)
|
|
374
532
|
});
|
|
375
533
|
}
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
if (!
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
params:
|
|
534
|
+
else for (const [layoutIndex, layoutModule] of (slot.configLayouts ?? []).entries()) {
|
|
535
|
+
const component = getDefaultExport(layoutModule);
|
|
536
|
+
if (!component) continue;
|
|
537
|
+
const treePosition = slot.configLayoutTreePositions?.[layoutIndex] ?? 0;
|
|
538
|
+
addBranchLayout(treePosition, {
|
|
539
|
+
component,
|
|
540
|
+
params: {
|
|
383
541
|
...slotOwnerParams,
|
|
384
|
-
...
|
|
385
|
-
}
|
|
386
|
-
children: slotElement
|
|
542
|
+
...resolveSlotLayoutParams(slotRouteSegments, treePosition, slotParams)
|
|
543
|
+
}
|
|
387
544
|
});
|
|
388
545
|
}
|
|
389
546
|
const slotLayoutComponent = overrideOrPageComponent ? getDefaultExport(slot.layout) : null;
|
|
390
|
-
if (slotLayoutComponent)
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
547
|
+
if (slotLayoutComponent) {
|
|
548
|
+
const rootEntries = branchLayouts.get(0) ?? [];
|
|
549
|
+
branchLayouts.set(0, [{
|
|
550
|
+
component: slotLayoutComponent,
|
|
551
|
+
params: slotOwnerParams
|
|
552
|
+
}, ...rootEntries]);
|
|
553
|
+
}
|
|
554
|
+
const branchLoadings = /* @__PURE__ */ new Map();
|
|
555
|
+
for (const entry of slotLoadingEntries) {
|
|
556
|
+
const component = getDefaultExport(entry.loadingModule);
|
|
557
|
+
if (!component) continue;
|
|
558
|
+
const components = branchLoadings.get(entry.treePosition) ?? [];
|
|
559
|
+
components.push(component);
|
|
560
|
+
branchLoadings.set(entry.treePosition, components);
|
|
561
|
+
}
|
|
399
562
|
const slotErrorComponent = getErrorBoundaryExport(slot.error);
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
563
|
+
const branchTreePositions = Array.from(/* @__PURE__ */ new Set([
|
|
564
|
+
...branchLayouts.keys(),
|
|
565
|
+
...branchLoadings.keys(),
|
|
566
|
+
...slotErrorComponent ? [0] : []
|
|
567
|
+
])).filter((treePosition) => !prefetchSlotLoadingEntry || !isOwnedAtRoutePrefetchCutoff && treePosition <= prefetchSlotLoadingEntry.treePosition).sort((left, right) => left - right);
|
|
568
|
+
for (let index = branchTreePositions.length - 1; index >= 0; index--) {
|
|
569
|
+
const treePosition = branchTreePositions[index];
|
|
570
|
+
const loadingComponents = prefetchSlotLoadingEntry ? [] : branchLoadings.get(treePosition) ?? [];
|
|
571
|
+
for (let loadingIndex = loadingComponents.length - 1; loadingIndex >= 0; loadingIndex--) {
|
|
572
|
+
const LoadingComponent = loadingComponents[loadingIndex];
|
|
573
|
+
const loadingResetKey = resolveAppPageSegmentStateKey(branchSegments, treePosition, slotParams);
|
|
574
|
+
slotElement = /* @__PURE__ */ jsx(Suspense, {
|
|
575
|
+
fallback: /* @__PURE__ */ jsx(LoadingComponent, {}),
|
|
576
|
+
children: slotElement
|
|
577
|
+
}, loadingResetKey || slotResetKey);
|
|
578
|
+
}
|
|
579
|
+
if (treePosition === 0 && slotErrorComponent) slotElement = /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
580
|
+
resetKey: slotResetKey,
|
|
581
|
+
fallback: slotErrorComponent,
|
|
582
|
+
children: slotElement
|
|
583
|
+
});
|
|
584
|
+
const layoutEntriesAtPosition = branchLayouts.get(treePosition) ?? [];
|
|
585
|
+
for (let layoutIndex = layoutEntriesAtPosition.length - 1; layoutIndex >= 0; layoutIndex--) {
|
|
586
|
+
const layoutEntry = layoutEntriesAtPosition[layoutIndex];
|
|
587
|
+
const LayoutComponent = layoutEntry.component;
|
|
588
|
+
slotElement = /* @__PURE__ */ jsx(LayoutComponent, {
|
|
589
|
+
params: options.makeThenableParams(layoutEntry.params),
|
|
590
|
+
children: slotElement
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
const ownerLoadingEntry = isPrefetchLoadingShell ? void 0 : findNearestLoadingEntryAtOrAbove(ownerTreePosition);
|
|
595
|
+
const ownerLoadingComponent = getDefaultExport(ownerLoadingEntry?.loadingModule);
|
|
596
|
+
if (ownerLoadingComponent && ownerLoadingEntry) {
|
|
597
|
+
const OwnerLoadingComponent = ownerLoadingComponent;
|
|
598
|
+
const ownerResetKey = resolveAppPageSegmentStateKey(routeSegments, ownerLoadingEntry.treePosition, options.matchedParams);
|
|
599
|
+
slotElement = /* @__PURE__ */ jsx(Suspense, {
|
|
600
|
+
fallback: /* @__PURE__ */ jsx(OwnerLoadingComponent, {}),
|
|
601
|
+
children: slotElement
|
|
602
|
+
}, ownerResetKey || slotResetKey);
|
|
603
|
+
}
|
|
405
604
|
elements[slotId] = renderAfterAppDependencies(slotElement, targetIndex >= 0 ? slotDependenciesByLayoutIndex[targetIndex] ?? [] : []);
|
|
406
605
|
}
|
|
407
606
|
let routeChildren = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(LayoutSegmentProvider, {
|
|
@@ -409,8 +608,8 @@ function buildAppPageElements(options) {
|
|
|
409
608
|
segmentMap: { children: [APP_PAGE_SEGMENT_KEY] },
|
|
410
609
|
children: /* @__PURE__ */ jsx(Slot, { id: pageElementId })
|
|
411
610
|
}), createAppPageStreamingMetadataOutlet(streamingMetadataOutletId, options.streamingMetadataOutletSuspended)] });
|
|
412
|
-
if (isPrefetchLoadingShell) if (
|
|
413
|
-
else routeChildren = /* @__PURE__ */ jsx(
|
|
611
|
+
if (isPrefetchLoadingShell) if (prefetchLoadingComponent === null) routeChildren = null;
|
|
612
|
+
else routeChildren = /* @__PURE__ */ jsx(prefetchLoadingComponent, {});
|
|
414
613
|
else {
|
|
415
614
|
routeChildren = /* @__PURE__ */ jsx(RedirectBoundary, { children: routeChildren });
|
|
416
615
|
if (routeLoadingComponent) routeChildren = /* @__PURE__ */ jsx(Suspense, {
|
|
@@ -420,7 +619,9 @@ function buildAppPageElements(options) {
|
|
|
420
619
|
routeChildren = /* @__PURE__ */ jsx(AppRouterScrollTarget, { children: routeChildren });
|
|
421
620
|
}
|
|
422
621
|
const lastLayoutErrorModule = errorEntries.length > 0 ? errorEntries[errorEntries.length - 1].errorModule : null;
|
|
423
|
-
const
|
|
622
|
+
const configuredNotFoundComponent = getDefaultExport(options.route.notFound) ?? getDefaultExport(options.rootNotFoundModule);
|
|
623
|
+
const defaultNotFoundOwnerLayoutId = configuredNotFoundComponent === null ? layoutEntries[0]?.id ?? null : null;
|
|
624
|
+
const notFoundComponent = configuredNotFoundComponent ?? (defaultNotFoundOwnerLayoutId === null ? DEFAULT_NOT_FOUND_COMPONENT : null);
|
|
424
625
|
if (notFoundComponent) routeChildren = /* @__PURE__ */ jsx(NotFoundBoundary, {
|
|
425
626
|
resetKey: routeResetKey,
|
|
426
627
|
fallback: /* @__PURE__ */ jsx(notFoundComponent, {}),
|
|
@@ -444,15 +645,24 @@ function buildAppPageElements(options) {
|
|
|
444
645
|
fallback: pageErrorComponent,
|
|
445
646
|
children: routeChildren
|
|
446
647
|
});
|
|
447
|
-
|
|
448
|
-
|
|
648
|
+
const renderedTreePositions = isPrefetchLoadingShell ? orderedTreePositions.filter(includesPrefetchTreePosition) : orderedTreePositions;
|
|
649
|
+
for (let index = renderedTreePositions.length - 1; index >= 0; index--) {
|
|
650
|
+
const treePosition = renderedTreePositions[index];
|
|
449
651
|
const segmentResetKey = resolveAppPageSegmentStateKey(routeSegments, treePosition, options.matchedParams);
|
|
450
652
|
let segmentChildren = routeChildren;
|
|
451
653
|
const layoutEntry = layoutEntriesByTreePosition.get(treePosition);
|
|
452
654
|
const templateEntry = templateEntriesByTreePosition.get(treePosition);
|
|
655
|
+
const loadingEntry = loadingEntriesByTreePosition.get(treePosition);
|
|
453
656
|
const errorEntry = errorEntriesByTreePosition.get(treePosition);
|
|
657
|
+
if (!isPrefetchLoadingShell && treePosition < routeSegments.length) {
|
|
658
|
+
const segmentLoadingComponent = getDefaultExport(loadingEntry?.loadingModule);
|
|
659
|
+
if (segmentLoadingComponent) segmentChildren = /* @__PURE__ */ jsx(Suspense, {
|
|
660
|
+
fallback: /* @__PURE__ */ jsx(segmentLoadingComponent, {}),
|
|
661
|
+
children: segmentChildren
|
|
662
|
+
}, segmentResetKey || routeResetKey);
|
|
663
|
+
}
|
|
454
664
|
if (layoutEntry) {
|
|
455
|
-
const layoutNotFoundComponent = getDefaultExport(layoutEntry.notFoundModule);
|
|
665
|
+
const layoutNotFoundComponent = getDefaultExport(layoutEntry.notFoundModule) ?? (layoutEntry.id === defaultNotFoundOwnerLayoutId ? DEFAULT_NOT_FOUND_COMPONENT : null);
|
|
456
666
|
if (layoutNotFoundComponent) segmentChildren = /* @__PURE__ */ jsx(NotFoundBoundary, {
|
|
457
667
|
resetKey: segmentResetKey,
|
|
458
668
|
fallback: /* @__PURE__ */ jsx(layoutNotFoundComponent, {}),
|
|
@@ -518,7 +728,7 @@ function buildAppPageElements(options) {
|
|
|
518
728
|
elements[routeId] = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
519
729
|
createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
|
|
520
730
|
routeChildren,
|
|
521
|
-
createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
|
|
731
|
+
createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash, options.scriptNonce),
|
|
522
732
|
createAppPageStreamingMetadataBody(streamingMetadataBodyId)
|
|
523
733
|
] });
|
|
524
734
|
registerAppElementRenderDependencies(elements, renderDependenciesByElementId);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { AppMiddlewareContext } from "./app-middleware.js";
|
|
2
|
+
import { EdgeApiExecutionRuntime } from "./edge-api-runtime.js";
|
|
2
3
|
|
|
3
4
|
//#region src/server/app-pages-bridge.d.ts
|
|
4
5
|
type PagesEntry = {
|
|
5
|
-
handleApiRoute?: (request: Request, url: string) => Promise<Response> | Response;
|
|
6
|
+
handleApiRoute?: (request: Request, url: string, ctx: unknown, trustedRevalidateOrigin: string | undefined, edgeRuntime: EdgeApiExecutionRuntime) => Promise<Response> | Response;
|
|
6
7
|
matchApiRoute?: (url: string, request: Request) => PagesRouteMatch | null;
|
|
7
8
|
matchPageRoute?: (url: string, request: Request) => PagesRouteMatch | null;
|
|
8
9
|
renderPage?: (request: Request, url: string, query: Record<string, unknown>, parsedUrl: unknown, middlewareRequestHeaders?: Headers | null, options?: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
1
2
|
import { cloneRequestWithHeaders, cloneRequestWithUrl } from "./request-pipeline.js";
|
|
2
3
|
import { pagesRouteHasPriorityOverAppRoute } from "./hybrid-route-priority.js";
|
|
3
4
|
//#region src/server/app-pages-bridge.ts
|
|
@@ -26,7 +27,8 @@ async function renderPagesFallback(options, dependencies) {
|
|
|
26
27
|
if (appRouteMatch !== null) {
|
|
27
28
|
if (apiMatch === null || !pagesRouteHasPriorityOverAppRoute(apiMatch.route, appRouteMatch.route)) return null;
|
|
28
29
|
}
|
|
29
|
-
const
|
|
30
|
+
const executionContext = getRequestExecutionContext();
|
|
31
|
+
const pagesApiResponse = await pagesEntry.handleApiRoute(pagesRequest, pagesUrl, void 0, executionContext?.trustedRevalidateOrigin ?? new URL(pagesRequest.url).origin, executionContext?.hostRuntime ?? "node");
|
|
30
32
|
const draftCookie = getDraftModeCookieHeader();
|
|
31
33
|
return applyDraftModeCookie(applyRouteHandlerMiddlewareContext(pagesApiResponse, middlewareContext), draftCookie);
|
|
32
34
|
}
|
|
@@ -12,6 +12,10 @@ async function readAppRouteHandlerCacheResponse(options) {
|
|
|
12
12
|
try {
|
|
13
13
|
const cached = await options.isrGet(routeKey);
|
|
14
14
|
const cachedValue = getCachedAppRouteValue(cached);
|
|
15
|
+
if (cached?.isExpired) {
|
|
16
|
+
options.isrDebug?.("MISS (expired route)", options.cleanPathname);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
15
19
|
if (cachedValue && !cached?.isStale) {
|
|
16
20
|
options.isrDebug?.("HIT (route)", options.cleanPathname);
|
|
17
21
|
options.clearRequestContext();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
1
|
+
import { closeAfterResponse, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
2
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
3
|
import { reportRequestError } from "./instrumentation.js";
|
|
4
4
|
import { consumeDynamicUsage, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
|
|
@@ -23,7 +23,7 @@ function buildRouteHandlerPageCacheTags(pathname, extraTags, routeSegments) {
|
|
|
23
23
|
return buildPageCacheTags(pathname, extraTags, routeSegments, "route");
|
|
24
24
|
}
|
|
25
25
|
async function runInRouteHandlerRevalidationContext(options, renderFn) {
|
|
26
|
-
|
|
26
|
+
const requestContext = createRequestContext({
|
|
27
27
|
headersContext: createStaticGenerationHeadersContext({
|
|
28
28
|
draftModeEnabled: false,
|
|
29
29
|
draftModeSecret: options.draftModeSecret,
|
|
@@ -33,7 +33,8 @@ async function runInRouteHandlerRevalidationContext(options, renderFn) {
|
|
|
33
33
|
}),
|
|
34
34
|
executionContext: getRequestExecutionContext(),
|
|
35
35
|
unstableCacheRevalidation: "foreground"
|
|
36
|
-
})
|
|
36
|
+
});
|
|
37
|
+
const revalidation = runWithRequestContext(requestContext, async () => {
|
|
37
38
|
ensureFetchPatch();
|
|
38
39
|
setCurrentFetchSoftTags(buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments));
|
|
39
40
|
setCurrentFetchCacheMode(options.fetchCacheMode);
|
|
@@ -44,6 +45,11 @@ async function runInRouteHandlerRevalidationContext(options, renderFn) {
|
|
|
44
45
|
await _drainPendingRevalidations();
|
|
45
46
|
}
|
|
46
47
|
});
|
|
48
|
+
try {
|
|
49
|
+
await revalidation;
|
|
50
|
+
} finally {
|
|
51
|
+
await closeAfterResponse(requestContext);
|
|
52
|
+
}
|
|
47
53
|
}
|
|
48
54
|
async function dispatchAppRouteHandler(options) {
|
|
49
55
|
const { route } = options;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "../utils/protocol-headers.js";
|
|
2
2
|
import "./headers.js";
|
|
3
3
|
import { processMiddlewareHeaders } from "./request-pipeline.js";
|
|
4
|
-
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
5
4
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
6
5
|
import { buildAppRouteMissIsrCacheControl, decideIsr } from "./isr-decision.js";
|
|
6
|
+
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
7
7
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
8
8
|
import { getSetCookieName } from "./cookie-utils.js";
|
|
9
9
|
//#region src/server/app-route-handler-response.ts
|
|
@@ -28,6 +28,8 @@ type LazyModuleLoaderArray = readonly (LazyModuleThunk | null | undefined)[];
|
|
|
28
28
|
type LazyLoadableIntercept = {
|
|
29
29
|
interceptLayouts?: readonly unknown[] | null;
|
|
30
30
|
__loadInterceptLayouts?: LazyModuleLoaderArray | null;
|
|
31
|
+
interceptLoadings?: readonly unknown[] | null;
|
|
32
|
+
__loadInterceptLoadings?: LazyModuleLoaderArray | null;
|
|
31
33
|
__loadState?: {
|
|
32
34
|
interceptLayoutsLoading: Promise<readonly unknown[]> | null;
|
|
33
35
|
};
|
|
@@ -38,6 +40,7 @@ type LazyLoadableSlot = {
|
|
|
38
40
|
layout?: unknown;
|
|
39
41
|
configLayouts?: readonly unknown[];
|
|
40
42
|
loading?: unknown;
|
|
43
|
+
loadings?: readonly unknown[];
|
|
41
44
|
error?: unknown;
|
|
42
45
|
notFound?: unknown;
|
|
43
46
|
__loadPage?: LazyModuleThunk | null;
|
|
@@ -45,6 +48,7 @@ type LazyLoadableSlot = {
|
|
|
45
48
|
__loadLayout?: LazyModuleThunk | null;
|
|
46
49
|
__loadConfigLayouts?: LazyModuleLoaderArray | null;
|
|
47
50
|
__loadLoading?: LazyModuleThunk | null;
|
|
51
|
+
__loadLoadings?: LazyModuleLoaderArray | null;
|
|
48
52
|
__loadError?: LazyModuleThunk | null;
|
|
49
53
|
__loadNotFound?: LazyModuleThunk | null; /** Hydrated only after an intercept matches, not with the slot's base modules. */
|
|
50
54
|
intercepts?: LazyLoadableIntercept[];
|
|
@@ -54,6 +58,7 @@ type LazyLoadableRoute = {
|
|
|
54
58
|
routeHandler?: unknown;
|
|
55
59
|
layouts?: unknown[];
|
|
56
60
|
templates?: unknown[];
|
|
61
|
+
loadings?: unknown[];
|
|
57
62
|
errors?: unknown[];
|
|
58
63
|
errorPaths?: unknown[];
|
|
59
64
|
notFounds?: unknown[];
|
|
@@ -70,6 +75,7 @@ type LazyLoadableRoute = {
|
|
|
70
75
|
__loadRouteHandler?: LazyModuleThunk | null;
|
|
71
76
|
__loadLayouts?: LazyModuleLoaderArray | null;
|
|
72
77
|
__loadTemplates?: LazyModuleLoaderArray | null;
|
|
78
|
+
__loadLoadings?: LazyModuleLoaderArray | null;
|
|
73
79
|
__loadErrors?: LazyModuleLoaderArray | null;
|
|
74
80
|
__loadErrorPaths?: LazyModuleLoaderArray | null;
|
|
75
81
|
__loadNotFounds?: LazyModuleLoaderArray | null;
|