vinext 0.1.7 → 0.1.8

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.
Files changed (92) hide show
  1. package/dist/check.d.ts +18 -0
  2. package/dist/check.js +37 -17
  3. package/dist/cli.js +2 -2
  4. package/dist/config/next-config.d.ts +2 -1
  5. package/dist/config/next-config.js +3 -0
  6. package/dist/config/server-external-packages.d.ts +4 -0
  7. package/dist/config/server-external-packages.js +91 -0
  8. package/dist/deploy.d.ts +7 -0
  9. package/dist/deploy.js +25 -18
  10. package/dist/entries/app-rsc-entry.js +54 -10
  11. package/dist/entries/app-rsc-manifest.js +8 -0
  12. package/dist/entries/pages-client-entry.js +1 -0
  13. package/dist/entries/pages-server-entry.js +1 -0
  14. package/dist/index.js +46 -20
  15. package/dist/init.js +2 -1
  16. package/dist/plugins/middleware-server-only.d.ts +8 -6
  17. package/dist/plugins/middleware-server-only.js +8 -7
  18. package/dist/plugins/optimize-imports.js +1 -1
  19. package/dist/routing/app-route-graph.d.ts +6 -2
  20. package/dist/routing/app-route-graph.js +61 -13
  21. package/dist/routing/app-router.d.ts +5 -0
  22. package/dist/routing/app-router.js +5 -0
  23. package/dist/routing/file-matcher.d.ts +5 -0
  24. package/dist/routing/file-matcher.js +7 -1
  25. package/dist/server/app-browser-entry.js +42 -147
  26. package/dist/server/app-browser-history-controller.d.ts +2 -1
  27. package/dist/server/app-browser-history-controller.js +6 -2
  28. package/dist/server/app-browser-server-action-client.d.ts +32 -0
  29. package/dist/server/app-browser-server-action-client.js +128 -0
  30. package/dist/server/app-fallback-renderer.d.ts +3 -1
  31. package/dist/server/app-fallback-renderer.js +6 -2
  32. package/dist/server/app-page-boundary-render.d.ts +3 -0
  33. package/dist/server/app-page-boundary-render.js +14 -3
  34. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  35. package/dist/server/app-page-cache-finalizer.js +8 -2
  36. package/dist/server/app-page-dispatch.d.ts +33 -4
  37. package/dist/server/app-page-dispatch.js +62 -90
  38. package/dist/server/app-page-element-builder.d.ts +7 -1
  39. package/dist/server/app-page-element-builder.js +56 -19
  40. package/dist/server/app-page-head.d.ts +16 -1
  41. package/dist/server/app-page-head.js +44 -22
  42. package/dist/server/app-page-params.d.ts +2 -1
  43. package/dist/server/app-page-params.js +8 -1
  44. package/dist/server/app-page-ppr-runtime.d.ts +7 -0
  45. package/dist/server/app-page-ppr-runtime.js +70 -0
  46. package/dist/server/app-page-probe.d.ts +1 -0
  47. package/dist/server/app-page-probe.js +1 -1
  48. package/dist/server/app-page-render.d.ts +4 -1
  49. package/dist/server/app-page-render.js +8 -3
  50. package/dist/server/app-page-request.d.ts +8 -1
  51. package/dist/server/app-page-request.js +23 -11
  52. package/dist/server/app-page-route-wiring.d.ts +6 -1
  53. package/dist/server/app-page-route-wiring.js +30 -8
  54. package/dist/server/app-page-search-params-observation.d.ts +4 -2
  55. package/dist/server/app-page-search-params-observation.js +11 -7
  56. package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
  57. package/dist/server/app-route-handler-dispatch.js +1 -0
  58. package/dist/server/app-route-handler-execution.js +2 -1
  59. package/dist/server/app-route-module-loader.d.ts +2 -0
  60. package/dist/server/app-route-module-loader.js +1 -0
  61. package/dist/server/app-router-entry.js +7 -6
  62. package/dist/server/app-rsc-errors.js +7 -1
  63. package/dist/server/app-rsc-handler.d.ts +2 -1
  64. package/dist/server/app-rsc-handler.js +6 -9
  65. package/dist/server/app-rsc-route-matching.d.ts +7 -0
  66. package/dist/server/app-rsc-route-matching.js +36 -3
  67. package/dist/server/app-segment-config.d.ts +1 -0
  68. package/dist/server/app-segment-config.js +32 -2
  69. package/dist/server/app-server-action-execution.d.ts +4 -0
  70. package/dist/server/app-server-action-execution.js +41 -10
  71. package/dist/server/app-ssr-entry.js +4 -1
  72. package/dist/server/app-static-generation.d.ts +1 -0
  73. package/dist/server/app-static-generation.js +1 -0
  74. package/dist/server/headers.d.ts +3 -1
  75. package/dist/server/headers.js +3 -1
  76. package/dist/server/prod-server.js +15 -6
  77. package/dist/server/worker-utils.d.ts +2 -1
  78. package/dist/server/worker-utils.js +7 -1
  79. package/dist/shims/error-boundary.d.ts +19 -1
  80. package/dist/shims/error-boundary.js +11 -1
  81. package/dist/shims/headers.d.ts +3 -1
  82. package/dist/shims/headers.js +16 -5
  83. package/dist/shims/link.js +16 -12
  84. package/dist/shims/metadata.d.ts +3 -2
  85. package/dist/shims/metadata.js +8 -4
  86. package/dist/shims/router.js +13 -2
  87. package/dist/typegen.js +6 -5
  88. package/dist/utils/path.d.ts +2 -1
  89. package/dist/utils/path.js +1 -1
  90. package/dist/utils/project.d.ts +4 -0
  91. package/dist/utils/project.js +5 -1
  92. package/package.json +7 -3
@@ -0,0 +1,128 @@
1
+ import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER } from "./headers.js";
2
+ import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
3
+ import { AppElementsWire } from "./app-elements-wire.js";
4
+ import "./app-elements.js";
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";
7
+ import { resolveServerActionRequestState } from "./app-browser-state.js";
8
+ import { applyServerActionResultDecision } from "./app-browser-server-action-navigation.js";
9
+ import { throwOnServerActionNotFound } from "./server-action-not-found.js";
10
+ import { createFromFetch, createTemporaryReferenceSet, encodeReply } from "@vitejs/plugin-rsc/browser";
11
+ //#region src/server/app-browser-server-action-client.ts
12
+ function resolveActionRedirectTarget(response, performHardNavigation) {
13
+ const actionRedirect = response.headers.get(ACTION_REDIRECT_HEADER);
14
+ if (!actionRedirect) return null;
15
+ if (isDangerousScheme(actionRedirect)) {
16
+ console.error(DANGEROUS_URL_BLOCK_MESSAGE);
17
+ return null;
18
+ }
19
+ try {
20
+ let redirectUrl;
21
+ if (actionRedirect.startsWith("/") || /^[a-z]+:/i.test(actionRedirect)) redirectUrl = new URL(actionRedirect, window.location.href);
22
+ else {
23
+ const baseParsed = new URL(window.location.href);
24
+ let baseDir = baseParsed.pathname;
25
+ if (!baseDir.endsWith("/")) baseDir += "/";
26
+ redirectUrl = new URL(actionRedirect, `${baseParsed.origin}${baseDir}${baseParsed.search}`);
27
+ }
28
+ if (redirectUrl.origin !== window.location.origin) {
29
+ performHardNavigation(actionRedirect);
30
+ return null;
31
+ }
32
+ const statusHeader = response.headers.get(ACTION_REDIRECT_STATUS_HEADER);
33
+ return {
34
+ href: redirectUrl.href,
35
+ type: response.headers.get("x-action-redirect-type") ?? "push",
36
+ status: statusHeader ? parseInt(statusHeader, 10) : 307
37
+ };
38
+ } catch {
39
+ performHardNavigation(actionRedirect);
40
+ return null;
41
+ }
42
+ }
43
+ var ServerActionRedirectError = class extends Error {
44
+ digest;
45
+ handled = true;
46
+ constructor(target) {
47
+ super("NEXT_REDIRECT");
48
+ const redirectUrl = new URL(target.href, window.location.href);
49
+ const redirectHref = redirectUrl.pathname + redirectUrl.search + redirectUrl.hash;
50
+ const redirectType = target.type === "push" ? "push" : "replace";
51
+ this.digest = `NEXT_REDIRECT;${redirectType};${encodeURIComponent(redirectHref)};${target.status};`;
52
+ }
53
+ };
54
+ async function invokeClientServerAction(id, args, actionInitiation, deps) {
55
+ deps.syncServerActionHttpFallbackHead(null);
56
+ const temporaryReferences = createTemporaryReferenceSet();
57
+ deps.syncCurrentHistoryState(actionInitiation.routerState.previousNextUrl, actionInitiation.routerState.bfcacheIds);
58
+ const body = await encodeReply(args, { temporaryReferences });
59
+ const headers = resolveServerActionRequestState({
60
+ actionId: id,
61
+ basePath: deps.basePath,
62
+ elements: actionInitiation.routerState.elements,
63
+ previousNextUrl: actionInitiation.routerState.previousNextUrl
64
+ }).headers;
65
+ const fetchResponse = await fetch(createServerActionRequestUrl(actionInitiation.path), {
66
+ method: "POST",
67
+ headers,
68
+ body
69
+ });
70
+ throwOnServerActionNotFound(fetchResponse, id);
71
+ const hasActionRedirect = fetchResponse.headers.has(ACTION_REDIRECT_HEADER);
72
+ const actionRedirectTarget = resolveActionRedirectTarget(fetchResponse, (url, historyMode) => deps.performHardNavigation(url, historyMode));
73
+ if (hasActionRedirect && !actionRedirectTarget) return void 0;
74
+ const actionResultFacts = createServerActionResultFacts({
75
+ actionRedirectHref: actionRedirectTarget?.href ?? null,
76
+ actionRedirectType: actionRedirectTarget?.type ?? null,
77
+ clientCompatibilityId: deps.clientRscCompatibilityId,
78
+ compatibilityIdHeader: fetchResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
79
+ contentTypeHeader: fetchResponse.headers.get("content-type"),
80
+ currentHref: actionInitiation.href,
81
+ origin: window.location.origin,
82
+ responseUrl: fetchResponse.url
83
+ });
84
+ const fetchResponseIsRsc = actionResultFacts.isRscContentType;
85
+ if (applyServerActionResultDecision(deps.navigationPlanner.classifyServerActionResult(actionResultFacts), () => deps.clearClientNavigationCaches(), (url, historyMode) => deps.performHardNavigation(url, historyMode))) return;
86
+ const revalidation = parseServerActionRevalidationHeader(fetchResponse.headers);
87
+ if (revalidation !== "none") deps.clearClientNavigationCaches();
88
+ const invalidResponseError = await readInvalidServerActionResponseError(fetchResponse.clone(), actionRedirectTarget !== null);
89
+ if (invalidResponseError) throw invalidResponseError;
90
+ if (actionRedirectTarget && !fetchResponseIsRsc) {
91
+ deps.performHardNavigation(actionRedirectTarget.href);
92
+ return;
93
+ }
94
+ const flightResponse = fetchResponse.status === 303 ? new Response(fetchResponse.body, {
95
+ headers: fetchResponse.headers,
96
+ status: 200,
97
+ statusText: "OK"
98
+ }) : fetchResponse;
99
+ const result = await createFromFetch(Promise.resolve(flightResponse), { temporaryReferences });
100
+ if (revalidation === "none" && shouldClearClientNavigationCachesForServerActionResult(result, revalidation)) deps.clearClientNavigationCaches();
101
+ if (actionRedirectTarget) {
102
+ if (isServerActionResult(result) && result.root !== void 0) {
103
+ deps.renderRedirectPayload(AppElementsWire.decode(result.root), actionRedirectTarget, actionInitiation);
104
+ throw new ServerActionRedirectError(actionRedirectTarget);
105
+ }
106
+ deps.performHardNavigation(actionRedirectTarget.href);
107
+ return;
108
+ }
109
+ const hasSameUrlRerenderPayload = isServerActionResult(result) && result.root !== void 0;
110
+ deps.syncServerActionHttpFallbackHead(hasSameUrlRerenderPayload ? null : fetchResponse.status);
111
+ if (isServerActionResult(result)) {
112
+ if (result.root !== void 0) {
113
+ const returnValue = result.returnValue && !result.returnValue.ok ? {
114
+ ok: false,
115
+ data: normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status)
116
+ } : result.returnValue;
117
+ return deps.commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result.root)), actionInitiation, returnValue, revalidation);
118
+ }
119
+ if (result.returnValue) {
120
+ if (!result.returnValue.ok) throw normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
121
+ return result.returnValue.data;
122
+ }
123
+ return;
124
+ }
125
+ return deps.commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result)), actionInitiation, void 0, revalidation);
126
+ }
127
+ //#endregion
128
+ export { invokeClientServerAction };
@@ -4,6 +4,7 @@ import { NavigationContext } from "../shims/navigation-context-state.js";
4
4
  import { AppPageParams } from "./app-page-boundary.js";
5
5
  import { AppPageFontPreload } from "./app-page-execution.js";
6
6
  import { AppPageMiddlewareContext } from "./app-page-response.js";
7
+ import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
7
8
  import { AppPageSsrHandler } from "./app-page-stream.js";
8
9
  import { AppPageBoundaryRoute } from "./app-page-boundary-render.js";
9
10
  import { ReactNode } from "react";
@@ -27,6 +28,7 @@ type AppFallbackRendererFontProviders = {
27
28
  getFontStyles: () => string[];
28
29
  };
29
30
  type AppFallbackRendererOptions<TModule extends AppPageModule = AppPageModule> = {
31
+ applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
30
32
  clearRequestContext: () => void;
31
33
  createRscOnErrorHandler: (request: Request, pathname: string, routePath: string) => AppPageBoundaryOnError;
32
34
  fontProviders: AppFallbackRendererFontProviders;
@@ -73,7 +75,7 @@ type AppFallbackRendererCallContext = {
73
75
  sourcePageSegments?: readonly string[] | null;
74
76
  };
75
77
  type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
76
- renderErrorBoundary: (route: AppPageBoundaryRoute<TModule> | null, error: unknown, isRscRequest: boolean, request: Request, matchedParams: AppPageParams | undefined, scriptNonce: string | undefined, middlewareContext: AppPageMiddlewareContext, callContext?: AppFallbackRendererCallContext) => Promise<Response | null>;
78
+ 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>;
77
79
  renderHttpAccessFallback: (route: AppPageBoundaryRoute<TModule> | null, statusCode: number, isRscRequest: boolean, request: Request, opts: {
78
80
  boundaryComponent?: AppPageComponent | null;
79
81
  boundaryModule?: TModule | null;
@@ -7,7 +7,7 @@ const EMPTY_MW_CTX = {
7
7
  status: null
8
8
  };
9
9
  function createAppFallbackRenderer(options) {
10
- const { basePath = "", clearRequestContext, createRscOnErrorHandler: buildRscOnErrorHandler, fontProviders, getNavigationContext, globalErrorModule, loadGlobalNotFoundModule, makeThenableParams, metadataRoutes, resolveChildSegments, rootBoundaries, rscRenderer, sanitizer, ssrLoader, trailingSlash } = options;
10
+ const { applyFileBasedMetadata, basePath = "", clearRequestContext, createRscOnErrorHandler: buildRscOnErrorHandler, fontProviders, getNavigationContext, globalErrorModule, loadGlobalNotFoundModule, makeThenableParams, metadataRoutes, resolveChildSegments, rootBoundaries, rscRenderer, sanitizer, ssrLoader, trailingSlash } = options;
11
11
  const { rootForbiddenModule, rootLayouts, rootNotFoundModule, rootUnauthorizedModule } = rootBoundaries;
12
12
  const effectiveGlobalErrorModule = globalErrorModule ?? DEFAULT_GLOBAL_ERROR_MODULE;
13
13
  const effectiveRootNotFoundModule = rootNotFoundModule ?? DEFAULT_NOT_FOUND_MODULE;
@@ -23,6 +23,7 @@ function createAppFallbackRenderer(options) {
23
23
  const globalNotFoundModule = await resolveGlobalNotFoundModule();
24
24
  const globalNotFoundComponent = globalNotFoundModule?.default ?? null;
25
25
  if (globalNotFoundComponent) return renderAppPageHttpAccessFallback({
26
+ applyFileBasedMetadata,
26
27
  boundaryComponent: globalNotFoundComponent,
27
28
  boundaryModule: globalNotFoundModule ?? null,
28
29
  buildFontLinkHeader: fontProviders.buildFontLinkHeader,
@@ -57,6 +58,7 @@ function createAppFallbackRenderer(options) {
57
58
  });
58
59
  }
59
60
  return renderAppPageHttpAccessFallback({
61
+ applyFileBasedMetadata,
60
62
  basePath,
61
63
  trailingSlash,
62
64
  boundaryComponent: opts?.boundaryComponent ?? null,
@@ -95,8 +97,9 @@ function createAppFallbackRenderer(options) {
95
97
  renderNotFound(route, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, callContext) {
96
98
  return this.renderHttpAccessFallback(route, 404, isRscRequest, request, { matchedParams }, scriptNonce, middlewareContext, callContext);
97
99
  },
98
- renderErrorBoundary(route, error, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, callContext) {
100
+ renderErrorBoundary(route, error, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, callContext, errorOrigin = "rsc") {
99
101
  return renderAppPageErrorBoundary({
102
+ applyFileBasedMetadata,
100
103
  basePath,
101
104
  trailingSlash,
102
105
  buildFontLinkHeader: fontProviders.buildFontLinkHeader,
@@ -105,6 +108,7 @@ function createAppFallbackRenderer(options) {
105
108
  return buildRscOnErrorHandler(request, pathname, routePath);
106
109
  },
107
110
  error,
111
+ errorOrigin,
108
112
  getFontLinks: fontProviders.getFontLinks,
109
113
  getFontPreloads: fontProviders.getFontPreloads,
110
114
  getFontStyles: fontProviders.getFontStyles,
@@ -4,6 +4,7 @@ import { NavigationContext } from "../shims/navigation-context-state.js";
4
4
  import { AppPageParams } from "./app-page-boundary.js";
5
5
  import { AppPageFontPreload } from "./app-page-execution.js";
6
6
  import { AppPageMiddlewareContext } from "./app-page-response.js";
7
+ import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
7
8
  import { AppPageSsrHandler } from "./app-page-stream.js";
8
9
  import { ComponentType, ReactNode } from "react";
9
10
 
@@ -27,6 +28,7 @@ type AppPageBoundaryRoute<TModule extends AppPageModule = AppPageModule> = {
27
28
  unauthorized?: TModule | null;
28
29
  };
29
30
  type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageModule> = {
31
+ applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
30
32
  buildFontLinkHeader: (preloads: readonly AppPageFontPreload[] | null | undefined) => string;
31
33
  clearRequestContext: () => void;
32
34
  createRscOnErrorHandler: (pathname: string, routePath: string) => AppPageBoundaryOnError;
@@ -73,6 +75,7 @@ type RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppP
73
75
  } & AppPageBoundaryRenderCommonOptions<TModule>;
74
76
  type RenderAppPageErrorBoundaryOptions<TModule extends AppPageModule = AppPageModule> = {
75
77
  error: unknown;
78
+ errorOrigin?: "rsc" | "ssr";
76
79
  matchedParams?: AppPageParams | null;
77
80
  route?: AppPageBoundaryRoute<TModule> | null;
78
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";
@@ -152,6 +152,7 @@ async function renderAppPageHttpAccessFallback(options) {
152
152
  const pathname = new URL(options.requestUrl).pathname;
153
153
  const routeSegments = resolveHttpAccessFallbackHeadRouteSegments(options.route, layoutModules);
154
154
  const { metadata, viewport } = await resolveAppPageHead({
155
+ applyFileBasedMetadata: options.applyFileBasedMetadata,
155
156
  basePath: options.basePath ?? "",
156
157
  layoutModules,
157
158
  layoutTreePositions: resolveHttpAccessFallbackHeadLayoutTreePositions(options.route, layoutModules),
@@ -214,7 +215,7 @@ async function renderAppPageErrorBoundary(options) {
214
215
  if (!errorBoundary.component) return null;
215
216
  const rawError = options.error instanceof Error ? options.error : new Error(String(options.error));
216
217
  rewriteClientHookError(rawError);
217
- const errorObject = options.sanitizeErrorForClient(rawError);
218
+ const errorObject = options.errorOrigin === "ssr" ? rawError : options.sanitizeErrorForClient(rawError);
218
219
  const matchedParams = options.matchedParams ?? options.route?.params ?? {};
219
220
  const layoutModules = options.route?.layouts ?? options.rootLayouts;
220
221
  const pathname = new URL(options.requestUrl).pathname;
@@ -224,6 +225,7 @@ async function renderAppPageErrorBoundary(options) {
224
225
  })];
225
226
  if (!errorBoundary.isGlobalError) try {
226
227
  const { metadata, viewport } = await resolveAppPageHead({
228
+ applyFileBasedMetadata: options.applyFileBasedMetadata,
227
229
  basePath: options.basePath ?? "",
228
230
  fallbackOnFileMetadataError: true,
229
231
  layoutModules,
@@ -247,7 +249,16 @@ async function renderAppPageErrorBoundary(options) {
247
249
  console.error(`[vinext] App page error boundary head resolution failed for ${options.route?.pattern ?? pathname}:`, error);
248
250
  }
249
251
  const buildElement = (BoundaryComponent) => {
250
- const boundaryElement = createElement(BoundaryComponent, { error: errorObject });
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 });
251
262
  return wrapRenderedBoundaryElement({
252
263
  element: createElement(Fragment, null, ...headElements, errorBoundary.isGlobalError ? createElement(GlobalErrorBoundary, {
253
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);
@@ -10,8 +10,10 @@ import { AppPageSsrHandler } from "./app-page-stream.js";
10
10
  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
+ import { PprFallbackShellState } from "../shims/ppr-fallback-shell.js";
13
14
  import { FetchCacheMode } from "../shims/fetch-cache.js";
14
15
  import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
16
+ import { WarmPprFallbackShellCachesOptions } from "./app-ppr-fallback-shell-render.js";
15
17
  import { ValidateAppPageDynamicParamsOptions } from "./app-page-request.js";
16
18
  import { ReactNode } from "react";
17
19
  import { ReactFormState } from "react-dom/client";
@@ -32,7 +34,10 @@ type AppPageBackgroundRegenerationErrorContext = {
32
34
  type AppPageBackgroundRegenerator = (key: string, renderFn: () => Promise<void>, errorContext?: AppPageBackgroundRegenerationErrorContext) => void;
33
35
  type AppPageDispatchIntercept<TPage = unknown> = {
34
36
  interceptLayouts?: readonly unknown[] | null;
37
+ interceptLayoutSegments?: readonly (readonly string[])[] | null;
38
+ interceptBranchSegments?: readonly string[] | null;
35
39
  matchedParams: AppPageParams;
40
+ sourceMatchedParams?: AppPageParams;
36
41
  page: TPage;
37
42
  slotId?: string | null;
38
43
  slotKey: string;
@@ -42,6 +47,8 @@ type AppPageDispatchIntercept<TPage = unknown> = {
42
47
  type AppPageDispatchInterceptOptions<TPage = unknown> = {
43
48
  interceptionContext: string | null;
44
49
  interceptLayouts?: readonly unknown[] | null;
50
+ interceptLayoutSegments?: readonly (readonly string[])[] | null;
51
+ interceptBranchSegments?: readonly string[] | null;
45
52
  interceptPage: TPage;
46
53
  interceptParams: AppPageParams;
47
54
  interceptSlotId?: string | null;
@@ -80,6 +87,14 @@ type AppPageDispatchRoute = {
80
87
  unauthorized?: AppPageModule | null;
81
88
  unauthorizeds?: readonly (AppPageModule | null | undefined)[];
82
89
  };
90
+ type AppPagePprRuntime<TRoute extends AppPageDispatchRoute> = {
91
+ beginFinalRender(state: AppPagePprState): void;
92
+ getState(): AppPagePprState | null;
93
+ run<T>(shell: NonNullable<DispatchAppPageOptions<TRoute>["pprFallbackShell"]>, fn: () => T): T;
94
+ tryServe(options: DispatchAppPageOptions<TRoute>, currentRevalidateSeconds: number | null, isDraftMode: boolean, isForceStatic: boolean, isForceDynamic: boolean): Promise<Response | null>;
95
+ warm(options: WarmPprFallbackShellCachesOptions): Promise<void>;
96
+ };
97
+ type AppPagePprState = PprFallbackShellState;
83
98
  type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
84
99
  /** Configured basePath (e.g. "/blog"). Used to prefix redirect Locations. */basePath?: string;
85
100
  /**
@@ -94,7 +109,10 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
94
109
  * `next.config`. Undefined falls back to the React default downstream.
95
110
  */
96
111
  reactMaxHeadersLength?: number;
97
- buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker) => Promise<AppPageElement>;
112
+ buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker, options?: {
113
+ observeMetadataSearchParamsAccess?: boolean;
114
+ observePageSearchParamsAccess?: boolean;
115
+ }) => Promise<AppPageElement>;
98
116
  clientReuseManifest?: ClientReuseManifestParseResult;
99
117
  cleanPathname: string;
100
118
  displayPathname?: string;
@@ -147,6 +165,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
147
165
  fallbackParamNames: readonly string[];
148
166
  routePattern: string;
149
167
  };
168
+ pprRuntime?: AppPagePprRuntime<TRoute>;
150
169
  /**
151
170
  * Set of concrete URL paths that were pre-rendered at build time for this
152
171
  * route. When the exact cache entry for a known pregenerated path is absent
@@ -159,9 +178,9 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
159
178
  staticParamsValidationParams?: AppPageParams;
160
179
  rootParams?: RootParams;
161
180
  probeLayoutAt: (layoutIndex: number, layoutParamAccess?: AppLayoutParamAccessTracker) => unknown;
162
- probePage: () => unknown;
181
+ probePage: (searchParams?: URLSearchParams) => unknown;
163
182
  expireSeconds?: number;
164
- renderErrorBoundaryPage: (error: unknown) => Promise<Response | null>;
183
+ renderErrorBoundaryPage: (error: unknown, errorOrigin?: "rsc" | "ssr") => Promise<Response | null>;
165
184
  renderHttpAccessFallbackPage: (statusCode: number, opts: {
166
185
  boundaryComponent?: unknown;
167
186
  boundaryModule?: AppPageModule | null;
@@ -197,6 +216,16 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
197
216
  }) => void;
198
217
  renderMode?: AppRscRenderMode;
199
218
  };
219
+ declare function shouldReadAppPageCache(options: {
220
+ isProgressiveActionRender: boolean;
221
+ isDraftMode: boolean;
222
+ isForceDynamic: boolean;
223
+ isProduction: boolean;
224
+ isRscRequest: boolean;
225
+ revalidateSeconds: number | null;
226
+ scriptNonce?: string;
227
+ }): boolean;
228
+ declare function hasSearchParams(searchParams: URLSearchParams | null | undefined): boolean;
200
229
  declare function dispatchAppPage<TRoute extends AppPageDispatchRoute>(options: DispatchAppPageOptions<TRoute>): Promise<Response>;
201
230
  //#endregion
202
- export { dispatchAppPage };
231
+ export { AppPageBoundaryOnError, AppPageDispatchRoute, AppPagePprRuntime, AppPagePprState, AppPageRenderableElement, DispatchAppPageOptions, dispatchAppPage, hasSearchParams, shouldReadAppPageCache };