@qzsy/vinext 0.1.12 → 0.1.80
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 +19 -5
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +11 -4
- package/dist/build/report.d.ts +2 -1
- package/dist/build/report.js +2 -1
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +9 -0
- package/dist/build/standalone.js +2 -0
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +64 -28
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/cloudflare/deploy-config.d.ts +51 -0
- package/dist/cloudflare/deploy-config.js +153 -0
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/index.js +1 -1
- package/dist/cloudflare/project.d.ts +41 -0
- package/dist/cloudflare/project.js +243 -0
- package/dist/cloudflare/tpr.js +1 -1
- package/dist/config/config-matchers.js +14 -10
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +47 -1
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/deploy.d.ts +2 -122
- package/dist/deploy.js +20 -793
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +70 -12
- package/dist/entries/app-rsc-manifest.js +8 -0
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +2 -1
- package/dist/entries/pages-server-entry.js +6 -2
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +50 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +158 -109
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +1000 -0
- package/dist/init-platform.d.ts +38 -0
- package/dist/init-platform.js +150 -0
- package/dist/init.d.ts +14 -37
- package/dist/init.js +205 -95
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.js +3 -0
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +13 -2
- package/dist/routing/app-route-graph.js +116 -32
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +8 -0
- package/dist/routing/file-matcher.js +10 -1
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/app-browser-action-result.d.ts +2 -1
- package/dist/server/app-browser-action-result.js +5 -1
- package/dist/server/app-browser-entry.js +17 -12
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.js +1 -0
- package/dist/server/app-browser-server-action-client.js +2 -3
- package/dist/server/app-browser-state.d.ts +1 -0
- package/dist/server/app-browser-state.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -2
- package/dist/server/app-fallback-renderer.js +12 -7
- package/dist/server/app-middleware.d.ts +2 -3
- package/dist/server/app-middleware.js +3 -2
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +12 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +10 -3
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +4 -1
- package/dist/server/app-page-dispatch.d.ts +11 -3
- package/dist/server/app-page-dispatch.js +55 -15
- package/dist/server/app-page-element-builder.d.ts +5 -1
- package/dist/server/app-page-element-builder.js +57 -20
- package/dist/server/app-page-head.d.ts +12 -0
- package/dist/server/app-page-head.js +42 -19
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +6 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +8 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +89 -13
- package/dist/server/app-page-route-wiring.d.ts +6 -1
- package/dist/server/app-page-route-wiring.js +31 -15
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- package/dist/server/app-page-segment-state.js +2 -0
- package/dist/server/app-route-handler-dispatch.js +1 -0
- package/dist/server/app-route-handler-execution.js +7 -2
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.d.ts +12 -0
- package/dist/server/app-router-entry.js +22 -8
- package/dist/server/app-router-image-optimization.d.ts +37 -0
- package/dist/server/app-router-image-optimization.js +40 -0
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.js +27 -14
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +12 -0
- package/dist/server/app-segment-config.js +91 -5
- package/dist/server/app-server-action-execution.d.ts +5 -0
- package/dist/server/app-server-action-execution.js +94 -33
- package/dist/server/app-ssr-entry.js +12 -1
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-server.js +8 -15
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/headers.d.ts +5 -15
- package/dist/server/headers.js +4 -15
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-page-data.d.ts +23 -1
- package/dist/server/pages-page-data.js +43 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +10 -4
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +47 -25
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +9 -1
- package/dist/shims/headers.js +31 -6
- package/dist/shims/image-optimization-url.d.ts +4 -0
- package/dist/shims/image-optimization-url.js +33 -1
- package/dist/shims/image.js +46 -13
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -5
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/link.js +23 -16
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.js +4 -2
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +2 -5
- package/dist/shims/router.js +41 -22
- package/dist/shims/server.js +3 -2
- package/dist/typegen.js +6 -5
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +2 -2
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +9 -1
- package/dist/utils/project.js +21 -4
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +6 -1
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -41,6 +41,10 @@ function createServerActionHttpFallbackError(status) {
|
|
|
41
41
|
function normalizeServerActionThrownValue(data, responseStatus) {
|
|
42
42
|
return createServerActionHttpFallbackError(responseStatus) ?? data;
|
|
43
43
|
}
|
|
44
|
+
function shouldSyncServerActionHttpFallbackHead(result) {
|
|
45
|
+
if (!isServerActionResult(result) || result.root !== void 0) return false;
|
|
46
|
+
return result.returnValue?.ok !== false;
|
|
47
|
+
}
|
|
44
48
|
async function readInvalidServerActionResponseError(response, hasRedirectLocation) {
|
|
45
49
|
const contentType = response.headers.get("content-type") ?? "";
|
|
46
50
|
if (contentType.startsWith("text/x-component") || hasRedirectLocation) return null;
|
|
@@ -108,4 +112,4 @@ function createDiscardedServerActionRefreshScheduler(options) {
|
|
|
108
112
|
};
|
|
109
113
|
}
|
|
110
114
|
//#endregion
|
|
111
|
-
export { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult, shouldScheduleRefreshForDiscardedServerAction };
|
|
115
|
+
export { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult, shouldScheduleRefreshForDiscardedServerAction, shouldSyncServerActionHttpFallbackHead };
|
|
@@ -34,14 +34,12 @@ import { AppBrowserHistoryController } from "./app-browser-history-controller.js
|
|
|
34
34
|
import { createVisitedResponseCacheEntry, isVisitedResponseCacheEntryFresh } from "./app-visited-response-cache.js";
|
|
35
35
|
import { createPopstateRestoreHandler, restoreSynchronousPopstateScrollPosition } from "./app-browser-popstate.js";
|
|
36
36
|
import { createDevOnCaughtError, createOnUncaughtError, createProdOnCaughtError, prodOnRecoverableError } from "./app-browser-error.js";
|
|
37
|
-
import { dismissOverlay } from "./dev-error-overlay-store.js";
|
|
38
|
-
import { devOnCaughtError, installDevErrorOverlay, installViteHmrErrorHandler, reportInitialDevServerErrors } from "./dev-error-overlay.js";
|
|
39
37
|
import { createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
|
|
40
38
|
import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
|
|
41
39
|
import { createElement, startTransition, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
42
40
|
import { flushSync } from "react-dom";
|
|
43
|
-
import { createFromFetch, createFromReadableStream, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
44
41
|
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
42
|
+
import { createFromFetch, createFromReadableStream, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
45
43
|
import { hasServerActions, loadServerActionClient } from "virtual:vinext-app-capabilities";
|
|
46
44
|
//#region src/server/app-browser-entry.ts
|
|
47
45
|
function toActionType(kind) {
|
|
@@ -375,6 +373,10 @@ function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, par
|
|
|
375
373
|
function clientNavigationSnapshotHref(snapshot) {
|
|
376
374
|
return `${window.location.origin}${createSnapshotPathAndSearch(snapshot)}`;
|
|
377
375
|
}
|
|
376
|
+
function getCurrentMatchedRoutePathname() {
|
|
377
|
+
const routeKey = AppElementsWire.parseElementKey(getBrowserRouterState().routeId);
|
|
378
|
+
return routeKey?.kind === "route" ? routeKey.path : null;
|
|
379
|
+
}
|
|
378
380
|
function getRequestState(navigationKind, targetPathname, previousNextUrlOverride, traverseHistoryState) {
|
|
379
381
|
if (previousNextUrlOverride !== void 0) return {
|
|
380
382
|
interceptionContext: resolveInterceptionContextFromPreviousNextUrl(previousNextUrlOverride, __basePath),
|
|
@@ -399,6 +401,7 @@ function getRequestState(navigationKind, targetPathname, previousNextUrlOverride
|
|
|
399
401
|
};
|
|
400
402
|
const middlewareRewriteInterceptionContext = resolveMiddlewareRewriteNavigationInterceptionContext({
|
|
401
403
|
basePath: __basePath,
|
|
404
|
+
currentMatchedPathname: getCurrentMatchedRoutePathname(),
|
|
402
405
|
currentPathname: window.location.pathname,
|
|
403
406
|
routeManifest: getBrowserRouteManifest(),
|
|
404
407
|
targetPathname
|
|
@@ -692,24 +695,26 @@ async function main() {
|
|
|
692
695
|
if (!claimInitialAppRouterBootstrap()) return;
|
|
693
696
|
if (hasServerActions) registerServerActionCallback();
|
|
694
697
|
installAppNavigationFailureListeners();
|
|
698
|
+
let devErrorOverlay = null;
|
|
695
699
|
if (import.meta.env.DEV) {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
700
|
+
devErrorOverlay = await import("../client/dev-error-overlay.js");
|
|
701
|
+
devErrorOverlay.installDevErrorOverlay();
|
|
702
|
+
devErrorOverlay.installViteHmrErrorHandler(import.meta.hot);
|
|
703
|
+
devErrorOverlay.reportInitialDevServerErrors();
|
|
699
704
|
}
|
|
700
705
|
const rscStream = await readInitialRscStream();
|
|
701
706
|
if (rscStream === null) return;
|
|
702
|
-
bootstrapHydration(rscStream);
|
|
707
|
+
bootstrapHydration(rscStream, devErrorOverlay);
|
|
703
708
|
}
|
|
704
|
-
function bootstrapHydration(rscStream) {
|
|
709
|
+
function bootstrapHydration(rscStream, devErrorOverlay) {
|
|
705
710
|
const root = decodeAppElementsPromise(createFromReadableStream(rscStream));
|
|
706
711
|
const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
707
712
|
historyController.writeBootstrapHistoryMetadata();
|
|
708
713
|
const onUncaughtError = createOnUncaughtError();
|
|
709
714
|
const formState = consumeInitialFormState(getVinextBrowserGlobal());
|
|
710
|
-
const hydrateRootOptions = import.meta.env.DEV ? createVinextHydrateRootOptions({
|
|
715
|
+
const hydrateRootOptions = import.meta.env.DEV && devErrorOverlay ? createVinextHydrateRootOptions({
|
|
711
716
|
formState,
|
|
712
|
-
onCaughtError: createDevOnCaughtError(devOnCaughtError, onUncaughtError),
|
|
717
|
+
onCaughtError: createDevOnCaughtError(devErrorOverlay.devOnCaughtError, onUncaughtError),
|
|
713
718
|
onUncaughtError
|
|
714
719
|
}) : createVinextHydrateRootOptions({
|
|
715
720
|
formState,
|
|
@@ -1036,7 +1041,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1036
1041
|
restorePopstateScrollPosition
|
|
1037
1042
|
}, event.state);
|
|
1038
1043
|
});
|
|
1039
|
-
if (import.meta.hot) {
|
|
1044
|
+
if (import.meta.env.DEV && import.meta.hot) {
|
|
1040
1045
|
const applyRscHmrUpdate = async (updateId) => {
|
|
1041
1046
|
if (updateId !== latestRscHmrUpdateId) return;
|
|
1042
1047
|
if (document.documentElement.id === "__next_error__") {
|
|
@@ -1052,7 +1057,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1052
1057
|
if (!browserNavigationController.hasBrowserRouterState()) return;
|
|
1053
1058
|
clearClientNavigationCaches();
|
|
1054
1059
|
const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
1055
|
-
dismissOverlay();
|
|
1060
|
+
devErrorOverlay?.dismissOverlay();
|
|
1056
1061
|
const hmrHeaders = createRscRequestHeaders();
|
|
1057
1062
|
await browserNavigationController.hmrReplaceTree(decodeAppElementsPromise(createFromFetch(fetch(await createRscRequestUrl(window.location.pathname + window.location.search, hmrHeaders), { headers: hmrHeaders }))), navigationSnapshot);
|
|
1058
1063
|
};
|
|
@@ -45,6 +45,7 @@ type CommitNavigationHistoryOptions = {
|
|
|
45
45
|
targetHistoryIndex?: number | null;
|
|
46
46
|
stageClientParams: () => void;
|
|
47
47
|
};
|
|
48
|
+
declare function createCanonicalBrowserHistoryHref(href: string): string;
|
|
48
49
|
/**
|
|
49
50
|
* Owns App Router browser-history metadata and traversal bookkeeping behind a
|
|
50
51
|
* typed seam: traversal index allocation/commit, push/replace/traverse/hash-only
|
|
@@ -101,4 +102,4 @@ declare class AppBrowserHistoryController {
|
|
|
101
102
|
restoreHistorySnapshot(options: RestoreHistorySnapshotOptions): boolean;
|
|
102
103
|
}
|
|
103
104
|
//#endregion
|
|
104
|
-
export { AppBrowserHistoryController, RestorableSnapshotCandidate };
|
|
105
|
+
export { AppBrowserHistoryController, RestorableSnapshotCandidate, createCanonicalBrowserHistoryHref };
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { RestorableClientStateController, createHistoryStateWithNavigationMetadata, readHistoryStateBfcacheIds, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
|
|
2
2
|
//#region src/server/app-browser-history-controller.ts
|
|
3
|
+
function createCanonicalBrowserHistoryHref(href) {
|
|
4
|
+
const url = new URL(href);
|
|
5
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
6
|
+
}
|
|
3
7
|
function stripVinextScrollState(state) {
|
|
4
8
|
if (!state || typeof state !== "object") return state;
|
|
5
9
|
const nextState = {};
|
|
@@ -166,7 +170,7 @@ var AppBrowserHistoryController = class {
|
|
|
166
170
|
this.#replaceHistoryState(createHistoryStateWithNavigationMetadata(this.#readHistoryState(), {
|
|
167
171
|
previousNextUrl: null,
|
|
168
172
|
traversalIndex: this.#currentHistoryTraversalIndex
|
|
169
|
-
}), this.#readCurrentHref());
|
|
173
|
+
}), createCanonicalBrowserHistoryHref(this.#readCurrentHref()));
|
|
170
174
|
}
|
|
171
175
|
/** History write performed on the first committed (hydrated) render. */
|
|
172
176
|
writeHydratedHistoryMetadata(options) {
|
|
@@ -207,4 +211,4 @@ function areBfcacheIdMapsEqual(a, b) {
|
|
|
207
211
|
return aEntries.every(([key, value]) => b[key] === value);
|
|
208
212
|
}
|
|
209
213
|
//#endregion
|
|
210
|
-
export { AppBrowserHistoryController };
|
|
214
|
+
export { AppBrowserHistoryController, createCanonicalBrowserHistoryHref };
|
|
@@ -3,6 +3,7 @@ import { RouteManifest } from "../routing/app-route-graph.js";
|
|
|
3
3
|
//#region src/server/app-browser-interception-context.d.ts
|
|
4
4
|
type ResolveManifestNavigationInterceptionContextOptions = {
|
|
5
5
|
basePath: string;
|
|
6
|
+
currentMatchedPathname?: string | null;
|
|
6
7
|
currentPathname: string;
|
|
7
8
|
routeManifest: RouteManifest | null;
|
|
8
9
|
targetPathname: string;
|
|
@@ -29,13 +29,15 @@ function resolveManifestNavigationInterceptionContext(options) {
|
|
|
29
29
|
function resolveMiddlewareRewriteNavigationInterceptionContext(options) {
|
|
30
30
|
if (options.routeManifest === null) return null;
|
|
31
31
|
const currentPathname = stripBasePath(options.currentPathname, options.basePath);
|
|
32
|
+
const currentMatchedPathname = options.currentMatchedPathname ? stripBasePath(options.currentMatchedPathname, options.basePath) : null;
|
|
32
33
|
const targetPathname = stripBasePath(options.targetPathname, options.basePath);
|
|
33
34
|
const sourceParts = splitPathnameForRouteMatch(currentPathname);
|
|
35
|
+
const matchedSourceParts = currentMatchedPathname ? splitPathnameForRouteMatch(currentMatchedPathname) : null;
|
|
34
36
|
const targetParts = splitPathnameForRouteMatch(targetPathname);
|
|
35
37
|
for (const interception of options.routeManifest.segmentGraph.interceptions.values()) {
|
|
36
|
-
if (!matchRoutePatternPrefix(sourceParts, interception.sourcePatternParts)) continue;
|
|
37
38
|
if (!matchRoutePatternWithOptionalDynamicSegments(targetParts, interception.targetPatternParts)) continue;
|
|
38
|
-
return currentPathname;
|
|
39
|
+
if (matchRoutePatternPrefix(sourceParts, interception.sourcePatternParts)) return currentPathname;
|
|
40
|
+
if (currentMatchedPathname !== null && matchedSourceParts !== null && matchRoutePatternPrefix(matchedSourceParts, interception.sourcePatternParts)) return currentMatchedPathname;
|
|
39
41
|
}
|
|
40
42
|
return null;
|
|
41
43
|
}
|
|
@@ -280,6 +280,7 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
280
280
|
previousNextUrl: options.restoredState.previousNextUrl,
|
|
281
281
|
rootLayoutTreePath: options.restoredState.rootLayoutTreePath,
|
|
282
282
|
routeId: options.restoredState.routeId,
|
|
283
|
+
restoredHistorySnapshot: true,
|
|
283
284
|
skippedLayoutIds: []
|
|
284
285
|
};
|
|
285
286
|
}
|
|
@@ -3,7 +3,7 @@ import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-saf
|
|
|
3
3
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
4
4
|
import "./app-elements.js";
|
|
5
5
|
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createServerActionRequestUrl } from "./app-rsc-cache-busting.js";
|
|
6
|
-
import { createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
|
|
6
|
+
import { createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult, shouldSyncServerActionHttpFallbackHead } from "./app-browser-action-result.js";
|
|
7
7
|
import { resolveServerActionRequestState } from "./app-browser-state.js";
|
|
8
8
|
import { applyServerActionResultDecision } from "./app-browser-server-action-navigation.js";
|
|
9
9
|
import { throwOnServerActionNotFound } from "./server-action-not-found.js";
|
|
@@ -106,8 +106,7 @@ async function invokeClientServerAction(id, args, actionInitiation, deps) {
|
|
|
106
106
|
deps.performHardNavigation(actionRedirectTarget.href);
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
|
-
|
|
110
|
-
deps.syncServerActionHttpFallbackHead(hasSameUrlRerenderPayload ? null : fetchResponse.status);
|
|
109
|
+
deps.syncServerActionHttpFallbackHead(shouldSyncServerActionHttpFallbackHead(result) ? fetchResponse.status : null);
|
|
111
110
|
if (isServerActionResult(result)) {
|
|
112
111
|
if (result.root !== void 0) {
|
|
113
112
|
const returnValue = result.returnValue && !result.returnValue.ok ? {
|
|
@@ -126,7 +126,7 @@ function createMountedParallelSlotSnapshots(elements) {
|
|
|
126
126
|
}
|
|
127
127
|
function createVisibleRouteSnapshot(state) {
|
|
128
128
|
const displayUrl = createSnapshotPathAndSearch(state.navigationSnapshot);
|
|
129
|
-
const matchedUrl = normalizeNavigationSnapshotMatchedUrl(state.navigationSnapshot.pathname);
|
|
129
|
+
const matchedUrl = state.interception?.targetMatchedUrl ?? normalizeNavigationSnapshotMatchedUrl(state.navigationSnapshot.pathname);
|
|
130
130
|
return {
|
|
131
131
|
displayUrl,
|
|
132
132
|
interception: state.interception,
|
|
@@ -144,7 +144,7 @@ function createVisibleRouteSnapshot(state) {
|
|
|
144
144
|
}
|
|
145
145
|
function createPendingRouteSnapshot(pending) {
|
|
146
146
|
const displayUrl = createSnapshotPathAndSearch(pending.action.navigationSnapshot);
|
|
147
|
-
const matchedUrl = normalizeNavigationSnapshotMatchedUrl(pending.action.navigationSnapshot.pathname);
|
|
147
|
+
const matchedUrl = pending.action.interception?.targetMatchedUrl ?? normalizeNavigationSnapshotMatchedUrl(pending.action.navigationSnapshot.pathname);
|
|
148
148
|
return {
|
|
149
149
|
displayUrl,
|
|
150
150
|
interception: pending.action.interception,
|
|
@@ -188,6 +188,7 @@ function planPendingRootBoundaryFlightResponse(options) {
|
|
|
188
188
|
kind: "flightResponseArrived",
|
|
189
189
|
result: {
|
|
190
190
|
...cacheEntryReuseProof ? { cacheEntryReuseProof } : {},
|
|
191
|
+
...options.pending.restoredHistorySnapshot ? { restoredHistorySnapshot: true } : {},
|
|
191
192
|
href: options.targetHref ?? options.targetSnapshot.displayUrl,
|
|
192
193
|
targetSnapshot: options.targetSnapshot
|
|
193
194
|
},
|
|
@@ -33,7 +33,8 @@ type AppFallbackRendererOptions<TModule extends AppPageModule = AppPageModule> =
|
|
|
33
33
|
createRscOnErrorHandler: (request: Request, pathname: string, routePath: string) => AppPageBoundaryOnError;
|
|
34
34
|
fontProviders: AppFallbackRendererFontProviders;
|
|
35
35
|
getNavigationContext: () => NavigationContext | null;
|
|
36
|
-
globalErrorModule?: TModule | null;
|
|
36
|
+
globalErrorModule?: TModule | null; /** Whether experimental.globalNotFound is enabled for route-miss 404s. */
|
|
37
|
+
globalNotFoundEnabled?: boolean;
|
|
37
38
|
/**
|
|
38
39
|
* Loader for the user's `app/global-not-found.tsx` module. When provided,
|
|
39
40
|
* route-miss 404s render this module as a standalone document (skipping the
|
|
@@ -75,7 +76,7 @@ type AppFallbackRendererCallContext = {
|
|
|
75
76
|
sourcePageSegments?: readonly string[] | null;
|
|
76
77
|
};
|
|
77
78
|
type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
|
|
78
|
-
renderErrorBoundary: (route: AppPageBoundaryRoute<TModule> | null, error: unknown, isRscRequest: boolean, request: Request, matchedParams: AppPageParams | undefined, scriptNonce: string | undefined, middlewareContext: AppPageMiddlewareContext, callContext?: AppFallbackRendererCallContext) => Promise<Response | null>;
|
|
79
|
+
renderErrorBoundary: (route: AppPageBoundaryRoute<TModule> | null, error: unknown, isRscRequest: boolean, request: Request, matchedParams: AppPageParams | undefined, scriptNonce: string | undefined, middlewareContext: AppPageMiddlewareContext, callContext?: AppFallbackRendererCallContext, errorOrigin?: "rsc" | "ssr") => Promise<Response | null>;
|
|
79
80
|
renderHttpAccessFallback: (route: AppPageBoundaryRoute<TModule> | null, statusCode: number, isRscRequest: boolean, request: Request, opts: {
|
|
80
81
|
boundaryComponent?: AppPageComponent | null;
|
|
81
82
|
boundaryModule?: TModule | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
|
|
2
2
|
import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
|
|
3
|
+
import { DEFAULT_GLOBAL_NOT_FOUND_MODULE } from "./default-global-not-found-module.js";
|
|
3
4
|
import { DEFAULT_NOT_FOUND_MODULE } from "./default-not-found-module.js";
|
|
4
5
|
//#region src/server/app-fallback-renderer.ts
|
|
5
6
|
const EMPTY_MW_CTX = {
|
|
@@ -7,7 +8,7 @@ const EMPTY_MW_CTX = {
|
|
|
7
8
|
status: null
|
|
8
9
|
};
|
|
9
10
|
function createAppFallbackRenderer(options) {
|
|
10
|
-
const { applyFileBasedMetadata, basePath = "", clearRequestContext, createRscOnErrorHandler: buildRscOnErrorHandler, fontProviders, getNavigationContext, globalErrorModule, loadGlobalNotFoundModule, makeThenableParams, metadataRoutes, resolveChildSegments, rootBoundaries, rscRenderer, sanitizer, ssrLoader, trailingSlash } = options;
|
|
11
|
+
const { applyFileBasedMetadata, basePath = "", clearRequestContext, createRscOnErrorHandler: buildRscOnErrorHandler, fontProviders, getNavigationContext, globalErrorModule, globalNotFoundEnabled = false, loadGlobalNotFoundModule, makeThenableParams, metadataRoutes, resolveChildSegments, rootBoundaries, rscRenderer, sanitizer, ssrLoader, trailingSlash } = options;
|
|
11
12
|
const { rootForbiddenModule, rootLayouts, rootNotFoundModule, rootUnauthorizedModule } = rootBoundaries;
|
|
12
13
|
const effectiveGlobalErrorModule = globalErrorModule ?? DEFAULT_GLOBAL_ERROR_MODULE;
|
|
13
14
|
const effectiveRootNotFoundModule = rootNotFoundModule ?? DEFAULT_NOT_FOUND_MODULE;
|
|
@@ -19,7 +20,8 @@ function createAppFallbackRenderer(options) {
|
|
|
19
20
|
}
|
|
20
21
|
return {
|
|
21
22
|
async renderHttpAccessFallback(route, statusCode, isRscRequest, request, opts, scriptNonce, middlewareContext, callContext) {
|
|
22
|
-
|
|
23
|
+
const useGlobalNotFound = statusCode === 404 && globalNotFoundEnabled && !route && !opts?.boundaryComponent;
|
|
24
|
+
if (useGlobalNotFound && loadGlobalNotFoundModule) {
|
|
23
25
|
const globalNotFoundModule = await resolveGlobalNotFoundModule();
|
|
24
26
|
const globalNotFoundComponent = globalNotFoundModule?.default ?? null;
|
|
25
27
|
if (globalNotFoundComponent) return renderAppPageHttpAccessFallback({
|
|
@@ -57,6 +59,7 @@ function createAppFallbackRenderer(options) {
|
|
|
57
59
|
statusCode
|
|
58
60
|
});
|
|
59
61
|
}
|
|
62
|
+
const routeMissRootNotFoundModule = useGlobalNotFound ? DEFAULT_GLOBAL_NOT_FOUND_MODULE : effectiveRootNotFoundModule;
|
|
60
63
|
return renderAppPageHttpAccessFallback({
|
|
61
64
|
applyFileBasedMetadata,
|
|
62
65
|
basePath,
|
|
@@ -75,7 +78,7 @@ function createAppFallbackRenderer(options) {
|
|
|
75
78
|
globalErrorModule: effectiveGlobalErrorModule,
|
|
76
79
|
isEdgeRuntime: callContext?.isEdgeRuntime,
|
|
77
80
|
isRscRequest,
|
|
78
|
-
layoutModules: opts?.layouts ?? null,
|
|
81
|
+
layoutModules: useGlobalNotFound ? [] : opts?.layouts ?? null,
|
|
79
82
|
loadSsrHandler: ssrLoader,
|
|
80
83
|
makeThenableParams,
|
|
81
84
|
matchedParams: opts?.matchedParams ?? route?.params ?? {},
|
|
@@ -84,12 +87,13 @@ function createAppFallbackRenderer(options) {
|
|
|
84
87
|
requestUrl: request.url,
|
|
85
88
|
resolveChildSegments,
|
|
86
89
|
rootForbiddenModule,
|
|
87
|
-
rootLayouts,
|
|
88
|
-
rootNotFoundModule:
|
|
90
|
+
rootLayouts: useGlobalNotFound ? [] : rootLayouts,
|
|
91
|
+
rootNotFoundModule: routeMissRootNotFoundModule,
|
|
89
92
|
rootUnauthorizedModule,
|
|
90
|
-
route,
|
|
93
|
+
route: useGlobalNotFound ? null : route,
|
|
91
94
|
renderToReadableStream: rscRenderer,
|
|
92
95
|
scriptNonce,
|
|
96
|
+
skipLayoutWrapping: useGlobalNotFound,
|
|
93
97
|
sourcePageSegments: callContext?.sourcePageSegments,
|
|
94
98
|
statusCode
|
|
95
99
|
});
|
|
@@ -97,7 +101,7 @@ function createAppFallbackRenderer(options) {
|
|
|
97
101
|
renderNotFound(route, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, callContext) {
|
|
98
102
|
return this.renderHttpAccessFallback(route, 404, isRscRequest, request, { matchedParams }, scriptNonce, middlewareContext, callContext);
|
|
99
103
|
},
|
|
100
|
-
renderErrorBoundary(route, error, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, callContext) {
|
|
104
|
+
renderErrorBoundary(route, error, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, callContext, errorOrigin = "rsc") {
|
|
101
105
|
return renderAppPageErrorBoundary({
|
|
102
106
|
applyFileBasedMetadata,
|
|
103
107
|
basePath,
|
|
@@ -108,6 +112,7 @@ function createAppFallbackRenderer(options) {
|
|
|
108
112
|
return buildRscOnErrorHandler(request, pathname, routePath);
|
|
109
113
|
},
|
|
110
114
|
error,
|
|
115
|
+
errorOrigin,
|
|
111
116
|
getFontLinks: fontProviders.getFontLinks,
|
|
112
117
|
getFontPreloads: fontProviders.getFontPreloads,
|
|
113
118
|
getFontStyles: fontProviders.getFontStyles,
|
|
@@ -14,9 +14,8 @@ type ApplyAppMiddlewareOptions = {
|
|
|
14
14
|
context: AppMiddlewareContext;
|
|
15
15
|
i18nConfig?: NextI18nConfig | null;
|
|
16
16
|
/**
|
|
17
|
-
* Whether the inbound request was a `_next/data` fetch
|
|
18
|
-
*
|
|
19
|
-
* INTERNAL_HEADERS and is stripped before this function runs.
|
|
17
|
+
* Whether the inbound request was recognized as a `_next/data` fetch from
|
|
18
|
+
* trusted URL normalization before internal headers were stripped.
|
|
20
19
|
*/
|
|
21
20
|
isDataRequest?: boolean;
|
|
22
21
|
filePath?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { VINEXT_MW_CTX_HEADER } from "../utils/protocol-headers.js";
|
|
2
|
+
import { FLIGHT_HEADERS } from "./headers.js";
|
|
3
|
+
import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
|
|
3
4
|
import { isExternalUrl, proxyExternalRequest } from "../config/config-matchers.js";
|
|
4
5
|
import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
5
6
|
import { cloneRequestWithHeaders, processMiddlewareHeaders } from "./request-pipeline.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { buildParams, decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
2
2
|
import { stripBasePath } from "../utils/base-path.js";
|
|
3
|
-
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
4
3
|
import { isUnknownRecord } from "../utils/record.js";
|
|
5
4
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
6
5
|
import "./app-elements.js";
|
|
6
|
+
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
7
7
|
import { stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
8
8
|
import { Suspense, createElement, isValidElement } from "react";
|
|
9
9
|
//#region src/server/app-optimistic-routing.ts
|
|
@@ -75,6 +75,7 @@ type RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppP
|
|
|
75
75
|
} & AppPageBoundaryRenderCommonOptions<TModule>;
|
|
76
76
|
type RenderAppPageErrorBoundaryOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
77
77
|
error: unknown;
|
|
78
|
+
errorOrigin?: "rsc" | "ssr";
|
|
78
79
|
matchedParams?: AppPageParams | null;
|
|
79
80
|
route?: AppPageBoundaryRoute<TModule> | null;
|
|
80
81
|
sanitizeErrorForClient: (error: Error) => Error;
|
|
@@ -3,7 +3,7 @@ import { AppElementsWire } from "./app-elements-wire.js";
|
|
|
3
3
|
import "./app-elements.js";
|
|
4
4
|
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
5
5
|
import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
6
|
-
import { ErrorBoundary, GlobalErrorBoundary } from "../shims/error-boundary.js";
|
|
6
|
+
import { ErrorBoundary, GlobalErrorBoundary, SerializedErrorBoundary } from "../shims/error-boundary.js";
|
|
7
7
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
8
8
|
import { MetadataHead, ViewportHead } from "../shims/metadata.js";
|
|
9
9
|
import { resolveAppPageSpecialError } from "./app-page-execution.js";
|
|
@@ -215,7 +215,7 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
215
215
|
if (!errorBoundary.component) return null;
|
|
216
216
|
const rawError = options.error instanceof Error ? options.error : new Error(String(options.error));
|
|
217
217
|
rewriteClientHookError(rawError);
|
|
218
|
-
const errorObject = options.sanitizeErrorForClient(rawError);
|
|
218
|
+
const errorObject = options.errorOrigin === "ssr" ? rawError : options.sanitizeErrorForClient(rawError);
|
|
219
219
|
const matchedParams = options.matchedParams ?? options.route?.params ?? {};
|
|
220
220
|
const layoutModules = options.route?.layouts ?? options.rootLayouts;
|
|
221
221
|
const pathname = new URL(options.requestUrl).pathname;
|
|
@@ -249,7 +249,16 @@ async function renderAppPageErrorBoundary(options) {
|
|
|
249
249
|
console.error(`[vinext] App page error boundary head resolution failed for ${options.route?.pattern ?? pathname}:`, error);
|
|
250
250
|
}
|
|
251
251
|
const buildElement = (BoundaryComponent) => {
|
|
252
|
-
const
|
|
252
|
+
const serializedError = {
|
|
253
|
+
digest: "digest" in errorObject ? String(errorObject.digest) : void 0,
|
|
254
|
+
message: errorObject.message,
|
|
255
|
+
name: errorObject.name,
|
|
256
|
+
stack: process.env.NODE_ENV !== "production" ? errorObject.stack : void 0
|
|
257
|
+
};
|
|
258
|
+
const boundaryElement = errorBoundary.isGlobalError && BoundaryComponent !== DEFAULT_GLOBAL_ERROR_COMPONENT ? createElement(SerializedErrorBoundary, {
|
|
259
|
+
error: serializedError,
|
|
260
|
+
fallback: BoundaryComponent
|
|
261
|
+
}) : createElement(BoundaryComponent, { error: errorObject });
|
|
253
262
|
return wrapRenderedBoundaryElement({
|
|
254
263
|
element: createElement(Fragment, null, ...headElements, errorBoundary.isGlobalError ? createElement(GlobalErrorBoundary, {
|
|
255
264
|
fallback: DEFAULT_GLOBAL_ERROR_COMPONENT,
|
|
@@ -30,6 +30,7 @@ type FinalizeAppPageHtmlCacheResponseOptions = {
|
|
|
30
30
|
isrRscKey: AppPageRscCacheKeyBuilder;
|
|
31
31
|
isrSet: AppPageCacheSetter;
|
|
32
32
|
interceptionContext?: string | null;
|
|
33
|
+
omitPendingDynamicCacheState?: boolean;
|
|
33
34
|
preserveClientResponseHeaders?: boolean;
|
|
34
35
|
expireSeconds?: number;
|
|
35
36
|
revalidateSeconds: number | null;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import { NEXTJS_CACHE_HEADER, VINEXT_CACHE_HEADER } from "./headers.js";
|
|
1
2
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
2
3
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
3
4
|
import { buildAppPageCacheValue } from "./isr-cache.js";
|
|
4
5
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
5
6
|
import { createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
6
7
|
//#region src/server/app-page-cache-finalizer.ts
|
|
7
|
-
function applyPendingDynamicCdnHeaders(headers, tags) {
|
|
8
|
+
function applyPendingDynamicCdnHeaders(headers, tags, options = {}) {
|
|
8
9
|
applyCdnResponseHeaders(headers, {
|
|
9
10
|
cacheControl: headers.get("Cache-Control") ?? "",
|
|
10
11
|
pendingDynamicCheck: true,
|
|
11
12
|
tags
|
|
12
13
|
});
|
|
14
|
+
if (options.omitCacheState === true) {
|
|
15
|
+
headers.delete(VINEXT_CACHE_HEADER);
|
|
16
|
+
headers.delete(NEXTJS_CACHE_HEADER);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
13
19
|
setCacheStateHeaders(headers, "MISS");
|
|
14
20
|
}
|
|
15
21
|
function resolveAppPageCacheWritePolicy(options) {
|
|
@@ -30,7 +36,7 @@ function finalizeAppPageHtmlCacheResponse(response, options) {
|
|
|
30
36
|
const htmlKey = options.isrHtmlKey(options.cleanPathname);
|
|
31
37
|
const rscKey = options.isrRscKey(options.cleanPathname, null, void 0, options.interceptionContext);
|
|
32
38
|
const clientHeaders = new Headers(response.headers);
|
|
33
|
-
if (options.preserveClientResponseHeaders !== true) applyPendingDynamicCdnHeaders(clientHeaders, options.getPageTags());
|
|
39
|
+
if (options.preserveClientResponseHeaders !== true) applyPendingDynamicCdnHeaders(clientHeaders, options.getPageTags(), { omitCacheState: options.omitPendingDynamicCacheState === true });
|
|
34
40
|
const cachePromise = (async () => {
|
|
35
41
|
try {
|
|
36
42
|
const cachedHtml = await readStreamAsText(streamForCache);
|
|
@@ -57,7 +63,8 @@ function finalizeAppPageHtmlCacheResponse(response, options) {
|
|
|
57
63
|
cacheTags: pageTags,
|
|
58
64
|
state: observationState
|
|
59
65
|
});
|
|
60
|
-
const
|
|
66
|
+
const linkHeader = response.headers.get("link");
|
|
67
|
+
const writes = [options.isrSet(htmlKey, buildAppPageCacheValue(cachedHtml, void 0, 200, htmlRenderObservation, linkHeader ? { link: linkHeader } : void 0), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)];
|
|
61
68
|
if (options.capturedRscDataPromise) writes.push(options.capturedRscDataPromise.then((rscData) => options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200, rscRenderObservation), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)));
|
|
62
69
|
await Promise.all(writes);
|
|
63
70
|
options.isrDebug?.("HTML cache written", htmlKey);
|
|
@@ -38,6 +38,7 @@ type RenderAppPageCacheArtifactsResult = {
|
|
|
38
38
|
cacheControl?: CacheControlMetadata;
|
|
39
39
|
html: string;
|
|
40
40
|
htmlRenderObservation: ReturnType<typeof createAppPageRenderObservation>;
|
|
41
|
+
linkHeader?: string;
|
|
41
42
|
rscData?: ArrayBuffer;
|
|
42
43
|
rscRenderObservation?: ReturnType<typeof createAppPageRenderObservation>;
|
|
43
44
|
tags: string[];
|
|
@@ -2,9 +2,9 @@ import { consumeDynamicUsage, consumeInvalidDynamicUsageError } from "../shims/h
|
|
|
2
2
|
import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
3
3
|
import { getCollectedFetchTags } from "../shims/fetch-cache.js";
|
|
4
4
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
5
|
-
import { teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
5
|
+
import { buildAppPageFontLinkHeader, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
6
6
|
import { consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
|
|
7
|
-
import { isAppSsrRenderResult } from "./app-page-stream.js";
|
|
7
|
+
import { buildAppPageLinkHeader, isAppSsrRenderResult } from "./app-page-stream.js";
|
|
8
8
|
import { buildAppPageTags } from "./implicit-tags.js";
|
|
9
9
|
//#region src/server/app-page-cache-render.ts
|
|
10
10
|
/**
|
|
@@ -16,10 +16,11 @@ import { buildAppPageTags } from "./implicit-tags.js";
|
|
|
16
16
|
async function renderAppPageCacheArtifacts(options) {
|
|
17
17
|
const rscCapture = teeAppPageRscStreamForCapture(options.renderToReadableStream(options.element, { onError: options.onError }), options.captureRscData);
|
|
18
18
|
const capturedRscDataRef = { value: null };
|
|
19
|
+
const fontPreloads = options.getFontPreloads();
|
|
19
20
|
const htmlResult = await (await options.loadSsrHandler()).handleSsr(rscCapture.ssrStream, options.getNavigationContext(), {
|
|
20
21
|
links: options.getFontLinks(),
|
|
21
22
|
styles: options.getFontStyles(),
|
|
22
|
-
preloads:
|
|
23
|
+
preloads: fontPreloads
|
|
23
24
|
}, {
|
|
24
25
|
basePath: options.basePath,
|
|
25
26
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
@@ -31,7 +32,9 @@ async function renderAppPageCacheArtifacts(options) {
|
|
|
31
32
|
capturedRscDataRef
|
|
32
33
|
} : {}
|
|
33
34
|
});
|
|
34
|
-
const
|
|
35
|
+
const htmlStream = isAppSsrRenderResult(htmlResult) ? htmlResult.htmlStream : htmlResult;
|
|
36
|
+
const linkHeader = buildAppPageLinkHeader(isAppSsrRenderResult(htmlResult) ? htmlResult.linkHeader : void 0, buildAppPageFontLinkHeader(fontPreloads), options.reactMaxHeadersLength);
|
|
37
|
+
const html = await readStreamAsText(htmlStream);
|
|
35
38
|
let rscData;
|
|
36
39
|
if (options.captureRscData) {
|
|
37
40
|
const capturedPromise = capturedRscDataRef.value;
|
|
@@ -60,6 +63,7 @@ async function renderAppPageCacheArtifacts(options) {
|
|
|
60
63
|
params: options.navigationParams,
|
|
61
64
|
state: observationState
|
|
62
65
|
}),
|
|
66
|
+
...linkHeader ? { linkHeader } : {},
|
|
63
67
|
tags,
|
|
64
68
|
cacheControl: typeof cacheLife?.revalidate === "number" ? {
|
|
65
69
|
revalidate: cacheLife.revalidate,
|
|
@@ -43,6 +43,8 @@ function buildAppPageCachedHeaders(options) {
|
|
|
43
43
|
applyCdnResponseHeaders(headers, { cacheControl: options.cacheControl });
|
|
44
44
|
setCacheStateHeaders(headers, options.cacheState);
|
|
45
45
|
applyEdgeRuntimeHeader(headers, options.isEdgeRuntime);
|
|
46
|
+
if (options.linkHeader) if (Array.isArray(options.linkHeader)) for (const value of options.linkHeader) headers.append("Link", value);
|
|
47
|
+
else headers.set("Link", options.linkHeader);
|
|
46
48
|
if (options.mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
|
|
47
49
|
mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
|
|
48
50
|
return headers;
|
|
@@ -84,6 +86,7 @@ function buildAppPageCachedResponse(cachedValue, options) {
|
|
|
84
86
|
cacheState: options.cacheState,
|
|
85
87
|
contentType: "text/html; charset=utf-8",
|
|
86
88
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
89
|
+
linkHeader: cachedValue.headers?.link,
|
|
87
90
|
middlewareHeaders: options.middlewareHeaders
|
|
88
91
|
});
|
|
89
92
|
return new Response(cachedValue.html, {
|
|
@@ -177,7 +180,7 @@ async function readAppPageCacheResponse(options) {
|
|
|
177
180
|
const revalidateSeconds = revalidatedPage.cacheControl?.revalidate ?? options.revalidateSeconds;
|
|
178
181
|
const expireSeconds = revalidatedPage.cacheControl?.expire ?? options.expireSeconds;
|
|
179
182
|
const writes = [options.isrSet(options.isRscRequest ? isrKey : options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode, options.interceptionContext), buildAppPageCacheValue("", revalidatedPage.rscData, 200, revalidatedPage.rscRenderObservation), revalidateSeconds, revalidatedPage.tags, expireSeconds)];
|
|
180
|
-
if (!options.isRscRequest) writes.push(options.isrSet(isrKey, buildAppPageCacheValue(revalidatedPage.html, void 0, 200, revalidatedPage.htmlRenderObservation), revalidateSeconds, revalidatedPage.tags, expireSeconds));
|
|
183
|
+
if (!options.isRscRequest) writes.push(options.isrSet(isrKey, buildAppPageCacheValue(revalidatedPage.html, void 0, 200, revalidatedPage.htmlRenderObservation, revalidatedPage.linkHeader ? { link: revalidatedPage.linkHeader } : void 0), revalidateSeconds, revalidatedPage.tags, expireSeconds));
|
|
181
184
|
await Promise.all(writes);
|
|
182
185
|
options.isrDebug?.("regen complete", options.cleanPathname);
|
|
183
186
|
});
|
|
@@ -34,7 +34,10 @@ type AppPageBackgroundRegenerationErrorContext = {
|
|
|
34
34
|
type AppPageBackgroundRegenerator = (key: string, renderFn: () => Promise<void>, errorContext?: AppPageBackgroundRegenerationErrorContext) => void;
|
|
35
35
|
type AppPageDispatchIntercept<TPage = unknown> = {
|
|
36
36
|
interceptLayouts?: readonly unknown[] | null;
|
|
37
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
38
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
37
39
|
matchedParams: AppPageParams;
|
|
40
|
+
sourceMatchedParams?: AppPageParams;
|
|
38
41
|
page: TPage;
|
|
39
42
|
slotId?: string | null;
|
|
40
43
|
slotKey: string;
|
|
@@ -44,6 +47,8 @@ type AppPageDispatchIntercept<TPage = unknown> = {
|
|
|
44
47
|
type AppPageDispatchInterceptOptions<TPage = unknown> = {
|
|
45
48
|
interceptionContext: string | null;
|
|
46
49
|
interceptLayouts?: readonly unknown[] | null;
|
|
50
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
51
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
47
52
|
interceptPage: TPage;
|
|
48
53
|
interceptParams: AppPageParams;
|
|
49
54
|
interceptSlotId?: string | null;
|
|
@@ -104,7 +109,10 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
104
109
|
* `next.config`. Undefined falls back to the React default downstream.
|
|
105
110
|
*/
|
|
106
111
|
reactMaxHeadersLength?: number;
|
|
107
|
-
buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker
|
|
112
|
+
buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker, options?: {
|
|
113
|
+
observeMetadataSearchParamsAccess?: boolean;
|
|
114
|
+
observePageSearchParamsAccess?: boolean;
|
|
115
|
+
}) => Promise<AppPageElement>;
|
|
108
116
|
clientReuseManifest?: ClientReuseManifestParseResult;
|
|
109
117
|
cleanPathname: string;
|
|
110
118
|
displayPathname?: string;
|
|
@@ -170,9 +178,9 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
170
178
|
staticParamsValidationParams?: AppPageParams;
|
|
171
179
|
rootParams?: RootParams;
|
|
172
180
|
probeLayoutAt: (layoutIndex: number, layoutParamAccess?: AppLayoutParamAccessTracker) => unknown;
|
|
173
|
-
probePage: () => unknown;
|
|
181
|
+
probePage: (searchParams?: URLSearchParams) => unknown;
|
|
174
182
|
expireSeconds?: number;
|
|
175
|
-
renderErrorBoundaryPage: (error: unknown) => Promise<Response | null>;
|
|
183
|
+
renderErrorBoundaryPage: (error: unknown, errorOrigin?: "rsc" | "ssr") => Promise<Response | null>;
|
|
176
184
|
renderHttpAccessFallbackPage: (statusCode: number, opts: {
|
|
177
185
|
boundaryComponent?: unknown;
|
|
178
186
|
boundaryModule?: AppPageModule | null;
|