vinext 0.1.2 → 0.1.4

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