vinext 1.1.0 → 1.2.1

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 (288) hide show
  1. package/README.md +22 -10
  2. package/dist/build/client-build-config.d.ts +10 -0
  3. package/dist/build/client-build-config.js +18 -2
  4. package/dist/build/output-root-externals.d.ts +21 -0
  5. package/dist/build/output-root-externals.js +40 -0
  6. package/dist/build/pages-client-assets-module.d.ts +8 -0
  7. package/dist/build/pages-client-assets-module.js +21 -1
  8. package/dist/build/prerender-paths.js +6 -4
  9. package/dist/build/prerender.js +1 -1
  10. package/dist/build/run-prerender.js +1 -1
  11. package/dist/build/ssr-manifest.d.ts +2 -0
  12. package/dist/build/ssr-manifest.js +6 -2
  13. package/dist/check.js +12 -12
  14. package/dist/cli-dev-config.js +3 -3
  15. package/dist/cli.js +3 -2
  16. package/dist/client/client-redirect-matcher.d.ts +14 -0
  17. package/dist/client/client-redirect-matcher.js +37 -0
  18. package/dist/client/client-redirects.d.ts +27 -0
  19. package/dist/client/client-redirects.js +28 -0
  20. package/dist/client/client-rewrites.d.ts +2 -1
  21. package/dist/client/client-rewrites.js +1 -1
  22. package/dist/config/config-matchers.d.ts +26 -11
  23. package/dist/config/config-matchers.js +90 -88
  24. package/dist/config/destination-params.d.ts +47 -0
  25. package/dist/config/destination-params.js +116 -0
  26. package/dist/config/next-config.d.ts +7 -0
  27. package/dist/config/next-config.js +3 -0
  28. package/dist/entries/app-rsc-entry.d.ts +4 -0
  29. package/dist/entries/app-rsc-entry.js +20 -6
  30. package/dist/entries/pages-client-entry.js +3 -1
  31. package/dist/entries/pages-server-entry.js +13 -37
  32. package/dist/index.d.ts +3 -1
  33. package/dist/index.js +246 -136
  34. package/dist/init-cloudflare.d.ts +9 -0
  35. package/dist/init-cloudflare.js +107 -31
  36. package/dist/init-platform.d.ts +4 -0
  37. package/dist/init-platform.js +27 -2
  38. package/dist/init.d.ts +2 -1
  39. package/dist/init.js +153 -9
  40. package/dist/plugins/ast-scope.d.ts +7 -0
  41. package/dist/plugins/ast-scope.js +59 -3
  42. package/dist/plugins/ast-utils.d.ts +53 -2
  43. package/dist/plugins/ast-utils.js +90 -2
  44. package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
  45. package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
  46. package/dist/plugins/commonjs-esm-facade.js +2 -2
  47. package/dist/plugins/css-module-imports.js +13 -20
  48. package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
  49. package/dist/plugins/dynamic-preload-metadata.js +11 -11
  50. package/dist/plugins/extensionless-dynamic-import.js +2 -3
  51. package/dist/plugins/fonts.d.ts +1 -1
  52. package/dist/plugins/fonts.js +3 -3
  53. package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
  54. package/dist/plugins/ignore-dynamic-requests.js +5 -7
  55. package/dist/plugins/import-meta-url.js +3 -4
  56. package/dist/plugins/instrumentation-client.js +3 -2
  57. package/dist/plugins/middleware-export-validation.js +2 -3
  58. package/dist/plugins/middleware-server-only.d.ts +5 -4
  59. package/dist/plugins/middleware-server-only.js +8 -5
  60. package/dist/plugins/og-harfbuzz.js +2 -3
  61. package/dist/plugins/optimize-imports.js +3 -4
  62. package/dist/plugins/pages-node-externals.js +3 -4
  63. package/dist/plugins/remove-console.js +2 -18
  64. package/dist/plugins/require-condition-resolution.js +3 -3
  65. package/dist/plugins/require-context.js +2 -3
  66. package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
  67. package/dist/plugins/rsc-scan-glob-imports.js +50 -0
  68. package/dist/plugins/strip-server-exports.js +265 -102
  69. package/dist/plugins/styled-jsx.js +2 -3
  70. package/dist/plugins/transform-result.d.ts +9 -5
  71. package/dist/plugins/transitive-externals.js +1 -1
  72. package/dist/plugins/typeof-window.d.ts +2 -2
  73. package/dist/plugins/use-cache-callable.d.ts +21 -2
  74. package/dist/plugins/use-cache-callable.js +84 -35
  75. package/dist/plugins/worker-image-imports.js +30 -33
  76. package/dist/plugins/worker-server-only-imports.d.ts +20 -0
  77. package/dist/plugins/worker-server-only-imports.js +31 -0
  78. package/dist/plugins/worker-use-server.d.ts +25 -0
  79. package/dist/plugins/worker-use-server.js +153 -0
  80. package/dist/server/api-handler.d.ts +1 -0
  81. package/dist/server/api-handler.js +3 -2
  82. package/dist/server/app-action-forwarding.js +2 -2
  83. package/dist/server/app-browser-action-result.d.ts +1 -1
  84. package/dist/server/app-browser-action-result.js +9 -2
  85. package/dist/server/app-browser-entry.js +3 -3
  86. package/dist/server/app-browser-interception-context.js +1 -1
  87. package/dist/server/app-browser-navigation-controller.js +1 -1
  88. package/dist/server/app-browser-prefetch-response.js +2 -2
  89. package/dist/server/app-browser-server-action-client.js +1 -1
  90. package/dist/server/app-browser-state.js +1 -1
  91. package/dist/server/app-browser-supplemental-refresh.js +1 -1
  92. package/dist/server/app-middleware.d.ts +11 -0
  93. package/dist/server/app-middleware.js +17 -2
  94. package/dist/server/app-optimistic-routing.js +1 -1
  95. package/dist/server/app-page-cache.d.ts +1 -1
  96. package/dist/server/app-page-cache.js +1 -1
  97. package/dist/server/app-page-dispatch.d.ts +3 -1
  98. package/dist/server/app-page-dispatch.js +5 -4
  99. package/dist/server/app-page-ppr-runtime.js +1 -1
  100. package/dist/server/app-page-render-observation.js +1 -1
  101. package/dist/server/app-page-render.js +1 -1
  102. package/dist/server/app-page-request.js +53 -15
  103. package/dist/server/app-page-route-wiring.js +2 -2
  104. package/dist/server/app-pages-bridge.d.ts +1 -1
  105. package/dist/server/app-pages-bridge.js +3 -4
  106. package/dist/server/app-prerender-endpoints.js +9 -6
  107. package/dist/server/app-render-abort-error.d.ts +19 -0
  108. package/dist/server/app-render-abort-error.js +31 -1
  109. package/dist/server/app-request-stage-dispatch.js +6 -2
  110. package/dist/server/app-request-stage-independent-entry.js +29 -9
  111. package/dist/server/app-response-stage-entry.js +11 -3
  112. package/dist/server/app-route-handler-cache.d.ts +1 -0
  113. package/dist/server/app-route-handler-cache.js +1 -0
  114. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  115. package/dist/server/app-route-handler-dispatch.js +5 -2
  116. package/dist/server/app-route-handler-execution.d.ts +1 -0
  117. package/dist/server/app-route-handler-execution.js +1 -0
  118. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  119. package/dist/server/app-route-handler-runtime.js +46 -25
  120. package/dist/server/app-router-entry.js +29 -10
  121. package/dist/server/app-rsc-cache-busting.d.ts +16 -0
  122. package/dist/server/app-rsc-cache-busting.js +30 -13
  123. package/dist/server/app-rsc-errors.js +20 -16
  124. package/dist/server/app-rsc-handler.d.ts +7 -0
  125. package/dist/server/app-rsc-handler.js +89 -39
  126. package/dist/server/app-rsc-request-normalization.js +3 -3
  127. package/dist/server/app-rsc-response-stage.js +5 -3
  128. package/dist/server/app-segment-config.d.ts +2 -1
  129. package/dist/server/app-server-action-execution.d.ts +2 -1
  130. package/dist/server/app-server-action-execution.js +62 -23
  131. package/dist/server/app-ssr-entry.js +7 -5
  132. package/dist/server/app-visited-response-cache.js +2 -2
  133. package/dist/server/app-worker-stages.d.ts +5 -0
  134. package/dist/server/app-worker-stages.js +1 -1
  135. package/dist/server/cacheability-request.js +2 -2
  136. package/dist/server/client-build-files.d.ts +16 -0
  137. package/dist/server/client-build-files.js +36 -0
  138. package/dist/server/client-reuse-manifest.js +1 -1
  139. package/dist/server/config-headers.js +1 -1
  140. package/dist/server/defer-until-stream-consumed.d.ts +2 -1
  141. package/dist/server/defer-until-stream-consumed.js +3 -1
  142. package/dist/server/dev-server.js +39 -28
  143. package/dist/server/dev-stack-sourcemap.js +18 -23
  144. package/dist/server/document-initial-head.d.ts +0 -11
  145. package/dist/server/document-initial-head.js +1 -1
  146. package/dist/server/forwarded-middleware-context.d.ts +5 -0
  147. package/dist/server/forwarded-middleware-context.js +22 -0
  148. package/dist/server/headers.d.ts +4 -1
  149. package/dist/server/headers.js +4 -1
  150. package/dist/server/http-conditional.d.ts +11 -0
  151. package/dist/server/http-conditional.js +10 -1
  152. package/dist/server/http-error-responses.d.ts +1 -1
  153. package/dist/server/image-optimization.d.ts +38 -0
  154. package/dist/server/image-optimization.js +94 -4
  155. package/dist/server/isr-cache.d.ts +10 -0
  156. package/dist/server/isr-cache.js +41 -6
  157. package/dist/server/metadata-route-response.js +11 -10
  158. package/dist/server/middleware-matcher.d.ts +2 -0
  159. package/dist/server/middleware-matcher.js +23 -2
  160. package/dist/server/middleware-path-to-regexp.js +1 -1
  161. package/dist/server/middleware-runtime.d.ts +13 -0
  162. package/dist/server/middleware-runtime.js +38 -25
  163. package/dist/server/middleware.d.ts +1 -1
  164. package/dist/server/middleware.js +3 -1
  165. package/dist/server/multi-stage.d.ts +11 -0
  166. package/dist/server/navigation-planner.js +1 -1
  167. package/dist/server/normalize-path.d.ts +0 -13
  168. package/dist/server/normalize-path.js +1 -34
  169. package/dist/server/open-redirect.d.ts +11 -4
  170. package/dist/server/open-redirect.js +11 -4
  171. package/dist/server/pages-api-route.d.ts +3 -2
  172. package/dist/server/pages-api-route.js +6 -5
  173. package/dist/server/pages-cache-tag.d.ts +12 -0
  174. package/dist/server/pages-cache-tag.js +19 -0
  175. package/dist/server/pages-client-assets.d.ts +2 -0
  176. package/dist/server/pages-data-route.d.ts +10 -0
  177. package/dist/server/pages-data-route.js +21 -3
  178. package/dist/server/pages-document-asset-props.d.ts +5 -1
  179. package/dist/server/pages-document-asset-props.js +13 -5
  180. package/dist/server/pages-document-splice.d.ts +19 -0
  181. package/dist/server/pages-document-splice.js +55 -0
  182. package/dist/server/pages-i18n.d.ts +12 -1
  183. package/dist/server/pages-i18n.js +18 -4
  184. package/dist/server/pages-node-compat.d.ts +16 -5
  185. package/dist/server/pages-node-compat.js +20 -12
  186. package/dist/server/pages-page-data.d.ts +32 -24
  187. package/dist/server/pages-page-data.js +51 -121
  188. package/dist/server/pages-page-handler.d.ts +0 -6
  189. package/dist/server/pages-page-handler.js +189 -127
  190. package/dist/server/pages-page-response.d.ts +12 -6
  191. package/dist/server/pages-page-response.js +42 -35
  192. package/dist/server/pages-request-pipeline.d.ts +10 -2
  193. package/dist/server/pages-request-pipeline.js +41 -22
  194. package/dist/server/pages-request-stage-entry.d.ts +6 -0
  195. package/dist/server/pages-request-stage-entry.js +75 -16
  196. package/dist/server/pages-response-stage-entry.js +4 -0
  197. package/dist/server/pages-revalidate.js +3 -3
  198. package/dist/server/pages-router-entry.js +5 -4
  199. package/dist/server/prerender-manifest.d.ts +3 -3
  200. package/dist/server/prerender-manifest.js +4 -3
  201. package/dist/server/prerender-work-unit-setup.js +4 -0
  202. package/dist/server/prod-server.d.ts +12 -0
  203. package/dist/server/prod-server.js +204 -74
  204. package/dist/server/proper-error.d.ts +4 -0
  205. package/dist/server/proper-error.js +31 -0
  206. package/dist/server/request-pipeline.d.ts +4 -1
  207. package/dist/server/request-pipeline.js +3 -2
  208. package/dist/server/revalidation-request.d.ts +1 -0
  209. package/dist/server/revalidation-request.js +1 -1
  210. package/dist/server/rsc-stream-hints.d.ts +1 -1
  211. package/dist/server/rsc-stream-hints.js +52 -5
  212. package/dist/server/seed-cache.d.ts +1 -0
  213. package/dist/server/seed-cache.js +5 -4
  214. package/dist/server/server-reference-loader.d.ts +4 -0
  215. package/dist/server/server-reference-loader.js +29 -0
  216. package/dist/server/socket-error-backstop.d.ts +9 -1
  217. package/dist/server/socket-error-backstop.js +46 -17
  218. package/dist/server/static-file-signal.d.ts +15 -4
  219. package/dist/server/static-file-signal.js +46 -12
  220. package/dist/server/worker-image-optimization.d.ts +34 -0
  221. package/dist/server/worker-image-optimization.js +99 -0
  222. package/dist/server/worker-stages.d.ts +1 -1
  223. package/dist/server/worker-stages.js +2 -2
  224. package/dist/server/worker-utils.d.ts +8 -3
  225. package/dist/server/worker-utils.js +12 -7
  226. package/dist/shims/app-router-scroll.js +4 -1
  227. package/dist/shims/app-router-tree-context.d.ts +5 -0
  228. package/dist/shims/app-router-tree-context.js +27 -0
  229. package/dist/shims/cache-callable-runtime.d.ts +4 -2
  230. package/dist/shims/cache-callable-runtime.js +21 -12
  231. package/dist/shims/cache-handler.js +1 -9
  232. package/dist/shims/cache-runtime.d.ts +6 -1
  233. package/dist/shims/cache-runtime.js +2 -1
  234. package/dist/shims/cache.d.ts +2 -2
  235. package/dist/shims/cache.js +40 -13
  236. package/dist/shims/cdn-cache.d.ts +8 -0
  237. package/dist/shims/cdn-cache.js +17 -1
  238. package/dist/shims/disable-smooth-scroll.d.ts +3 -0
  239. package/dist/shims/disable-smooth-scroll.js +36 -0
  240. package/dist/shims/document-placeholders.d.ts +19 -0
  241. package/dist/shims/document-placeholders.js +45 -0
  242. package/dist/shims/document.js +21 -5
  243. package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
  244. package/dist/shims/dynamic-preload-chunks.js +13 -9
  245. package/dist/shims/dynamic.d.ts +1 -1
  246. package/dist/shims/dynamic.js +60 -8
  247. package/dist/shims/fetch-cache-state.d.ts +66 -0
  248. package/dist/shims/fetch-cache-state.js +92 -0
  249. package/dist/shims/fetch-cache.d.ts +3 -67
  250. package/dist/shims/fetch-cache.js +160 -125
  251. package/dist/shims/head.d.ts +10 -6
  252. package/dist/shims/head.js +16 -14
  253. package/dist/shims/headers.js +2 -2
  254. package/dist/shims/image.js +2 -1
  255. package/dist/shims/internal/hybrid-client-route-owner-direct.js +1 -1
  256. package/dist/shims/internal/hybrid-client-route-owner.js +1 -0
  257. package/dist/shims/internal/work-store-scope.d.ts +5 -0
  258. package/dist/shims/internal/work-store-scope.js +24 -0
  259. package/dist/shims/link-prefetch.js +5 -4
  260. package/dist/shims/link.js +2 -2
  261. package/dist/shims/navigation.js +34 -9
  262. package/dist/shims/request-context.d.ts +2 -0
  263. package/dist/shims/request-state-types.d.ts +2 -1
  264. package/dist/shims/router.js +21 -32
  265. package/dist/shims/server.d.ts +27 -4
  266. package/dist/shims/server.js +65 -9
  267. package/dist/shims/unified-request-context.d.ts +1 -1
  268. package/dist/shims/url-utils.d.ts +9 -0
  269. package/dist/shims/url-utils.js +15 -4
  270. package/dist/utils/client-runtime-metadata.js +1 -1
  271. package/dist/utils/domain-locale.js +1 -1
  272. package/dist/utils/hash.d.ts +7 -0
  273. package/dist/utils/hash.js +11 -1
  274. package/dist/utils/package-name.d.ts +6 -0
  275. package/dist/utils/package-name.js +12 -1
  276. package/dist/utils/plugin-rsc-version.d.ts +6 -0
  277. package/dist/utils/plugin-rsc-version.js +41 -0
  278. package/dist/utils/prerender-output-paths.js +15 -4
  279. package/dist/utils/public-file-path.d.ts +10 -2
  280. package/dist/utils/public-file-path.js +13 -9
  281. package/dist/utils/public-routes.js +2 -2
  282. package/dist/utils/react-version.d.ts +10 -0
  283. package/dist/utils/react-version.js +39 -16
  284. package/package.json +11 -7
  285. package/dist/build/nitro-route-rules.d.ts +0 -47
  286. package/dist/build/nitro-route-rules.js +0 -79
  287. package/dist/plugins/cache-flight-codec.d.ts +0 -19
  288. package/dist/plugins/cache-flight-codec.js +0 -68
@@ -1,7 +1,7 @@
1
- import { normalizePathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { stripBasePath } from "../utils/base-path.js";
3
2
  import { VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } from "./app-rsc-vary.js";
4
3
  import { NEXT_ACTION_HEADER, RSC_ACTION_HEADER } from "./headers.js";
4
+ import { normalizePathnameForRouteMatch } from "../routing/utils.js";
5
5
  import { normalizePath } from "./normalize-path.js";
6
6
  import { AppElementsWire } from "./app-elements-wire.js";
7
7
  import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
@@ -1,5 +1,5 @@
1
- import { normalizePathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { addBasePathToPathname, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
2
+ import { normalizePathnameForRouteMatch } from "../routing/utils.js";
3
3
  import { normalizePath } from "./normalize-path.js";
4
4
  import { APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_SLOT_BINDINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
5
5
  import "./app-elements.js";
@@ -34,6 +34,8 @@ export type ApplyAppMiddlewareOptions = {
34
34
  * `trailingSlash`.
35
35
  */
36
36
  trailingSlash?: boolean;
37
+ /** next.config `skipTrailingSlashRedirect`, forwarded to `executeMiddleware`. */
38
+ skipTrailingSlashRedirect?: boolean;
37
39
  };
38
40
  export type ApplyAppMiddlewareResult = {
39
41
  kind: "continue";
@@ -43,6 +45,8 @@ export type ApplyAppMiddlewareResult = {
43
45
  /** True when this pathname can match middleware for some request context. */
44
46
  pathnameEligible?: boolean;
45
47
  rewritten: boolean;
48
+ /** False when a same-origin rewrite target was outside the basePath. */
49
+ rewriteHadBasePath?: boolean;
46
50
  search: string | null;
47
51
  } | {
48
52
  kind: "response";
@@ -53,6 +57,13 @@ export type ApplyAppMiddlewareResult = {
53
57
  response: Response;
54
58
  };
55
59
  export declare function isExternalMiddlewareRewrite(rewriteUrl: string, request: Request): boolean;
60
+ /**
61
+ * The request an external rewrite forwards after middleware ran: the complete
62
+ * middleware request-header override, so deleted credentials stay deleted.
63
+ * Flight headers come from the original request, matching Next.js, which
64
+ * treats them as non-overridable.
65
+ */
66
+ export declare function requestWithMiddlewareContextHeaders(request: Request, context: AppMiddlewareContext): Request;
56
67
  export declare function proxyExternalMiddlewareRewrite(request: Request, rewriteUrl: string, context: AppMiddlewareContext): Promise<Response>;
57
68
  export declare function applyAppMiddleware(options: ApplyAppMiddlewareOptions): Promise<ApplyAppMiddlewareResult>;
58
69
  //#endregion
@@ -75,8 +75,17 @@ function restoreFlightHeaders(request, source) {
75
75
  }
76
76
  return changed ? cloneRequestWithHeaders(request, headers) : request;
77
77
  }
78
+ /**
79
+ * The request an external rewrite forwards after middleware ran: the complete
80
+ * middleware request-header override, so deleted credentials stay deleted.
81
+ * Flight headers come from the original request, matching Next.js, which
82
+ * treats them as non-overridable.
83
+ */
84
+ function requestWithMiddlewareContextHeaders(request, context) {
85
+ return restoreFlightHeaders(requestWithMiddlewareRequestHeaders(request, context.requestHeaders ?? context.headers), request);
86
+ }
78
87
  async function proxyExternalMiddlewareRewrite(request, rewriteUrl, context) {
79
- const proxyRequest = restoreFlightHeaders(requestWithMiddlewareRequestHeaders(request, context.requestHeaders ?? context.headers), request);
88
+ const proxyRequest = requestWithMiddlewareContextHeaders(request, context);
80
89
  setHeadersContext(null);
81
90
  setNavigationContext(null);
82
91
  const { proxyExternalRequest } = await import("../config/config-matchers.js");
@@ -129,6 +138,7 @@ function applyForwardedMiddlewareContext(request, context) {
129
138
  if (typeof data.s === "number") context.status = data.s;
130
139
  if (typeof data.r === "string" && data.r.length > 0) return {
131
140
  applied: true,
141
+ rewriteHadBasePath: typeof data.b === "boolean" ? data.b : void 0,
132
142
  rewriteUrl: data.r
133
143
  };
134
144
  return { applied: true };
@@ -143,6 +153,7 @@ async function applyAppMiddleware(options) {
143
153
  let pathnameEligible = forwarded.applied;
144
154
  let cleanPathname = options.cleanPathname;
145
155
  let rewritten = false;
156
+ let rewriteHadBasePath;
146
157
  let search = null;
147
158
  if (forwarded.rewriteUrl) try {
148
159
  if (isExternalMiddlewareRewrite(forwarded.rewriteUrl, options.request)) {
@@ -168,6 +179,7 @@ async function applyAppMiddleware(options) {
168
179
  const rewriteParsed = new URL(forwarded.rewriteUrl, options.request.url);
169
180
  cleanPathname = rewriteParsed.pathname;
170
181
  rewritten = true;
182
+ rewriteHadBasePath = forwarded.rewriteHadBasePath;
171
183
  search = rewriteParsed.search;
172
184
  } catch (e) {
173
185
  console.error("[vinext] Failed to apply forwarded middleware rewrite:", e);
@@ -194,6 +206,7 @@ async function applyAppMiddleware(options) {
194
206
  },
195
207
  requestBodyAlreadyIsolated: true,
196
208
  request: middlewareRequest,
209
+ skipTrailingSlashRedirect: options.skipTrailingSlashRedirect,
197
210
  trailingSlash: options.trailingSlash
198
211
  });
199
212
  } finally {
@@ -243,6 +256,7 @@ async function applyAppMiddleware(options) {
243
256
  const rewriteParsed = new URL(result.rewriteUrl, middlewareRequest.url);
244
257
  cleanPathname = rewriteParsed.pathname;
245
258
  rewritten = true;
259
+ rewriteHadBasePath = result.rewriteHadBasePath;
246
260
  search = rewriteParsed.search;
247
261
  }
248
262
  }
@@ -258,8 +272,9 @@ async function applyAppMiddleware(options) {
258
272
  matched,
259
273
  pathnameEligible,
260
274
  rewritten,
275
+ rewriteHadBasePath,
261
276
  search
262
277
  };
263
278
  }
264
279
  //#endregion
265
- export { FLIGHT_HEADERS, applyAppMiddleware, isExternalMiddlewareRewrite, proxyExternalMiddlewareRewrite };
280
+ export { FLIGHT_HEADERS, applyAppMiddleware, isExternalMiddlewareRewrite, proxyExternalMiddlewareRewrite, requestWithMiddlewareContextHeaders };
@@ -1,6 +1,6 @@
1
1
  import { isUnknownRecord } from "../utils/record.js";
2
- import { buildParams, decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
3
2
  import { stripBasePath } from "../utils/base-path.js";
3
+ import { buildParams, decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
4
4
  import { extractRawRoutePatternParams, matchRoutePattern } from "../routing/route-pattern.js";
5
5
  import { AppElementsWire } from "./app-elements-wire.js";
6
6
  import "./app-elements.js";
@@ -93,7 +93,7 @@ type ReadAppPageFallbackShellCacheResponseOptions = {
93
93
  isEdgeRuntime?: boolean;
94
94
  isrDebug?: AppPageDebugLogger;
95
95
  isrGet: AppPageCacheGetter;
96
- isrHtmlKey: (pathname: string) => string;
96
+ isrFallbackShellHtmlKey: (pathname: string) => string;
97
97
  middlewareHeaders?: Headers | null;
98
98
  middlewareStatus?: number | null;
99
99
  revalidateSeconds: number;
@@ -375,7 +375,7 @@ see more here https://nextjs.org/docs/messages/app-static-to-dynamic-error`);
375
375
  return null;
376
376
  }
377
377
  async function readAppPageFallbackShellCacheResponse(options) {
378
- const isrKey = options.isrHtmlKey(options.fallbackPathname);
378
+ const isrKey = options.isrFallbackShellHtmlKey(options.fallbackPathname);
379
379
  try {
380
380
  const cached = await options.isrGet(isrKey);
381
381
  const cachedValue = getCachedAppPageValue(cached);
@@ -13,7 +13,8 @@ import { AppPageSsrHandler } from "./app-page-stream.js";
13
13
  import { AppRenderErrorContextOverrides } from "./app-rsc-error-handler.js";
14
14
  import { AppPageCacheSetter, ISRCacheEntry } from "./isr-cache.js";
15
15
  import { PprFallbackShellState } from "../shims/ppr-fallback-shell.js";
16
- import { FetchCacheMode } from "../shims/fetch-cache.js";
16
+ import { FetchCacheMode } from "../shims/fetch-cache-state.js";
17
+ import "../shims/fetch-cache.js";
17
18
  import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
18
19
  import { WarmPprFallbackShellCachesOptions } from "./app-ppr-fallback-shell-render.js";
19
20
  import { ValidateAppPageDynamicParamsOptions } from "./app-page-request.js";
@@ -197,6 +198,7 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
197
198
  isRscRequest: boolean;
198
199
  isrDebug?: AppPageDebugLogger;
199
200
  isrGet: AppPageCacheGetter;
201
+ isrFallbackShellHtmlKey: (pathname: string) => string;
200
202
  isrHtmlKey: (pathname: string) => string;
201
203
  isrRscKey: (pathname: string, mountedSlotsHeader?: string | null, renderMode?: AppRscRenderMode, interceptionContext?: string | null, interceptionId?: string | null) => string;
202
204
  isrSet: AppPageCacheSetter;
@@ -1,8 +1,9 @@
1
1
  import { closeAfterResponse, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
2
  import "../utils/protocol-headers.js";
3
- import { getRequestExecutionContext } from "../shims/request-context.js";
4
3
  import { VINEXT_INTERCEPTION_ID_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
5
4
  import "./headers.js";
5
+ import { getRequestExecutionContext } from "../shims/request-context.js";
6
+ import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
6
7
  import { beginRouteCacheability, isRouteCacheabilityIdentityProbe, isRouteCacheabilityProbe, markRouteCacheabilityPatternDynamic, readRouteCacheabilityState } from "../shims/cacheability-classification.js";
7
8
  import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL } from "./app-rsc-render-mode.js";
8
9
  import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, peekDynamicUsage, peekRenderRequestApiUsage, runWithIsolatedDynamicUsage, setHeadersContext } from "../shims/headers.js";
@@ -150,7 +151,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
150
151
  executionContext: getRequestExecutionContext(),
151
152
  unstableCacheRevalidation: "foreground"
152
153
  });
153
- const revalidation = runWithRequestContext(requestContext, async () => {
154
+ const revalidation = runWithRequestContext(requestContext, () => runInWorkStoreScope(async () => {
154
155
  ensureFetchPatch();
155
156
  setRefreshStaleFetchesInForeground(process.env.VINEXT_PRERENDER === "1");
156
157
  setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));
@@ -160,7 +161,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
160
161
  params: options.params
161
162
  });
162
163
  return await runWithFetchDedupe(renderFn);
163
- });
164
+ }));
164
165
  try {
165
166
  return await revalidation;
166
167
  } finally {
@@ -313,7 +314,7 @@ async function dispatchAppPageInner(options) {
313
314
  });
314
315
  const isNeverStoredPath = options.pprRuntime === void 0 && hasNoManifestAdmissionState(route.pattern);
315
316
  const shouldReadCache = !isRouteCacheabilityProbe() && isCacheEligibleRender && !isNeverStoredPath;
316
- const isCacheCandidate = isCacheEligibleRender && isStaticEligible && options.pprRuntime === void 0 && !isNeverStoredPath;
317
+ const isCacheCandidate = isCacheEligibleRender && isStaticEligible && options.pprFallbackShell === void 0 && !isNeverStoredPath;
317
318
  if (shouldReadCache && isStaticEligible) {
318
319
  traceOperation = resolveAppPageTraceOperation({
319
320
  hasRequestSearchParams,
@@ -34,7 +34,7 @@ async function probePprFallbackShellCache(options, fallbackShells, currentRevali
34
34
  isEdgeRuntime: options.isEdgeRuntime,
35
35
  isrDebug: options.isrDebug,
36
36
  isrGet: options.isrGet,
37
- isrHtmlKey: options.isrHtmlKey,
37
+ isrFallbackShellHtmlKey: options.isrFallbackShellHtmlKey,
38
38
  middlewareHeaders: options.middlewareContext.headers,
39
39
  middlewareStatus: options.middlewareContext.status,
40
40
  revalidateSeconds: currentRevalidateSeconds ?? 0,
@@ -1,5 +1,5 @@
1
- import { fnv1a64 } from "../utils/hash.js";
2
1
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
2
+ import { fnv1a64 } from "../utils/hash.js";
3
3
  import { consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage } from "../shims/headers.js";
4
4
  import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
5
5
  import { consumeDynamicFetchObservations } from "../shims/fetch-cache.js";
@@ -1,8 +1,8 @@
1
1
  import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
2
2
  import { bindRequestContext } from "../shims/unified-request-context.js";
3
- import { getRequestExecutionContext } from "../shims/request-context.js";
4
3
  import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_RSC_COMPLETION_METADATA_HEADER } from "./headers.js";
5
4
  import { internalServerErrorResponse } from "./http-error-responses.js";
5
+ import { getRequestExecutionContext } from "../shims/request-context.js";
6
6
  import { isRouteCacheabilityEvaluation, recordRouteCacheabilityClientTraceMetadataMarker } from "../shims/cacheability-classification.js";
7
7
  import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders, isCdnResponsePolicyHeader } from "./cache-control.js";
8
8
  import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
@@ -183,24 +183,62 @@ async function generateIndependentStaticParams(sources, primaryParams, requestPa
183
183
  validated
184
184
  };
185
185
  }
186
- async function generateChainedStaticParams(sources) {
187
- let generatedParams = [];
186
+ function isStaticParamsRowConsistentWithRequest(row, requestParams) {
187
+ const sharedKeys = Object.keys(row).filter((key) => requestParams[key] !== void 0);
188
+ return areStaticParamsAllowed(requestParams, [row], false, sharedKeys);
189
+ }
190
+ function rewritesParentParams(parentParams, item) {
191
+ return Object.keys(item).some((key) => Object.hasOwn(parentParams, key) && JSON.stringify(item[key]) !== JSON.stringify(parentParams[key]));
192
+ }
193
+ async function generateChainedStaticParams(sources, requestParams, results = /* @__PURE__ */ new Map()) {
194
+ let generatedRows = [];
195
+ let skippedParents = false;
196
+ let needsEveryCombination = false;
188
197
  for (const source of sources) {
189
- const hasParentParams = generatedParams.length > 0;
190
- const parents = hasParentParams ? generatedParams : [{}];
191
- const nextParams = [];
192
- for (const parentParams of parents) {
193
- const result = await runWithFetchDedupe(() => source.generateStaticParams({ params: parentParams }));
194
- if (Array.isArray(result) && result.length > 0) {
195
- for (const item of result) if (item !== null && typeof item === "object" && !Array.isArray(item)) nextParams.push({
196
- ...parentParams,
197
- ...item
198
+ let sourceResults = results.get(source);
199
+ if (!sourceResults) {
200
+ sourceResults = /* @__PURE__ */ new Map();
201
+ results.set(source, sourceResults);
202
+ }
203
+ const hasParentParams = generatedRows.length > 0;
204
+ let parents = hasParentParams ? generatedRows : [{
205
+ params: {},
206
+ lineage: ""
207
+ }];
208
+ const nextRows = [];
209
+ if (requestParams) {
210
+ const consistent = parents.filter((row) => isStaticParamsRowConsistentWithRequest(row.params, requestParams));
211
+ parents = consistent.length > 0 ? consistent : parents.slice(0, 1);
212
+ }
213
+ if (hasParentParams && parents.length < generatedRows.length) skippedParents = true;
214
+ for (const parent of parents) {
215
+ let result = sourceResults.get(parent.lineage);
216
+ if (!sourceResults.has(parent.lineage)) {
217
+ result = await runWithFetchDedupe(() => source.generateStaticParams({ params: parent.params }));
218
+ sourceResults.set(parent.lineage, result);
219
+ }
220
+ if (Array.isArray(result) && result.length > 0) result.forEach((item, index) => {
221
+ if (item === null || typeof item !== "object" || Array.isArray(item)) return;
222
+ const row = item;
223
+ if (skippedParents && rewritesParentParams(parent.params, row)) needsEveryCombination = true;
224
+ nextRows.push({
225
+ params: {
226
+ ...parent.params,
227
+ ...row
228
+ },
229
+ lineage: `${parent.lineage}/${index}`
198
230
  });
199
- } else if (hasParentParams) nextParams.push(parentParams);
231
+ });
232
+ else if (hasParentParams) nextRows.push({
233
+ params: parent.params,
234
+ lineage: `${parent.lineage}/-`
235
+ });
200
236
  }
201
- generatedParams = nextParams;
237
+ if (skippedParents && nextRows.length === 0) needsEveryCombination = true;
238
+ generatedRows = nextRows;
202
239
  }
203
- return generatedParams;
240
+ if (needsEveryCombination) return generateChainedStaticParams(sources, null, results);
241
+ return generatedRows.map((row) => row.params);
204
242
  }
205
243
  function normalizeGenerateStaticParams(generateStaticParams) {
206
244
  return (Array.isArray(generateStaticParams) ? generateStaticParams : [generateStaticParams]).flatMap((source) => {
@@ -218,7 +256,7 @@ async function validateAppPageDynamicParams(options) {
218
256
  if (generateStaticParamsSources.length === 0) return notFoundResponse();
219
257
  const chainedSources = generateStaticParamsSources.filter((source) => source.chained);
220
258
  let chainedStaticParams = null;
221
- if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources);
259
+ if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources, generateStaticParamsSources.some((source) => !source.chained) ? null : options.params);
222
260
  const independentChains = /* @__PURE__ */ new Map();
223
261
  for (const source of generateStaticParamsSources.filter((source) => !source.chained)) {
224
262
  const chain = independentChains.get(source.independentChain ?? source) ?? [];
@@ -1,5 +1,5 @@
1
- import { fnv1a64 } from "../utils/hash.js";
2
1
  import { APP_RSC_RENDER_MODE_PREFETCH_EMPTY, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "./app-rsc-render-mode.js";
2
+ import { fnv1a64 } from "../utils/hash.js";
3
3
  import { createInlineScriptTag, escapeHtmlAttr } from "./html.js";
4
4
  import { createAppRenderDependency, registerAppElementRenderDependencies, renderAfterAppDependencies, renderAppComponentWithDependencyBarrier } from "./app-render-dependency.js";
5
5
  import { APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
@@ -289,7 +289,7 @@ function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement, t
289
289
  streamedIconKey
290
290
  });
291
291
  const metadataKey = streamedIconKey ? createStreamedIconKey(pathname, renderedMetadataHtml) : "";
292
- const parserInsertedMetadataHtml = (streamedIconKey ? renderedMetadataHtml.replaceAll(`<link data-vinext-streamed-icon="${STREAMED_ICON_KEY_PLACEHOLDER}:`, `<link data-vinext-streamed-icon="${escapeHtmlAttr(metadataKey)}:`) : renderedMetadataHtml) + createInlineScriptTag(REINSERT_STREAMED_ICONS_SCRIPT, scriptNonce);
292
+ const parserInsertedMetadataHtml = (streamedIconKey ? renderedMetadataHtml.replaceAll(`<link data-vinext-streamed-icon="${STREAMED_ICON_KEY_PLACEHOLDER}:`, () => `<link data-vinext-streamed-icon="${escapeHtmlAttr(metadataKey)}:`) : renderedMetadataHtml) + createInlineScriptTag(REINSERT_STREAMED_ICONS_SCRIPT, scriptNonce);
293
293
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
294
294
  hidden: true,
295
295
  suppressHydrationWarning: true,
@@ -24,7 +24,6 @@ type AppRouteMatch = {
24
24
  type RenderPagesFallbackDependencies = {
25
25
  loadPagesEntry: () => Promise<PagesEntry> | PagesEntry;
26
26
  buildRequestHeaders: (requestHeaders: Headers, middlewareRequestHeaders: Headers) => Headers | null;
27
- decodePathParams: (pathname: string) => string;
28
27
  applyRouteHandlerMiddlewareContext: (response: Response, middlewareContext: AppMiddlewareContext) => Response;
29
28
  /**
30
29
  * Returns the `__prerender_bypass` Set-Cookie header emitted by a
@@ -51,6 +50,7 @@ type RenderPagesFallbackOptions = {
51
50
  initialResponseHeaders?: Headers;
52
51
  matchKind?: "dynamic" | "static";
53
52
  middlewareContext: AppMiddlewareContext;
53
+ /** Raw (still percent-encoded) Pages route URL; defaults to `url.pathname`. */
54
54
  pathname?: string;
55
55
  pagesDataRequest?: Request | null;
56
56
  request: Request;
@@ -1,5 +1,5 @@
1
- import { getRequestExecutionContext } from "../shims/request-context.js";
2
1
  import { cloneRequestWithHeaders, cloneRequestWithUrl } from "./request-pipeline.js";
2
+ import { getRequestExecutionContext } from "../shims/request-context.js";
3
3
  import { beginRouteCacheability } from "../shims/cacheability-classification.js";
4
4
  import { mergeHeaders } from "./worker-utils.js";
5
5
  import { pagesRouteHasPriorityOverAppRoute } from "./hybrid-route-priority.js";
@@ -19,7 +19,7 @@ function applyPagesMiddlewareContext(response, middlewareContext) {
19
19
  */
20
20
  async function renderPagesFallback(options, dependencies) {
21
21
  const { allowRscDocumentFallback = false, appRouteMatch = null, isDataRequest = false, isRscRequest, initialResponseHeaders, matchKind, middlewareContext, pathname = options.url.pathname, pagesDataRequest = null, request, url } = options;
22
- const { loadPagesEntry, buildRequestHeaders, decodePathParams, applyRouteHandlerMiddlewareContext, getDraftModeCookieHeader } = dependencies;
22
+ const { loadPagesEntry, buildRequestHeaders, applyRouteHandlerMiddlewareContext, getDraftModeCookieHeader } = dependencies;
23
23
  if (isRscRequest && !allowRscDocumentFallback) return null;
24
24
  const pagesEntry = await loadPagesEntry();
25
25
  const pagesRequestHeaders = middlewareContext.requestHeaders ? buildRequestHeaders(request.headers, middlewareContext.requestHeaders) : null;
@@ -27,8 +27,7 @@ async function renderPagesFallback(options, dependencies) {
27
27
  if (pagesRequestHeaders) pagesRequest = cloneRequestWithHeaders(request, pagesRequestHeaders);
28
28
  const queryIndex = pathname.indexOf("?");
29
29
  const pagesPathname = queryIndex === -1 ? pathname : pathname.slice(0, queryIndex);
30
- const pagesSearch = queryIndex === -1 ? url.search || "" : pathname.slice(queryIndex);
31
- const pagesUrl = decodePathParams(pagesPathname) + pagesSearch;
30
+ const pagesUrl = pagesPathname + (queryIndex === -1 ? url.search || "" : pathname.slice(queryIndex));
32
31
  if (pagesPathname.startsWith("/api/") || pagesPathname === "/api") {
33
32
  if (typeof pagesEntry.handleApiRoute !== "function") return null;
34
33
  const hasApiMatcher = typeof pagesEntry.matchApiRoute === "function";
@@ -1,5 +1,6 @@
1
1
  import "./headers.js";
2
2
  import { notFoundResponse } from "./http-error-responses.js";
3
+ import { runInWorkStoreScope, runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
3
4
  import { callAppPrerenderStaticParams } from "./app-prerender-static-params.js";
4
5
  //#region src/server/app-prerender-endpoints.ts
5
6
  const JSON_HEADERS = {
@@ -39,13 +40,13 @@ async function handleStaticParamsEndpoint(request, options) {
39
40
  if (typeof generateStaticParams !== "function") return jsonNullResponse();
40
41
  try {
41
42
  const params = parseParentParams(url.searchParams.get("parentParams"));
42
- const result = await callAppPrerenderStaticParams({
43
+ const result = await runInWorkStoreScope(() => callAppPrerenderStaticParams({
43
44
  fn: generateStaticParams,
44
45
  params,
45
46
  pattern,
46
47
  rejectEmptyResults: url.searchParams.get("rejectEmptyResults") === "1",
47
48
  rootParamNamesByPattern: options.rootParamNamesByPattern ?? {}
48
- });
49
+ }));
49
50
  if (result === null) return jsonNullResponse();
50
51
  return jsonResponse(result);
51
52
  } catch (error) {
@@ -63,10 +64,12 @@ async function handlePagesStaticPathsEndpoint(request, options) {
63
64
  try {
64
65
  const getStaticPaths = findPageRoute(await options.loadPagesRoutes?.(), pattern)?.module?.getStaticPaths;
65
66
  if (typeof getStaticPaths !== "function") return jsonNullResponse();
66
- return jsonResponse(await getStaticPaths({
67
- locales: parseLocales(url.searchParams.get("locales")),
68
- defaultLocale: url.searchParams.get("defaultLocale") ?? ""
69
- }));
67
+ const locales = parseLocales(url.searchParams.get("locales"));
68
+ const defaultLocale = url.searchParams.get("defaultLocale") ?? "";
69
+ return jsonResponse(await runOutsideWorkStoreScope(() => getStaticPaths({
70
+ locales,
71
+ defaultLocale
72
+ })));
70
73
  } catch (error) {
71
74
  return jsonResponse({ error: String(error) }, 500);
72
75
  }
@@ -1,3 +1,22 @@
1
1
  //#region src/server/app-render-abort-error.d.ts
2
2
  export declare function isAppRenderAbortError(error: unknown): boolean;
3
+ export type RenderStreamCancellation = {
4
+ /** Records the reason the render's output stream ended early with. */
5
+ record: (reason: unknown) => void;
6
+ /** Whether React is reporting that recorded cancellation as an error. */
7
+ isReason: (error: unknown) => boolean;
8
+ };
9
+ /**
10
+ * Tracks the cancellation of a React render's output stream.
11
+ *
12
+ * React aborts the render with the cancel reason and passes it to `onError`
13
+ * as though the render had failed. Next.js cancels with its own
14
+ * `ResponseAborted`, which `isAppRenderAbortError` skips, but the reason is
15
+ * whatever the consumer chose: Workers runtimes cancel a disconnected
16
+ * response's body with their own (workerd's is `Error("Network connection
17
+ * lost.")`) and a tee picks its own reason for its source (Node passes both
18
+ * branches' reasons). So recognize the cancellation itself rather than the
19
+ * reason's shape.
20
+ */
21
+ export declare function createRenderStreamCancellation(): RenderStreamCancellation;
3
22
  //#endregion
@@ -4,5 +4,35 @@ function isAppRenderAbortError(error) {
4
4
  const name = Reflect.get(error, "name");
5
5
  return name === "AbortError" || name === "ResponseAborted";
6
6
  }
7
+ /**
8
+ * Tracks the cancellation of a React render's output stream.
9
+ *
10
+ * React aborts the render with the cancel reason and passes it to `onError`
11
+ * as though the render had failed. Next.js cancels with its own
12
+ * `ResponseAborted`, which `isAppRenderAbortError` skips, but the reason is
13
+ * whatever the consumer chose: Workers runtimes cancel a disconnected
14
+ * response's body with their own (workerd's is `Error("Network connection
15
+ * lost.")`) and a tee picks its own reason for its source (Node passes both
16
+ * branches' reasons). So recognize the cancellation itself rather than the
17
+ * reason's shape.
18
+ */
19
+ function createRenderStreamCancellation() {
20
+ let cancelled = false;
21
+ let cancelReason;
22
+ return {
23
+ record: (reason) => {
24
+ if (cancelled) return;
25
+ cancelled = true;
26
+ cancelReason = reason;
27
+ },
28
+ isReason: (error) => {
29
+ if (!cancelled) return false;
30
+ if (Object.is(error, cancelReason)) return true;
31
+ if (!(error instanceof Error)) return false;
32
+ if (cancelReason === void 0) return error.message === "The render was aborted by the server without a reason.";
33
+ return typeof cancelReason === "object" && cancelReason !== null && error.message === "The render was aborted by the server with a promise.";
34
+ }
35
+ };
36
+ }
7
37
  //#endregion
8
- export { isAppRenderAbortError };
38
+ export { createRenderStreamCancellation, isAppRenderAbortError };
@@ -1,8 +1,10 @@
1
1
  import "../utils/protocol-headers.js";
2
2
  import "./headers.js";
3
3
  import { restoreStaticFileSignalFromTransport } from "./static-file-signal.js";
4
+ import { attachRequestCfMetadata } from "./request-pipeline.js";
4
5
  import { isDraftModeRequest } from "../shims/headers.js";
5
6
  import { getScriptNonceFromHeaderSources } from "./csp.js";
7
+ import { restoreImageOptimizationSignalFromTransport } from "./image-optimization.js";
6
8
  import { isRouteTreePrefetchRequest } from "./app-route-tree-prefetch.js";
7
9
  import "./app-worker-stages.js";
8
10
  //#region src/server/app-request-stage-dispatch.ts
@@ -29,7 +31,8 @@ async function dispatchAppRequestStage(request, ctx, dispatchResponseStage, opti
29
31
  if (!dispatchResponseStage) throw new Error("App request stage requires a response-stage dispatcher");
30
32
  if (appRequestUsesFullResponseGraph(request, options)) {
31
33
  const staticFileSignalToken = crypto.randomUUID();
32
- const response = await dispatchResponseStage(request, {
34
+ const headRequest = request.method === "HEAD";
35
+ const response = await dispatchResponseStage(headRequest ? attachRequestCfMetadata(new Request(request, { method: "GET" }), request) : request, {
33
36
  kind: "app-full-request",
34
37
  buildId: options.buildId,
35
38
  cacheability: {
@@ -38,6 +41,7 @@ async function dispatchAppRequestStage(request, ctx, dispatchResponseStage, opti
38
41
  resolvedRoutePathname: new URL(request.url).pathname
39
42
  },
40
43
  draftModeCookie: null,
44
+ headRequest,
41
45
  middlewareCookieOverlay: null,
42
46
  prerenderDiscovery: options.prerenderDiscovery,
43
47
  protocolVersion: 11,
@@ -46,7 +50,7 @@ async function dispatchAppRequestStage(request, ctx, dispatchResponseStage, opti
46
50
  staticFileSignalToken,
47
51
  trustedPrerenderState: options.trustedPrerenderState ?? null
48
52
  }, { cache: "bypass" });
49
- return restoreStaticFileSignalFromTransport(response, staticFileSignalToken);
53
+ return await restoreImageOptimizationSignalFromTransport(await restoreStaticFileSignalFromTransport(response, staticFileSignalToken), staticFileSignalToken);
50
54
  }
51
55
  return options.handleRequest(request, ctx, false, dispatchResponseStage, options.probeMode);
52
56
  }
@@ -1,23 +1,28 @@
1
1
  import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
- import { runWithExecutionContext } from "../shims/request-context.js";
3
- import "./server-globals.js";
4
2
  import "./app-rsc-vary.js";
5
3
  import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM, VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./headers.js";
6
4
  import { badRequestResponse } from "./http-error-responses.js";
7
- import { cloneRequestWithHeaders, filterInternalHeaders, guardProtocolRelativeUrl } from "./request-pipeline.js";
5
+ import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, guardProtocolRelativeUrl } from "./request-pipeline.js";
6
+ import { assetPrefixPathname } from "../utils/asset-prefix.js";
7
+ import { runWithExecutionContext } from "../shims/request-context.js";
8
+ import "./server-globals.js";
8
9
  import { getExplicitCdnCacheAdapter } from "../shims/cdn-cache-state.js";
9
10
  import { applyCdnResponseIdentityHeaders, validateCdnRequest } from "./cache-control.js";
10
11
  import { registerLazyDataCacheHandler } from "../shims/cache-handler.js";
11
- import { getImageOptimizer, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
12
+ import { getImageOptimizer, readImageOptimizationSignal } from "./image-optimization.js";
12
13
  import { consumeFrameworkRequestRoute, traceFrameworkRequest } from "./request-tracing.js";
13
14
  import { createStaticAssetRequest, resolveStaticAssetSignal } from "./worker-utils.js";
14
15
  import { readTrustedPrerenderStateFromHeaders } from "./prerender-route-params.js";
16
+ import { resolveClientBuildFile } from "./client-build-files.js";
15
17
  import { createWorkerRevalidationContext } from "./worker-revalidation-context.js";
16
18
  import { createWorkerPrerenderDiscoveryContext, createWorkerPrerenderReadinessResponse } from "./worker-prerender-discovery.js";
17
- import requestRscHandler, { __ensureHybridPagesApplication, __ensureInstrumentation, __imageAllowedWidths, __imageConfig, __prerenderSecret } from "virtual:vinext-app-request-entry";
19
+ import requestRscHandler, { __assetPrefix, __basePath, __clientBuildFiles, __ensureHybridPagesApplication, __ensureInstrumentation, __imageAllowedWidths, __imageConfig, __prerenderSecret } from "virtual:vinext-app-request-entry";
18
20
  import * as configuredCdnCacheAdapters from "virtual:vinext-cdn-cache-adapter";
19
21
  import { registerConfiguredImageOptimizer } from "virtual:vinext-image-adapters";
20
22
  //#region src/server/app-request-stage-independent-entry.ts
23
+ const clientBuildFiles = new Set(__clientBuildFiles);
24
+ const assetPathPrefix = assetPrefixPathname(__assetPrefix);
25
+ const rejectResponseStage = () => Promise.resolve(new Response(null, { status: 404 }));
21
26
  function handleRequestStage(request, env, ctx, dispatchResponseStage) {
22
27
  const originalRequest = request;
23
28
  const handleStage = async () => {
@@ -42,6 +47,7 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
42
47
  (await import("virtual:vinext-cache-adapters")).registerConfiguredCacheAdapters(env);
43
48
  });
44
49
  registerConfiguredImageOptimizer(env);
50
+ const requestCtx = ctx;
45
51
  ctx = createWorkerPrerenderDiscoveryContext(ctx, request, __prerenderSecret);
46
52
  const readinessResponse = createWorkerPrerenderReadinessResponse(ctx, request);
47
53
  let didValidateCdnRequest = false;
@@ -61,7 +67,7 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
61
67
  probeRoute = readWorkerCacheabilityProbeRoute(request);
62
68
  const probeUrl = new URL(request.url);
63
69
  probeUrl.searchParams.delete(VINEXT_CACHEABILITY_PROBE_QUERY_PARAM);
64
- request = new Request(probeUrl, request);
70
+ request = cloneRequestWithUrl(request, probeUrl.href);
65
71
  }
66
72
  }
67
73
  if (!didValidateCdnRequest) {
@@ -69,7 +75,7 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
69
75
  if (cdnValidationResponse) return cdnValidationResponse;
70
76
  }
71
77
  const url = new URL(request.url);
72
- if (isImageOptimizationPath(url.pathname) && assets && getImageOptimizer()) return handleConfiguredImageOptimization(request, (assetPath) => Promise.resolve(assets.fetch(new Request(new URL(assetPath, request.url)))), __imageAllowedWidths, __imageConfig);
78
+ const servesImages = Boolean(assets) && getImageOptimizer() !== null;
73
79
  const protocolRelativeGuard = guardProtocolRelativeUrl(url.pathname, url.search);
74
80
  if (protocolRelativeGuard) return protocolRelativeGuard;
75
81
  try {
@@ -77,6 +83,10 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
77
83
  } catch {
78
84
  return badRequestResponse();
79
85
  }
86
+ if (assets && (request.method === "GET" || request.method === "HEAD")) {
87
+ const clientBuildFile = resolveClientBuildFile(url.pathname, __basePath, clientBuildFiles);
88
+ if (clientBuildFile) return await assets.fetch(createStaticAssetRequest(clientBuildFile, request));
89
+ }
80
90
  const trustedPrerenderState = readTrustedPrerenderStateFromHeaders(request.headers, __prerenderSecret);
81
91
  const filteredHeaders = ctx.isInternalPagesRevalidation ? new Headers(request.headers) : filterInternalHeaders(request.headers);
82
92
  filteredHeaders.delete(VINEXT_PRERENDER_SECRET_HEADER);
@@ -94,8 +104,18 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
94
104
  };
95
105
  const handle = () => requestRscHandler(request, ctx, trackedDispatchResponseStage, probeMode, ctx.isPrerenderPathDiscovery === true, trustedPrerenderState);
96
106
  let response = await runWithExecutionContext(ctx, handle);
97
- if (assets) {
98
- const assetResponse = await resolveStaticAssetSignal(response, { fetchAsset: (path) => Promise.resolve(assets.fetch(createStaticAssetRequest(path, request))) });
107
+ const imageSignal = servesImages ? readImageOptimizationSignal(response) : null;
108
+ if (imageSignal && assets) {
109
+ const { fetchSignalledPublicFile, serveWorkerImageOptimization } = await import("./worker-image-optimization.js");
110
+ response = await serveWorkerImageOptimization(request, imageSignal, __imageAllowedWidths, __imageConfig, {
111
+ assets,
112
+ basePath: __basePath,
113
+ assetPathPrefix,
114
+ clientBuildFiles,
115
+ fetchPublicFile: async (sourceRequest) => fetchSignalledPublicFile(await runWithExecutionContext(requestCtx, () => requestRscHandler(sourceRequest, requestCtx, rejectResponseStage, null, false, null)), sourceRequest, assets)
116
+ });
117
+ } else if (assets) {
118
+ const assetResponse = await resolveStaticAssetSignal(response, { fetchAsset: (path, requestHeaders) => Promise.resolve(assets.fetch(createStaticAssetRequest(path, request, requestHeaders))) });
99
119
  if (assetResponse) response = assetResponse;
100
120
  }
101
121
  if (probeMode && probeRoute && !responseStageDispatched) {