vinext 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -5
- package/dist/build/client-build-config.d.ts +7 -1
- package/dist/build/client-build-config.js +9 -1
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +41 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/check.js +4 -3
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/navigation-runtime.d.ts +3 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/window-next.d.ts +8 -5
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -4
- package/dist/config/config-matchers.js +88 -16
- package/dist/config/next-config.d.ts +59 -4
- package/dist/config/next-config.js +149 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +189 -101
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +71 -6
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +54 -9
- package/dist/entries/pages-server-entry.js +48 -11
- package/dist/index.d.ts +0 -2
- package/dist/index.js +285 -139
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +10 -5
- package/dist/plugins/optimize-imports.js +27 -21
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +25 -2
- package/dist/routing/app-route-graph.js +91 -22
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +23 -2
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +19 -10
- package/dist/server/app-browser-entry.js +269 -297
- package/dist/server/app-browser-error.d.ts +10 -3
- package/dist/server/app-browser-error.js +47 -6
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +7 -4
- package/dist/server/app-browser-navigation-controller.js +33 -9
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.js +4 -7
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -1
- package/dist/server/app-fallback-renderer.js +6 -2
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +24 -3
- package/dist/server/app-page-boundary-render.d.ts +3 -1
- package/dist/server/app-page-boundary-render.js +31 -16
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +71 -8
- package/dist/server/app-page-dispatch.d.ts +34 -0
- package/dist/server/app-page-dispatch.js +167 -97
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +42 -10
- package/dist/server/app-page-execution.d.ts +7 -2
- package/dist/server/app-page-execution.js +53 -18
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +13 -2
- package/dist/server/app-page-render.js +48 -17
- package/dist/server/app-page-request.d.ts +3 -0
- package/dist/server/app-page-request.js +5 -3
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +5 -1
- package/dist/server/app-page-route-wiring.js +21 -11
- package/dist/server/app-page-stream.d.ts +16 -9
- package/dist/server/app-page-stream.js +12 -9
- package/dist/server/app-pages-bridge.d.ts +18 -0
- package/dist/server/app-pages-bridge.js +22 -5
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.js +12 -1
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +25 -0
- package/dist/server/app-rsc-handler.js +153 -53
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +2 -0
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +12 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +81 -8
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +287 -63
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +186 -22
- package/dist/server/navigation-planner.js +302 -0
- package/dist/server/navigation-trace.d.ts +18 -1
- package/dist/server/navigation-trace.js +18 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +20 -3
- package/dist/server/pages-api-route.js +19 -3
- package/dist/server/pages-asset-tags.d.ts +16 -4
- package/dist/server/pages-asset-tags.js +22 -12
- package/dist/server/pages-data-route.d.ts +8 -1
- package/dist/server/pages-data-route.js +16 -3
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-node-compat.d.ts +3 -11
- package/dist/server/pages-node-compat.js +175 -122
- package/dist/server/pages-page-data.d.ts +39 -2
- package/dist/server/pages-page-data.js +261 -46
- package/dist/server/pages-page-handler.d.ts +5 -2
- package/dist/server/pages-page-handler.js +78 -25
- package/dist/server/pages-page-response.d.ts +47 -2
- package/dist/server/pages-page-response.js +73 -9
- package/dist/server/pages-readiness.d.ts +1 -1
- package/dist/server/pages-request-pipeline.d.ts +16 -1
- package/dist/server/pages-request-pipeline.js +96 -38
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +39 -1
- package/dist/server/prod-server.js +107 -37
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/cache-runtime.js +12 -4
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +79 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +6 -4
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +38 -11
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +11 -1
- package/dist/shims/fetch-cache.js +55 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +66 -5
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +18 -23
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +12 -5
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +14 -17
- package/dist/shims/navigation.js +93 -46
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +13 -2
- package/dist/shims/router.js +434 -116
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +33 -2
- package/dist/shims/server.js +75 -18
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/client-build-manifest.js +15 -5
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +8 -1
- package/dist/utils/path.js +13 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { addBasePathToPathname } from "../utils/base-path.js";
|
|
2
2
|
import { VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
|
|
3
|
+
import { runWithConnectionProbe } from "../shims/headers.js";
|
|
3
4
|
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, createRscRedirectLocation } from "./app-rsc-cache-busting.js";
|
|
4
5
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
5
6
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
@@ -180,10 +181,15 @@ async function buildAppPageSpecialErrorResponse(options) {
|
|
|
180
181
|
}
|
|
181
182
|
if (options.renderFallbackPage) {
|
|
182
183
|
const fallbackResponse = await options.renderFallbackPage(options.specialError.statusCode);
|
|
183
|
-
if (fallbackResponse) return mergeAppPageSpecialErrorHeaders(fallbackResponse,
|
|
184
|
+
if (fallbackResponse) return mergeAppPageSpecialErrorHeaders(options.specialError.fromMetadata === true && options.serveStreamingMetadata !== false ? new Response(fallbackResponse.body, {
|
|
185
|
+
headers: fallbackResponse.headers,
|
|
186
|
+
status: 200,
|
|
187
|
+
statusText: fallbackResponse.statusText
|
|
188
|
+
}) : fallbackResponse, options.middlewareContext);
|
|
184
189
|
}
|
|
185
190
|
options.clearRequestContext();
|
|
186
|
-
|
|
191
|
+
const responseStatus = options.specialError.fromMetadata === true && options.serveStreamingMetadata !== false ? 200 : options.specialError.statusCode;
|
|
192
|
+
return mergeAppPageSpecialErrorHeaders(new Response(getAppPageStatusText(options.specialError.statusCode), { status: responseStatus }), options.middlewareContext);
|
|
187
193
|
}
|
|
188
194
|
/** See `LayoutFlags` type docblock in app-elements.ts for lifecycle. */
|
|
189
195
|
async function probeAppPageLayouts(options) {
|
|
@@ -210,7 +216,10 @@ async function probeAppPageLayouts(options) {
|
|
|
210
216
|
if (cls) {
|
|
211
217
|
const layoutId = cls.getLayoutId(layoutIndex);
|
|
212
218
|
try {
|
|
213
|
-
const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(() =>
|
|
219
|
+
const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(async () => {
|
|
220
|
+
const outcome = await runWithConnectionProbe(() => options.probeLayoutAt(layoutIndex));
|
|
221
|
+
return outcome.completed ? outcome.result : null;
|
|
222
|
+
});
|
|
214
223
|
const observationDynamic = cls.isLayoutObservationDynamic?.(layoutId) === true;
|
|
215
224
|
const layoutDynamic = dynamicDetected || observationDynamic;
|
|
216
225
|
layoutFlags[layoutId] = layoutDynamic ? "d" : "s";
|
|
@@ -239,25 +248,51 @@ async function probeAppPageLayouts(options) {
|
|
|
239
248
|
};
|
|
240
249
|
}
|
|
241
250
|
async function probeLayoutForErrors(options, layoutIndex) {
|
|
242
|
-
|
|
243
|
-
const layoutResult = options.probeLayoutAt(layoutIndex);
|
|
244
|
-
if (isPromiseLike(layoutResult)) await layoutResult;
|
|
245
|
-
} catch (error) {
|
|
246
|
-
return options.onLayoutError(error, layoutIndex);
|
|
247
|
-
}
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
async function probeAppPageComponent(options) {
|
|
251
|
-
return options.runWithSuppressedHookWarning(async () => {
|
|
251
|
+
const outcome = await runWithConnectionProbe(async () => {
|
|
252
252
|
try {
|
|
253
|
-
const
|
|
254
|
-
if (isPromiseLike(
|
|
255
|
-
else Promise.resolve(pageResult).catch(() => {});
|
|
253
|
+
const layoutResult = options.probeLayoutAt(layoutIndex);
|
|
254
|
+
if (isPromiseLike(layoutResult)) await layoutResult;
|
|
256
255
|
} catch (error) {
|
|
257
|
-
return options.
|
|
256
|
+
return options.onLayoutError(error, layoutIndex);
|
|
258
257
|
}
|
|
259
258
|
return null;
|
|
260
259
|
});
|
|
260
|
+
return outcome.completed ? outcome.result : null;
|
|
261
|
+
}
|
|
262
|
+
async function probeAppPageComponent(options) {
|
|
263
|
+
return options.runWithSuppressedHookWarning(async () => {
|
|
264
|
+
const outcome = await runWithConnectionProbe(async () => {
|
|
265
|
+
try {
|
|
266
|
+
const pageResult = options.probePage();
|
|
267
|
+
if (isPromiseLike(pageResult)) if (options.awaitAsyncResult) await pageResult;
|
|
268
|
+
else Promise.resolve(pageResult).catch(() => {});
|
|
269
|
+
} catch (error) {
|
|
270
|
+
return options.onError(error);
|
|
271
|
+
}
|
|
272
|
+
return null;
|
|
273
|
+
});
|
|
274
|
+
return outcome.completed ? outcome.result : null;
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
async function probeAppPageThrownError(options) {
|
|
278
|
+
return options.runWithSuppressedHookWarning(async () => {
|
|
279
|
+
const outcome = await runWithConnectionProbe(async () => {
|
|
280
|
+
try {
|
|
281
|
+
const pageResult = options.probePage();
|
|
282
|
+
if (isPromiseLike(pageResult)) await pageResult;
|
|
283
|
+
} catch (error) {
|
|
284
|
+
return {
|
|
285
|
+
error,
|
|
286
|
+
thrown: true
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
error: null,
|
|
291
|
+
thrown: false
|
|
292
|
+
};
|
|
293
|
+
});
|
|
294
|
+
return outcome.completed && outcome.result.thrown ? outcome.result.error : null;
|
|
295
|
+
});
|
|
261
296
|
}
|
|
262
297
|
async function readAppPageBinaryStream(stream) {
|
|
263
298
|
const reader = stream.getReader();
|
|
@@ -290,4 +325,4 @@ function buildAppPageFontLinkHeader(preloads) {
|
|
|
290
325
|
return preloads.map((preload) => `<${preload.href}>; rel=preload; as=font; type=${preload.type}; crossorigin`).join(", ");
|
|
291
326
|
}
|
|
292
327
|
//#endregion
|
|
293
|
-
export { buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
|
|
328
|
+
export { buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, probeAppPageThrownError, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
|
|
@@ -119,6 +119,7 @@ type ProbeAppPageBeforeRenderResult = {
|
|
|
119
119
|
};
|
|
120
120
|
type ProbeAppPageBeforeRenderOptions = {
|
|
121
121
|
hasLoadingBoundary: boolean;
|
|
122
|
+
skipProbes?: boolean;
|
|
122
123
|
layoutCount: number;
|
|
123
124
|
probeLayoutAt: (layoutIndex: number) => unknown;
|
|
124
125
|
probePage: () => unknown;
|
|
@@ -227,6 +227,10 @@ function buildAppPageProbes(options) {
|
|
|
227
227
|
}
|
|
228
228
|
async function probeAppPageBeforeRender(options) {
|
|
229
229
|
let layoutFlags = {};
|
|
230
|
+
if (options.skipProbes) return {
|
|
231
|
+
response: null,
|
|
232
|
+
layoutFlags
|
|
233
|
+
};
|
|
230
234
|
if (options.layoutCount > 0) {
|
|
231
235
|
const layoutProbeResult = await probeAppPageLayouts({
|
|
232
236
|
layoutCount: options.layoutCount,
|
|
@@ -7,6 +7,8 @@ type AppPageRenderObservationState = Readonly<{
|
|
|
7
7
|
requestApis: readonly RenderRequestApiKind[];
|
|
8
8
|
}>;
|
|
9
9
|
declare function createEmptyAppPageRenderObservationState(): AppPageRenderObservationState;
|
|
10
|
+
declare function consumeAppPageRenderObservationState(): AppPageRenderObservationState;
|
|
11
|
+
declare function discardAppPageRenderState(): void;
|
|
10
12
|
declare function createAppPageRenderObservation(options: {
|
|
11
13
|
boundaryOutcome: BoundaryOutcome;
|
|
12
14
|
cacheTags: readonly string[];
|
|
@@ -31,4 +33,4 @@ declare function createAppPageHtmlOutputScope(options: {
|
|
|
31
33
|
routePattern: string;
|
|
32
34
|
}): CacheProofOutputScope;
|
|
33
35
|
//#endregion
|
|
34
|
-
export { AppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState };
|
|
36
|
+
export { AppPageRenderObservationState, consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState, discardAppPageRenderState };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage } from "../shims/headers.js";
|
|
1
2
|
import { fnv1a64 } from "../utils/hash.js";
|
|
3
|
+
import { _consumeRequestScopedCacheLife } from "../shims/cache.js";
|
|
2
4
|
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
3
5
|
import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
|
|
4
6
|
import "./app-elements.js";
|
|
7
|
+
import { consumeDynamicFetchObservations } from "../shims/fetch-cache.js";
|
|
5
8
|
import { buildRenderObservation, buildRenderRequestApiObservations } from "./cache-proof.js";
|
|
6
9
|
//#region src/server/app-page-render-observation.ts
|
|
7
10
|
function readRootBoundaryId(element) {
|
|
@@ -30,6 +33,19 @@ function createEmptyAppPageRenderObservationState() {
|
|
|
30
33
|
requestApis: []
|
|
31
34
|
};
|
|
32
35
|
}
|
|
36
|
+
function consumeAppPageRenderObservationState() {
|
|
37
|
+
return {
|
|
38
|
+
dynamicFetches: consumeDynamicFetchObservations(),
|
|
39
|
+
requestApis: consumeRenderRequestApiUsage()
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function discardAppPageRenderState() {
|
|
43
|
+
_consumeRequestScopedCacheLife();
|
|
44
|
+
consumeDynamicFetchObservations();
|
|
45
|
+
consumeRenderRequestApiUsage();
|
|
46
|
+
consumeInvalidDynamicUsageError();
|
|
47
|
+
consumeDynamicUsage();
|
|
48
|
+
}
|
|
33
49
|
function createAppPageRenderObservation(options) {
|
|
34
50
|
return buildRenderObservation({
|
|
35
51
|
boundaryOutcome: options.boundaryOutcome,
|
|
@@ -63,4 +79,4 @@ function createAppPageHtmlOutputScope(options) {
|
|
|
63
79
|
};
|
|
64
80
|
}
|
|
65
81
|
//#endregion
|
|
66
|
-
export { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState };
|
|
82
|
+
export { consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState, discardAppPageRenderState };
|
|
@@ -7,8 +7,8 @@ import { AppPageMiddlewareContext } from "./app-page-response.js";
|
|
|
7
7
|
import { RootParams } from "../shims/root-params.js";
|
|
8
8
|
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
9
9
|
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
10
|
-
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
11
10
|
import { AppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
11
|
+
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
12
12
|
import { ReactNode } from "react";
|
|
13
13
|
import { ReactFormState } from "react-dom/client";
|
|
14
14
|
|
|
@@ -49,6 +49,7 @@ type RenderAppPageLifecycleOptions = {
|
|
|
49
49
|
peekRequestCacheLife?: () => AppPageRequestCacheLife | null;
|
|
50
50
|
getDraftModeCookieHeader: () => string | null | undefined;
|
|
51
51
|
handlerStart: number;
|
|
52
|
+
hasCustomGlobalError?: boolean;
|
|
52
53
|
hasLoadingBoundary: boolean;
|
|
53
54
|
dynamicStaleTimeSeconds?: number;
|
|
54
55
|
isDynamicError: boolean;
|
|
@@ -68,7 +69,11 @@ type RenderAppPageLifecycleOptions = {
|
|
|
68
69
|
layoutCount: number;
|
|
69
70
|
loadSsrHandler: () => Promise<AppPageSsrHandler>;
|
|
70
71
|
middlewareContext: AppPageMiddlewareContext;
|
|
72
|
+
navigationParams: Record<string, unknown>;
|
|
71
73
|
params: Record<string, unknown>;
|
|
74
|
+
pprFallbackShellSignal?: AbortSignal;
|
|
75
|
+
pprFallbackShellReactSignal?: AbortSignal;
|
|
76
|
+
abortPprFallbackShell?: () => void;
|
|
72
77
|
rootParams?: RootParams;
|
|
73
78
|
peekRenderObservationState?: () => AppPageRenderObservationState;
|
|
74
79
|
probeLayoutAt: (layoutIndex: number) => unknown;
|
|
@@ -81,8 +86,14 @@ type RenderAppPageLifecycleOptions = {
|
|
|
81
86
|
renderPageSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
|
|
82
87
|
renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
|
|
83
88
|
onError: AppPageBoundaryOnError;
|
|
89
|
+
signal?: AbortSignal;
|
|
84
90
|
}) => ReadableStream<Uint8Array>;
|
|
85
|
-
|
|
91
|
+
prerenderToReadableStream?: (element: ReactNode | AppOutgoingElements, options: {
|
|
92
|
+
onError: AppPageBoundaryOnError;
|
|
93
|
+
signal?: AbortSignal;
|
|
94
|
+
}) => Promise<{
|
|
95
|
+
prelude: ReadableStream<Uint8Array>;
|
|
96
|
+
}>;
|
|
86
97
|
routePattern: string;
|
|
87
98
|
runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
|
|
88
99
|
scriptNonce?: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
|
|
1
2
|
import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
|
|
2
3
|
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
3
4
|
import "./app-elements.js";
|
|
4
5
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
5
|
-
import { NO_STORE_CACHE_CONTROL } from "./cache-control.js";
|
|
6
6
|
import { buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy } from "./app-page-response.js";
|
|
7
7
|
import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageSpecialError, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
8
8
|
import { probeAppPageBeforeRender } from "./app-page-probe.js";
|
|
@@ -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 { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery
|
|
13
|
+
import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } 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";
|
|
@@ -249,6 +249,7 @@ function wrapRscResponseForDevErrorReporting(response, consumeInvalidDynamicUsag
|
|
|
249
249
|
async function renderAppPageLifecycle(options) {
|
|
250
250
|
const preRenderResult = await probeAppPageBeforeRender({
|
|
251
251
|
hasLoadingBoundary: options.hasLoadingBoundary,
|
|
252
|
+
skipProbes: options.pprFallbackShellSignal !== void 0,
|
|
252
253
|
layoutCount: options.layoutCount,
|
|
253
254
|
probeLayoutAt(layoutIndex) {
|
|
254
255
|
return options.probeLayoutAt(layoutIndex);
|
|
@@ -293,7 +294,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
293
294
|
cleanPathname: options.cleanPathname,
|
|
294
295
|
completeness: "partial",
|
|
295
296
|
output: rscOutputScope,
|
|
296
|
-
params: options.
|
|
297
|
+
params: options.navigationParams,
|
|
297
298
|
state: options.peekRenderObservationState?.() ?? createEmptyAppPageRenderObservationState()
|
|
298
299
|
});
|
|
299
300
|
const skipDisposition = options.skipDisposition ?? createRenderLifecycleSkipDisposition({
|
|
@@ -315,11 +316,31 @@ async function renderAppPageLifecycle(options) {
|
|
|
315
316
|
});
|
|
316
317
|
const compileEnd = options.isProduction ? void 0 : performance.now();
|
|
317
318
|
const rscErrorTracker = createAppPageRscErrorTracker(options.createRscOnErrorHandler(options.cleanPathname, options.routePattern));
|
|
318
|
-
|
|
319
|
+
let rscStream = await runWithFetchDedupe(async () => {
|
|
320
|
+
if (options.pprFallbackShellSignal && options.prerenderToReadableStream) {
|
|
321
|
+
const reactSignal = options.pprFallbackShellReactSignal ?? options.pprFallbackShellSignal;
|
|
322
|
+
const pendingResult = options.prerenderToReadableStream(outgoingElement, {
|
|
323
|
+
onError: rscErrorTracker.onRenderError,
|
|
324
|
+
signal: reactSignal
|
|
325
|
+
});
|
|
326
|
+
if (options.abortPprFallbackShell) setTimeout(options.abortPprFallbackShell, 0);
|
|
327
|
+
return (await pendingResult).prelude;
|
|
328
|
+
}
|
|
329
|
+
return options.renderToReadableStream(outgoingElement, { onError: rscErrorTracker.onRenderError });
|
|
330
|
+
});
|
|
331
|
+
let pprFallbackShellRsc = null;
|
|
332
|
+
if (options.pprFallbackShellSignal) pprFallbackShellRsc = new Uint8Array(await readAppPageBinaryStream(rscStream));
|
|
319
333
|
let revalidateSeconds = options.revalidateSeconds;
|
|
320
334
|
let expireSeconds = options.expireSeconds;
|
|
321
335
|
const shouldCaptureRscForCacheMetadata = options.isProgressiveActionRender !== true && (options.isProduction || options.isPrerender === true) && (revalidateSeconds === null || revalidateSeconds > 0 && revalidateSeconds !== Infinity) && !options.isDraftMode && !options.isForceDynamic && !shouldBypassRscCacheForSkipTransport;
|
|
322
|
-
const
|
|
336
|
+
const createBufferedRscStream = (close) => new ReadableStream({ start(controller) {
|
|
337
|
+
if (pprFallbackShellRsc) controller.enqueue(pprFallbackShellRsc);
|
|
338
|
+
if (close) controller.close();
|
|
339
|
+
} });
|
|
340
|
+
const rscCapture = pprFallbackShellRsc ? {
|
|
341
|
+
ssrStream: createBufferedRscStream(false),
|
|
342
|
+
...shouldCaptureRscForCacheMetadata ? { sideStream: createBufferedRscStream(true) } : {}
|
|
343
|
+
} : teeAppPageRscStreamForCapture(rscStream, shouldCaptureRscForCacheMetadata);
|
|
323
344
|
const rscForResponse = rscCapture.ssrStream;
|
|
324
345
|
const capturedRscDataRef = { value: null };
|
|
325
346
|
if (rscCapture.sideStream && options.isRscRequest) capturedRscDataRef.value = readAppPageBinaryStream(rscCapture.sideStream);
|
|
@@ -349,7 +370,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
349
370
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
350
371
|
middlewareContext: options.middlewareContext,
|
|
351
372
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
352
|
-
params: options.
|
|
373
|
+
params: options.navigationParams,
|
|
353
374
|
policy: rscResponsePolicy,
|
|
354
375
|
timing: buildResponseTiming({
|
|
355
376
|
compileEnd,
|
|
@@ -371,7 +392,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
371
392
|
cleanPathname: options.cleanPathname,
|
|
372
393
|
completeness: "complete",
|
|
373
394
|
output: rscOutputScope,
|
|
374
|
-
params: options.
|
|
395
|
+
params: options.navigationParams,
|
|
375
396
|
state: input.state
|
|
376
397
|
});
|
|
377
398
|
},
|
|
@@ -415,17 +436,19 @@ async function renderAppPageLifecycle(options) {
|
|
|
415
436
|
return renderAppPageHtmlStream({
|
|
416
437
|
capturedRscDataRef,
|
|
417
438
|
fontData,
|
|
439
|
+
hasCustomGlobalError: options.hasCustomGlobalError,
|
|
418
440
|
navigationContext: options.getNavigationContext(),
|
|
419
441
|
basePath: options.basePath,
|
|
420
442
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
421
443
|
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
422
444
|
rootParams: options.rootParams,
|
|
445
|
+
pprFallbackShellSignal: options.pprFallbackShellSignal,
|
|
423
446
|
formState: options.formState ?? null,
|
|
424
447
|
rscStream: rscForResponse,
|
|
425
448
|
scriptNonce: options.scriptNonce,
|
|
426
449
|
sideStream: rscCapture.sideStream,
|
|
427
450
|
ssrHandler,
|
|
428
|
-
waitForAllReady: options.isPrerender
|
|
451
|
+
waitForAllReady: options.isPrerender === true
|
|
429
452
|
});
|
|
430
453
|
},
|
|
431
454
|
renderSpecialErrorResponse(specialError) {
|
|
@@ -448,13 +471,6 @@ async function renderAppPageLifecycle(options) {
|
|
|
448
471
|
}
|
|
449
472
|
}
|
|
450
473
|
}
|
|
451
|
-
if (shouldRerenderAppPageWithGlobalError({
|
|
452
|
-
capturedError: rscErrorTracker.getCapturedError(),
|
|
453
|
-
hasLocalBoundary: options.routeHasLocalBoundary
|
|
454
|
-
})) {
|
|
455
|
-
const cleanResponse = await options.renderErrorBoundaryResponse(rscErrorTracker.getCapturedError());
|
|
456
|
-
if (cleanResponse) return cleanResponse;
|
|
457
|
-
}
|
|
458
474
|
if (options.isPrerender === true) {
|
|
459
475
|
await settleCapturedRscRenderForCacheMetadata(htmlRender.capturedRscData);
|
|
460
476
|
({expireSeconds, revalidateSeconds} = applyRequestCacheLife({
|
|
@@ -489,6 +505,21 @@ async function renderAppPageLifecycle(options) {
|
|
|
489
505
|
renderEnd,
|
|
490
506
|
responseKind: "html"
|
|
491
507
|
});
|
|
508
|
+
if (htmlRender.shellErrorRecovered) {
|
|
509
|
+
const response = buildAppPageHtmlResponse(safeHtmlStream, {
|
|
510
|
+
draftCookie,
|
|
511
|
+
linkHeader,
|
|
512
|
+
isEdgeRuntime: options.isEdgeRuntime,
|
|
513
|
+
middlewareContext: {
|
|
514
|
+
headers: options.middlewareContext.headers,
|
|
515
|
+
status: 500
|
|
516
|
+
},
|
|
517
|
+
policy: { cacheControl: NEVER_CACHE_CONTROL },
|
|
518
|
+
timing: htmlResponseTiming
|
|
519
|
+
});
|
|
520
|
+
applyCdnResponseHeaders(response.headers, { cacheControl: NEVER_CACHE_CONTROL });
|
|
521
|
+
return response;
|
|
522
|
+
}
|
|
492
523
|
const shouldSpeculativelyWriteCache = options.isProduction && shouldCaptureRscForCacheMetadata && revalidateSeconds === null && !options.isDynamicError && !options.isForceStatic && !options.scriptNonce && options.isProgressiveActionRender !== true && !dynamicUsedDuringRender;
|
|
493
524
|
if (htmlResponsePolicy.shouldWriteToCache || shouldSpeculativelyWriteCache) {
|
|
494
525
|
const isrResponse = buildAppPageHtmlResponse(safeHtmlStream, {
|
|
@@ -516,7 +547,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
516
547
|
cleanPathname: options.cleanPathname,
|
|
517
548
|
completeness: "complete",
|
|
518
549
|
output: htmlOutputScope,
|
|
519
|
-
params: options.
|
|
550
|
+
params: options.navigationParams,
|
|
520
551
|
state: input.state
|
|
521
552
|
});
|
|
522
553
|
},
|
|
@@ -528,7 +559,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
528
559
|
cleanPathname: options.cleanPathname,
|
|
529
560
|
completeness: "complete",
|
|
530
561
|
output: rscOutputScope,
|
|
531
|
-
params: options.
|
|
562
|
+
params: options.navigationParams,
|
|
532
563
|
state: input.state
|
|
533
564
|
});
|
|
534
565
|
},
|
|
@@ -29,6 +29,7 @@ type ResolveAppPageGenerateStaticParamsSourcesOptions = {
|
|
|
29
29
|
};
|
|
30
30
|
type BuildAppPageElementOptions<TElement> = {
|
|
31
31
|
buildPageElement: () => Promise<TElement>;
|
|
32
|
+
probePageSpecialError?: () => Promise<AppPageSpecialError | null>;
|
|
32
33
|
renderErrorBoundaryPage: (error: unknown) => Promise<Response | null>;
|
|
33
34
|
renderSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
|
|
34
35
|
resolveSpecialError: (error: unknown) => AppPageSpecialError | null;
|
|
@@ -44,6 +45,7 @@ type AppPageInterceptMatch<TPage = unknown> = {
|
|
|
44
45
|
slotId?: string | null;
|
|
45
46
|
slotKey: string;
|
|
46
47
|
sourceRouteIndex: number;
|
|
48
|
+
sourcePageSegments?: readonly string[] | null;
|
|
47
49
|
};
|
|
48
50
|
type ResolveAppPageInterceptMatchOptions<TRoute, TPage, TInterceptOpts> = {
|
|
49
51
|
cleanPathname: string;
|
|
@@ -87,6 +89,7 @@ type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
|
|
|
87
89
|
getSourceRoute: (sourceRouteIndex: number) => Awaitable<TRoute | undefined>;
|
|
88
90
|
isRscRequest: boolean;
|
|
89
91
|
layoutParamAccess?: AppLayoutParamAccessTracker;
|
|
92
|
+
resolveNavigationParams: (route: TRoute, params: AppPageParams, pathname: string, interceptOpts: TInterceptOpts) => AppPageParams;
|
|
90
93
|
renderInterceptResponse: (route: TRoute, element: TElement) => Promise<Response> | Response;
|
|
91
94
|
searchParams: URLSearchParams;
|
|
92
95
|
setNavigationContext: (context: {
|
|
@@ -155,13 +155,14 @@ async function resolveAppPageIntercept(options) {
|
|
|
155
155
|
});
|
|
156
156
|
if (interceptState.kind === "source-route") {
|
|
157
157
|
const renderRoute = interceptState.sourceRoute;
|
|
158
|
+
const interceptOpts = options.toInterceptOpts(interceptState.intercept);
|
|
158
159
|
const renderParams = pickRouteParams(interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute));
|
|
159
160
|
options.setNavigationContext({
|
|
160
|
-
params: interceptState.intercept.matchedParams,
|
|
161
|
+
params: options.resolveNavigationParams(renderRoute, interceptState.intercept.matchedParams, options.cleanPathname, interceptOpts),
|
|
161
162
|
pathname: options.cleanPathname,
|
|
162
163
|
searchParams: options.searchParams
|
|
163
164
|
});
|
|
164
|
-
const interceptElement = await options.buildPageElement(renderRoute, renderParams,
|
|
165
|
+
const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, options.searchParams, options.layoutParamAccess);
|
|
165
166
|
return {
|
|
166
167
|
interceptOpts: void 0,
|
|
167
168
|
response: await options.renderInterceptResponse(renderRoute, interceptElement)
|
|
@@ -179,7 +180,8 @@ async function buildAppPageElement(options) {
|
|
|
179
180
|
response: null
|
|
180
181
|
};
|
|
181
182
|
} catch (error) {
|
|
182
|
-
const
|
|
183
|
+
const buildSpecialError = options.resolveSpecialError(error);
|
|
184
|
+
const specialError = (buildSpecialError ? await options.probePageSpecialError?.() : null) ?? buildSpecialError;
|
|
183
185
|
if (specialError) return {
|
|
184
186
|
element: null,
|
|
185
187
|
response: await options.renderSpecialError(specialError)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER, VINEXT_TIMING_HEADER } from "./headers.js";
|
|
2
2
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
3
|
-
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
4
3
|
import { NO_STORE_CACHE_CONTROL, STATIC_CACHE_CONTROL, buildRevalidateCacheControl } from "./cache-control.js";
|
|
4
|
+
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
5
5
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
6
6
|
//#region src/server/app-page-response.ts
|
|
7
7
|
function applyTimingHeader(headers, timing) {
|
|
@@ -113,6 +113,7 @@ type BuildAppPageRouteElementOptions<TModule extends AppPageModule = AppPageModu
|
|
|
113
113
|
resolvedMetadata: Metadata | null;
|
|
114
114
|
resolvedMetadataPathname?: string;
|
|
115
115
|
resolvedViewport: Viewport;
|
|
116
|
+
trailingSlash?: boolean;
|
|
116
117
|
rootForbiddenModule?: TModule | null;
|
|
117
118
|
rootNotFoundModule?: TModule | null;
|
|
118
119
|
rootUnauthorizedModule?: TModule | null;
|
|
@@ -129,6 +130,7 @@ type BuildAppPageElementsOptions<TModule extends AppPageModule = AppPageModule,
|
|
|
129
130
|
renderIdentity?: AppPageRenderIdentity;
|
|
130
131
|
renderMode?: AppRscRenderMode;
|
|
131
132
|
routePath: string;
|
|
133
|
+
sourcePageSegments?: readonly string[] | null;
|
|
132
134
|
};
|
|
133
135
|
declare function createAppPageTreePath(routeSegments: readonly string[] | null | undefined, treePosition: number): string;
|
|
134
136
|
declare function probeAppPageLayoutWithTracking<TModule extends AppPageModule>(options: {
|
|
@@ -142,6 +144,8 @@ declare function createAppPageLayoutEntries<TModule extends AppPageModule, TErro
|
|
|
142
144
|
forbiddens?: readonly (TModule | null | undefined)[] | null;
|
|
143
145
|
unauthorizeds?: readonly (TModule | null | undefined)[] | null;
|
|
144
146
|
}): AppPageLayoutEntry<TModule, TErrorModule>[];
|
|
147
|
+
declare function createAppPageSourcePage(routeSegments: readonly string[] | null | undefined): string;
|
|
148
|
+
declare function createAppPageRouteBodyMetadata(metadata: Metadata | null, pathname: string, metadataPlacement: "body" | "head", trailingSlash?: boolean): ReactNode;
|
|
145
149
|
declare function buildAppPageElements<TModule extends AppPageModule, TErrorModule extends AppPageErrorModule>(options: BuildAppPageElementsOptions<TModule, TErrorModule>): AppElements;
|
|
146
150
|
//#endregion
|
|
147
|
-
export { AppPageErrorModule, AppPageModule, AppPageRouteWiringRoute, AppPageSlotOverride, buildAppPageElements, createAppPageLayoutEntries, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
|
|
151
|
+
export { AppPageErrorModule, AppPageModule, AppPageRouteWiringRoute, AppPageSlotOverride, buildAppPageElements, createAppPageLayoutEntries, createAppPageRouteBodyMetadata, createAppPageSourcePage, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
|
|
@@ -2,7 +2,8 @@ import { createAppRenderDependency, registerAppElementRenderDependencies, render
|
|
|
2
2
|
import { APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
3
3
|
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL, shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
|
|
4
4
|
import { APP_PREFETCH_LOADING_SHELL_MARKER_KEY } from "./app-elements.js";
|
|
5
|
-
import
|
|
5
|
+
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
6
|
+
import { ErrorBoundary, ForbiddenBoundary, GlobalErrorBoundary, NotFoundBoundary, RedirectBoundary, UnauthorizedBoundary } from "../shims/error-boundary.js";
|
|
6
7
|
import { AppRouterScrollTarget } from "../shims/app-router-scroll.js";
|
|
7
8
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
8
9
|
import { MetadataHead, ViewportHead, renderMetadataToHtml } from "../shims/metadata.js";
|
|
@@ -14,6 +15,7 @@ import { Fragment, Suspense } from "react";
|
|
|
14
15
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
15
16
|
//#region src/server/app-page-route-wiring.tsx
|
|
16
17
|
const APP_PAGE_LAYOUT_PROBE_CHILD = /* @__PURE__ */ jsx(Fragment, {});
|
|
18
|
+
const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
|
|
17
19
|
function getDefaultExport(module) {
|
|
18
20
|
return module?.default ?? null;
|
|
19
21
|
}
|
|
@@ -85,6 +87,9 @@ function createAppPageTemplateEntries(route) {
|
|
|
85
87
|
};
|
|
86
88
|
});
|
|
87
89
|
}
|
|
90
|
+
function createAppPageSourcePage(routeSegments) {
|
|
91
|
+
return `/${[...routeSegments ?? [], "page"].join("/")}`;
|
|
92
|
+
}
|
|
88
93
|
function createAppPageErrorEntries(route) {
|
|
89
94
|
return (route.errorPaths ?? route.errors ?? []).flatMap((errorModule, index) => {
|
|
90
95
|
if (!errorModule) return [];
|
|
@@ -139,21 +144,22 @@ function createAppPageSlotBindings(route, layoutEntries, resolveSlotOverride, op
|
|
|
139
144
|
}
|
|
140
145
|
return normalizeAppElementsSlotBindings(bindings, { layoutIds: layoutEntries.map((entry) => entry.id) });
|
|
141
146
|
}
|
|
142
|
-
function createAppPageRouteHead(metadata, viewport, pathname, metadataPlacement) {
|
|
147
|
+
function createAppPageRouteHead(metadata, viewport, pathname, metadataPlacement, trailingSlash) {
|
|
143
148
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
144
149
|
/* @__PURE__ */ jsx("meta", { charSet: "utf-8" }),
|
|
145
150
|
metadata && metadataPlacement === "head" ? /* @__PURE__ */ jsx(MetadataHead, {
|
|
146
151
|
metadata,
|
|
147
|
-
pathname
|
|
152
|
+
pathname,
|
|
153
|
+
trailingSlash
|
|
148
154
|
}) : null,
|
|
149
155
|
/* @__PURE__ */ jsx(ViewportHead, { viewport })
|
|
150
156
|
] });
|
|
151
157
|
}
|
|
152
|
-
function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement) {
|
|
158
|
+
function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement, trailingSlash) {
|
|
153
159
|
if (!metadata || metadataPlacement !== "body") return null;
|
|
154
160
|
return /* @__PURE__ */ jsx("div", {
|
|
155
161
|
hidden: true,
|
|
156
|
-
dangerouslySetInnerHTML: { __html: renderMetadataToHtml(metadata, pathname) }
|
|
162
|
+
dangerouslySetInnerHTML: { __html: renderMetadataToHtml(metadata, pathname, { trailingSlash }) }
|
|
157
163
|
});
|
|
158
164
|
}
|
|
159
165
|
function buildAppPageElements(options) {
|
|
@@ -205,6 +211,7 @@ function buildAppPageElements(options) {
|
|
|
205
211
|
layoutIds: options.route.ids?.layouts ?? layoutEntries.map((entry) => entry.id),
|
|
206
212
|
rootLayoutTreePath,
|
|
207
213
|
routeId,
|
|
214
|
+
sourcePage: createAppPageSourcePage(options.sourcePageSegments ?? routeSegments),
|
|
208
215
|
slotBindings: createAppPageSlotBindings(options.route, layoutEntries, resolveSlotOverride, {
|
|
209
216
|
interception: renderIdentity?.interception ?? options.interception ?? null,
|
|
210
217
|
interceptionContext,
|
|
@@ -426,17 +433,20 @@ function buildAppPageElements(options) {
|
|
|
426
433
|
});
|
|
427
434
|
}
|
|
428
435
|
const globalErrorComponent = getErrorBoundaryExport(options.globalErrorModule);
|
|
429
|
-
|
|
430
|
-
fallback:
|
|
431
|
-
children:
|
|
436
|
+
routeChildren = /* @__PURE__ */ jsx(GlobalErrorBoundary, {
|
|
437
|
+
fallback: DEFAULT_GLOBAL_ERROR_COMPONENT,
|
|
438
|
+
children: globalErrorComponent ? /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
439
|
+
fallback: globalErrorComponent,
|
|
440
|
+
children: routeChildren
|
|
441
|
+
}) : routeChildren
|
|
432
442
|
});
|
|
433
443
|
elements[routeId] = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
434
|
-
createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement),
|
|
444
|
+
createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
|
|
435
445
|
routeChildren,
|
|
436
|
-
createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement)
|
|
446
|
+
createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash)
|
|
437
447
|
] });
|
|
438
448
|
registerAppElementRenderDependencies(elements, renderDependenciesByElementId);
|
|
439
449
|
return elements;
|
|
440
450
|
}
|
|
441
451
|
//#endregion
|
|
442
|
-
export { buildAppPageElements, createAppPageLayoutEntries, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
|
|
452
|
+
export { buildAppPageElements, createAppPageLayoutEntries, createAppPageRouteBodyMetadata, createAppPageSourcePage, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
|
|
@@ -18,6 +18,7 @@ type AppSsrRenderResult = {
|
|
|
18
18
|
htmlStream: ReadableStream<Uint8Array>;
|
|
19
19
|
metadataReady: Promise<void>;
|
|
20
20
|
capturedRscData: Promise<ArrayBuffer> | null;
|
|
21
|
+
shellErrorRecovered?: boolean;
|
|
21
22
|
/**
|
|
22
23
|
* Preload `Link` header value emitted by React during SSR (via `onHeaders`),
|
|
23
24
|
* already capped to `reactMaxHeadersLength`. Empty/undefined when React
|
|
@@ -62,9 +63,14 @@ type AppPageSsrHandler = {
|
|
|
62
63
|
sideStream?: ReadableStream<Uint8Array>;
|
|
63
64
|
capturedRscDataRef?: {
|
|
64
65
|
value: Promise<ArrayBuffer> | null;
|
|
65
|
-
}; /**
|
|
66
|
+
}; /** Abort signal for a build-time PPR fallback-shell static render. */
|
|
67
|
+
pprFallbackShellSignal?: AbortSignal; /** When true, wait for the full React tree before emitting bytes. */
|
|
66
68
|
waitForAllReady?: boolean; /** Dev-only: original server error to surface in the browser overlay. */
|
|
67
69
|
initialDevServerError?: unknown;
|
|
70
|
+
/** When true, an SSR-phase-only shell render error resolves to the
|
|
71
|
+
* default `__next_error__` error-document shell (with the original
|
|
72
|
+
* flight payload and bootstrap) instead of rejecting. See handleSsr. */
|
|
73
|
+
fallbackToErrorDocumentOnShellError?: boolean;
|
|
68
74
|
}) => Promise<ReadableStream<Uint8Array> | AppSsrRenderResult>;
|
|
69
75
|
};
|
|
70
76
|
type RenderAppPageHtmlStreamOptions = {
|
|
@@ -93,9 +99,14 @@ type RenderAppPageHtmlStreamOptions = {
|
|
|
93
99
|
sideStream?: ReadableStream<Uint8Array>; /** Out-parameter filled with accumulated raw RSC bytes after stream consumption. */
|
|
94
100
|
capturedRscDataRef?: {
|
|
95
101
|
value: Promise<ArrayBuffer> | null;
|
|
96
|
-
}; /**
|
|
102
|
+
}; /** Abort signal for a build-time PPR fallback-shell static render. */
|
|
103
|
+
pprFallbackShellSignal?: AbortSignal; /** When true, wait for the full React tree before emitting bytes. */
|
|
97
104
|
waitForAllReady?: boolean; /** Dev-only: original server error to surface in the browser overlay. */
|
|
98
105
|
initialDevServerError?: unknown;
|
|
106
|
+
/** True when the app supplies a custom global-error.tsx. Disables the
|
|
107
|
+
* default error-document shell fallback so SSR shell errors keep driving
|
|
108
|
+
* the server-rendered global-error boundary re-render. */
|
|
109
|
+
hasCustomGlobalError?: boolean;
|
|
99
110
|
};
|
|
100
111
|
type RenderAppPageHtmlResponseOptions = {
|
|
101
112
|
clearRequestContext: () => void;
|
|
@@ -108,7 +119,8 @@ type AppPageHtmlStreamRecoveryResult = {
|
|
|
108
119
|
htmlStream: ReadableStream<Uint8Array> | null;
|
|
109
120
|
response: Response | null;
|
|
110
121
|
metadataReady: Promise<void>;
|
|
111
|
-
capturedRscData: Promise<ArrayBuffer> | null;
|
|
122
|
+
capturedRscData: Promise<ArrayBuffer> | null;
|
|
123
|
+
shellErrorRecovered: boolean; /** React-emitted preload `Link` header (already capped). */
|
|
112
124
|
linkHeader?: string;
|
|
113
125
|
};
|
|
114
126
|
type RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError> = {
|
|
@@ -129,10 +141,6 @@ type AppPageRscErrorTracker = {
|
|
|
129
141
|
getCapturedSpecialError: () => unknown;
|
|
130
142
|
onRenderError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;
|
|
131
143
|
};
|
|
132
|
-
type ShouldRerenderAppPageWithGlobalErrorOptions = {
|
|
133
|
-
capturedError: unknown;
|
|
134
|
-
hasLocalBoundary: boolean;
|
|
135
|
-
};
|
|
136
144
|
declare function createAppPageFontData(options: CreateAppPageFontDataOptions): AppPageFontData;
|
|
137
145
|
declare function renderAppPageHtmlStream(options: RenderAppPageHtmlStreamOptions): Promise<AppSsrRenderResult>;
|
|
138
146
|
/**
|
|
@@ -146,6 +154,5 @@ declare function deferUntilStreamConsumed(stream: ReadableStream<Uint8Array>, on
|
|
|
146
154
|
declare function renderAppPageHtmlResponse(options: RenderAppPageHtmlResponseOptions): Promise<Response>;
|
|
147
155
|
declare function renderAppPageHtmlStreamWithRecovery<TSpecialError>(options: RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError>): Promise<AppPageHtmlStreamRecoveryResult>;
|
|
148
156
|
declare function createAppPageRscErrorTracker(baseOnError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown): AppPageRscErrorTracker;
|
|
149
|
-
declare function shouldRerenderAppPageWithGlobalError(options: ShouldRerenderAppPageWithGlobalErrorOptions): boolean;
|
|
150
157
|
//#endregion
|
|
151
|
-
export { AppPageFontData, AppPageSsrHandler, AppSsrRenderResult, buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, isAppSsrRenderResult, renderAppPageHtmlResponse, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery
|
|
158
|
+
export { AppPageFontData, AppPageSsrHandler, AppSsrRenderResult, buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, isAppSsrRenderResult, renderAppPageHtmlResponse, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery };
|