vinext 1.2.0 → 1.3.0

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 (283) hide show
  1. package/README.md +13 -10
  2. package/dist/build/client-build-config.d.ts +64 -3
  3. package/dist/build/client-build-config.js +131 -4
  4. package/dist/build/client-reference-groups.d.ts +163 -0
  5. package/dist/build/client-reference-groups.js +534 -0
  6. package/dist/build/module-dependency-cache.d.ts +31 -0
  7. package/dist/build/module-dependency-cache.js +51 -1
  8. package/dist/build/next-client-runtime-manifests.d.ts +10 -1
  9. package/dist/build/next-client-runtime-manifests.js +19 -4
  10. package/dist/build/nitro-public-files.d.ts +24 -0
  11. package/dist/build/nitro-public-files.js +60 -0
  12. package/dist/build/output-root-externals.d.ts +21 -0
  13. package/dist/build/output-root-externals.js +40 -0
  14. package/dist/build/pages-client-assets-module.js +1 -1
  15. package/dist/build/prerender-paths.js +6 -3
  16. package/dist/build/prerender.js +1 -1
  17. package/dist/build/server-actions-encryption-key.d.ts +23 -0
  18. package/dist/build/server-actions-encryption-key.js +101 -0
  19. package/dist/build/ssr-manifest.d.ts +3 -0
  20. package/dist/build/ssr-manifest.js +10 -1
  21. package/dist/check.js +5 -6
  22. package/dist/cli-dev-config.js +3 -3
  23. package/dist/cli.js +1 -1
  24. package/dist/client/client-rewrite-params.d.ts +9 -0
  25. package/dist/client/client-rewrite-params.js +20 -0
  26. package/dist/client/dev-error-overlay.js +2 -1
  27. package/dist/client/navigation-runtime.d.ts +25 -2
  28. package/dist/client/navigation-runtime.js +42 -11
  29. package/dist/client/vinext-next-data.d.ts +0 -1
  30. package/dist/config/config-matchers.d.ts +15 -40
  31. package/dist/config/config-matchers.js +195 -262
  32. package/dist/config/config-source.d.ts +34 -0
  33. package/dist/config/config-source.js +141 -0
  34. package/dist/config/header-params.d.ts +29 -0
  35. package/dist/config/header-params.js +106 -0
  36. package/dist/config/next-config.d.ts +7 -5
  37. package/dist/config/next-config.js +120 -7
  38. package/dist/entries/app-browser-entry.d.ts +14 -1
  39. package/dist/entries/app-browser-entry.js +26 -36
  40. package/dist/entries/app-rsc-entry.d.ts +2 -0
  41. package/dist/entries/app-rsc-entry.js +92 -57
  42. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  43. package/dist/entries/app-rsc-manifest.js +20 -1
  44. package/dist/entries/app-ssr-entry.d.ts +4 -1
  45. package/dist/entries/app-ssr-entry.js +9 -2
  46. package/dist/entries/pages-client-entry.d.ts +1 -0
  47. package/dist/entries/pages-client-entry.js +6 -6
  48. package/dist/entries/pages-server-entry.js +17 -14
  49. package/dist/index.d.ts +11 -0
  50. package/dist/index.js +350 -175
  51. package/dist/init.d.ts +1 -1
  52. package/dist/init.js +103 -6
  53. package/dist/plugins/ast-utils.d.ts +53 -2
  54. package/dist/plugins/ast-utils.js +90 -2
  55. package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
  56. package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
  57. package/dist/plugins/commonjs-esm-facade.js +2 -2
  58. package/dist/plugins/css-module-imports.js +13 -20
  59. package/dist/plugins/dynamic-preload-metadata.js +2 -3
  60. package/dist/plugins/extensionless-dynamic-import.js +2 -3
  61. package/dist/plugins/fonts.d.ts +1 -1
  62. package/dist/plugins/fonts.js +3 -3
  63. package/dist/plugins/ignore-dynamic-requests.js +2 -3
  64. package/dist/plugins/import-meta-url.js +3 -4
  65. package/dist/plugins/instrumentation-client.js +3 -2
  66. package/dist/plugins/middleware-export-validation.js +2 -3
  67. package/dist/plugins/og-harfbuzz.js +2 -3
  68. package/dist/plugins/optimize-imports.d.ts +25 -2
  69. package/dist/plugins/optimize-imports.js +109 -24
  70. package/dist/plugins/pages-node-externals.js +2 -3
  71. package/dist/plugins/remove-console.js +2 -18
  72. package/dist/plugins/require-condition-resolution.js +3 -3
  73. package/dist/plugins/require-context.js +2 -3
  74. package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
  75. package/dist/plugins/rsc-client-reference-loaders.js +336 -18
  76. package/dist/plugins/strip-server-exports.js +3 -4
  77. package/dist/plugins/styled-jsx.js +2 -3
  78. package/dist/plugins/use-cache-callable.d.ts +26 -2
  79. package/dist/plugins/use-cache-callable.js +101 -36
  80. package/dist/plugins/worker-image-imports.d.ts +1 -0
  81. package/dist/plugins/worker-image-imports.js +31 -34
  82. package/dist/plugins/worker-use-server.js +38 -14
  83. package/dist/routing/app-route-graph.d.ts +1 -1
  84. package/dist/routing/browser-route-manifest.d.ts +43 -0
  85. package/dist/routing/browser-route-manifest.js +195 -0
  86. package/dist/routing/hashed-route-patterns.d.ts +4 -0
  87. package/dist/routing/hashed-route-patterns.js +22 -0
  88. package/dist/routing/optimistic-route-trie.d.ts +27 -0
  89. package/dist/routing/optimistic-route-trie.js +102 -0
  90. package/dist/routing/route-validation.d.ts +6 -1
  91. package/dist/routing/route-validation.js +26 -10
  92. package/dist/server/api-handler.js +1 -1
  93. package/dist/server/app-action-forwarding.d.ts +8 -0
  94. package/dist/server/app-action-forwarding.js +17 -3
  95. package/dist/server/app-browser-entry.js +149 -62
  96. package/dist/server/app-browser-error.d.ts +3 -1
  97. package/dist/server/app-browser-error.js +7 -2
  98. package/dist/server/app-browser-interception-context.d.ts +2 -2
  99. package/dist/server/app-browser-interception-context.js +1 -1
  100. package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
  101. package/dist/server/app-browser-mpa-navigation.js +6 -5
  102. package/dist/server/app-browser-navigation-controller.d.ts +17 -6
  103. package/dist/server/app-browser-navigation-controller.js +88 -26
  104. package/dist/server/app-browser-prefetch-response.js +2 -2
  105. package/dist/server/app-browser-state.d.ts +2 -2
  106. package/dist/server/app-browser-state.js +1 -1
  107. package/dist/server/app-browser-supplemental-refresh.js +1 -1
  108. package/dist/server/app-browser-visible-commit.d.ts +4 -4
  109. package/dist/server/app-client-reference-preloader.d.ts +23 -0
  110. package/dist/server/app-client-reference-preloader.js +30 -7
  111. package/dist/server/app-fallback-renderer.js +2 -1
  112. package/dist/server/app-middleware.d.ts +6 -0
  113. package/dist/server/app-middleware.js +8 -10
  114. package/dist/server/app-optimistic-routing.d.ts +8 -10
  115. package/dist/server/app-optimistic-routing.js +4 -95
  116. package/dist/server/app-page-boundary-render.js +8 -1
  117. package/dist/server/app-page-cache-render.js +1 -0
  118. package/dist/server/app-page-dispatch.js +3 -1
  119. package/dist/server/app-page-render.js +4 -2
  120. package/dist/server/app-page-rsc-render-status.d.ts +1 -0
  121. package/dist/server/app-page-rsc-render-status.js +1 -0
  122. package/dist/server/app-page-search-params-observation.d.ts +1 -4
  123. package/dist/server/app-page-search-params-observation.js +8 -10
  124. package/dist/server/app-page-stream.d.ts +7 -0
  125. package/dist/server/app-page-stream.js +1 -0
  126. package/dist/server/app-pages-bridge.d.ts +2 -1
  127. package/dist/server/app-pages-bridge.js +12 -8
  128. package/dist/server/app-prerender-endpoints.js +1 -1
  129. package/dist/server/app-prerender-static-params.js +3 -2
  130. package/dist/server/app-render-abort-error.d.ts +19 -0
  131. package/dist/server/app-render-abort-error.js +31 -1
  132. package/dist/server/app-render-dependency.js +42 -2
  133. package/dist/server/app-request-stage-independent-entry.js +7 -7
  134. package/dist/server/app-response-stage-entry.js +5 -5
  135. package/dist/server/app-route-handler-dispatch.js +3 -1
  136. package/dist/server/app-route-handler-execution.d.ts +2 -0
  137. package/dist/server/app-route-handler-execution.js +9 -2
  138. package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
  139. package/dist/server/app-route-handler-middleware-context.js +3 -3
  140. package/dist/server/app-route-handler-response.d.ts +2 -1
  141. package/dist/server/app-route-handler-response.js +2 -2
  142. package/dist/server/app-route-handler-runtime.d.ts +2 -0
  143. package/dist/server/app-route-handler-runtime.js +21 -4
  144. package/dist/server/app-route-module-loader.js +7 -6
  145. package/dist/server/app-route-tree.d.ts +20 -0
  146. package/dist/server/app-route-tree.js +18 -0
  147. package/dist/server/app-router-entry.js +7 -7
  148. package/dist/server/app-rsc-cache-busting.d.ts +16 -0
  149. package/dist/server/app-rsc-cache-busting.js +29 -12
  150. package/dist/server/app-rsc-combined-handler.js +8 -1
  151. package/dist/server/app-rsc-errors.d.ts +7 -0
  152. package/dist/server/app-rsc-errors.js +9 -2
  153. package/dist/server/app-rsc-handler.d.ts +4 -1
  154. package/dist/server/app-rsc-handler.js +151 -135
  155. package/dist/server/app-rsc-request-normalization.js +3 -3
  156. package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
  157. package/dist/server/app-rsc-response-finalizer.js +4 -1
  158. package/dist/server/app-rsc-response-stage.js +5 -3
  159. package/dist/server/app-rsc-route-matching.d.ts +1 -0
  160. package/dist/server/app-rsc-route-matching.js +1 -1
  161. package/dist/server/app-server-action-execution.d.ts +23 -6
  162. package/dist/server/app-server-action-execution.js +51 -57
  163. package/dist/server/app-ssr-entry.d.ts +6 -0
  164. package/dist/server/app-ssr-entry.js +21 -11
  165. package/dist/server/app-ssr-stream.d.ts +7 -0
  166. package/dist/server/app-ssr-stream.js +13 -1
  167. package/dist/server/app-visited-response-cache.js +2 -2
  168. package/dist/server/config-headers.js +13 -4
  169. package/dist/server/defer-until-stream-consumed.d.ts +2 -1
  170. package/dist/server/defer-until-stream-consumed.js +3 -1
  171. package/dist/server/dev-server.js +1 -1
  172. package/dist/server/image-optimization.js +1 -0
  173. package/dist/server/isolate-shared-promise.d.ts +10 -0
  174. package/dist/server/isolate-shared-promise.js +33 -0
  175. package/dist/server/isr-cache.js +3 -2
  176. package/dist/server/metadata-route-response.js +2 -2
  177. package/dist/server/middleware-matcher-pattern.d.ts +0 -1
  178. package/dist/server/middleware-matcher-pattern.js +11 -140
  179. package/dist/server/middleware-matcher.js +5 -6
  180. package/dist/server/middleware-response-headers.d.ts +31 -0
  181. package/dist/server/middleware-response-headers.js +57 -1
  182. package/dist/server/middleware-runtime.js +30 -17
  183. package/dist/server/navigation-planner.d.ts +2 -2
  184. package/dist/server/navigation-planner.js +1 -1
  185. package/dist/server/nitro-public-files-plugin.d.ts +38 -0
  186. package/dist/server/nitro-public-files-plugin.js +106 -0
  187. package/dist/server/nitro-public-files.d.ts +21 -0
  188. package/dist/server/nitro-public-files.js +39 -0
  189. package/dist/server/open-redirect.d.ts +11 -4
  190. package/dist/server/open-redirect.js +11 -4
  191. package/dist/server/pages-api-route.js +2 -2
  192. package/dist/server/pages-asset-tags.d.ts +5 -0
  193. package/dist/server/pages-asset-tags.js +9 -2
  194. package/dist/server/pages-client-assets.d.ts +4 -1
  195. package/dist/server/pages-data-route.js +2 -1
  196. package/dist/server/pages-i18n.d.ts +18 -0
  197. package/dist/server/pages-i18n.js +18 -2
  198. package/dist/server/pages-node-compat.d.ts +5 -3
  199. package/dist/server/pages-node-compat.js +35 -16
  200. package/dist/server/pages-page-data.js +1 -1
  201. package/dist/server/pages-page-handler.js +1 -1
  202. package/dist/server/pages-page-response.js +1 -1
  203. package/dist/server/pages-request-pipeline.d.ts +6 -1
  204. package/dist/server/pages-request-pipeline.js +35 -39
  205. package/dist/server/pages-request-stage-entry.js +20 -10
  206. package/dist/server/pages-response-stage-entry.js +1 -1
  207. package/dist/server/pages-revalidate.js +3 -2
  208. package/dist/server/pages-router-entry.js +2 -2
  209. package/dist/server/prod-server.d.ts +2 -2
  210. package/dist/server/prod-server.js +74 -36
  211. package/dist/server/proxy-trust.d.ts +6 -0
  212. package/dist/server/proxy-trust.js +12 -6
  213. package/dist/server/request-pipeline.d.ts +5 -0
  214. package/dist/server/request-pipeline.js +12 -1
  215. package/dist/server/rsc-stream-hints.d.ts +1 -1
  216. package/dist/server/rsc-stream-hints.js +21 -3
  217. package/dist/server/server-reference-loader.js +10 -1
  218. package/dist/server/static-file-cache.js +15 -3
  219. package/dist/server/worker-image-optimization.js +19 -6
  220. package/dist/server/worker-utils.js +1 -1
  221. package/dist/shims/cache-handler.js +3 -2
  222. package/dist/shims/cache-request-state.d.ts +40 -3
  223. package/dist/shims/cache-request-state.js +70 -5
  224. package/dist/shims/cache-runtime.js +47 -19
  225. package/dist/shims/cache.d.ts +2 -2
  226. package/dist/shims/cache.js +17 -8
  227. package/dist/shims/cdn-purge-routes.d.ts +24 -0
  228. package/dist/shims/cdn-purge-routes.js +77 -0
  229. package/dist/shims/dynamic.js +17 -4
  230. package/dist/shims/form.js +8 -3
  231. package/dist/shims/head.js +1 -1
  232. package/dist/shims/headers.js +2 -2
  233. package/dist/shims/image-props.d.ts +93 -0
  234. package/dist/shims/image-props.js +323 -0
  235. package/dist/shims/image.d.ts +4 -18
  236. package/dist/shims/image.js +4 -319
  237. package/dist/shims/internal/headers-state.d.ts +7 -0
  238. package/dist/shims/internal/headers-state.js +14 -2
  239. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
  240. package/dist/shims/internal/hybrid-client-route-owner-direct.js +32 -15
  241. package/dist/shims/internal/hybrid-client-route-owner.js +9 -8
  242. package/dist/shims/link-prefetch.js +5 -4
  243. package/dist/shims/link.js +7 -5
  244. package/dist/shims/navigation.d.ts +1 -1
  245. package/dist/shims/navigation.js +21 -10
  246. package/dist/shims/og.js +35 -10
  247. package/dist/shims/request-context.d.ts +13 -0
  248. package/dist/shims/router.js +28 -52
  249. package/dist/shims/server.d.ts +42 -8
  250. package/dist/shims/server.js +99 -15
  251. package/dist/shims/thenable-params.d.ts +6 -1
  252. package/dist/shims/thenable-params.js +11 -2
  253. package/dist/shims/unified-request-context.d.ts +5 -0
  254. package/dist/shims/unified-request-context.js +2 -0
  255. package/dist/shims/url-utils.d.ts +7 -0
  256. package/dist/shims/url-utils.js +12 -3
  257. package/dist/utils/asset-prefix.d.ts +7 -0
  258. package/dist/utils/asset-prefix.js +10 -1
  259. package/dist/utils/client-build-manifest.js +12 -5
  260. package/dist/utils/client-runtime-metadata.d.ts +1 -0
  261. package/dist/utils/client-runtime-metadata.js +15 -2
  262. package/dist/utils/domain-locale.js +1 -1
  263. package/dist/utils/lazy-chunks.d.ts +4 -0
  264. package/dist/utils/manifest-paths.d.ts +14 -0
  265. package/dist/utils/manifest-paths.js +22 -1
  266. package/dist/utils/path-to-regexp.d.ts +21 -0
  267. package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
  268. package/dist/utils/plugin-react-version.d.ts +15 -0
  269. package/dist/utils/plugin-react-version.js +64 -0
  270. package/dist/utils/plugin-rsc-version.d.ts +2 -0
  271. package/dist/utils/plugin-rsc-version.js +28 -2
  272. package/dist/utils/public-routes.d.ts +2 -0
  273. package/dist/utils/public-routes.js +18 -7
  274. package/dist/utils/react-version.d.ts +7 -0
  275. package/dist/utils/react-version.js +39 -16
  276. package/package.json +6 -6
  277. package/dist/build/nitro-route-rules.d.ts +0 -47
  278. package/dist/build/nitro-route-rules.js +0 -79
  279. package/dist/plugins/cache-flight-codec.d.ts +0 -19
  280. package/dist/plugins/cache-flight-codec.js +0 -68
  281. package/dist/server/middleware-path-to-regexp.d.ts +0 -13
  282. package/dist/utils/regex-safety.d.ts +0 -17
  283. package/dist/utils/regex-safety.js +0 -789
@@ -1,11 +1,9 @@
1
- import { RouteManifest, RouteManifestRoute } from "../routing/app-route-graph.js";
1
+ import { BrowserRouteManifest, BrowserRouteManifestRoute } from "../routing/browser-route-manifest.js";
2
+ import { OptimisticRouteTrieMatch } from "../routing/optimistic-route-trie.js";
2
3
  import { AppElements } from "./app-elements-wire.js";
3
4
  import "./app-elements.js";
4
5
  //#region src/server/app-optimistic-routing.d.ts
5
- type OptimisticRouteMatch = {
6
- params: Record<string, string | string[]>;
7
- route: RouteManifestRoute;
8
- };
6
+ type OptimisticRouteMatch = OptimisticRouteTrieMatch<BrowserRouteManifestRoute>;
9
7
  export type OptimisticRouteTemplate = {
10
8
  elements: AppElements;
11
9
  mountedSlotsHeader: string | null;
@@ -34,12 +32,12 @@ export declare function getOptimisticPrefetchSourceKey(options: {
34
32
  export declare function matchOptimisticRouteManifestRoute(options: {
35
33
  basePath: string;
36
34
  href: string;
37
- routeManifest: RouteManifest;
35
+ routeManifest: BrowserRouteManifest;
38
36
  }): OptimisticRouteMatch | null;
39
37
  export declare function resolveOptimisticNavigationParamsForHref(options: {
40
38
  basePath: string;
41
39
  href: string;
42
- routeManifest: RouteManifest;
40
+ routeManifest: BrowserRouteManifest;
43
41
  }): Record<string, string | string[]> | null;
44
42
  export declare function createOptimisticRouteTemplate(options: {
45
43
  allowLoadingShell?: boolean;
@@ -48,7 +46,7 @@ export declare function createOptimisticRouteTemplate(options: {
48
46
  href: string;
49
47
  interceptionContext: string | null;
50
48
  mountedSlotsHeader: string | null;
51
- routeManifest: RouteManifest;
49
+ routeManifest: BrowserRouteManifest;
52
50
  }): OptimisticRouteTemplate | null;
53
51
  export declare function createOptimisticRouteElements(template: OptimisticRouteTemplate): AppElements;
54
52
  /**
@@ -63,7 +61,7 @@ export declare function canCommitOptimisticRouteTemplate(options: {
63
61
  currentElements: AppElements;
64
62
  currentLayoutIds: readonly string[];
65
63
  currentParams: Readonly<Record<string, string | string[]>>;
66
- routeManifest: RouteManifest;
64
+ routeManifest: BrowserRouteManifest;
67
65
  targetRouteParams: Readonly<Record<string, string | string[]>>;
68
66
  targetUrlParts: readonly string[];
69
67
  template: OptimisticRouteTemplate;
@@ -73,7 +71,7 @@ export declare function resolveOptimisticNavigationPayload(options: {
73
71
  href: string;
74
72
  interceptionContext: string | null;
75
73
  mountedSlotsHeader: string | null;
76
- routeManifest: RouteManifest;
74
+ routeManifest: BrowserRouteManifest;
77
75
  templates: ReadonlyMap<string, OptimisticRouteTemplate>;
78
76
  }): OptimisticNavigationPayload | null;
79
77
  //#endregion
@@ -1,7 +1,8 @@
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 { decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
4
4
  import { extractRawRoutePatternParams, matchRoutePattern } from "../routing/route-pattern.js";
5
+ import { buildOptimisticRouteTrie, matchOptimisticRouteTrie } from "../routing/optimistic-route-trie.js";
5
6
  import { AppElementsWire } from "./app-elements-wire.js";
6
7
  import "./app-elements.js";
7
8
  import { createNestedBfcacheSlotSegmentId, deriveBfcacheSegmentIdentity, isNestedBfcacheSlotSegmentId } from "./bfcache-identity.js";
@@ -17,61 +18,8 @@ function getOptimisticRouteTemplateKey(options) {
17
18
  function getOptimisticPrefetchSourceKey(options) {
18
19
  return `${options.cacheKey}\0${options.interceptionContext ?? ""}\0${options.mountedSlotsHeader ?? ""}`;
19
20
  }
20
- function createNode() {
21
- return {
22
- catchAllChild: null,
23
- dynamicChild: null,
24
- optionalCatchAllChild: null,
25
- route: null,
26
- staticChildren: /* @__PURE__ */ new Map()
27
- };
28
- }
29
21
  function buildRouteTrie(routeManifest) {
30
- const root = createNode();
31
- for (const route of routeManifest.segmentGraph.routes.values()) {
32
- let node = root;
33
- const parts = route.patternParts;
34
- if (parts.length === 0) {
35
- node.route ??= route;
36
- continue;
37
- }
38
- for (const [index, part] of parts.entries()) {
39
- const isTerminal = index === parts.length - 1;
40
- if (part.startsWith(":") && part.endsWith("+")) {
41
- if (isTerminal && node.catchAllChild === null) node.catchAllChild = {
42
- paramName: part.slice(1, -1),
43
- route
44
- };
45
- break;
46
- }
47
- if (part.startsWith(":") && part.endsWith("*")) {
48
- if (isTerminal && node.optionalCatchAllChild === null) node.optionalCatchAllChild = {
49
- paramName: part.slice(1, -1),
50
- route
51
- };
52
- break;
53
- }
54
- if (part.startsWith(":")) {
55
- const paramName = part.slice(1);
56
- if (node.dynamicChild === null) node.dynamicChild = {
57
- node: createNode(),
58
- paramName
59
- };
60
- else if (node.dynamicChild.paramName !== paramName && import.meta.env.DEV) console.warn(`[vinext] Optimistic route trie found conflicting dynamic segments at the same level: :${node.dynamicChild.paramName} vs ${part}`);
61
- node = node.dynamicChild.node;
62
- if (isTerminal) node.route ??= route;
63
- continue;
64
- }
65
- let staticChild = node.staticChildren.get(part);
66
- if (staticChild === void 0) {
67
- staticChild = createNode();
68
- node.staticChildren.set(part, staticChild);
69
- }
70
- node = staticChild;
71
- if (isTerminal) node.route ??= route;
72
- }
73
- }
74
- return root;
22
+ return buildOptimisticRouteTrie(routeManifest.segmentGraph.routes.values(), import.meta.env.DEV ? (existingParamName, part) => console.warn(`[vinext] Optimistic route trie found conflicting dynamic segments at the same level: :${existingParamName} vs ${part}`) : void 0);
75
23
  }
76
24
  function getRouteTrie(routeManifest) {
77
25
  const existing = routeTrieCache.get(routeManifest);
@@ -80,45 +28,6 @@ function getRouteTrie(routeManifest) {
80
28
  routeTrieCache.set(routeManifest, trie);
81
29
  return trie;
82
30
  }
83
- function matchNode(node, urlParts, index, entries) {
84
- if (index === urlParts.length) {
85
- if (node.route !== null) return {
86
- route: node.route,
87
- params: buildParams(entries)
88
- };
89
- if (node.optionalCatchAllChild !== null) return {
90
- route: node.optionalCatchAllChild.route,
91
- params: buildParams(entries)
92
- };
93
- return null;
94
- }
95
- const segment = urlParts[index];
96
- const staticChild = node.staticChildren.get(segment);
97
- if (staticChild !== void 0) return matchNode(staticChild, urlParts, index + 1, entries);
98
- if (node.dynamicChild !== null) {
99
- entries.push([node.dynamicChild.paramName, segment]);
100
- const match = matchNode(node.dynamicChild.node, urlParts, index + 1, entries);
101
- if (match !== null) return match;
102
- entries.pop();
103
- }
104
- if (node.catchAllChild !== null) {
105
- const params = buildParams(entries);
106
- params[node.catchAllChild.paramName] = urlParts.slice(index);
107
- return {
108
- route: node.catchAllChild.route,
109
- params
110
- };
111
- }
112
- if (node.optionalCatchAllChild !== null) {
113
- const params = buildParams(entries);
114
- params[node.optionalCatchAllChild.paramName] = urlParts.slice(index);
115
- return {
116
- route: node.optionalCatchAllChild.route,
117
- params
118
- };
119
- }
120
- return null;
121
- }
122
31
  function hrefToRouteParts(href, basePath) {
123
32
  let url;
124
33
  try {
@@ -138,7 +47,7 @@ function hrefToRouteParts(href, basePath) {
138
47
  function matchOptimisticRouteManifestRoute(options) {
139
48
  const urlParts = hrefToRouteParts(options.href, options.basePath);
140
49
  if (urlParts === null) return null;
141
- const match = matchNode(getRouteTrie(options.routeManifest), urlParts.normalized, 0, []);
50
+ const match = matchOptimisticRouteTrie(getRouteTrie(options.routeManifest), urlParts.normalized);
142
51
  if (match === null) return null;
143
52
  decodeMatchedParams(match.params);
144
53
  return match;
@@ -1,6 +1,7 @@
1
1
  import { stripBasePath } from "../utils/base-path.js";
2
2
  import { isNavigationSignalError } from "../utils/navigation-signal.js";
3
3
  import { NEVER_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
4
+ import { createArtifactCompatibilityEnvelope } from "./artifact-compatibility.js";
4
5
  import { AppElementsWire } from "./app-elements-wire.js";
5
6
  import "./app-elements.js";
6
7
  import DefaultGlobalError from "../shims/default-global-error.js";
@@ -96,14 +97,19 @@ function createAppPageBoundaryRscPayload(options) {
96
97
  const routeId = AppElementsWire.encodeRouteId(options.pathname, null);
97
98
  const layoutEntries = createAppPageBoundaryLayoutEntries(options.route, options.layoutModules);
98
99
  const sourcePageSegments = options.sourcePageSegments ?? options.route?.routeSegments;
100
+ const rootLayoutTreePath = layoutEntries[0]?.treePath ?? null;
99
101
  return {
100
102
  ...AppElementsWire.createMetadataEntries({
101
103
  interceptionContext: null,
102
104
  layoutIds: layoutEntries.map((entry) => entry.id),
103
- rootLayoutTreePath: layoutEntries[0]?.treePath ?? null,
105
+ rootLayoutTreePath,
104
106
  routeId,
105
107
  sourcePage: sourcePageSegments ? createAppPageSourcePage(sourcePageSegments) : null
106
108
  }),
109
+ [AppElementsWire.keys.artifactCompatibility]: createArtifactCompatibilityEnvelope({
110
+ deploymentVersion: process.env.__VINEXT_BUILD_ID ?? null,
111
+ rootBoundaryId: rootLayoutTreePath
112
+ }),
107
113
  [routeId]: options.element
108
114
  };
109
115
  }
@@ -157,6 +163,7 @@ async function renderAppPageBoundaryElementResponse(options) {
157
163
  isCacheCandidate: options.isCacheCandidate,
158
164
  isEdgeRuntime: options.isEdgeRuntime,
159
165
  middlewareHeaders: options.middlewareContext.headers,
166
+ preloadRoutePattern: options.route ? options.route.pattern : null,
160
167
  navigationContext: options.getNavigationContext() ?? {
161
168
  pathname,
162
169
  searchParams: requestUrl.searchParams,
@@ -43,6 +43,7 @@ async function renderAppPageCacheArtifactsImpl(options, renderSpan) {
43
43
  mirrorNextFlight: options.mirrorNextFlight,
44
44
  isStaticGeneration: true,
45
45
  isForceStatic: options.isForceStatic,
46
+ preloadRoutePattern: options.route.pattern,
46
47
  onSsrError: options.onSsrError && options.isCapturedRscError ? createAppPageSsrErrorHandler((error) => {
47
48
  recordAppPageRenderError(renderSpan, error);
48
49
  return options.onSsrError?.(error);
@@ -1,8 +1,8 @@
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
6
  import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
7
7
  import { beginRouteCacheability, isRouteCacheabilityIdentityProbe, isRouteCacheabilityProbe, markRouteCacheabilityPatternDynamic, readRouteCacheabilityState } from "../shims/cacheability-classification.js";
8
8
  import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL } from "./app-rsc-render-mode.js";
@@ -149,6 +149,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
149
149
  currentFetchRevalidate: options.currentFetchRevalidate ?? null,
150
150
  currentForceDynamicFetchDefault: options.dynamicConfig === "force-dynamic",
151
151
  executionContext: getRequestExecutionContext(),
152
+ rootParams: options.rootParams ?? null,
152
153
  unstableCacheRevalidation: "foreground"
153
154
  });
154
155
  const revalidation = runWithRequestContext(requestContext, () => runInWorkStoreScope(async () => {
@@ -388,6 +389,7 @@ async function dispatchAppPageInner(options) {
388
389
  draftModeSecret: options.draftModeSecret,
389
390
  dynamicConfig: revalidationDynamicConfig,
390
391
  params: revalidationTarget.navigationParams,
392
+ rootParams: options.rootParams,
391
393
  routePattern: revalidationTarget.route.pattern,
392
394
  routeSegments: revalidationTarget.route.routeSegments,
393
395
  setNavigationContext: options.setNavigationContext
@@ -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";
@@ -497,7 +497,8 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
497
497
  isForceStatic: options.isForceStatic,
498
498
  loadSsrHandler: options.loadSsrHandler,
499
499
  navigationContext: options.getNavigationContext(),
500
- rootParams: options.rootParams
500
+ rootParams: options.rootParams,
501
+ routePattern: options.routePattern
501
502
  }) : void 0;
502
503
  let requestCacheLifeForPrerender = null;
503
504
  if (shouldWaitForAllReady) await settleCapturedRscRenderForCacheMetadata(capturedRscDataRef.value);
@@ -812,6 +813,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
812
813
  reactMaxHeadersLength: options.reactMaxHeadersLength,
813
814
  rootParams: options.rootParams,
814
815
  pprFallbackShellSignal: options.pprFallbackShellSignal,
816
+ preloadRoutePattern: options.routePattern,
815
817
  formState: options.formState ?? null,
816
818
  rscStream: rscForResponse,
817
819
  scriptNonce: options.scriptNonce,
@@ -31,6 +31,7 @@ type CreateAppPageRscRenderStatusResolverOptions = {
31
31
  loadSsrHandler: () => Promise<AppPageSsrHandler>;
32
32
  navigationContext: NavigationContext | null;
33
33
  rootParams?: RootParams;
34
+ routePattern: string;
34
35
  };
35
36
  /**
36
37
  * Resolve an RSC-only render's status once its Flight payload is complete.
@@ -28,6 +28,7 @@ async function resolveAppPageRscRenderStatus(options) {
28
28
  isForceStatic: options.isForceStatic,
29
29
  isStaticGeneration: true,
30
30
  onSsrError: () => void 0,
31
+ preloadRoutePattern: options.routePattern,
31
32
  rootParams: options.rootParams
32
33
  });
33
34
  } catch (error) {
@@ -1,15 +1,12 @@
1
1
  import { ThenableParams, ThenableParamsObserver } from "../shims/thenable-params.js";
2
2
  import { AppPageSearchParams } from "./app-page-head.js";
3
3
  //#region src/server/app-page-search-params-observation.d.ts
4
- type AppPageSearchParamsObservationOptions = {
5
- observeReactPromiseStatus?: boolean;
6
- };
7
4
  type ClientPageSsrSearchParamsOptions = {
8
5
  isForceStatic?: boolean;
9
6
  isPprFallbackShell?: boolean;
10
7
  };
11
8
  export declare function createAppPageSearchParamsObserver(): ThenableParamsObserver;
12
- export declare function makeObservedAppPageSearchParamsThenable(pageSearchParams: AppPageSearchParams, options?: AppPageSearchParamsObservationOptions): ThenableParams<AppPageSearchParams>;
9
+ export declare function makeObservedAppPageSearchParamsThenable(pageSearchParams: AppPageSearchParams): ThenableParams<AppPageSearchParams>;
13
10
  /**
14
11
  * The `searchParams` a client page receives during SSR (see
15
12
  * `shims/client-page-root.tsx`). Its RSC payload carries no query, so this is
@@ -9,17 +9,15 @@ function markAppPageSearchParamsAccess() {
9
9
  markRenderRequestApiUsage("searchParams");
10
10
  }
11
11
  function createAppPageSearchParamsObserver() {
12
- return { observeParamAccess() {
13
- markAppPageSearchParamsAccess();
14
- } };
12
+ return {
13
+ observeParamAccess() {
14
+ markAppPageSearchParamsAccess();
15
+ },
16
+ observeThenRead: throwIfStaticGenerationAccessError
17
+ };
15
18
  }
16
- function makeObservedAppPageSearchParamsThenable(pageSearchParams, options = {}) {
17
- const observer = createAppPageSearchParamsObserver();
18
- if (options.observeReactPromiseStatus === true) return makeThenableParams(pageSearchParams, {
19
- ...observer,
20
- observeReactPromiseStatus: true
21
- });
22
- return makeThenableParams(pageSearchParams, observer);
19
+ function makeObservedAppPageSearchParamsThenable(pageSearchParams) {
20
+ return makeThenableParams(pageSearchParams, createAppPageSearchParamsObserver());
23
21
  }
24
22
  /**
25
23
  * The `searchParams` a client page receives during SSR (see
@@ -71,6 +71,8 @@ export type AppPageSsrHandler = {
71
71
  };
72
72
  /** Abort signal for a build-time PPR fallback-shell static render. */
73
73
  pprFallbackShellSignal?: AbortSignal;
74
+ /** Route whose client references load before the render; null for none. */
75
+ preloadRoutePattern?: string | null;
74
76
  /** When true, wait for the full React tree before emitting bytes. */
75
77
  waitForAllReady?: boolean;
76
78
  /** Render is producing a static/prerendered HTML artifact. */
@@ -128,6 +130,11 @@ type RenderAppPageHtmlStreamOptions = {
128
130
  };
129
131
  /** Abort signal for a build-time PPR fallback-shell static render. */
130
132
  pprFallbackShellSignal?: AbortSignal;
133
+ /**
134
+ * Route whose client references load before the render, or null for a
135
+ * render without a route. Undefined loads every client reference.
136
+ */
137
+ preloadRoutePattern?: string | null;
131
138
  /** When true, wait for the full React tree before emitting bytes. */
132
139
  waitForAllReady?: boolean;
133
140
  /** Render is producing a static/prerendered HTML artifact. */
@@ -78,6 +78,7 @@ async function renderAppPageHtmlStream(options) {
78
78
  sideStream: options.sideStream,
79
79
  capturedRscDataRef: options.capturedRscDataRef,
80
80
  pprFallbackShellSignal: options.pprFallbackShellSignal,
81
+ preloadRoutePattern: options.preloadRoutePattern,
81
82
  waitForAllReady: options.waitForAllReady,
82
83
  isStaticGeneration: options.isStaticGeneration,
83
84
  isForceStatic: options.isForceStatic,
@@ -1,4 +1,5 @@
1
1
  import { AppMiddlewareContext } from "./app-middleware.js";
2
+ import { MiddlewareResponseMergeOptions } from "./middleware-response-headers.js";
2
3
  import { EdgeApiExecutionRuntime } from "./edge-api-runtime.js";
3
4
  //#region src/server/app-pages-bridge.d.ts
4
5
  export type PagesEntry = {
@@ -24,7 +25,7 @@ type AppRouteMatch = {
24
25
  type RenderPagesFallbackDependencies = {
25
26
  loadPagesEntry: () => Promise<PagesEntry> | PagesEntry;
26
27
  buildRequestHeaders: (requestHeaders: Headers, middlewareRequestHeaders: Headers) => Headers | null;
27
- applyRouteHandlerMiddlewareContext: (response: Response, middlewareContext: AppMiddlewareContext) => Response;
28
+ applyRouteHandlerMiddlewareContext: (response: Response, middlewareContext: AppMiddlewareContext, options?: MiddlewareResponseMergeOptions) => Response;
28
29
  /**
29
30
  * Returns the `__prerender_bypass` Set-Cookie header emitted by a
30
31
  * `draftMode().enable()`/`disable()` call inside middleware, if any. Reading
@@ -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";
@@ -23,15 +23,18 @@ async function renderPagesFallback(options, 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;
26
- let pagesRequest = request;
27
- if (pagesRequestHeaders) pagesRequest = cloneRequestWithHeaders(request, pagesRequestHeaders);
26
+ const matchRequest = pagesRequestHeaders ? new Request(request.url, {
27
+ headers: pagesRequestHeaders,
28
+ method: request.method
29
+ }) : request;
30
+ const claimPagesRequest = () => pagesRequestHeaders ? cloneRequestWithHeaders(request, pagesRequestHeaders) : request;
28
31
  const queryIndex = pathname.indexOf("?");
29
32
  const pagesPathname = queryIndex === -1 ? pathname : pathname.slice(0, queryIndex);
30
33
  const pagesUrl = pagesPathname + (queryIndex === -1 ? url.search || "" : pathname.slice(queryIndex));
31
34
  if (pagesPathname.startsWith("/api/") || pagesPathname === "/api") {
32
35
  if (typeof pagesEntry.handleApiRoute !== "function") return null;
33
36
  const hasApiMatcher = typeof pagesEntry.matchApiRoute === "function";
34
- const apiMatch = hasApiMatcher ? pagesEntry.matchApiRoute?.(pagesUrl, pagesRequest) ?? null : null;
37
+ const apiMatch = hasApiMatcher ? pagesEntry.matchApiRoute?.(pagesUrl, matchRequest) ?? null : null;
35
38
  if (hasApiMatcher && apiMatch === null) return null;
36
39
  if (apiMatch !== null && matchKind === "static" && apiMatch.route.isDynamic) return null;
37
40
  if (apiMatch !== null && matchKind === "dynamic" && !apiMatch.route.isDynamic) return null;
@@ -41,24 +44,25 @@ async function renderPagesFallback(options, dependencies) {
41
44
  if (apiMatch !== null) beginRouteCacheability("pages-api", apiMatch.route.pattern);
42
45
  const executionContext = getRequestExecutionContext();
43
46
  const apiArgs = [
44
- pagesRequest,
47
+ claimPagesRequest(),
45
48
  pagesUrl,
46
49
  executionContext ?? void 0,
47
- executionContext?.trustedRevalidateOrigin ?? new URL(pagesRequest.url).origin,
50
+ executionContext?.trustedRevalidateOrigin,
48
51
  executionContext?.hostRuntime ?? "node"
49
52
  ];
50
53
  const pagesApiResponse = await (initialResponseHeaders ? pagesEntry.handleApiRoute(...apiArgs, initialResponseHeaders) : pagesEntry.handleApiRoute(...apiArgs));
51
54
  const draftCookie = getDraftModeCookieHeader();
52
- return applyDraftModeCookie(applyRouteHandlerMiddlewareContext(pagesApiResponse, middlewareContext), draftCookie);
55
+ return applyDraftModeCookie(applyRouteHandlerMiddlewareContext(pagesApiResponse, middlewareContext, { appendResponseChallenges: false }), draftCookie);
53
56
  }
54
57
  if (typeof pagesEntry.renderPage !== "function") return null;
55
58
  const hasPageMatcher = typeof pagesEntry.matchPageRoute === "function";
56
- const pageMatch = hasPageMatcher ? pagesEntry.matchPageRoute?.(pagesUrl, pagesRequest) ?? null : null;
59
+ const pageMatch = hasPageMatcher ? pagesEntry.matchPageRoute?.(pagesUrl, matchRequest) ?? null : null;
57
60
  if (hasPageMatcher && pageMatch === null) return null;
58
61
  if (pageMatch !== null && matchKind === "static" && pageMatch.route.isDynamic) return null;
59
62
  if (pageMatch !== null && matchKind === "dynamic" && !pageMatch.route.isDynamic) return null;
60
63
  if (appRouteMatch !== null && (pageMatch === null || !pagesRouteHasPriorityOverAppRoute(pageMatch.route, appRouteMatch.route))) return null;
61
64
  if (pageMatch !== null) beginRouteCacheability("pages-page", pageMatch.route.pattern);
65
+ const pagesRequest = claimPagesRequest();
62
66
  const renderArgs = [
63
67
  pagesDataRequest ? cloneRequestWithUrl(pagesRequest, pagesDataRequest.url) : pagesRequest,
64
68
  pagesUrl,
@@ -1,6 +1,6 @@
1
1
  import "./headers.js";
2
- import { runInWorkStoreScope, runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
3
2
  import { notFoundResponse } from "./http-error-responses.js";
3
+ import { runInWorkStoreScope, runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
4
4
  import { callAppPrerenderStaticParams } from "./app-prerender-static-params.js";
5
5
  //#region src/server/app-prerender-endpoints.ts
6
6
  const JSON_HEADERS = {
@@ -1,4 +1,5 @@
1
1
  import { isUnknownRecord } from "../utils/record.js";
2
+ import { shareIsolatePromise } from "./isolate-shared-promise.js";
2
3
  import { pickRootParams, runWithRootParamsScope } from "../shims/root-params.js";
3
4
  //#region src/server/app-prerender-static-params.ts
4
5
  /**
@@ -42,7 +43,7 @@ function createAppPrerenderStaticParamsResolver(sources, rootParamNames) {
42
43
  let resolvePromise = null;
43
44
  const resolveFns = () => {
44
45
  if (resolvedFns) return Promise.resolve(resolvedFns);
45
- if (!resolvePromise) resolvePromise = (async () => {
46
+ if (!resolvePromise) resolvePromise = shareIsolatePromise((async () => {
46
47
  resolvedFns = (await Promise.all(usableSources.map(async (source) => {
47
48
  if (isGenerateStaticParamsFunction(source)) return source;
48
49
  const mod = await source.load();
@@ -50,7 +51,7 @@ function createAppPrerenderStaticParamsResolver(sources, rootParamNames) {
50
51
  return isGenerateStaticParamsFunction(fn) ? fn : null;
51
52
  }))).filter((fn) => fn !== null);
52
53
  return resolvedFns;
53
- })();
54
+ })());
54
55
  return resolvePromise;
55
56
  };
56
57
  return async (input) => {
@@ -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,5 +1,5 @@
1
1
  import { isPromiseLike } from "../utils/promise.js";
2
- import { createElement, use } from "react";
2
+ import { Fragment, createElement, isValidElement, use } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  //#region src/server/app-render-dependency.tsx
5
5
  const REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference");
@@ -21,7 +21,47 @@ function invokeAppComponent(component, props) {
21
21
  if (candidate.$$typeof === REACT_LAZY && candidate._init) return invokeAppComponent(candidate._init(candidate._payload), props);
22
22
  if (candidate.$$typeof === REACT_FORWARD_REF && candidate.render) return candidate.render(props, void 0);
23
23
  if (isReactOwnedAppComponent(candidate)) return createElement(candidate, props);
24
- return candidate(props);
24
+ const result = candidate(props);
25
+ return isPromiseLike(result) ? result : invokeCssWrappedComponent(result, props);
26
+ }
27
+ /**
28
+ * Whether `elementProps` are what `createElement(type, props)` produces: the
29
+ * same values, plus any `type.defaultProps` for keys that are `undefined`.
30
+ * Defaulted values aren't read again, since a default can be a getter.
31
+ */
32
+ function isElementOfProps(elementProps, props, defaultProps) {
33
+ const keys = new Set(Object.keys(props));
34
+ const defaulted = /* @__PURE__ */ new Set();
35
+ for (const key in defaultProps) if (props[key] === void 0) {
36
+ keys.add(key);
37
+ defaulted.add(key);
38
+ }
39
+ return Object.keys(elementProps).length === keys.size && [...keys].every((key) => Object.hasOwn(elementProps, key) && (defaulted.has(key) || Object.is(elementProps[key], props[key])));
40
+ }
41
+ /**
42
+ * `@vitejs/plugin-rsc` wraps a server component export whose module imports
43
+ * CSS (`__vite_rsc_wrap_css__`). The wrapper returns
44
+ * `<><Css /><Component {...props} /></>`, so a component vinext invokes
45
+ * directly renders as an element with its props after all. React's dev build
46
+ * serializes an element's props as debug info and calls `then` on `params`
47
+ * and `searchParams`, which counts as reading them. Invoke the inner
48
+ * component from an element without props instead, as for an export without
49
+ * CSS.
50
+ */
51
+ function invokeCssWrappedComponent(result, props) {
52
+ if (!isValidElement(result) || result.type !== Fragment || result.key !== null) return result;
53
+ const children = result.props.children;
54
+ if (!Array.isArray(children) || children.length !== 2) return result;
55
+ const [css, inner] = children;
56
+ if (!isValidElement(inner) || typeof inner.type !== "function" || inner.key !== null) return result;
57
+ const component = inner.type;
58
+ if (!isElementOfProps(inner.props, props, component.defaultProps)) return result;
59
+ const componentProps = inner.props;
60
+ function CssWrappedComponent() {
61
+ return invokeAppComponent(component, componentProps);
62
+ }
63
+ CssWrappedComponent.displayName = component.displayName ?? component.name;
64
+ return createElement(Fragment, null, css, createElement(CssWrappedComponent));
25
65
  }
26
66
  const appElementRenderDependencies = /* @__PURE__ */ new WeakMap();
27
67
  function registerAppElementRenderDependencies(elements, dependenciesByElementId) {
@@ -1,11 +1,11 @@
1
1
  import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
- import { assetPrefixPathname } from "../utils/asset-prefix.js";
3
- import { runWithExecutionContext } from "../shims/request-context.js";
4
- import "./server-globals.js";
5
2
  import "./app-rsc-vary.js";
6
3
  import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM, VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./headers.js";
7
4
  import { badRequestResponse } from "./http-error-responses.js";
8
- 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";
9
9
  import { getExplicitCdnCacheAdapter } from "../shims/cdn-cache-state.js";
10
10
  import { applyCdnResponseIdentityHeaders, validateCdnRequest } from "./cache-control.js";
11
11
  import { registerLazyDataCacheHandler } from "../shims/cache-handler.js";
@@ -26,7 +26,7 @@ const rejectResponseStage = () => Promise.resolve(new Response(null, { status: 4
26
26
  function handleRequestStage(request, env, ctx, dispatchResponseStage) {
27
27
  const originalRequest = request;
28
28
  const handleStage = async () => {
29
- await __ensureInstrumentation();
29
+ await __ensureInstrumentation(ctx);
30
30
  const url = new URL(request.url);
31
31
  return traceFrameworkRequest({
32
32
  callback: () => handleRequest(request, env, ctx, dispatchResponseStage, ctx?.assets).then((response) => applyCdnResponseIdentityHeaders(response, originalRequest)),
@@ -56,7 +56,7 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
56
56
  if (validationResponse) return validationResponse;
57
57
  didValidateCdnRequest = true;
58
58
  if (readinessResponse.status !== 204) return readinessResponse;
59
- await __ensureHybridPagesApplication();
59
+ await __ensureHybridPagesApplication(ctx);
60
60
  }
61
61
  let probeMode = null;
62
62
  let probeRoute = null;
@@ -67,7 +67,7 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
67
67
  probeRoute = readWorkerCacheabilityProbeRoute(request);
68
68
  const probeUrl = new URL(request.url);
69
69
  probeUrl.searchParams.delete(VINEXT_CACHEABILITY_PROBE_QUERY_PARAM);
70
- request = new Request(probeUrl, request);
70
+ request = cloneRequestWithUrl(request, probeUrl.href);
71
71
  }
72
72
  }
73
73
  if (!didValidateCdnRequest) {