vinext 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/README.md +2 -5
  2. package/dist/build/client-build-config.d.ts +7 -1
  3. package/dist/build/client-build-config.js +9 -1
  4. package/dist/build/prerender.d.ts +9 -1
  5. package/dist/build/prerender.js +41 -12
  6. package/dist/build/run-prerender.d.ts +10 -2
  7. package/dist/build/run-prerender.js +15 -1
  8. package/dist/check.js +4 -3
  9. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  10. package/dist/client/app-nav-failure-handler.js +44 -0
  11. package/dist/client/navigation-runtime.d.ts +3 -2
  12. package/dist/client/vinext-next-data.d.ts +18 -1
  13. package/dist/client/window-next.d.ts +8 -5
  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 -4
  17. package/dist/config/config-matchers.js +88 -16
  18. package/dist/config/next-config.d.ts +59 -4
  19. package/dist/config/next-config.js +149 -48
  20. package/dist/deploy.d.ts +30 -11
  21. package/dist/deploy.js +189 -101
  22. package/dist/entries/app-browser-entry.d.ts +9 -3
  23. package/dist/entries/app-browser-entry.js +21 -3
  24. package/dist/entries/app-rsc-entry.d.ts +2 -0
  25. package/dist/entries/app-rsc-entry.js +71 -6
  26. package/dist/entries/app-rsc-manifest.js +2 -0
  27. package/dist/entries/app-ssr-entry.js +1 -1
  28. package/dist/entries/pages-client-entry.js +54 -9
  29. package/dist/entries/pages-server-entry.js +48 -11
  30. package/dist/index.d.ts +0 -2
  31. package/dist/index.js +285 -139
  32. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  33. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  34. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  35. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  36. package/dist/plugins/og-assets.js +2 -2
  37. package/dist/plugins/optimize-imports.d.ts +10 -5
  38. package/dist/plugins/optimize-imports.js +27 -21
  39. package/dist/plugins/postcss.js +7 -7
  40. package/dist/plugins/sass.d.ts +53 -24
  41. package/dist/plugins/sass.js +249 -1
  42. package/dist/plugins/typeof-window.d.ts +14 -0
  43. package/dist/plugins/typeof-window.js +150 -0
  44. package/dist/plugins/wasm-module-import.d.ts +15 -0
  45. package/dist/plugins/wasm-module-import.js +50 -0
  46. package/dist/routing/app-route-graph.d.ts +25 -2
  47. package/dist/routing/app-route-graph.js +91 -22
  48. package/dist/routing/file-matcher.d.ts +10 -1
  49. package/dist/routing/file-matcher.js +23 -2
  50. package/dist/routing/pages-router.js +3 -3
  51. package/dist/routing/utils.d.ts +35 -6
  52. package/dist/routing/utils.js +59 -7
  53. package/dist/server/api-handler.d.ts +6 -1
  54. package/dist/server/api-handler.js +21 -15
  55. package/dist/server/app-browser-action-result.d.ts +19 -6
  56. package/dist/server/app-browser-action-result.js +19 -10
  57. package/dist/server/app-browser-entry.js +269 -297
  58. package/dist/server/app-browser-error.d.ts +10 -3
  59. package/dist/server/app-browser-error.js +47 -6
  60. package/dist/server/app-browser-history-controller.d.ts +104 -0
  61. package/dist/server/app-browser-history-controller.js +210 -0
  62. package/dist/server/app-browser-hydration.d.ts +2 -0
  63. package/dist/server/app-browser-hydration.js +1 -0
  64. package/dist/server/app-browser-navigation-controller.d.ts +7 -4
  65. package/dist/server/app-browser-navigation-controller.js +33 -9
  66. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  67. package/dist/server/app-browser-rsc-redirect.js +30 -8
  68. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  69. package/dist/server/app-browser-server-action-navigation.js +9 -0
  70. package/dist/server/app-browser-state.js +4 -7
  71. package/dist/server/app-browser-stream.js +86 -43
  72. package/dist/server/app-browser-visible-commit.js +1 -1
  73. package/dist/server/app-elements-wire.d.ts +6 -1
  74. package/dist/server/app-elements-wire.js +14 -4
  75. package/dist/server/app-elements.d.ts +2 -2
  76. package/dist/server/app-elements.js +2 -2
  77. package/dist/server/app-fallback-renderer.d.ts +3 -1
  78. package/dist/server/app-fallback-renderer.js +6 -2
  79. package/dist/server/app-middleware.js +1 -0
  80. package/dist/server/app-optimistic-routing.js +24 -3
  81. package/dist/server/app-page-boundary-render.d.ts +3 -1
  82. package/dist/server/app-page-boundary-render.js +31 -16
  83. package/dist/server/app-page-cache-render.d.ts +53 -0
  84. package/dist/server/app-page-cache-render.js +91 -0
  85. package/dist/server/app-page-cache.d.ts +16 -2
  86. package/dist/server/app-page-cache.js +71 -8
  87. package/dist/server/app-page-dispatch.d.ts +34 -0
  88. package/dist/server/app-page-dispatch.js +167 -97
  89. package/dist/server/app-page-element-builder.d.ts +23 -2
  90. package/dist/server/app-page-element-builder.js +42 -10
  91. package/dist/server/app-page-execution.d.ts +7 -2
  92. package/dist/server/app-page-execution.js +53 -18
  93. package/dist/server/app-page-probe.d.ts +1 -0
  94. package/dist/server/app-page-probe.js +4 -0
  95. package/dist/server/app-page-render-observation.d.ts +3 -1
  96. package/dist/server/app-page-render-observation.js +17 -1
  97. package/dist/server/app-page-render.d.ts +13 -2
  98. package/dist/server/app-page-render.js +48 -17
  99. package/dist/server/app-page-request.d.ts +3 -0
  100. package/dist/server/app-page-request.js +5 -3
  101. package/dist/server/app-page-response.js +1 -1
  102. package/dist/server/app-page-route-wiring.d.ts +5 -1
  103. package/dist/server/app-page-route-wiring.js +21 -11
  104. package/dist/server/app-page-stream.d.ts +16 -9
  105. package/dist/server/app-page-stream.js +12 -9
  106. package/dist/server/app-pages-bridge.d.ts +18 -0
  107. package/dist/server/app-pages-bridge.js +22 -5
  108. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  109. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  110. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  111. package/dist/server/app-ppr-fallback-shell.js +8 -1
  112. package/dist/server/app-route-handler-dispatch.js +9 -2
  113. package/dist/server/app-route-handler-policy.d.ts +1 -0
  114. package/dist/server/app-route-handler-response.js +11 -10
  115. package/dist/server/app-route-handler-runtime.js +12 -1
  116. package/dist/server/app-router-entry.js +5 -0
  117. package/dist/server/app-rsc-cache-busting.js +2 -0
  118. package/dist/server/app-rsc-handler.d.ts +25 -0
  119. package/dist/server/app-rsc-handler.js +153 -53
  120. package/dist/server/app-rsc-response-finalizer.js +1 -1
  121. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  122. package/dist/server/app-rsc-route-matching.js +2 -0
  123. package/dist/server/app-segment-config.d.ts +9 -1
  124. package/dist/server/app-segment-config.js +12 -3
  125. package/dist/server/app-server-action-execution.d.ts +12 -0
  126. package/dist/server/app-server-action-execution.js +47 -15
  127. package/dist/server/app-ssr-entry.d.ts +2 -0
  128. package/dist/server/app-ssr-entry.js +81 -8
  129. package/dist/server/app-ssr-stream.js +9 -1
  130. package/dist/server/cache-control.js +4 -0
  131. package/dist/server/dev-lockfile.js +2 -1
  132. package/dist/server/dev-server.d.ts +2 -2
  133. package/dist/server/dev-server.js +287 -63
  134. package/dist/server/headers.d.ts +8 -1
  135. package/dist/server/headers.js +8 -1
  136. package/dist/server/hybrid-route-priority.d.ts +22 -0
  137. package/dist/server/hybrid-route-priority.js +33 -0
  138. package/dist/server/image-optimization.d.ts +18 -9
  139. package/dist/server/image-optimization.js +37 -23
  140. package/dist/server/implicit-tags.d.ts +2 -1
  141. package/dist/server/implicit-tags.js +4 -1
  142. package/dist/server/instrumentation-runtime.d.ts +6 -0
  143. package/dist/server/instrumentation-runtime.js +8 -0
  144. package/dist/server/isr-decision.d.ts +79 -0
  145. package/dist/server/isr-decision.js +70 -0
  146. package/dist/server/metadata-route-response.js +5 -3
  147. package/dist/server/middleware-runtime.d.ts +13 -0
  148. package/dist/server/middleware-runtime.js +11 -7
  149. package/dist/server/middleware.js +1 -0
  150. package/dist/server/navigation-planner.d.ts +186 -22
  151. package/dist/server/navigation-planner.js +302 -0
  152. package/dist/server/navigation-trace.d.ts +18 -1
  153. package/dist/server/navigation-trace.js +18 -1
  154. package/dist/server/normalize-path.d.ts +0 -8
  155. package/dist/server/normalize-path.js +3 -1
  156. package/dist/server/otel-tracer-extension.d.ts +45 -0
  157. package/dist/server/otel-tracer-extension.js +89 -0
  158. package/dist/server/pages-api-route.d.ts +20 -3
  159. package/dist/server/pages-api-route.js +19 -3
  160. package/dist/server/pages-asset-tags.d.ts +16 -4
  161. package/dist/server/pages-asset-tags.js +22 -12
  162. package/dist/server/pages-data-route.d.ts +8 -1
  163. package/dist/server/pages-data-route.js +16 -3
  164. package/dist/server/pages-get-initial-props.d.ts +54 -4
  165. package/dist/server/pages-get-initial-props.js +43 -1
  166. package/dist/server/pages-node-compat.d.ts +3 -11
  167. package/dist/server/pages-node-compat.js +175 -122
  168. package/dist/server/pages-page-data.d.ts +39 -2
  169. package/dist/server/pages-page-data.js +261 -46
  170. package/dist/server/pages-page-handler.d.ts +5 -2
  171. package/dist/server/pages-page-handler.js +78 -25
  172. package/dist/server/pages-page-response.d.ts +47 -2
  173. package/dist/server/pages-page-response.js +73 -9
  174. package/dist/server/pages-readiness.d.ts +1 -1
  175. package/dist/server/pages-request-pipeline.d.ts +16 -1
  176. package/dist/server/pages-request-pipeline.js +96 -38
  177. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  178. package/dist/server/pregenerated-concrete-paths.js +2 -19
  179. package/dist/server/prerender-manifest.d.ts +33 -0
  180. package/dist/server/prerender-manifest.js +54 -0
  181. package/dist/server/prerender-route-params.d.ts +1 -2
  182. package/dist/server/prod-server.d.ts +39 -1
  183. package/dist/server/prod-server.js +107 -37
  184. package/dist/server/request-pipeline.d.ts +3 -15
  185. package/dist/server/request-pipeline.js +58 -47
  186. package/dist/server/rsc-stream-hints.d.ts +5 -1
  187. package/dist/server/rsc-stream-hints.js +6 -1
  188. package/dist/server/seed-cache.js +10 -18
  189. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  190. package/dist/shims/app-router-scroll-state.js +14 -2
  191. package/dist/shims/app-router-scroll.d.ts +3 -0
  192. package/dist/shims/app-router-scroll.js +28 -18
  193. package/dist/shims/cache-runtime.js +12 -4
  194. package/dist/shims/cache.d.ts +1 -0
  195. package/dist/shims/cache.js +1 -1
  196. package/dist/shims/cdn-cache.d.ts +5 -5
  197. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  198. package/dist/shims/dynamic-preload-chunks.js +79 -0
  199. package/dist/shims/dynamic.d.ts +4 -0
  200. package/dist/shims/dynamic.js +4 -2
  201. package/dist/shims/error-boundary.d.ts +6 -4
  202. package/dist/shims/error-boundary.js +7 -0
  203. package/dist/shims/error.js +38 -11
  204. package/dist/shims/error.react-server.d.ts +9 -0
  205. package/dist/shims/error.react-server.js +6 -0
  206. package/dist/shims/fetch-cache.d.ts +11 -1
  207. package/dist/shims/fetch-cache.js +55 -20
  208. package/dist/shims/hash-scroll.js +6 -1
  209. package/dist/shims/head.js +6 -1
  210. package/dist/shims/headers.d.ts +16 -2
  211. package/dist/shims/headers.js +66 -5
  212. package/dist/shims/image-config.js +7 -1
  213. package/dist/shims/internal/als-registry.js +28 -1
  214. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  215. package/dist/shims/internal/app-route-detection.js +18 -23
  216. package/dist/shims/internal/app-router-context.d.ts +5 -0
  217. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  218. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  219. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  220. package/dist/shims/internal/navigation-untracked.js +55 -0
  221. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  222. package/dist/shims/internal/pages-data-target.js +17 -8
  223. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  224. package/dist/shims/internal/pages-router-accessor.js +13 -0
  225. package/dist/shims/internal/router-context.d.ts +2 -1
  226. package/dist/shims/internal/router-context.js +3 -1
  227. package/dist/shims/link.js +12 -5
  228. package/dist/shims/metadata.d.ts +6 -2
  229. package/dist/shims/metadata.js +32 -14
  230. package/dist/shims/navigation.d.ts +14 -17
  231. package/dist/shims/navigation.js +93 -46
  232. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  233. package/dist/shims/ppr-fallback-shell.js +28 -7
  234. package/dist/shims/router.d.ts +13 -2
  235. package/dist/shims/router.js +434 -116
  236. package/dist/shims/script-nonce-context.d.ts +1 -1
  237. package/dist/shims/script-nonce-context.js +11 -3
  238. package/dist/shims/server.d.ts +33 -2
  239. package/dist/shims/server.js +75 -18
  240. package/dist/shims/slot.js +1 -1
  241. package/dist/shims/unified-request-context.js +2 -0
  242. package/dist/typegen.js +1 -0
  243. package/dist/utils/built-asset-url.d.ts +4 -0
  244. package/dist/utils/built-asset-url.js +11 -0
  245. package/dist/utils/client-build-manifest.js +15 -5
  246. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  247. package/dist/utils/client-runtime-metadata.js +63 -0
  248. package/dist/utils/commonjs-loader.d.ts +16 -0
  249. package/dist/utils/commonjs-loader.js +100 -0
  250. package/dist/utils/deployment-id.d.ts +8 -0
  251. package/dist/utils/deployment-id.js +22 -0
  252. package/dist/utils/hash.d.ts +17 -1
  253. package/dist/utils/hash.js +36 -1
  254. package/dist/utils/html-limited-bots.d.ts +18 -1
  255. package/dist/utils/html-limited-bots.js +23 -1
  256. package/dist/utils/lazy-chunks.d.ts +27 -1
  257. package/dist/utils/lazy-chunks.js +65 -1
  258. package/dist/utils/manifest-paths.d.ts +20 -2
  259. package/dist/utils/manifest-paths.js +38 -3
  260. package/dist/utils/parse-cookie.d.ts +13 -0
  261. package/dist/utils/parse-cookie.js +52 -0
  262. package/dist/utils/path.d.ts +8 -1
  263. package/dist/utils/path.js +13 -1
  264. package/package.json +2 -2
  265. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  266. 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,
@@ -168,7 +172,8 @@ async function renderAppPageHttpAccessFallback(options) {
168
172
  if (metadata) headElements.push(createElement(MetadataHead, {
169
173
  key: "metadata",
170
174
  metadata,
171
- pathname
175
+ pathname,
176
+ trailingSlash: options.trailingSlash
172
177
  }));
173
178
  headElements.push(createElement(ViewportHead, {
174
179
  key: "viewport",
@@ -231,7 +236,8 @@ async function renderAppPageErrorBoundary(options) {
231
236
  if (metadata) headElements.push(createElement(MetadataHead, {
232
237
  key: "metadata",
233
238
  metadata,
234
- pathname
239
+ pathname,
240
+ trailingSlash: options.trailingSlash
235
241
  }));
236
242
  headElements.push(createElement(ViewportHead, {
237
243
  key: "viewport",
@@ -259,16 +265,25 @@ async function renderAppPageErrorBoundary(options) {
259
265
  skipLayoutWrapping: errorBoundary.isGlobalError
260
266
  });
261
267
  };
262
- const renderWith = (BoundaryComponent) => renderAppPageBoundaryElementResponse({
263
- ...options,
264
- element: buildElement(BoundaryComponent),
265
- initialDevServerError: rawError,
266
- layoutModules,
267
- navigationParams: matchedParams,
268
- route: options.route,
269
- routePattern: options.route?.pattern,
270
- status: 200
271
- });
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
+ };
272
287
  try {
273
288
  return await renderWith(errorBoundary.component);
274
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 };
@@ -1,14 +1,16 @@
1
1
  import { VINEXT_MOUNTED_SLOTS_HEADER } from "./headers.js";
2
2
  import { setCacheStateHeaders } from "./cache-headers.js";
3
3
  import { encodeCacheTag } from "../utils/encode-cache-tag.js";
4
+ import { applyCdnResponseHeaders } from "./cache-control.js";
5
+ import { decideIsr } from "./isr-decision.js";
4
6
  import { buildAppPageCacheValue } from "./isr-cache.js";
5
7
  import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
6
8
  import { readStreamAsText } from "../utils/text-stream.js";
7
- import { applyCdnResponseHeaders, buildCachedRevalidateCacheControl } from "./cache-control.js";
8
9
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
9
10
  import { applyEdgeRuntimeHeader } from "./app-page-response.js";
10
11
  import { hasCompleteNegativeRequestApiProof } from "./cache-proof.js";
11
12
  import { createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
13
+ import { isAppPprDynamicFallbackShellHtml } from "./app-ppr-fallback-shell.js";
12
14
  //#region src/server/app-page-cache.ts
13
15
  /**
14
16
  * Apply the CDN cache adapter's headers to a freshly-streamed response whose
@@ -52,9 +54,6 @@ function buildAppPageCacheTags(pathname, extraTags) {
52
54
  for (const tag of extraTags) if (!tags.includes(tag)) tags.push(tag);
53
55
  return tags.map(encodeCacheTag);
54
56
  }
55
- function buildAppPageCacheControl(cacheState, revalidateSeconds, expireSeconds) {
56
- return buildCachedRevalidateCacheControl(cacheState, revalidateSeconds, expireSeconds);
57
- }
58
57
  function buildAppPageCachedHeaders(options) {
59
58
  const headers = new Headers({
60
59
  "Content-Type": options.contentType,
@@ -87,9 +86,13 @@ function resolveAppPageCacheWritePolicy(options) {
87
86
  }
88
87
  function buildAppPageCachedResponse(cachedValue, options) {
89
88
  const status = options.middlewareStatus ?? (cachedValue.status || 200);
90
- const revalidateSeconds = options.cacheControl?.revalidate ?? options.revalidateSeconds;
91
- const expireSeconds = options.cacheControl === void 0 ? void 0 : options.cacheControl.expire ?? options.expireSeconds;
92
- const cacheControl = buildAppPageCacheControl(options.cacheState, revalidateSeconds, expireSeconds);
89
+ const { cacheControl } = decideIsr({
90
+ cacheState: options.cacheState,
91
+ kind: "app-page",
92
+ revalidateSeconds: options.revalidateSeconds,
93
+ expireSeconds: options.expireSeconds,
94
+ cacheControlMeta: options.cacheControl
95
+ });
93
96
  if (options.isRscRequest) {
94
97
  if (!cachedValue.rscData) return null;
95
98
  const rscHeaders = buildAppPageCachedHeaders({
@@ -119,6 +122,29 @@ function buildAppPageCachedResponse(cachedValue, options) {
119
122
  headers: htmlHeaders
120
123
  });
121
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
+ }
122
148
  async function readAppPageCacheResponse(options) {
123
149
  const isrKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode, options.interceptionContext) : options.isrHtmlKey(options.cleanPathname);
124
150
  const artifact = options.isRscRequest ? "rsc" : "html";
@@ -237,6 +263,43 @@ async function readAppPageCacheResponse(options) {
237
263
  }
238
264
  return null;
239
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
+ }
240
303
  function finalizeAppPageHtmlCacheResponse(response, options) {
241
304
  if (!response.body) return response;
242
305
  const [streamForClient, streamForCache] = response.body.tee();
@@ -332,4 +395,4 @@ function scheduleAppPageRscCacheWrite(options) {
332
395
  return true;
333
396
  }
334
397
  //#endregion
335
- 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,12 +47,19 @@ 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;
51
54
  dynamic?: unknown;
52
55
  revalidate?: unknown;
53
56
  };
57
+ type AppPageDispatchSlot = {
58
+ default?: AppPageModule | null;
59
+ page?: AppPageModule | null;
60
+ slotPatternParts?: readonly string[] | null;
61
+ slotParamNames?: readonly string[] | null;
62
+ };
54
63
  type AppPageDispatchRoute = {
55
64
  __buildTimeClassifications?: LayoutClassificationOptions["buildTimeClassifications"];
56
65
  __buildTimeReasons?: LayoutClassificationOptions["buildTimeReasons"];
@@ -67,6 +76,7 @@ type AppPageDispatchRoute = {
67
76
  params: readonly string[];
68
77
  pattern: string;
69
78
  routeSegments: readonly string[];
79
+ slots?: Readonly<Record<string, AppPageDispatchSlot>>;
70
80
  unauthorized?: AppPageModule | null;
71
81
  unauthorizeds?: readonly (AppPageModule | null | undefined)[];
72
82
  };
@@ -87,6 +97,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
87
97
  buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker) => Promise<AppPageElement>;
88
98
  clientReuseManifest?: ClientReuseManifestParseResult;
89
99
  cleanPathname: string;
100
+ displayPathname?: string;
90
101
  clearRequestContext: () => void;
91
102
  createRscOnErrorHandler: (pathname: string, routePath: string) => AppPageBoundaryOnError;
92
103
  debugClassification?: (layoutId: string, reason: ClassificationReason) => void;
@@ -112,6 +123,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
112
123
  getNavigationContext: () => NavigationContext | null;
113
124
  getSourceRoute: (sourceRouteIndex: number) => TRoute | undefined;
114
125
  hasGenerateStaticParams: boolean;
126
+ hasCustomGlobalError?: boolean;
115
127
  hasPageDefaultExport: boolean;
116
128
  hasPageModule: boolean;
117
129
  handlerStart: number;
@@ -130,6 +142,20 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
130
142
  middlewareContext: AppPageMiddlewareContext;
131
143
  mountedSlotsHeader?: string | null;
132
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;
133
159
  staticParamsValidationParams?: AppPageParams;
134
160
  rootParams?: RootParams;
135
161
  probeLayoutAt: (layoutIndex: number, layoutParamAccess?: AppLayoutParamAccessTracker) => unknown;
@@ -144,10 +170,18 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
144
170
  }, middlewareContext: AppPageMiddlewareContext | null) => Promise<Response | null>;
145
171
  renderToReadableStream: (element: AppPageRenderableElement, options: {
146
172
  onError: AppPageBoundaryOnError;
173
+ signal?: AbortSignal;
147
174
  }) => ReadableStream<Uint8Array>;
175
+ prerenderToReadableStream?: (element: AppPageRenderableElement, options: {
176
+ onError: AppPageBoundaryOnError;
177
+ signal?: AbortSignal;
178
+ }) => Promise<{
179
+ prelude: ReadableStream<Uint8Array>;
180
+ }>;
148
181
  request: Request;
149
182
  revalidateSeconds: number | null;
150
183
  resolveRouteFetchCacheMode?: (route: TRoute) => FetchCacheMode | null;
184
+ resolveRouteDynamicConfig?: (route: TRoute) => string | null | undefined;
151
185
  rootForbiddenModule?: AppPageModule | null;
152
186
  rootNotFoundModule?: AppPageModule | null;
153
187
  rootUnauthorizedModule?: AppPageModule | null;