vinext 0.1.2 → 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/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/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/vinext-next-data.d.ts +18 -1
- 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.js +73 -14
- package/dist/config/next-config.d.ts +46 -4
- package/dist/config/next-config.js +147 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +180 -99
- 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 +64 -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 +53 -8
- package/dist/entries/pages-server-entry.js +41 -5
- package/dist/index.js +200 -62
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- 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/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 +44 -14
- 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 +19 -10
- package/dist/server/app-browser-entry.js +167 -90
- 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 +4 -2
- 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-stream.js +86 -43
- 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 +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-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 +154 -54
- 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 +1 -0
- package/dist/server/app-server-action-execution.js +42 -13
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +83 -10
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +244 -51
- 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/navigation-planner.d.ts +133 -30
- package/dist/server/navigation-planner.js +114 -0
- package/dist/server/navigation-trace.d.ts +8 -1
- package/dist/server/navigation-trace.js +8 -1
- 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 +8 -1
- package/dist/server/pages-data-route.js +11 -2
- 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.js +2 -2
- package/dist/server/pages-page-data.d.ts +11 -2
- package/dist/server/pages-page-data.js +204 -33
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +59 -22
- package/dist/server/pages-page-response.d.ts +2 -1
- package/dist/server/pages-page-response.js +7 -4
- package/dist/server/pages-request-pipeline.d.ts +1 -0
- package/dist/server/pages-request-pipeline.js +73 -36
- 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.js +9 -3
- 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 +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/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/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-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/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +61 -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 +13 -2
- package/dist/shims/router.js +419 -128
- 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/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/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
|
@@ -88,8 +88,7 @@ function resolveAppPageSegmentConfig(options) {
|
|
|
88
88
|
}
|
|
89
89
|
if (config.dynamicConfig === "force-dynamic") config.revalidateSeconds = 0;
|
|
90
90
|
if (config.fetchCache === void 0) {
|
|
91
|
-
if (config.dynamicConfig === "
|
|
92
|
-
else if (config.dynamicConfig === "error") config.fetchCache = "only-cache";
|
|
91
|
+
if (config.dynamicConfig === "error") config.fetchCache = "only-cache";
|
|
93
92
|
}
|
|
94
93
|
if (config.dynamicParamsConfig === void 0 && (config.dynamicConfig === "error" || config.dynamicConfig === "force-static")) config.dynamicParamsConfig = false;
|
|
95
94
|
return config;
|
|
@@ -97,8 +96,18 @@ function resolveAppPageSegmentConfig(options) {
|
|
|
97
96
|
function resolveAppPageFetchCacheMode(options) {
|
|
98
97
|
return resolveAppPageSegmentConfig(options).fetchCache ?? null;
|
|
99
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Resolve the `fetchCache` segment config exported by a route handler module.
|
|
101
|
+
*
|
|
102
|
+
* Route handlers have no layout chain, so the module's own export applies
|
|
103
|
+
* directly. Mirrors upstream's app-route module, which copies
|
|
104
|
+
* `userland.fetchCache` into the work store before invoking the handler.
|
|
105
|
+
*/
|
|
106
|
+
function resolveAppRouteHandlerFetchCacheMode(handler) {
|
|
107
|
+
return isRouteSegmentFetchCache(handler.fetchCache) ? handler.fetchCache : null;
|
|
108
|
+
}
|
|
100
109
|
function isEdgeRuntime(runtime) {
|
|
101
110
|
return isEdgeApiRuntime(runtime);
|
|
102
111
|
}
|
|
103
112
|
//#endregion
|
|
104
|
-
export { isEdgeRuntime, resolveAppPageFetchCacheMode, resolveAppPageSegmentConfig };
|
|
113
|
+
export { isEdgeRuntime, resolveAppPageFetchCacheMode, resolveAppPageSegmentConfig, resolveAppRouteHandlerFetchCacheMode };
|
|
@@ -173,6 +173,7 @@ type HandleServerActionRscRequestOptions<TElement, TRoute extends AppServerActio
|
|
|
173
173
|
renderToReadableStream: (model: AppServerActionRscModel<TElement>, options: RenderServerActionRscStreamOptions<TTemporaryReferences>) => BodyInit | null | Promise<BodyInit | null>;
|
|
174
174
|
reportRequestError: AppServerActionErrorReporter;
|
|
175
175
|
resolveRouteFetchCacheMode?: (route: TRoute) => FetchCacheMode | null;
|
|
176
|
+
resolveRouteDynamicConfig?: (route: TRoute) => string | null | undefined;
|
|
176
177
|
resolveRouteRuntime?: (route: TRoute) => AppServerActionRouteRuntime;
|
|
177
178
|
request: Request;
|
|
178
179
|
sanitizeErrorForClient: (error: unknown) => unknown;
|
|
@@ -7,7 +7,7 @@ import { validateCsrfOrigin, validateServerActionPayload } from "./request-pipel
|
|
|
7
7
|
import { headersContextFromRequest, setHeadersContext } from "../shims/headers.js";
|
|
8
8
|
import { getAndClearActionRevalidationKind } from "../shims/cache.js";
|
|
9
9
|
import { APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI } from "./app-rsc-render-mode.js";
|
|
10
|
-
import { setCurrentFetchCacheMode, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
10
|
+
import { setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
11
11
|
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
12
12
|
import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
|
|
13
13
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
@@ -15,9 +15,9 @@ import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
|
15
15
|
import { getNextErrorDigest, parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
16
16
|
import { createServerActionNotFoundResponse, getServerActionNotFoundMessage, isServerActionNotFoundError } from "./server-action-not-found.js";
|
|
17
17
|
import { deferUntilStreamConsumed } from "./app-page-stream.js";
|
|
18
|
+
import { buildAppPageTags } from "./implicit-tags.js";
|
|
18
19
|
import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
|
|
19
20
|
import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
|
|
20
|
-
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
21
21
|
import { getSetCookieName } from "./cookie-utils.js";
|
|
22
22
|
//#region src/server/app-server-action-execution.ts
|
|
23
23
|
/**
|
|
@@ -46,6 +46,10 @@ function resolveActionRevalidationKind(hasModifiedCookies) {
|
|
|
46
46
|
if (hasModifiedCookies) return ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC;
|
|
47
47
|
return revalidationKind;
|
|
48
48
|
}
|
|
49
|
+
function clearRejectedActionSideEffects(getAndClearPendingCookies) {
|
|
50
|
+
getAndClearPendingCookies();
|
|
51
|
+
getAndClearActionRevalidationKind();
|
|
52
|
+
}
|
|
49
53
|
function cloneActionRedirectHeaders(requestHeaders) {
|
|
50
54
|
const headers = new Headers(requestHeaders);
|
|
51
55
|
for (const header of ACTION_REDIRECT_RENDER_STRIPPED_HEADERS) headers.delete(header);
|
|
@@ -233,7 +237,7 @@ function applyActionRedirectBasePath(url, basePath) {
|
|
|
233
237
|
return `${addBasePathToPathname(pathname, basePath)}${suffix}`;
|
|
234
238
|
}
|
|
235
239
|
function buildServerActionPageTags(route, pathname) {
|
|
236
|
-
return
|
|
240
|
+
return buildAppPageTags(pathname, [], route.routeSegments ?? []);
|
|
237
241
|
}
|
|
238
242
|
function resolveInternalActionRedirectTarget(redirectUrl, requestUrl, basePath) {
|
|
239
243
|
if (isExternalUrl(redirectUrl)) {
|
|
@@ -331,6 +335,7 @@ async function handleProgressiveServerActionRequest(options) {
|
|
|
331
335
|
}
|
|
332
336
|
const payloadResponse = await validateServerActionPayload(body);
|
|
333
337
|
if (payloadResponse) {
|
|
338
|
+
clearRejectedActionSideEffects(options.getAndClearPendingCookies);
|
|
334
339
|
options.clearRequestContext();
|
|
335
340
|
return payloadResponse;
|
|
336
341
|
}
|
|
@@ -482,6 +487,24 @@ async function handleServerActionRscRequest(options) {
|
|
|
482
487
|
if (csrfResponse) return csrfResponse;
|
|
483
488
|
if (parseInt(options.request.headers.get("content-length") || "0", 10) > options.maxActionBodySize) return renderFetchActionBodyExceededResponse(options);
|
|
484
489
|
try {
|
|
490
|
+
let action;
|
|
491
|
+
if (options.contentType.startsWith("multipart/form-data")) {
|
|
492
|
+
let loadedAction;
|
|
493
|
+
try {
|
|
494
|
+
loadedAction = await options.loadServerAction(options.actionId);
|
|
495
|
+
} catch (error) {
|
|
496
|
+
if (isServerActionNotFoundError(error, options.actionId)) return createActionNotFoundResponse(options.actionId, {
|
|
497
|
+
clearRequestContext: options.clearRequestContext,
|
|
498
|
+
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
499
|
+
});
|
|
500
|
+
throw error;
|
|
501
|
+
}
|
|
502
|
+
if (!isAppServerActionFunction(loadedAction)) return createActionNotFoundResponse(options.actionId, {
|
|
503
|
+
clearRequestContext: options.clearRequestContext,
|
|
504
|
+
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
505
|
+
});
|
|
506
|
+
action = loadedAction;
|
|
507
|
+
}
|
|
485
508
|
let body;
|
|
486
509
|
try {
|
|
487
510
|
body = options.contentType.startsWith("multipart/form-data") ? await options.readFormDataWithLimit(options.request, options.maxActionBodySize) : await options.readBodyWithLimit(options.request, options.maxActionBodySize);
|
|
@@ -491,23 +514,27 @@ async function handleServerActionRscRequest(options) {
|
|
|
491
514
|
}
|
|
492
515
|
const payloadResponse = await validateServerActionPayload(body);
|
|
493
516
|
if (payloadResponse) {
|
|
517
|
+
clearRejectedActionSideEffects(options.getAndClearPendingCookies);
|
|
494
518
|
options.clearRequestContext();
|
|
495
519
|
return payloadResponse;
|
|
496
520
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
521
|
+
if (action === void 0) {
|
|
522
|
+
let loadedAction;
|
|
523
|
+
try {
|
|
524
|
+
loadedAction = await options.loadServerAction(options.actionId);
|
|
525
|
+
} catch (error) {
|
|
526
|
+
if (isServerActionNotFoundError(error, options.actionId)) return createActionNotFoundResponse(options.actionId, {
|
|
527
|
+
clearRequestContext: options.clearRequestContext,
|
|
528
|
+
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
529
|
+
});
|
|
530
|
+
throw error;
|
|
531
|
+
}
|
|
532
|
+
if (!isAppServerActionFunction(loadedAction)) return createActionNotFoundResponse(options.actionId, {
|
|
502
533
|
clearRequestContext: options.clearRequestContext,
|
|
503
534
|
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
504
535
|
});
|
|
505
|
-
|
|
536
|
+
action = loadedAction;
|
|
506
537
|
}
|
|
507
|
-
if (!isAppServerActionFunction(action)) return createActionNotFoundResponse(options.actionId, {
|
|
508
|
-
clearRequestContext: options.clearRequestContext,
|
|
509
|
-
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
510
|
-
});
|
|
511
538
|
const temporaryReferences = options.createTemporaryReferenceSet();
|
|
512
539
|
const args = await options.decodeReply(body, { temporaryReferences });
|
|
513
540
|
let returnValue;
|
|
@@ -599,6 +626,7 @@ async function handleServerActionRscRequest(options) {
|
|
|
599
626
|
params: redirectNavigationParams
|
|
600
627
|
});
|
|
601
628
|
setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(targetMatch.route) ?? null);
|
|
629
|
+
setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(targetMatch.route) === "force-dynamic");
|
|
602
630
|
setCurrentFetchSoftTags(buildServerActionPageTags(targetMatch.route, targetPathname));
|
|
603
631
|
const element = options.buildPageElement({
|
|
604
632
|
cleanPathname: targetPathname,
|
|
@@ -677,6 +705,7 @@ async function handleServerActionRscRequest(options) {
|
|
|
677
705
|
});
|
|
678
706
|
await options.ensureRouteLoaded?.(actionRerenderTarget.route);
|
|
679
707
|
setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(actionRerenderTarget.route) ?? null);
|
|
708
|
+
setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(actionRerenderTarget.route) === "force-dynamic");
|
|
680
709
|
setCurrentFetchSoftTags(buildServerActionPageTags(actionRerenderTarget.route, options.cleanPathname));
|
|
681
710
|
element = options.buildPageElement({
|
|
682
711
|
cleanPathname: options.cleanPathname,
|
|
@@ -22,6 +22,7 @@ declare function handleSsr(rscStream: ReadableStream<Uint8Array>, navContext: Na
|
|
|
22
22
|
capturedRscDataRef?: {
|
|
23
23
|
value: Promise<ArrayBuffer> | null;
|
|
24
24
|
};
|
|
25
|
+
pprFallbackShellSignal?: AbortSignal;
|
|
25
26
|
formState?: ReactFormState | null;
|
|
26
27
|
basePath?: string;
|
|
27
28
|
/**
|
|
@@ -42,6 +43,7 @@ declare function handleSsr(rscStream: ReadableStream<Uint8Array>, navContext: Na
|
|
|
42
43
|
* to resolve before returning the HTML stream. Used for static prerender
|
|
43
44
|
* and ISR cache writes to avoid caching fallback content. */
|
|
44
45
|
waitForAllReady?: boolean;
|
|
46
|
+
fallbackToErrorDocumentOnShellError?: boolean;
|
|
45
47
|
}): Promise<AppSsrRenderResult>;
|
|
46
48
|
declare const _default: {
|
|
47
49
|
fetch(request: Request): Promise<Response>;
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import "./server-globals.js";
|
|
2
2
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
3
3
|
import { isOpenRedirectShaped } from "./request-pipeline.js";
|
|
4
|
+
import { isPprFallbackShellAbortError } from "../shims/ppr-fallback-shell.js";
|
|
4
5
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
5
6
|
import "./app-elements.js";
|
|
6
7
|
import { AppRouterContext } from "../shims/internal/app-router-context.js";
|
|
8
|
+
import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
7
9
|
import { ServerInsertedHTMLContext, appRouterInstance, clearServerInsertedHTML, getBfcacheIdMapContext, renderServerInsertedHTML, setNavigationContext, useServerInsertedHTML } from "../shims/navigation.js";
|
|
8
10
|
import { runWithNavigationContext } from "../shims/navigation-state.js";
|
|
9
11
|
import { withScriptNonce } from "../shims/script-nonce-context.js";
|
|
10
12
|
import { createInlineScriptTag, createNonceAttribute, escapeHtmlAttr, safeJsonStringify } from "./html.js";
|
|
11
13
|
import { getClientTraceMetadataHTML } from "./client-trace-metadata.js";
|
|
14
|
+
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
12
15
|
import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
|
|
13
16
|
import { createSsrErrorMetaRenderer } from "./app-ssr-error-meta.js";
|
|
14
17
|
import { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform } from "./app-ssr-stream.js";
|
|
18
|
+
import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
|
|
19
|
+
import { runWithRootParamsScope } from "../shims/root-params.js";
|
|
15
20
|
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-browser-state.js";
|
|
16
21
|
import { RSC_FORM_STATE_GLOBAL } from "./app-browser-hydration.js";
|
|
17
22
|
import { createClientReferencePreloader } from "./app-client-reference-preloader.js";
|
|
18
23
|
import { deferUntilStreamConsumed } from "./app-page-stream.js";
|
|
19
|
-
import { runWithRootParamsScope } from "../shims/root-params.js";
|
|
20
|
-
import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
|
|
21
24
|
import { createInitialDevServerErrorScript } from "./dev-initial-server-error.js";
|
|
22
25
|
import { Fragment, createElement, use } from "react";
|
|
23
26
|
import { renderToReadableStream, renderToStaticMarkup } from "react-dom/server.edge";
|
|
@@ -31,6 +34,50 @@ import clientReferences from "virtual:vite-rsc/client-references";
|
|
|
31
34
|
* the response-layer combine cap.
|
|
32
35
|
*/
|
|
33
36
|
const DEFAULT_REACT_MAX_HEADERS_LENGTH = 6e3;
|
|
37
|
+
function isReactDevelopmentRuntime() {
|
|
38
|
+
if (process.env.NODE_ENV === "production") return false;
|
|
39
|
+
if (process.env.NODE_ENV === "development") return true;
|
|
40
|
+
return Function.prototype.toString.call(createElement).includes("getOwner");
|
|
41
|
+
}
|
|
42
|
+
function isStaticPrerenderModule(value) {
|
|
43
|
+
return typeof value === "object" && value !== null && "prerender" in value && typeof value.prerender === "function";
|
|
44
|
+
}
|
|
45
|
+
async function loadStaticPrerender() {
|
|
46
|
+
const staticRenderer = await import("react-dom/static.edge");
|
|
47
|
+
if (isStaticPrerenderModule(staticRenderer)) return staticRenderer.prerender;
|
|
48
|
+
if (isReactDevelopmentRuntime()) try {
|
|
49
|
+
const [{ createRequire }, path] = await Promise.all([import("node:module"), import("node:path")]);
|
|
50
|
+
const reactDomPackageJson = createRequire(import.meta.url).resolve("react-dom/package.json");
|
|
51
|
+
const reactDomDir = path.dirname(reactDomPackageJson);
|
|
52
|
+
const devRenderer = await import(path.join(reactDomDir, "cjs/react-dom-server.edge.development.js"));
|
|
53
|
+
if (isStaticPrerenderModule(devRenderer)) return devRenderer.prerender;
|
|
54
|
+
const devRendererDefault = typeof devRenderer === "object" && devRenderer !== null && "default" in devRenderer && devRenderer.default;
|
|
55
|
+
if (isStaticPrerenderModule(devRendererDefault)) return devRendererDefault.prerender;
|
|
56
|
+
throw new Error("react-dom development renderer did not expose prerender().");
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new Error("[vinext] Failed to load React static development renderer.", { cause: error });
|
|
59
|
+
}
|
|
60
|
+
throw new Error("[vinext] react-dom/static.edge did not expose prerender().");
|
|
61
|
+
}
|
|
62
|
+
function createUtf8Stream(html) {
|
|
63
|
+
const encoder = new TextEncoder();
|
|
64
|
+
return new ReadableStream({ start(controller) {
|
|
65
|
+
controller.enqueue(encoder.encode(html));
|
|
66
|
+
controller.close();
|
|
67
|
+
} });
|
|
68
|
+
}
|
|
69
|
+
function buildBootstrapModuleScript(bootstrapModuleUrl, nonce) {
|
|
70
|
+
if (!bootstrapModuleUrl) return "";
|
|
71
|
+
return `<script type="module"${createNonceAttribute(nonce)} src="` + escapeHtmlAttr(bootstrapModuleUrl) + "\" id=\"_R_\" async=\"\"><\/script>";
|
|
72
|
+
}
|
|
73
|
+
function renderSsrErrorDocumentShell(bootstrapModuleUrl, nonce) {
|
|
74
|
+
const html = renderToStaticMarkup(createElement(DefaultGlobalError, { error: null })).replace("<style>", "<style data-vinext-error-shell-style=\"\">");
|
|
75
|
+
const bootstrapScript = buildBootstrapModuleScript(bootstrapModuleUrl, nonce);
|
|
76
|
+
if (!bootstrapScript) return createUtf8Stream(`<!DOCTYPE html>${html}`);
|
|
77
|
+
const documentClose = "</body></html>";
|
|
78
|
+
if (!html.endsWith(documentClose)) return createUtf8Stream(`<!DOCTYPE html>${html}${bootstrapScript}`);
|
|
79
|
+
return createUtf8Stream(`<!DOCTYPE html>${html.slice(0, -14)}${bootstrapScript}${documentClose}`);
|
|
80
|
+
}
|
|
34
81
|
const clientReferencePreloader = createClientReferencePreloader({
|
|
35
82
|
getReferences() {
|
|
36
83
|
return clientReferences;
|
|
@@ -94,8 +141,8 @@ function renderFontHtml(fontData, nonce, options = {}) {
|
|
|
94
141
|
let fontHTML = "";
|
|
95
142
|
const nonceAttr = createNonceAttribute(nonce);
|
|
96
143
|
const includeStyles = options.includeStyles ?? true;
|
|
97
|
-
for (const url of fontData.links ?? []) fontHTML += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(url)}" />\n`;
|
|
98
|
-
for (const preload of fontData.preloads ?? []) fontHTML += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(preload.href)}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n`;
|
|
144
|
+
for (const url of fontData.links ?? []) fontHTML += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(url))}" />\n`;
|
|
145
|
+
for (const preload of fontData.preloads ?? []) fontHTML += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(preload.href))}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n`;
|
|
99
146
|
if (includeStyles && fontData.styles && fontData.styles.length > 0) fontHTML += `<style data-vinext-fonts${nonceAttr}>${fontData.styles.join("\n")}</style>\n`;
|
|
100
147
|
return fontHTML;
|
|
101
148
|
}
|
|
@@ -182,24 +229,50 @@ async function handleSsr(rscStream, navContext, fontData, options) {
|
|
|
182
229
|
const ssrRoot = withScriptNonce(createElement(BeforeInteractiveContext.Provider, { value: registerBeforeInteractiveInlineScript }, ssrTree), options?.scriptNonce);
|
|
183
230
|
const bootstrapModuleUrl = extractBootstrapModuleUrl(await import.meta.viteRsc.loadBootstrapScriptContent("index"));
|
|
184
231
|
const errorMetaRenderer = createSsrErrorMetaRenderer({ basePath: options?.basePath });
|
|
232
|
+
const pprFallbackShellSignal = options?.pprFallbackShellSignal;
|
|
185
233
|
let reactLinkHeader = "";
|
|
186
234
|
const maxHeadersLength = options?.reactMaxHeadersLength ?? DEFAULT_REACT_MAX_HEADERS_LENGTH;
|
|
187
235
|
const captureHeaders = maxHeadersLength > 0;
|
|
188
|
-
const
|
|
236
|
+
const renderOptions = {
|
|
237
|
+
bootstrapModules: bootstrapModuleUrl ? [bootstrapModuleUrl] : void 0,
|
|
238
|
+
formState: options?.formState ?? null,
|
|
239
|
+
nonce: options?.scriptNonce,
|
|
189
240
|
onHeaders: captureHeaders ? (headers) => {
|
|
190
241
|
const link = headers.get("Link");
|
|
191
242
|
if (link) reactLinkHeader = link;
|
|
192
243
|
} : void 0,
|
|
193
244
|
maxHeadersLength: captureHeaders ? maxHeadersLength : void 0,
|
|
194
|
-
bootstrapModules: bootstrapModuleUrl ? [bootstrapModuleUrl] : void 0,
|
|
195
|
-
formState: options?.formState ?? null,
|
|
196
|
-
nonce: options?.scriptNonce,
|
|
197
245
|
onError(error) {
|
|
246
|
+
if (pprFallbackShellSignal && isPprFallbackShellAbortError(error)) return;
|
|
198
247
|
errorMetaRenderer.capture(error);
|
|
199
248
|
if (error && typeof error === "object" && "digest" in error) return String(error.digest);
|
|
200
249
|
if (process.env.NODE_ENV === "production" && error) return ssrErrorDigest(getErrorMessage(error) + (error instanceof Error ? error.stack ?? "" : ""));
|
|
201
250
|
}
|
|
202
|
-
}
|
|
251
|
+
};
|
|
252
|
+
let htmlStream;
|
|
253
|
+
let shellErrorRecovered = false;
|
|
254
|
+
if (pprFallbackShellSignal) {
|
|
255
|
+
const prerender = await loadStaticPrerender();
|
|
256
|
+
const htmlAbortController = new AbortController();
|
|
257
|
+
const pendingHtml = prerender(ssrRoot, {
|
|
258
|
+
...renderOptions,
|
|
259
|
+
signal: htmlAbortController.signal
|
|
260
|
+
});
|
|
261
|
+
setTimeout(() => htmlAbortController.abort(), 0);
|
|
262
|
+
htmlStream = (await pendingHtml).prelude;
|
|
263
|
+
} else {
|
|
264
|
+
let streamingHtmlStream;
|
|
265
|
+
try {
|
|
266
|
+
streamingHtmlStream = await renderToReadableStream(ssrRoot, { ...renderOptions });
|
|
267
|
+
if (options?.waitForAllReady === true) await streamingHtmlStream.allReady;
|
|
268
|
+
htmlStream = streamingHtmlStream;
|
|
269
|
+
} catch (error) {
|
|
270
|
+
streamingHtmlStream?.cancel().catch(() => {});
|
|
271
|
+
if (options?.fallbackToErrorDocumentOnShellError !== true || options?.waitForAllReady === true || typeof error?.digest === "string") throw error;
|
|
272
|
+
shellErrorRecovered = true;
|
|
273
|
+
htmlStream = renderSsrErrorDocumentShell(bootstrapModuleUrl, options?.scriptNonce);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
203
276
|
const inlineCssManifest = globalThis.__VINEXT_INLINE_CSS__;
|
|
204
277
|
const fontStyles = fontData?.styles ?? [];
|
|
205
278
|
const mergeFontStylesIntoInlineCss = fontStyles.length > 0 && hasInlineCssManifest(inlineCssManifest);
|
|
@@ -221,11 +294,11 @@ async function handleSsr(rscStream, navContext, fontData, options) {
|
|
|
221
294
|
return buildHeadInjectionHtml(ssrNavigationContext, bootstrapModuleUrl, options?.formState ?? null, insertedHTML + errorMetaHTML + getTraceMetaHTML() + initialDevServerErrorHTML, fontHTML, options?.scriptNonce);
|
|
222
295
|
};
|
|
223
296
|
const getBeforeInteractiveHeadHTML = () => renderBeforeInteractiveInlineScripts(beforeInteractiveInlineScripts);
|
|
224
|
-
if (options?.waitForAllReady === true) await htmlStream.allReady;
|
|
225
297
|
return {
|
|
226
298
|
htmlStream: deferUntilStreamConsumed(htmlStream.pipeThrough(createTickBufferedTransform(rscEmbed, getInsertedHTML, getBeforeInteractiveHeadHTML, inlineCssManifest, inlineCssFontStyles, inlineCssFontStyleFallbackHTML, options?.scriptNonce)), cleanup),
|
|
227
299
|
metadataReady: Promise.resolve(),
|
|
228
300
|
capturedRscData: options?.capturedRscDataRef?.value ?? null,
|
|
301
|
+
shellErrorRecovered,
|
|
229
302
|
linkHeader: reactLinkHeader
|
|
230
303
|
};
|
|
231
304
|
} catch (error) {
|
|
@@ -19,6 +19,10 @@ function applyCdnResponseHeaders(headers, input) {
|
|
|
19
19
|
headers.delete("Cache-Control");
|
|
20
20
|
const map = getCdnCacheAdapter().buildResponseHeaders(input);
|
|
21
21
|
for (const [name, value] of Object.entries(map)) {
|
|
22
|
+
if (value === null) {
|
|
23
|
+
headers.delete(name);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
22
26
|
if (value === "") continue;
|
|
23
27
|
headers.set(name, value);
|
|
24
28
|
}
|
|
@@ -43,7 +43,7 @@ declare function createSSRHandler(server: ViteDevServer, runner: ModuleImporter,
|
|
|
43
43
|
* `next.config`. When undefined or empty, no meta tags are emitted.
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
|
-
clientTraceMetadata?: readonly string[]): (req: IncomingMessage, res: ServerResponse, url: string, /** Status code override — propagated from middleware rewrite status. */
|
|
46
|
+
clientTraceMetadata?: readonly string[], htmlLimitedBots?: string): (req: IncomingMessage, res: ServerResponse, url: string, /** Status code override — propagated from middleware rewrite status. */
|
|
47
47
|
|
|
48
48
|
statusCode?: number,
|
|
49
49
|
/**
|
|
@@ -53,6 +53,6 @@ statusCode?: number,
|
|
|
53
53
|
* client-side navigations in the Pages Router.
|
|
54
54
|
*/
|
|
55
55
|
|
|
56
|
-
isDataReq?: boolean) => Promise<void>;
|
|
56
|
+
isDataReq?: boolean, originalUrl?: string) => Promise<void>;
|
|
57
57
|
//#endregion
|
|
58
58
|
export { createSSRHandler, detectLocaleFromHeaders, extractLocaleFromUrl, parseCookieLocale };
|