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
@@ -11,7 +11,8 @@ function normalizeAppSsrRenderResult(raw, fallbackCapturedRscData = null) {
11
11
  return {
12
12
  htmlStream: raw,
13
13
  metadataReady: resolvedMetadataReady,
14
- capturedRscData: fallbackCapturedRscData
14
+ capturedRscData: fallbackCapturedRscData,
15
+ shellErrorRecovered: false
15
16
  };
16
17
  }
17
18
  /**
@@ -62,8 +63,10 @@ async function renderAppPageHtmlStream(options) {
62
63
  rootParams: options.rootParams,
63
64
  sideStream: options.sideStream,
64
65
  capturedRscDataRef: options.capturedRscDataRef,
66
+ pprFallbackShellSignal: options.pprFallbackShellSignal,
65
67
  waitForAllReady: options.waitForAllReady,
66
- initialDevServerError: options.initialDevServerError
68
+ initialDevServerError: options.initialDevServerError,
69
+ fallbackToErrorDocumentOnShellError: options.waitForAllReady !== true && options.hasCustomGlobalError === false
67
70
  };
68
71
  return normalizeAppSsrRenderResult(await options.ssrHandler.handleSsr(options.rscStream, options.navigationContext, options.fontData, ssrOptions), options.capturedRscDataRef?.value ?? null);
69
72
  }
@@ -121,13 +124,14 @@ async function renderAppPageHtmlResponse(options) {
121
124
  }
122
125
  async function renderAppPageHtmlStreamWithRecovery(options) {
123
126
  try {
124
- const { htmlStream, metadataReady, capturedRscData, linkHeader } = normalizeAppSsrRenderResult(await options.renderHtmlStream());
127
+ const { htmlStream, metadataReady, capturedRscData, linkHeader, shellErrorRecovered } = normalizeAppSsrRenderResult(await options.renderHtmlStream());
125
128
  options.onShellRendered?.();
126
129
  return {
127
130
  htmlStream,
128
131
  response: null,
129
132
  metadataReady,
130
133
  capturedRscData,
134
+ shellErrorRecovered: shellErrorRecovered === true,
131
135
  linkHeader
132
136
  };
133
137
  } catch (error) {
@@ -136,14 +140,16 @@ async function renderAppPageHtmlStreamWithRecovery(options) {
136
140
  htmlStream: null,
137
141
  response: await options.renderSpecialErrorResponse(specialError),
138
142
  metadataReady: resolvedMetadataReady,
139
- capturedRscData: null
143
+ capturedRscData: null,
144
+ shellErrorRecovered: false
140
145
  };
141
146
  const boundaryResponse = await options.renderErrorBoundaryResponse(error);
142
147
  if (boundaryResponse) return {
143
148
  htmlStream: null,
144
149
  response: boundaryResponse,
145
150
  metadataReady: resolvedMetadataReady,
146
- capturedRscData: null
151
+ capturedRscData: null,
152
+ shellErrorRecovered: false
147
153
  };
148
154
  throw error;
149
155
  }
@@ -166,8 +172,5 @@ function createAppPageRscErrorTracker(baseOnError) {
166
172
  }
167
173
  };
168
174
  }
169
- function shouldRerenderAppPageWithGlobalError(options) {
170
- return Boolean(options.capturedError) && !options.hasLocalBoundary;
171
- }
172
175
  //#endregion
173
- export { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, isAppSsrRenderResult, renderAppPageHtmlResponse, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery, shouldRerenderAppPageWithGlobalError };
176
+ export { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, isAppSsrRenderResult, renderAppPageHtmlResponse, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery };
@@ -3,8 +3,22 @@ import { AppMiddlewareContext } from "./app-middleware.js";
3
3
  //#region src/server/app-pages-bridge.d.ts
4
4
  type PagesEntry = {
5
5
  handleApiRoute?: (request: Request, url: string) => Promise<Response> | Response;
6
+ matchApiRoute?: (url: string, request: Request) => PagesRouteMatch | null;
7
+ matchPageRoute?: (url: string, request: Request) => PagesRouteMatch | null;
6
8
  renderPage?: (request: Request, url: string, query: Record<string, unknown>, parsedUrl: unknown, middlewareRequestHeaders?: Headers | null) => Promise<Response> | Response;
7
9
  };
10
+ type PagesRouteMatch = {
11
+ route: {
12
+ isDynamic: boolean;
13
+ pattern: string;
14
+ };
15
+ };
16
+ type AppRouteMatch = {
17
+ route: {
18
+ isDynamic: boolean;
19
+ pattern: string;
20
+ };
21
+ };
8
22
  type RenderPagesFallbackDependencies = {
9
23
  loadPagesEntry: () => Promise<PagesEntry> | PagesEntry;
10
24
  buildRequestHeaders: (requestHeaders: Headers, middlewareRequestHeaders: Headers) => Headers | null;
@@ -28,8 +42,12 @@ type RenderPagesFallbackDependencies = {
28
42
  getDraftModeCookieHeader: () => string | null | undefined;
29
43
  };
30
44
  type RenderPagesFallbackOptions = {
45
+ allowRscDocumentFallback?: boolean;
46
+ appRouteMatch?: AppRouteMatch | null;
31
47
  isRscRequest: boolean;
48
+ matchKind?: "dynamic" | "static";
32
49
  middlewareContext: AppMiddlewareContext;
50
+ pathname?: string;
33
51
  request: Request;
34
52
  url: URL;
35
53
  };
@@ -1,11 +1,12 @@
1
+ import { pagesRouteHasPriorityOverAppRoute } from "./hybrid-route-priority.js";
1
2
  //#region src/server/app-pages-bridge.ts
2
3
  /**
3
4
  * Fallback handler to route App Router requests to the Pages Router when no App Router route matches.
4
5
  */
5
6
  async function renderPagesFallback(options, dependencies) {
6
- const { isRscRequest, middlewareContext, request, url } = options;
7
+ const { allowRscDocumentFallback = false, appRouteMatch = null, isRscRequest, matchKind, middlewareContext, pathname = options.url.pathname, request, url } = options;
7
8
  const { loadPagesEntry, buildRequestHeaders, decodePathParams, applyRouteHandlerMiddlewareContext, getDraftModeCookieHeader } = dependencies;
8
- if (isRscRequest) return null;
9
+ if (isRscRequest && !allowRscDocumentFallback) return null;
9
10
  const pagesEntry = await loadPagesEntry();
10
11
  const pagesRequestHeaders = middlewareContext.requestHeaders ? buildRequestHeaders(request.headers, middlewareContext.requestHeaders) : null;
11
12
  let pagesRequest = request;
@@ -20,17 +21,33 @@ async function renderPagesFallback(options, dependencies) {
20
21
  }
21
22
  pagesRequest = new Request(request.url, pagesRequestInit);
22
23
  }
23
- const pagesUrl = decodePathParams(url.pathname) + (url.search || "");
24
- const pagesPathname = url.pathname;
24
+ const queryIndex = pathname.indexOf("?");
25
+ const pagesPathname = queryIndex === -1 ? pathname : pathname.slice(0, queryIndex);
26
+ const pagesSearch = queryIndex === -1 ? url.search || "" : pathname.slice(queryIndex);
27
+ const pagesUrl = decodePathParams(pagesPathname) + pagesSearch;
25
28
  if (pagesPathname.startsWith("/api/") || pagesPathname === "/api") {
26
29
  if (typeof pagesEntry.handleApiRoute !== "function") return null;
30
+ const hasApiMatcher = typeof pagesEntry.matchApiRoute === "function";
31
+ const apiMatch = hasApiMatcher ? pagesEntry.matchApiRoute?.(pagesUrl, pagesRequest) ?? null : null;
32
+ if (hasApiMatcher && apiMatch === null) return null;
33
+ if (apiMatch !== null && matchKind === "static" && apiMatch.route.isDynamic) return null;
34
+ if (apiMatch !== null && matchKind === "dynamic" && !apiMatch.route.isDynamic) return null;
35
+ if (appRouteMatch !== null) {
36
+ if (apiMatch === null || !pagesRouteHasPriorityOverAppRoute(apiMatch.route, appRouteMatch.route)) return null;
37
+ }
27
38
  const pagesApiResponse = await pagesEntry.handleApiRoute(pagesRequest, pagesUrl);
28
39
  const draftCookie = getDraftModeCookieHeader();
29
40
  return applyDraftModeCookie(applyRouteHandlerMiddlewareContext(pagesApiResponse, middlewareContext), draftCookie);
30
41
  }
31
42
  if (typeof pagesEntry.renderPage !== "function") return null;
43
+ const hasPageMatcher = typeof pagesEntry.matchPageRoute === "function";
44
+ const pageMatch = hasPageMatcher ? pagesEntry.matchPageRoute?.(pagesUrl, pagesRequest) ?? null : null;
45
+ if (hasPageMatcher && pageMatch === null) return null;
46
+ if (pageMatch !== null && matchKind === "static" && pageMatch.route.isDynamic) return null;
47
+ if (pageMatch !== null && matchKind === "dynamic" && !pageMatch.route.isDynamic) return null;
48
+ if (appRouteMatch !== null && (pageMatch === null || !pagesRouteHasPriorityOverAppRoute(pageMatch.route, appRouteMatch.route))) return null;
32
49
  const pagesRes = await pagesEntry.renderPage(pagesRequest, pagesUrl, {}, void 0, middlewareContext.requestHeaders);
33
- if (pagesRes.status === 404) return null;
50
+ if (pagesRes.status === 404 && pageMatch === null) return null;
34
51
  return applyDraftModeCookie(pagesRes, getDraftModeCookieHeader());
35
52
  }
36
53
  /**
@@ -0,0 +1,17 @@
1
+ import { PprFallbackShellState } from "../shims/ppr-fallback-shell.js";
2
+ import { ReactNode } from "react";
3
+
4
+ //#region src/server/app-ppr-fallback-shell-render.d.ts
5
+ type AppPageBoundaryOnError = (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;
6
+ type AppPageRenderableElement = ReactNode | Record<string, ReactNode>;
7
+ declare function warmPprFallbackShellCaches(options: {
8
+ element: AppPageRenderableElement;
9
+ onError: AppPageBoundaryOnError;
10
+ renderToReadableStream: (element: AppPageRenderableElement, options: {
11
+ onError: AppPageBoundaryOnError;
12
+ signal?: AbortSignal;
13
+ }) => ReadableStream<Uint8Array>;
14
+ state: PprFallbackShellState;
15
+ }): Promise<void>;
16
+ //#endregion
17
+ export { warmPprFallbackShellCaches };
@@ -0,0 +1,26 @@
1
+ import { isPprFallbackShellAbortError, preparePprFallbackShellFinalRender, waitForPprFallbackShellCacheReady } from "../shims/ppr-fallback-shell.js";
2
+ import { readAppPageBinaryStream } from "./app-page-execution.js";
3
+ //#region src/server/app-ppr-fallback-shell-render.ts
4
+ async function warmPprFallbackShellCaches(options) {
5
+ let warmupError = null;
6
+ const warmupDrain = readAppPageBinaryStream(options.renderToReadableStream(options.element, {
7
+ signal: options.state.abortController.signal,
8
+ onError(error, requestInfo, errorContext) {
9
+ if (options.state.abortController.signal.aborted || isPprFallbackShellAbortError(error)) return;
10
+ return options.onError(error, requestInfo, errorContext);
11
+ }
12
+ })).catch((error) => {
13
+ if (options.state.abortController.signal.aborted || isPprFallbackShellAbortError(error)) return;
14
+ warmupError = error;
15
+ });
16
+ try {
17
+ await waitForPprFallbackShellCacheReady(options.state);
18
+ } finally {
19
+ options.state.abortController.abort();
20
+ await warmupDrain;
21
+ preparePprFallbackShellFinalRender(options.state);
22
+ }
23
+ if (warmupError) throw warmupError;
24
+ }
25
+ //#endregion
26
+ export { warmPprFallbackShellCaches };
@@ -9,6 +9,18 @@ type AppPprFallbackShell = {
9
9
  pathname: string;
10
10
  params: Record<string, string | string[]>;
11
11
  };
12
+ /**
13
+ * A fallback-shell cache entry as consumed by the dispatch layer.
14
+ * Produced at build time by the PPR prerender and served at request time
15
+ * when the exact cache entry for a dynamic child param is missing.
16
+ */
17
+ type AppPagePprFallbackCacheShell = {
18
+ fallbackParamNames: readonly string[];
19
+ params: Record<string, string | string[]>;
20
+ pathname: string;
21
+ };
22
+ declare function markAppPprDynamicFallbackShellHtml(html: string): string;
23
+ declare function isAppPprDynamicFallbackShellHtml(html: string): boolean;
12
24
  declare function createAppPprFallbackShell(route: AppPprFallbackShellRoute, matchedParams: Record<string, string | string[]>): AppPprFallbackShell | null;
13
25
  declare function createAppPprFallbackShells(route: AppPprFallbackShellRoute, matchedParams: Record<string, string | string[]>): AppPprFallbackShell[];
14
26
  declare function rewriteAppPprFallbackShellHtmlNavigation(options: {
@@ -18,4 +30,4 @@ declare function rewriteAppPprFallbackShellHtmlNavigation(options: {
18
30
  searchParams: URLSearchParams;
19
31
  }): string;
20
32
  //#endregion
21
- export { createAppPprFallbackShell, createAppPprFallbackShells, rewriteAppPprFallbackShellHtmlNavigation };
33
+ export { AppPagePprFallbackCacheShell, createAppPprFallbackShell, createAppPprFallbackShells, isAppPprDynamicFallbackShellHtml, markAppPprDynamicFallbackShellHtml, rewriteAppPprFallbackShellHtmlNavigation };
@@ -1,6 +1,13 @@
1
1
  import { createInlineScriptTag } from "./html.js";
2
2
  import { createNavigationRuntimeRscMetadataScript } from "./app-ssr-stream.js";
3
3
  //#region src/server/app-ppr-fallback-shell.ts
4
+ const PPR_DYNAMIC_FALLBACK_SHELL_MARKER = "<!--vinext-ppr-dynamic-fallback-shell-->";
5
+ function markAppPprDynamicFallbackShellHtml(html) {
6
+ return html + PPR_DYNAMIC_FALLBACK_SHELL_MARKER;
7
+ }
8
+ function isAppPprDynamicFallbackShellHtml(html) {
9
+ return html.includes(PPR_DYNAMIC_FALLBACK_SHELL_MARKER);
10
+ }
4
11
  function routeRootParamNames(route) {
5
12
  return new Set(route.rootParamNames ?? []);
6
13
  }
@@ -79,4 +86,4 @@ function rewriteAppPprFallbackShellHtmlNavigation(options) {
79
86
  return metadataScript + options.html;
80
87
  }
81
88
  //#endregion
82
- export { createAppPprFallbackShell, createAppPprFallbackShells, rewriteAppPprFallbackShellHtmlNavigation };
89
+ export { createAppPprFallbackShell, createAppPprFallbackShells, isAppPprDynamicFallbackShellHtml, markAppPprDynamicFallbackShellHtml, rewriteAppPprFallbackShellHtmlNavigation };
@@ -2,16 +2,17 @@ import { createRequestContext, runWithRequestContext } from "../shims/unified-re
2
2
  import { getRequestExecutionContext } from "../shims/request-context.js";
3
3
  import { reportRequestError } from "./instrumentation.js";
4
4
  import { consumeDynamicUsage, getAndClearPendingCookies, getDraftModeCookieHeader, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
5
- import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
5
+ import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
6
6
  import { setNavigationContext } from "../shims/navigation.js";
7
7
  import { makeThenableParams } from "../shims/thenable-params.js";
8
+ import { buildPageCacheTags } from "./implicit-tags.js";
8
9
  import { isKnownDynamicAppRoute, isValidHTTPMethod } from "./app-route-handler-runtime.js";
9
10
  import { getAppRouteHandlerRevalidateSeconds, hasAppRouteHandlerDefaultExport, resolveAppRouteHandlerMethod, shouldReadAppRouteHandlerCache } from "./app-route-handler-policy.js";
10
11
  import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
11
- import { buildPageCacheTags } from "./implicit-tags.js";
12
12
  import { applyRouteHandlerMiddlewareContext } from "./app-route-handler-response.js";
13
13
  import { executeAppRouteHandler } from "./app-route-handler-execution.js";
14
14
  import { readAppRouteHandlerCacheResponse } from "./app-route-handler-cache.js";
15
+ import { resolveAppRouteHandlerFetchCacheMode } from "./app-segment-config.js";
15
16
  //#region src/server/app-route-handler-dispatch.ts
16
17
  function isAppRouteHandlerFunction(value) {
17
18
  return typeof value === "function";
@@ -32,6 +33,8 @@ async function runInRouteHandlerRevalidationContext(options, renderFn) {
32
33
  }), async () => {
33
34
  ensureFetchPatch();
34
35
  setCurrentFetchSoftTags(buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments));
36
+ setCurrentFetchCacheMode(options.fetchCacheMode);
37
+ setCurrentForceDynamicFetchDefault(options.dynamicConfig === "force-dynamic");
35
38
  await renderFn();
36
39
  });
37
40
  }
@@ -56,6 +59,9 @@ async function dispatchAppRouteHandler(options) {
56
59
  }), options.middlewareContext);
57
60
  }
58
61
  const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : void 0;
62
+ const fetchCacheMode = resolveAppRouteHandlerFetchCacheMode(handler);
63
+ setCurrentFetchCacheMode(fetchCacheMode);
64
+ setCurrentForceDynamicFetchDefault(handler.dynamic === "force-dynamic");
59
65
  if (revalidateSeconds !== null && shouldReadAppRouteHandlerCache({
60
66
  dynamicConfig: handler.dynamic,
61
67
  handlerFn: resolvedHandlerFn,
@@ -96,6 +102,7 @@ async function dispatchAppRouteHandler(options) {
96
102
  cleanPathname: options.cleanPathname,
97
103
  draftModeSecret: options.draftModeSecret,
98
104
  dynamicConfig: handler.dynamic,
105
+ fetchCacheMode,
99
106
  routePattern: route.pattern,
100
107
  routeSegments: route.routeSegments
101
108
  }, renderFn);
@@ -3,6 +3,7 @@ import { RouteHandlerHttpMethod, RouteHandlerModule } from "./app-route-handler-
3
3
  //#region src/server/app-route-handler-policy.d.ts
4
4
  type AppRouteHandlerModule = {
5
5
  dynamic?: string;
6
+ fetchCache?: unknown;
6
7
  revalidate?: unknown;
7
8
  } & RouteHandlerModule;
8
9
  type AppRouteHandlerFunction = (...args: unknown[]) => unknown;
@@ -1,7 +1,8 @@
1
1
  import "./headers.js";
2
2
  import { processMiddlewareHeaders } from "./request-pipeline.js";
3
3
  import { setCacheStateHeaders } from "./cache-headers.js";
4
- import { NEVER_CACHE_CONTROL, STATIC_CACHE_CONTROL, applyCdnResponseHeaders, buildCachedRevalidateCacheControl } from "./cache-control.js";
4
+ import { applyCdnResponseHeaders } from "./cache-control.js";
5
+ import { buildAppRouteMissIsrCacheControl, decideIsr } from "./isr-decision.js";
5
6
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
6
7
  import { getSetCookieName } from "./cookie-utils.js";
7
8
  //#region src/server/app-route-handler-response.ts
@@ -11,11 +12,6 @@ function hasMiddlewareHeader(headers) {
11
12
  for (const key of headers.keys()) if (key.startsWith("x-middleware-")) return true;
12
13
  return false;
13
14
  }
14
- function buildRouteHandlerCacheControl(cacheState, revalidateSeconds, expireSeconds) {
15
- if (revalidateSeconds === 0) return NEVER_CACHE_CONTROL;
16
- if (revalidateSeconds === Infinity) return STATIC_CACHE_CONTROL;
17
- return buildCachedRevalidateCacheControl(cacheState, revalidateSeconds, expireSeconds);
18
- }
19
15
  function applyRouteHandlerMiddlewareContext(response, middlewareContext) {
20
16
  if (!middlewareContext.headers && middlewareContext.status == null) return response;
21
17
  const responseHeaders = new Headers(response.headers);
@@ -35,9 +31,14 @@ function buildRouteHandlerCachedResponse(cachedValue, options) {
35
31
  for (const [key, value] of Object.entries(cachedValue.headers)) if (Array.isArray(value)) for (const entry of value) headers.append(key, entry);
36
32
  else headers.set(key, value);
37
33
  setCacheStateHeaders(headers, options.cacheState);
38
- const revalidateSeconds = options.cacheControl?.revalidate ?? options.revalidateSeconds;
39
- const expireSeconds = options.cacheControl === void 0 ? void 0 : options.cacheControl.expire ?? options.expireSeconds;
40
- applyCdnResponseHeaders(headers, { cacheControl: buildRouteHandlerCacheControl(options.cacheState, revalidateSeconds, expireSeconds) });
34
+ const { cacheControl } = decideIsr({
35
+ cacheState: options.cacheState,
36
+ kind: "app-route",
37
+ revalidateSeconds: options.revalidateSeconds,
38
+ expireSeconds: options.expireSeconds,
39
+ cacheControlMeta: options.cacheControl
40
+ });
41
+ applyCdnResponseHeaders(headers, { cacheControl });
41
42
  return new Response(options.isHead ? null : cachedValue.body, {
42
43
  status: cachedValue.status,
43
44
  headers
@@ -45,7 +46,7 @@ function buildRouteHandlerCachedResponse(cachedValue, options) {
45
46
  }
46
47
  function applyRouteHandlerRevalidateHeader(response, revalidateSeconds, expireSeconds, tags) {
47
48
  applyCdnResponseHeaders(response.headers, {
48
- cacheControl: buildRouteHandlerCacheControl("HIT", revalidateSeconds, expireSeconds),
49
+ cacheControl: buildAppRouteMissIsrCacheControl(revalidateSeconds, expireSeconds),
49
50
  tags
50
51
  });
51
52
  }
@@ -1,3 +1,4 @@
1
+ import { addBasePathToPathname } from "../utils/base-path.js";
1
2
  import { buildRequestHeadersFromMiddlewareResponse } from "./middleware-request-headers.js";
2
3
  import { NextRequest, RequestCookies, sealRequestCookies, sealRequestHeaders } from "../shims/server.js";
3
4
  //#region src/server/app-route-handler-runtime.ts
@@ -156,7 +157,17 @@ function createTrackedAppRouteRequest(request, options = {}) {
156
157
  }
157
158
  } });
158
159
  };
159
- const wrapRequest = (input) => {
160
+ const wrapRequest = (rawInput) => {
161
+ let input = rawInput;
162
+ if (options.basePath) {
163
+ const inputUrl = new URL(rawInput.url);
164
+ const prefixedPathname = addBasePathToPathname(inputUrl.pathname, options.basePath);
165
+ if (prefixedPathname !== inputUrl.pathname) {
166
+ inputUrl.pathname = prefixedPathname;
167
+ const bodySource = rawInput.body && !rawInput.bodyUsed ? rawInput.clone() : rawInput;
168
+ input = new Request(inputUrl, bodySource);
169
+ }
170
+ }
160
171
  const requestHeaders = options.middlewareHeaders ? buildRequestHeadersFromMiddlewareResponse(input.headers, options.middlewareHeaders) : null;
161
172
  const requestWithOverrides = requestHeaders ? rebuildRequestWithHeaders(input, requestHeaders) : input;
162
173
  const nextRequest = requestWithOverrides instanceof NextRequest ? requestWithOverrides : new NextRequest(requestWithOverrides, { nextConfig: nextConfig ?? void 0 });
@@ -1,9 +1,11 @@
1
1
  import "./server-globals.js";
2
2
  import { runWithExecutionContext } from "../shims/request-context.js";
3
+ import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER } from "./headers.js";
3
4
  import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
4
5
  import { cloneRequestWithHeaders, filterInternalHeaders, isOpenRedirectShaped } from "./request-pipeline.js";
5
6
  import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
6
7
  import { resolveStaticAssetSignal } from "./worker-utils.js";
8
+ import { readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
7
9
  import rscHandler, { __assetPrefix, __basePath } from "virtual:vinext-rsc-entry";
8
10
  import { registerConfiguredCacheAdapters } from "virtual:vinext-cache-adapters";
9
11
  //#region src/server/app-router-entry.ts
@@ -23,7 +25,10 @@ async function handleRequest(request, env, ctx) {
23
25
  }
24
26
  if (isNextStaticPath(url.pathname, __workerBasePath, __workerAssetPathPrefix)) return notFoundStaticAssetResponse();
25
27
  {
28
+ const prerenderRouteParamsPayload = readTrustedPrerenderRouteParams(request);
26
29
  const filteredHeaders = filterInternalHeaders(request.headers);
30
+ const prerenderRouteParamsHeader = serializePrerenderRouteParamsHeader(prerenderRouteParamsPayload);
31
+ if (prerenderRouteParamsHeader !== null) filteredHeaders.set(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, prerenderRouteParamsHeader);
27
32
  request = cloneRequestWithHeaders(request, filteredHeaders);
28
33
  }
29
34
  const handleFn = () => rscHandler(request, ctx);
@@ -1,6 +1,7 @@
1
1
  import { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER } from "./headers.js";
2
2
  import { fnv1a64 } from "../utils/hash.js";
3
3
  import { parseAppRscRenderMode } from "./app-rsc-render-mode.js";
4
+ import { applyDeploymentIdHeader } from "../utils/deployment-id.js";
4
5
  //#region src/server/app-rsc-cache-busting.ts
5
6
  /**
6
7
  * RSC cache-busting hashes cover the headers that make an RSC payload vary.
@@ -148,6 +149,7 @@ function createRscRequestHeaders(options = {}) {
148
149
  Accept: VINEXT_RSC_CONTENT_TYPE,
149
150
  ["RSC"]: "1"
150
151
  });
152
+ applyDeploymentIdHeader(headers);
151
153
  if (options.interceptionContext !== void 0 && options.interceptionContext !== null) headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);
152
154
  if (options.mountedSlotsHeader !== void 0 && options.mountedSlotsHeader !== null) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
153
155
  if (options.clientReuseManifestHeader !== void 0 && options.clientReuseManifestHeader !== null) headers.set(VINEXT_CLIENT_REUSE_MANIFEST_HEADER, options.clientReuseManifestHeader);
@@ -1,4 +1,5 @@
1
1
  import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
2
+ import { ImageConfig } from "./image-optimization.js";
2
3
  import { ClientReuseManifestParseResult } from "./client-reuse-manifest.js";
3
4
  import { RootParams } from "../shims/root-params.js";
4
5
  import { MiddlewareModule } from "./middleware-runtime.js";
@@ -17,6 +18,7 @@ type RootParamNamesMap = Parameters<typeof handleAppPrerenderEndpoint>[1]["rootP
17
18
  type AppRscMiddlewareContext = AppMiddlewareContext;
18
19
  type AppRscHandlerRoute = {
19
20
  isDynamic: boolean;
21
+ params?: readonly string[];
20
22
  page?: unknown;
21
23
  pattern: string;
22
24
  rootParamNames?: readonly string[];
@@ -41,6 +43,17 @@ type DispatchMatchedPageOptions<TRoute> = {
41
43
  middlewareContext: AppRscMiddlewareContext;
42
44
  mountedSlotsHeader: string | null;
43
45
  params: AppPageParams;
46
+ pprFallbackCacheShells?: readonly {
47
+ fallbackParamNames: readonly string[];
48
+ params: AppPageParams;
49
+ pathname: string;
50
+ }[] | null;
51
+ pprFallbackShell?: {
52
+ fallbackParamNames: readonly string[];
53
+ routePattern: string;
54
+ };
55
+ renderedConcreteUrlPaths?: ReadonlySet<string>;
56
+ skipStaticParamsValidation?: boolean;
44
57
  staticParamsValidationParams?: AppPageParams;
45
58
  rootParams?: RootParams;
46
59
  request: Request;
@@ -110,8 +123,17 @@ type RenderNotFoundOptions<TRoute> = {
110
123
  scriptNonce?: string;
111
124
  };
112
125
  type RenderPagesFallbackOptions = {
126
+ allowRscDocumentFallback?: boolean;
127
+ appRouteMatch?: {
128
+ route: {
129
+ isDynamic: boolean;
130
+ pattern: string;
131
+ };
132
+ } | null;
113
133
  isRscRequest: boolean;
134
+ matchKind?: "dynamic" | "static";
114
135
  middlewareContext: AppRscMiddlewareContext;
136
+ pathname?: string;
115
137
  request: Request;
116
138
  url: URL;
117
139
  };
@@ -122,6 +144,7 @@ type NavigationContextValue = {
122
144
  };
123
145
  type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
124
146
  basePath: string;
147
+ cacheComponents?: boolean;
125
148
  clearRequestContext: () => void;
126
149
  configHeaders: NextHeader[];
127
150
  configRedirects: NextRedirect[];
@@ -150,6 +173,8 @@ type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
150
173
  handleProgressiveActionRequest: (options: HandleProgressiveActionRequestOptions) => Promise<Response | ProgressiveActionFormStateResult | null>;
151
174
  handleServerActionRequest: (options: HandleServerActionRequestOptions) => Promise<Response | null>;
152
175
  i18nConfig: NextI18nConfig | null;
176
+ imageConfig?: ImageConfig;
177
+ isDev: boolean;
153
178
  isMiddlewareProxy: boolean;
154
179
  loadPrerenderPagesRoutes?: () => Promise<unknown>;
155
180
  makeThenableParams: MakeThenableParams;