vinext 0.1.2 → 0.1.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/dist/build/client-build-config.d.ts +11 -2
- package/dist/build/client-build-config.js +17 -6
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +42 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/pages-router-link-navigation.d.ts +33 -7
- package/dist/client/pages-router-link-navigation.js +32 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/vinext-next-data.js +2 -0
- package/dist/client/window-next.d.ts +2 -1
- 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 -1
- package/dist/config/config-matchers.js +87 -16
- package/dist/config/next-config.d.ts +46 -4
- package/dist/config/next-config.js +147 -48
- package/dist/config/tsconfig-paths.js +14 -1
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +200 -112
- 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 +65 -5
- 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 +66 -20
- package/dist/entries/pages-server-entry.js +47 -31
- package/dist/index.js +417 -102
- package/dist/plugins/dynamic-preload-metadata.js +2 -4
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/fonts.js +5 -4
- package/dist/plugins/optimize-imports.d.ts +2 -1
- package/dist/plugins/optimize-imports.js +11 -9
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/strip-server-exports.d.ts +9 -7
- package/dist/plugins/strip-server-exports.js +493 -46
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/routing/app-route-graph.d.ts +2 -1
- package/dist/routing/app-route-graph.js +46 -16
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +22 -1
- 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 +20 -11
- package/dist/server/app-browser-entry.js +175 -91
- package/dist/server/app-browser-error.d.ts +10 -6
- package/dist/server/app-browser-error.js +43 -8
- 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 +5 -3
- package/dist/server/app-browser-navigation-controller.js +23 -2
- 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.d.ts +1 -1
- package/dist/server/app-browser-state.js +19 -11
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.d.ts +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 +1 -0
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-optimistic-routing.js +2 -2
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +27 -14
- 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 +62 -1
- package/dist/server/app-page-dispatch.d.ts +26 -0
- package/dist/server/app-page-dispatch.js +149 -92
- package/dist/server/app-page-element-builder.d.ts +1 -0
- package/dist/server/app-page-element-builder.js +5 -2
- package/dist/server/app-page-execution.d.ts +6 -1
- package/dist/server/app-page-execution.js +21 -1
- 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 +12 -1
- package/dist/server/app-page-render.js +42 -4
- package/dist/server/app-page-request.d.ts +2 -0
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +14 -5
- package/dist/server/app-page-stream.d.ts +15 -3
- package/dist/server/app-page-stream.js +11 -5
- package/dist/server/app-pages-bridge.d.ts +23 -1
- package/dist/server/app-pages-bridge.js +26 -17
- 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-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +28 -0
- package/dist/server/app-rsc-handler.js +195 -59
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +8 -2
- 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 +1 -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 +84 -39
- package/dist/server/before-interactive-head.d.ts +17 -0
- package/dist/server/before-interactive-head.js +35 -0
- package/dist/server/cache-control.js +4 -0
- package/dist/server/csp.js +1 -4
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +321 -83
- 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/middleware-matcher.js +12 -3
- package/dist/server/middleware-runtime.d.ts +3 -4
- package/dist/server/middleware-runtime.js +2 -0
- package/dist/server/navigation-planner.d.ts +135 -41
- package/dist/server/navigation-planner.js +138 -0
- package/dist/server/navigation-trace.d.ts +9 -1
- package/dist/server/navigation-trace.js +9 -1
- package/dist/server/operation-token.d.ts +40 -0
- package/dist/server/operation-token.js +85 -0
- package/dist/server/pages-api-route.d.ts +6 -0
- package/dist/server/pages-api-route.js +13 -2
- package/dist/server/pages-asset-tags.d.ts +2 -1
- package/dist/server/pages-asset-tags.js +6 -2
- package/dist/server/pages-data-route.d.ts +9 -2
- package/dist/server/pages-data-route.js +18 -6
- package/dist/server/pages-dev-module-url.d.ts +4 -0
- package/dist/server/pages-dev-module-url.js +15 -0
- package/dist/server/pages-document-initial-props.d.ts +4 -15
- package/dist/server/pages-document-initial-props.js +27 -56
- 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-i18n.js +2 -2
- package/dist/server/pages-node-compat.js +2 -2
- package/dist/server/pages-page-data.d.ts +11 -2
- package/dist/server/pages-page-data.js +207 -34
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +62 -23
- package/dist/server/pages-page-response.d.ts +4 -1
- package/dist/server/pages-page-response.js +11 -8
- package/dist/server/pages-readiness.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +8 -7
- package/dist/server/pages-request-pipeline.js +126 -47
- 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 +3 -1
- package/dist/server/prod-server.js +50 -13
- 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/server/static-file-cache.js +16 -4
- 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/before-interactive-context.d.ts +14 -3
- package/dist/shims/cache-runtime.js +3 -2
- 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/document.d.ts +15 -20
- package/dist/shims/document.js +5 -8
- package/dist/shims/dynamic-preload-chunks.js +6 -4
- package/dist/shims/error-boundary.d.ts +2 -0
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +3 -2
- 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 +3 -1
- package/dist/shims/fetch-cache.js +45 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/headers.js +29 -4
- package/dist/shims/image.js +9 -2
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.js +8 -17
- 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-fetch-dedup.d.ts +6 -7
- package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
- 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 +47 -19
- package/dist/shims/metadata.js +4 -4
- package/dist/shims/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +63 -31
- 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 +18 -3
- package/dist/shims/router.js +512 -142
- package/dist/shims/script.js +8 -4
- package/dist/shims/server.d.ts +16 -1
- package/dist/shims/server.js +44 -12
- package/dist/shims/unified-request-context.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/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/has-trailing-comma.d.ts +24 -0
- package/dist/utils/has-trailing-comma.js +62 -0
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +7 -1
- package/dist/utils/path.js +9 -1
- package/dist/utils/text-stream.d.ts +1 -1
- package/dist/utils/text-stream.js +2 -2
- package/dist/utils/vite-version.d.ts +12 -1
- package/dist/utils/vite-version.js +9 -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,14 +1,15 @@
|
|
|
1
|
+
import { NEVER_CACHE_CONTROL } from "./cache-control.js";
|
|
1
2
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
2
3
|
import "./app-elements.js";
|
|
4
|
+
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
3
5
|
import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
4
6
|
import { ErrorBoundary, GlobalErrorBoundary } from "../shims/error-boundary.js";
|
|
5
7
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
6
8
|
import { MetadataHead, ViewportHead } from "../shims/metadata.js";
|
|
7
9
|
import { resolveAppPageSpecialError } from "./app-page-execution.js";
|
|
8
10
|
import { resolveAppPageHead } from "./app-page-head.js";
|
|
9
|
-
import { createAppPageLayoutEntries } from "./app-page-route-wiring.js";
|
|
11
|
+
import { createAppPageLayoutEntries, createAppPageSourcePage } from "./app-page-route-wiring.js";
|
|
10
12
|
import { buildClientHookErrorMessage } from "../shims/client-hook-error.js";
|
|
11
|
-
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
12
13
|
import { renderAppPageBoundaryResponse, resolveAppPageErrorBoundary, resolveAppPageHttpAccessBoundaryModule, wrapAppPageBoundaryElement } from "./app-page-boundary.js";
|
|
13
14
|
import { createAppPageFontData, renderAppPageHtmlResponse } from "./app-page-stream.js";
|
|
14
15
|
import { Fragment, createElement } from "react";
|
|
@@ -76,12 +77,14 @@ function resolveHttpAccessFallbackHeadLayoutTreePositions(route, layoutModules)
|
|
|
76
77
|
function createAppPageBoundaryRscPayload(options) {
|
|
77
78
|
const routeId = AppElementsWire.encodeRouteId(options.pathname, null);
|
|
78
79
|
const layoutEntries = createAppPageBoundaryLayoutEntries(options.route, options.layoutModules);
|
|
80
|
+
const sourcePageSegments = options.sourcePageSegments ?? options.route?.routeSegments;
|
|
79
81
|
return {
|
|
80
82
|
...AppElementsWire.createMetadataEntries({
|
|
81
83
|
interceptionContext: null,
|
|
82
84
|
layoutIds: layoutEntries.map((entry) => entry.id),
|
|
83
85
|
rootLayoutTreePath: layoutEntries[0]?.treePath ?? null,
|
|
84
|
-
routeId
|
|
86
|
+
routeId,
|
|
87
|
+
sourcePage: sourcePageSegments ? createAppPageSourcePage(sourcePageSegments) : null
|
|
85
88
|
}),
|
|
86
89
|
[routeId]: options.element
|
|
87
90
|
};
|
|
@@ -122,7 +125,8 @@ async function renderAppPageBoundaryElementResponse(options) {
|
|
|
122
125
|
element: options.element,
|
|
123
126
|
layoutModules: options.layoutModules,
|
|
124
127
|
pathname,
|
|
125
|
-
route: options.route
|
|
128
|
+
route: options.route,
|
|
129
|
+
sourcePageSegments: options.sourcePageSegments
|
|
126
130
|
}),
|
|
127
131
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
128
132
|
isRscRequest: options.isRscRequest,
|
|
@@ -261,16 +265,25 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
261
265
|
skipLayoutWrapping: errorBoundary.isGlobalError
|
|
262
266
|
});
|
|
263
267
|
};
|
|
264
|
-
const renderWith = (BoundaryComponent) =>
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
268
|
+
const renderWith = async (BoundaryComponent) => {
|
|
269
|
+
const response = await renderAppPageBoundaryElementResponse({
|
|
270
|
+
...options,
|
|
271
|
+
element: buildElement(BoundaryComponent),
|
|
272
|
+
initialDevServerError: rawError,
|
|
273
|
+
layoutModules,
|
|
274
|
+
navigationParams: matchedParams,
|
|
275
|
+
route: options.route,
|
|
276
|
+
routePattern: options.route?.pattern,
|
|
277
|
+
status: errorBoundary.isGlobalError ? 500 : 200
|
|
278
|
+
});
|
|
279
|
+
if (errorBoundary.isGlobalError) {
|
|
280
|
+
response.headers.set("Cache-Control", NEVER_CACHE_CONTROL);
|
|
281
|
+
response.headers.delete("CDN-Cache-Control");
|
|
282
|
+
response.headers.delete("Cloudflare-CDN-Cache-Control");
|
|
283
|
+
response.headers.delete("Cache-Tag");
|
|
284
|
+
}
|
|
285
|
+
return response;
|
|
286
|
+
};
|
|
274
287
|
try {
|
|
275
288
|
return await renderWith(errorBoundary.component);
|
|
276
289
|
} catch (renderError) {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CacheControlMetadata } from "../shims/cache.js";
|
|
2
|
+
import { NavigationContext } from "../shims/navigation.js";
|
|
3
|
+
import { AppPageFontPreload } from "./app-page-execution.js";
|
|
4
|
+
import { RootParams } from "../shims/root-params.js";
|
|
5
|
+
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
6
|
+
import { createAppPageRenderObservation } from "./app-page-render-observation.js";
|
|
7
|
+
import { ReactNode } from "react";
|
|
8
|
+
|
|
9
|
+
//#region src/server/app-page-cache-render.d.ts
|
|
10
|
+
type AppPageRenderableElement = ReactNode | Record<string, ReactNode>;
|
|
11
|
+
type AppPageCacheRoute = {
|
|
12
|
+
pattern: string;
|
|
13
|
+
routeSegments: readonly string[];
|
|
14
|
+
};
|
|
15
|
+
type RenderAppPageCacheArtifactsOptions = {
|
|
16
|
+
basePath?: string;
|
|
17
|
+
captureRscData: boolean;
|
|
18
|
+
cleanPathname: string;
|
|
19
|
+
clientTraceMetadata?: readonly string[];
|
|
20
|
+
element: AppPageRenderableElement;
|
|
21
|
+
getFontLinks: () => string[];
|
|
22
|
+
getFontPreloads: () => AppPageFontPreload[];
|
|
23
|
+
getFontStyles: () => string[];
|
|
24
|
+
getNavigationContext: () => NavigationContext | null;
|
|
25
|
+
loadSsrHandler: () => Promise<AppPageSsrHandler>;
|
|
26
|
+
mountedSlotsHeader?: string | null;
|
|
27
|
+
navigationParams: Record<string, unknown>;
|
|
28
|
+
onError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;
|
|
29
|
+
reactMaxHeadersLength?: number;
|
|
30
|
+
renderToReadableStream: (element: AppPageRenderableElement, options: {
|
|
31
|
+
onError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;
|
|
32
|
+
}) => ReadableStream<Uint8Array>;
|
|
33
|
+
rootParams?: RootParams;
|
|
34
|
+
route: AppPageCacheRoute;
|
|
35
|
+
waitForAllReady?: boolean;
|
|
36
|
+
};
|
|
37
|
+
type RenderAppPageCacheArtifactsResult = {
|
|
38
|
+
cacheControl?: CacheControlMetadata;
|
|
39
|
+
html: string;
|
|
40
|
+
htmlRenderObservation: ReturnType<typeof createAppPageRenderObservation>;
|
|
41
|
+
rscData?: ArrayBuffer;
|
|
42
|
+
rscRenderObservation?: ReturnType<typeof createAppPageRenderObservation>;
|
|
43
|
+
tags: string[];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Render an App page element to HTML (and optionally its RSC payload) for cache
|
|
47
|
+
* storage. Combines the RSC stream, SSR handler, observation consumption, and
|
|
48
|
+
* cache-tag construction used by both normal ISR revalidation and PPR fallback
|
|
49
|
+
* shell regeneration.
|
|
50
|
+
*/
|
|
51
|
+
declare function renderAppPageCacheArtifacts(options: RenderAppPageCacheArtifactsOptions): Promise<RenderAppPageCacheArtifactsResult>;
|
|
52
|
+
//#endregion
|
|
53
|
+
export { RenderAppPageCacheArtifactsOptions, RenderAppPageCacheArtifactsResult, renderAppPageCacheArtifacts };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { consumeDynamicUsage, consumeInvalidDynamicUsageError } from "../shims/headers.js";
|
|
2
|
+
import { _consumeRequestScopedCacheLife } from "../shims/cache.js";
|
|
3
|
+
import { getCollectedFetchTags } from "../shims/fetch-cache.js";
|
|
4
|
+
import { readStreamAsText } from "../utils/text-stream.js";
|
|
5
|
+
import { teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
6
|
+
import { consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
|
|
7
|
+
import { isAppSsrRenderResult } from "./app-page-stream.js";
|
|
8
|
+
import { buildAppPageTags } from "./implicit-tags.js";
|
|
9
|
+
//#region src/server/app-page-cache-render.ts
|
|
10
|
+
/**
|
|
11
|
+
* Render an App page element to HTML (and optionally its RSC payload) for cache
|
|
12
|
+
* storage. Combines the RSC stream, SSR handler, observation consumption, and
|
|
13
|
+
* cache-tag construction used by both normal ISR revalidation and PPR fallback
|
|
14
|
+
* shell regeneration.
|
|
15
|
+
*/
|
|
16
|
+
async function renderAppPageCacheArtifacts(options) {
|
|
17
|
+
const rscCapture = teeAppPageRscStreamForCapture(options.renderToReadableStream(options.element, { onError: options.onError }), options.captureRscData);
|
|
18
|
+
const capturedRscDataRef = { value: null };
|
|
19
|
+
const htmlResult = await (await options.loadSsrHandler()).handleSsr(rscCapture.ssrStream, options.getNavigationContext(), {
|
|
20
|
+
links: options.getFontLinks(),
|
|
21
|
+
styles: options.getFontStyles(),
|
|
22
|
+
preloads: options.getFontPreloads()
|
|
23
|
+
}, {
|
|
24
|
+
basePath: options.basePath,
|
|
25
|
+
clientTraceMetadata: options.clientTraceMetadata,
|
|
26
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
27
|
+
rootParams: options.rootParams,
|
|
28
|
+
waitForAllReady: options.waitForAllReady,
|
|
29
|
+
...rscCapture.sideStream ? {
|
|
30
|
+
sideStream: rscCapture.sideStream,
|
|
31
|
+
capturedRscDataRef
|
|
32
|
+
} : {}
|
|
33
|
+
});
|
|
34
|
+
const html = await readStreamAsText(isAppSsrRenderResult(htmlResult) ? htmlResult.htmlStream : htmlResult);
|
|
35
|
+
let rscData;
|
|
36
|
+
if (options.captureRscData) {
|
|
37
|
+
const capturedPromise = capturedRscDataRef.value;
|
|
38
|
+
if (!capturedPromise) throw new Error("[vinext] Expected captured RSC data while rendering app page cache artifacts");
|
|
39
|
+
rscData = await capturedPromise;
|
|
40
|
+
}
|
|
41
|
+
const cacheLife = _consumeRequestScopedCacheLife();
|
|
42
|
+
const tags = buildAppPageTags(options.cleanPathname, getCollectedFetchTags(), options.route.routeSegments);
|
|
43
|
+
const observationState = consumeAppPageRenderObservationState();
|
|
44
|
+
consumeInvalidDynamicUsageError();
|
|
45
|
+
consumeDynamicUsage();
|
|
46
|
+
const result = {
|
|
47
|
+
html,
|
|
48
|
+
htmlRenderObservation: createAppPageRenderObservation({
|
|
49
|
+
boundaryOutcome: { kind: "success" },
|
|
50
|
+
cacheability: "public",
|
|
51
|
+
cacheTags: tags,
|
|
52
|
+
cleanPathname: options.cleanPathname,
|
|
53
|
+
completeness: "complete",
|
|
54
|
+
output: createAppPageHtmlOutputScope({
|
|
55
|
+
element: options.element,
|
|
56
|
+
renderEpoch: null,
|
|
57
|
+
rootBoundaryId: null,
|
|
58
|
+
routePattern: options.route.pattern
|
|
59
|
+
}),
|
|
60
|
+
params: options.navigationParams,
|
|
61
|
+
state: observationState
|
|
62
|
+
}),
|
|
63
|
+
tags,
|
|
64
|
+
cacheControl: typeof cacheLife?.revalidate === "number" ? {
|
|
65
|
+
revalidate: cacheLife.revalidate,
|
|
66
|
+
expire: cacheLife.expire
|
|
67
|
+
} : void 0
|
|
68
|
+
};
|
|
69
|
+
if (options.captureRscData) {
|
|
70
|
+
result.rscData = rscData;
|
|
71
|
+
result.rscRenderObservation = createAppPageRenderObservation({
|
|
72
|
+
boundaryOutcome: { kind: "success" },
|
|
73
|
+
cacheability: "public",
|
|
74
|
+
cacheTags: tags,
|
|
75
|
+
cleanPathname: options.cleanPathname,
|
|
76
|
+
completeness: "complete",
|
|
77
|
+
output: createAppPageRscOutputScope({
|
|
78
|
+
element: options.element,
|
|
79
|
+
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
80
|
+
renderEpoch: null,
|
|
81
|
+
rootBoundaryId: null,
|
|
82
|
+
routePattern: options.route.pattern
|
|
83
|
+
}),
|
|
84
|
+
params: options.navigationParams,
|
|
85
|
+
state: observationState
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { renderAppPageCacheArtifacts };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RenderObservation } from "./cache-proof.js";
|
|
2
2
|
import { CacheControlMetadata, CachedAppPageValue } from "../shims/cache.js";
|
|
3
|
+
import { AppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
3
4
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
4
5
|
import { ISRCacheEntry } from "./isr-cache.js";
|
|
5
|
-
import { AppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
6
6
|
|
|
7
7
|
//#region src/server/app-page-cache.d.ts
|
|
8
8
|
type AppPageDebugLogger = (event: string, detail: string) => void;
|
|
@@ -70,6 +70,19 @@ type ReadAppPageCacheResponseOptions = {
|
|
|
70
70
|
renderFreshPageForCache: () => Promise<AppPageCacheRenderResult>;
|
|
71
71
|
scheduleBackgroundRegeneration: AppPageBackgroundRegenerator;
|
|
72
72
|
};
|
|
73
|
+
type ReadAppPageFallbackShellCacheResponseOptions = {
|
|
74
|
+
clearRequestContext: () => void;
|
|
75
|
+
expireSeconds?: number;
|
|
76
|
+
fallbackPathname: string;
|
|
77
|
+
isEdgeRuntime?: boolean;
|
|
78
|
+
isrDebug?: AppPageDebugLogger;
|
|
79
|
+
isrGet: AppPageCacheGetter;
|
|
80
|
+
isrHtmlKey: (pathname: string) => string;
|
|
81
|
+
middlewareHeaders?: Headers | null;
|
|
82
|
+
middlewareStatus?: number | null;
|
|
83
|
+
revalidateSeconds: number;
|
|
84
|
+
rewriteHtml: (html: string) => string;
|
|
85
|
+
};
|
|
73
86
|
type FinalizeAppPageHtmlCacheResponseOptions = {
|
|
74
87
|
capturedDynamicUsageBeforeContextCleanup?: () => boolean;
|
|
75
88
|
capturedRscDataPromise: Promise<ArrayBuffer> | null;
|
|
@@ -113,8 +126,9 @@ type ScheduleAppPageRscCacheWriteOptions = {
|
|
|
113
126
|
declare function buildAppPageCacheTags(pathname: string, extraTags: readonly string[]): string[];
|
|
114
127
|
declare function buildAppPageCachedResponse(cachedValue: CachedAppPageValue, options: BuildAppPageCachedResponseOptions): Response | null;
|
|
115
128
|
declare function readAppPageCacheResponse(options: ReadAppPageCacheResponseOptions): Promise<Response | null>;
|
|
129
|
+
declare function readAppPageFallbackShellCacheResponse(options: ReadAppPageFallbackShellCacheResponseOptions): Promise<Response | null>;
|
|
116
130
|
declare function finalizeAppPageHtmlCacheResponse(response: Response, options: FinalizeAppPageHtmlCacheResponseOptions): Response;
|
|
117
131
|
declare function finalizeAppPageRscCacheResponse(response: Response, options: ScheduleAppPageRscCacheWriteOptions): Response;
|
|
118
132
|
declare function scheduleAppPageRscCacheWrite(options: ScheduleAppPageRscCacheWriteOptions): boolean;
|
|
119
133
|
//#endregion
|
|
120
|
-
export { AppPageCacheOutcomeMetric, buildAppPageCacheTags, buildAppPageCachedResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, readAppPageCacheResponse, scheduleAppPageRscCacheWrite };
|
|
134
|
+
export { AppPageCacheOutcomeMetric, buildAppPageCacheTags, buildAppPageCachedResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, readAppPageCacheResponse, readAppPageFallbackShellCacheResponse, scheduleAppPageRscCacheWrite };
|
|
@@ -10,6 +10,7 @@ import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js
|
|
|
10
10
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
11
11
|
import { hasCompleteNegativeRequestApiProof } from "./cache-proof.js";
|
|
12
12
|
import { createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
13
|
+
import { isAppPprDynamicFallbackShellHtml } from "./app-ppr-fallback-shell.js";
|
|
13
14
|
//#region src/server/app-page-cache.ts
|
|
14
15
|
/**
|
|
15
16
|
* Apply the CDN cache adapter's headers to a freshly-streamed response whose
|
|
@@ -121,6 +122,29 @@ function buildAppPageCachedResponse(cachedValue, options) {
|
|
|
121
122
|
headers: htmlHeaders
|
|
122
123
|
});
|
|
123
124
|
}
|
|
125
|
+
async function serveAppPageCachedHtml(options, transformValue) {
|
|
126
|
+
if (typeof options.cachedValue.html !== "string" || options.cachedValue.html.length === 0) {
|
|
127
|
+
if (options.cached?.isStale) options.scheduleRegeneration();
|
|
128
|
+
options.isrDebug?.(options.emptyDebugMessage, options.pathname);
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const cacheState = options.cached?.isStale ? "STALE" : "HIT";
|
|
132
|
+
if (options.cached?.isStale) options.scheduleRegeneration();
|
|
133
|
+
const response = buildAppPageCachedResponse(transformValue ? transformValue(options.cachedValue) : options.cachedValue, {
|
|
134
|
+
cacheState,
|
|
135
|
+
cacheControl: options.cached?.value.cacheControl,
|
|
136
|
+
expireSeconds: options.expireSeconds,
|
|
137
|
+
isEdgeRuntime: options.isEdgeRuntime,
|
|
138
|
+
isRscRequest: false,
|
|
139
|
+
middlewareHeaders: options.middlewareHeaders,
|
|
140
|
+
middlewareStatus: options.middlewareStatus,
|
|
141
|
+
revalidateSeconds: options.revalidateSeconds
|
|
142
|
+
});
|
|
143
|
+
if (!response) return null;
|
|
144
|
+
options.isrDebug?.(`${cacheState} (${options.stateDebugLabel})`, options.pathname);
|
|
145
|
+
options.clearRequestContext();
|
|
146
|
+
return response;
|
|
147
|
+
}
|
|
124
148
|
async function readAppPageCacheResponse(options) {
|
|
125
149
|
const isrKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode, options.interceptionContext) : options.isrHtmlKey(options.cleanPathname);
|
|
126
150
|
const artifact = options.isRscRequest ? "rsc" : "html";
|
|
@@ -239,6 +263,43 @@ async function readAppPageCacheResponse(options) {
|
|
|
239
263
|
}
|
|
240
264
|
return null;
|
|
241
265
|
}
|
|
266
|
+
async function readAppPageFallbackShellCacheResponse(options) {
|
|
267
|
+
const isrKey = options.isrHtmlKey(options.fallbackPathname);
|
|
268
|
+
try {
|
|
269
|
+
const cached = await options.isrGet(isrKey);
|
|
270
|
+
const cachedValue = getCachedAppPageValue(cached);
|
|
271
|
+
if (!cachedValue) {
|
|
272
|
+
options.isrDebug?.("MISS (fallback shell)", options.fallbackPathname);
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
if (isAppPprDynamicFallbackShellHtml(cachedValue.html)) {
|
|
276
|
+
options.isrDebug?.("MISS (dynamic fallback shell requires resume)", options.fallbackPathname);
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
return await serveAppPageCachedHtml({
|
|
280
|
+
cached,
|
|
281
|
+
cachedValue,
|
|
282
|
+
clearRequestContext: options.clearRequestContext,
|
|
283
|
+
emptyDebugMessage: "MISS (empty fallback shell)",
|
|
284
|
+
expireSeconds: options.expireSeconds,
|
|
285
|
+
isEdgeRuntime: options.isEdgeRuntime,
|
|
286
|
+
isrDebug: options.isrDebug,
|
|
287
|
+
middlewareHeaders: options.middlewareHeaders,
|
|
288
|
+
middlewareStatus: options.middlewareStatus,
|
|
289
|
+
pathname: options.fallbackPathname,
|
|
290
|
+
revalidateSeconds: options.revalidateSeconds,
|
|
291
|
+
scheduleRegeneration() {},
|
|
292
|
+
stateDebugLabel: "fallback shell"
|
|
293
|
+
}, (value) => ({
|
|
294
|
+
...value,
|
|
295
|
+
html: options.rewriteHtml(value.html)
|
|
296
|
+
}));
|
|
297
|
+
} catch (isrReadError) {
|
|
298
|
+
options.isrDebug?.("MISS (fallback shell read error)", options.fallbackPathname);
|
|
299
|
+
console.error("[vinext] ISR fallback shell cache read error:", isrReadError);
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
242
303
|
function finalizeAppPageHtmlCacheResponse(response, options) {
|
|
243
304
|
if (!response.body) return response;
|
|
244
305
|
const [streamForClient, streamForCache] = response.body.tee();
|
|
@@ -334,4 +395,4 @@ function scheduleAppPageRscCacheWrite(options) {
|
|
|
334
395
|
return true;
|
|
335
396
|
}
|
|
336
397
|
//#endregion
|
|
337
|
-
export { buildAppPageCacheTags, buildAppPageCachedResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, readAppPageCacheResponse, scheduleAppPageRscCacheWrite };
|
|
398
|
+
export { buildAppPageCacheTags, buildAppPageCachedResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, readAppPageCacheResponse, readAppPageFallbackShellCacheResponse, scheduleAppPageRscCacheWrite };
|
|
@@ -11,6 +11,7 @@ import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
|
11
11
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
12
12
|
import { ISRCacheEntry } from "./isr-cache.js";
|
|
13
13
|
import { FetchCacheMode } from "../shims/fetch-cache.js";
|
|
14
|
+
import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
|
|
14
15
|
import { ValidateAppPageDynamicParamsOptions } from "./app-page-request.js";
|
|
15
16
|
import { ReactNode } from "react";
|
|
16
17
|
import { ReactFormState } from "react-dom/client";
|
|
@@ -36,6 +37,7 @@ type AppPageDispatchIntercept<TPage = unknown> = {
|
|
|
36
37
|
slotId?: string | null;
|
|
37
38
|
slotKey: string;
|
|
38
39
|
sourceRouteIndex: number;
|
|
40
|
+
sourcePageSegments?: readonly string[] | null;
|
|
39
41
|
};
|
|
40
42
|
type AppPageDispatchInterceptOptions<TPage = unknown> = {
|
|
41
43
|
interceptionContext: string | null;
|
|
@@ -45,6 +47,7 @@ type AppPageDispatchInterceptOptions<TPage = unknown> = {
|
|
|
45
47
|
interceptSlotId?: string | null;
|
|
46
48
|
interceptSlotKey: string;
|
|
47
49
|
interceptSourceMatchedUrl?: string | null;
|
|
50
|
+
interceptSourcePageSegments?: readonly string[] | null;
|
|
48
51
|
};
|
|
49
52
|
type AppPageModule = {
|
|
50
53
|
default?: unknown;
|
|
@@ -120,6 +123,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
120
123
|
getNavigationContext: () => NavigationContext | null;
|
|
121
124
|
getSourceRoute: (sourceRouteIndex: number) => TRoute | undefined;
|
|
122
125
|
hasGenerateStaticParams: boolean;
|
|
126
|
+
hasCustomGlobalError?: boolean;
|
|
123
127
|
hasPageDefaultExport: boolean;
|
|
124
128
|
hasPageModule: boolean;
|
|
125
129
|
handlerStart: number;
|
|
@@ -138,6 +142,20 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
138
142
|
middlewareContext: AppPageMiddlewareContext;
|
|
139
143
|
mountedSlotsHeader?: string | null;
|
|
140
144
|
params: AppPageParams;
|
|
145
|
+
pprFallbackCacheShells?: readonly AppPagePprFallbackCacheShell[] | null;
|
|
146
|
+
pprFallbackShell?: {
|
|
147
|
+
fallbackParamNames: readonly string[];
|
|
148
|
+
routePattern: string;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Set of concrete URL paths that were pre-rendered at build time for this
|
|
152
|
+
* route. When the exact cache entry for a known pregenerated path is absent
|
|
153
|
+
* (evicted, stale-empty, cold start, read error), the fallback shell must
|
|
154
|
+
* NOT be served — the route is a valid generated route whose cache merely
|
|
155
|
+
* has a transient gap. Falls through to a fresh render instead.
|
|
156
|
+
*/
|
|
157
|
+
renderedConcreteUrlPaths?: ReadonlySet<string>;
|
|
158
|
+
skipStaticParamsValidation?: boolean;
|
|
141
159
|
staticParamsValidationParams?: AppPageParams;
|
|
142
160
|
rootParams?: RootParams;
|
|
143
161
|
probeLayoutAt: (layoutIndex: number, layoutParamAccess?: AppLayoutParamAccessTracker) => unknown;
|
|
@@ -152,10 +170,18 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
152
170
|
}, middlewareContext: AppPageMiddlewareContext | null) => Promise<Response | null>;
|
|
153
171
|
renderToReadableStream: (element: AppPageRenderableElement, options: {
|
|
154
172
|
onError: AppPageBoundaryOnError;
|
|
173
|
+
signal?: AbortSignal;
|
|
155
174
|
}) => ReadableStream<Uint8Array>;
|
|
175
|
+
prerenderToReadableStream?: (element: AppPageRenderableElement, options: {
|
|
176
|
+
onError: AppPageBoundaryOnError;
|
|
177
|
+
signal?: AbortSignal;
|
|
178
|
+
}) => Promise<{
|
|
179
|
+
prelude: ReadableStream<Uint8Array>;
|
|
180
|
+
}>;
|
|
156
181
|
request: Request;
|
|
157
182
|
revalidateSeconds: number | null;
|
|
158
183
|
resolveRouteFetchCacheMode?: (route: TRoute) => FetchCacheMode | null;
|
|
184
|
+
resolveRouteDynamicConfig?: (route: TRoute) => string | null | undefined;
|
|
159
185
|
rootForbiddenModule?: AppPageModule | null;
|
|
160
186
|
rootNotFoundModule?: AppPageModule | null;
|
|
161
187
|
rootUnauthorizedModule?: AppPageModule | null;
|