vinext 1.3.1 → 1.4.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 (271) hide show
  1. package/README.md +25 -22
  2. package/THIRD_PARTY_LICENSES.md +47 -0
  3. package/dist/_virtual/_rolldown/runtime.js +3 -2
  4. package/dist/build/prerender.js +4 -3
  5. package/dist/build/report.d.ts +0 -14
  6. package/dist/build/report.js +1 -51
  7. package/dist/check.js +4 -7
  8. package/dist/cli.js +3 -0
  9. package/dist/client/dev-error-overlay-store.d.ts +1 -0
  10. package/dist/client/dev-error-overlay.d.ts +2 -0
  11. package/dist/client/dev-error-overlay.js +20 -4
  12. package/dist/client/navigation-runtime.d.ts +13 -1
  13. package/dist/client/navigation-runtime.js +1 -1
  14. package/dist/config/config-matchers.js +2 -0
  15. package/dist/config/destination-params.d.ts +2 -1
  16. package/dist/config/destination-params.js +52 -2
  17. package/dist/config/next-config.d.ts +25 -0
  18. package/dist/config/next-config.js +82 -4
  19. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
  20. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
  21. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
  22. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
  23. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
  24. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
  25. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
  26. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
  27. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
  28. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
  29. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
  30. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
  31. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
  32. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
  33. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
  34. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
  35. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
  36. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
  37. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
  38. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
  39. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
  40. package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
  41. package/dist/entries/app-rsc-entry.js +17 -49
  42. package/dist/entries/app-rsc-manifest.js +3 -4
  43. package/dist/entries/app-ssr-entry.js +1 -0
  44. package/dist/entries/pages-server-entry.js +36 -9
  45. package/dist/index.js +112 -90
  46. package/dist/init-cloudflare.d.ts +1 -3
  47. package/dist/init-cloudflare.js +10 -48
  48. package/dist/init-platform.d.ts +2 -0
  49. package/dist/init-platform.js +4 -0
  50. package/dist/plugins/extensionless-dynamic-import.js +6 -2
  51. package/dist/plugins/next-intl-catalog.d.ts +12 -0
  52. package/dist/plugins/next-intl-catalog.js +85 -0
  53. package/dist/plugins/pages-node-externals.d.ts +1 -0
  54. package/dist/plugins/pages-node-externals.js +1 -1
  55. package/dist/plugins/strip-server-exports.js +2 -1
  56. package/dist/plugins/use-cache-callable.d.ts +1 -1
  57. package/dist/plugins/use-cache-callable.js +136 -94
  58. package/dist/routing/app-route-graph.d.ts +6 -0
  59. package/dist/routing/app-route-graph.js +9 -1
  60. package/dist/server/api-handler.js +21 -5
  61. package/dist/server/app-bfcache-identity.js +1 -1
  62. package/dist/server/app-browser-entry.js +86 -66
  63. package/dist/server/app-browser-history-controller.d.ts +5 -4
  64. package/dist/server/app-browser-history-controller.js +93 -15
  65. package/dist/server/app-browser-navigation-controller.d.ts +2 -2
  66. package/dist/server/app-browser-navigation-controller.js +1 -2
  67. package/dist/server/app-browser-rsc-redirect.js +7 -7
  68. package/dist/server/app-browser-server-action-client.d.ts +2 -0
  69. package/dist/server/app-browser-server-action-client.js +5 -4
  70. package/dist/server/app-browser-state.d.ts +2 -4
  71. package/dist/server/app-browser-state.js +9 -4
  72. package/dist/server/app-browser-supplemental-refresh.js +16 -1
  73. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  74. package/dist/server/app-browser-visible-commit.js +4 -14
  75. package/dist/server/app-elements-wire.d.ts +6 -38
  76. package/dist/server/app-elements-wire.js +4 -41
  77. package/dist/server/app-elements.d.ts +2 -2
  78. package/dist/server/app-elements.js +2 -2
  79. package/dist/server/app-history-state.d.ts +2 -2
  80. package/dist/server/app-history-state.js +5 -2
  81. package/dist/server/app-mounted-layouts.d.ts +21 -0
  82. package/dist/server/app-mounted-layouts.js +67 -0
  83. package/dist/server/app-optimistic-routing.d.ts +19 -1
  84. package/dist/server/app-optimistic-routing.js +43 -4
  85. package/dist/server/app-page-boundary-render.js +10 -14
  86. package/dist/server/app-page-boundary.js +2 -2
  87. package/dist/server/app-page-cache-finalizer.d.ts +12 -1
  88. package/dist/server/app-page-cache-finalizer.js +70 -29
  89. package/dist/server/app-page-cache.d.ts +13 -1
  90. package/dist/server/app-page-cache.js +31 -9
  91. package/dist/server/app-page-dispatch.d.ts +5 -11
  92. package/dist/server/app-page-dispatch.js +84 -155
  93. package/dist/server/app-page-element-builder.d.ts +2 -2
  94. package/dist/server/app-page-element-builder.js +13 -12
  95. package/dist/server/app-page-execution.d.ts +17 -52
  96. package/dist/server/app-page-execution.js +102 -95
  97. package/dist/server/app-page-head.d.ts +13 -0
  98. package/dist/server/app-page-head.js +44 -16
  99. package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
  100. package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
  101. package/dist/server/app-page-layout-gate.d.ts +35 -0
  102. package/dist/server/app-page-layout-gate.js +50 -0
  103. package/dist/server/app-page-params.d.ts +0 -1
  104. package/dist/server/app-page-params.js +1 -14
  105. package/dist/server/app-page-probe.d.ts +3 -21
  106. package/dist/server/app-page-probe.js +4 -37
  107. package/dist/server/app-page-render.d.ts +2 -13
  108. package/dist/server/app-page-render.js +103 -234
  109. package/dist/server/app-page-request.d.ts +1 -3
  110. package/dist/server/app-page-request.js +1 -1
  111. package/dist/server/app-page-response.js +3 -3
  112. package/dist/server/app-page-route-wiring.d.ts +13 -6
  113. package/dist/server/app-page-route-wiring.js +86 -63
  114. package/dist/server/app-page-rsc-render-status.d.ts +27 -1
  115. package/dist/server/app-page-rsc-render-status.js +121 -13
  116. package/dist/server/app-page-stream.d.ts +12 -8
  117. package/dist/server/app-page-stream.js +4 -3
  118. package/dist/server/app-pages-bridge.d.ts +4 -0
  119. package/dist/server/app-pages-bridge.js +7 -3
  120. package/dist/server/app-render-dependency.d.ts +11 -4
  121. package/dist/server/app-render-dependency.js +86 -38
  122. package/dist/server/app-request-stage-dispatch.js +1 -1
  123. package/dist/server/app-request-stage-independent-entry.js +1 -1
  124. package/dist/server/app-route-handler-cache.js +2 -2
  125. package/dist/server/app-route-handler-dispatch.js +14 -9
  126. package/dist/server/app-route-handler-execution.js +11 -5
  127. package/dist/server/app-route-handler-policy.d.ts +1 -1
  128. package/dist/server/app-route-handler-policy.js +3 -3
  129. package/dist/server/app-route-handler-response.js +1 -1
  130. package/dist/server/app-route-handler-runtime.d.ts +1 -1
  131. package/dist/server/app-route-handler-runtime.js +28 -11
  132. package/dist/server/app-router-entry.js +1 -1
  133. package/dist/server/app-rsc-cache-busting.d.ts +12 -12
  134. package/dist/server/app-rsc-cache-busting.js +31 -72
  135. package/dist/server/app-rsc-error-handler.d.ts +2 -1
  136. package/dist/server/app-rsc-error-handler.js +10 -2
  137. package/dist/server/app-rsc-errors.d.ts +8 -0
  138. package/dist/server/app-rsc-errors.js +11 -1
  139. package/dist/server/app-rsc-handler.d.ts +5 -5
  140. package/dist/server/app-rsc-handler.js +80 -83
  141. package/dist/server/app-rsc-request-normalization.d.ts +10 -16
  142. package/dist/server/app-rsc-request-normalization.js +12 -18
  143. package/dist/server/app-rsc-response-finalizer.js +2 -2
  144. package/dist/server/app-rsc-response-stage.js +9 -15
  145. package/dist/server/app-server-action-execution.d.ts +3 -1
  146. package/dist/server/app-server-action-execution.js +15 -8
  147. package/dist/server/app-ssr-entry.d.ts +8 -0
  148. package/dist/server/app-ssr-entry.js +22 -16
  149. package/dist/server/app-ssr-stream.js +1 -1
  150. package/dist/server/app-visited-response-cache.d.ts +36 -1
  151. package/dist/server/app-visited-response-cache.js +46 -5
  152. package/dist/server/app-worker-stages.d.ts +37 -6
  153. package/dist/server/app-worker-stages.js +81 -9
  154. package/dist/server/artifact-compatibility.d.ts +0 -1
  155. package/dist/server/artifact-compatibility.js +1 -10
  156. package/dist/server/bfcache-identity.d.ts +7 -0
  157. package/dist/server/bfcache-identity.js +10 -1
  158. package/dist/server/cache-proof.d.ts +1 -115
  159. package/dist/server/cache-proof.js +1 -544
  160. package/dist/server/cacheability-manifest.js +1 -2
  161. package/dist/server/cacheability-request.js +13 -8
  162. package/dist/server/dev-origin-check.d.ts +2 -1
  163. package/dist/server/dev-origin-check.js +2 -1
  164. package/dist/server/dev-server.js +6 -4
  165. package/dist/server/headers.d.ts +6 -3
  166. package/dist/server/headers.js +9 -5
  167. package/dist/server/image-optimization.d.ts +5 -0
  168. package/dist/server/image-optimization.js +6 -1
  169. package/dist/server/isr-cache.d.ts +8 -2
  170. package/dist/server/isr-cache.js +30 -2
  171. package/dist/server/metadata-route-response.js +32 -15
  172. package/dist/server/middleware-matcher.js +19 -6
  173. package/dist/server/middleware-runtime.js +6 -2
  174. package/dist/server/multi-stage.d.ts +57 -12
  175. package/dist/server/multi-stage.js +13 -1
  176. package/dist/server/navigation-planner.js +1 -1
  177. package/dist/server/pages-api-route.js +28 -19
  178. package/dist/server/pages-media-type.d.ts +21 -1
  179. package/dist/server/pages-media-type.js +69 -5
  180. package/dist/server/pages-node-compat.d.ts +1 -1
  181. package/dist/server/pages-node-compat.js +54 -27
  182. package/dist/server/pages-page-data.js +2 -1
  183. package/dist/server/pages-page-handler.js +28 -26
  184. package/dist/server/pages-page-response.d.ts +9 -0
  185. package/dist/server/pages-page-response.js +18 -4
  186. package/dist/server/pages-request-pipeline.d.ts +8 -0
  187. package/dist/server/pages-request-pipeline.js +2 -2
  188. package/dist/server/pages-request-stage-entry.js +36 -14
  189. package/dist/server/pages-response-stage-entry.js +9 -3
  190. package/dist/server/pages-router-entry.js +3 -2
  191. package/dist/server/prod-server.d.ts +2 -2
  192. package/dist/server/prod-server.js +47 -9
  193. package/dist/server/request-error-log.d.ts +9 -0
  194. package/dist/server/request-error-log.js +13 -0
  195. package/dist/server/request-pipeline.d.ts +15 -4
  196. package/dist/server/request-pipeline.js +43 -15
  197. package/dist/server/rsc-completion-metadata.js +3 -0
  198. package/dist/server/shared-cache-identity.d.ts +23 -0
  199. package/dist/server/shared-cache-identity.js +36 -0
  200. package/dist/server/static-file-cache.d.ts +9 -0
  201. package/dist/server/static-file-cache.js +13 -2
  202. package/dist/server/worker-stages.d.ts +16 -3
  203. package/dist/server/worker-stages.js +23 -4
  204. package/dist/shims/cache-handler.js +2 -2
  205. package/dist/shims/cache-request-state.d.ts +23 -26
  206. package/dist/shims/cache-request-state.js +22 -57
  207. package/dist/shims/cache-runtime.d.ts +3 -1
  208. package/dist/shims/cache-runtime.js +94 -48
  209. package/dist/shims/cache.d.ts +16 -10
  210. package/dist/shims/cache.js +47 -36
  211. package/dist/shims/cacheability-classification.d.ts +2 -0
  212. package/dist/shims/cdn-cache.d.ts +22 -5
  213. package/dist/shims/client-hook-error.d.ts +2 -0
  214. package/dist/shims/client-hook-error.js +16 -1
  215. package/dist/shims/client-page-root.js +2 -2
  216. package/dist/shims/dynamic.js +9 -6
  217. package/dist/shims/error-boundary.js +2 -2
  218. package/dist/shims/fetch-cache-state.d.ts +5 -1
  219. package/dist/shims/fetch-cache-state.js +1 -3
  220. package/dist/shims/fetch-cache.d.ts +2 -1
  221. package/dist/shims/fetch-cache.js +39 -25
  222. package/dist/shims/form.js +2 -2
  223. package/dist/shims/headers.d.ts +10 -24
  224. package/dist/shims/headers.js +22 -70
  225. package/dist/shims/internal/cache-context-accessor.d.ts +1 -1
  226. package/dist/shims/internal/navigation-untracked.js +1 -1
  227. package/dist/shims/link.js +8 -11
  228. package/dist/shims/metadata.d.ts +23 -21
  229. package/dist/shims/metadata.js +62 -24
  230. package/dist/shims/navigation-server.js +1 -1
  231. package/dist/shims/navigation.d.ts +74 -7
  232. package/dist/shims/navigation.js +184 -31
  233. package/dist/shims/navigation.react-server.js +2 -2
  234. package/dist/shims/request-state-types.d.ts +3 -2
  235. package/dist/shims/slot.d.ts +16 -0
  236. package/dist/shims/slot.js +44 -9
  237. package/dist/shims/unified-request-context.d.ts +7 -1
  238. package/dist/shims/unified-request-context.js +3 -3
  239. package/dist/utils/cache-control-metadata.d.ts +5 -0
  240. package/dist/utils/cache-control-metadata.js +9 -1
  241. package/dist/utils/cache-life-profiles.d.ts +33 -0
  242. package/dist/utils/cache-life-profiles.js +111 -0
  243. package/dist/utils/middleware-request-headers.d.ts +14 -3
  244. package/dist/utils/middleware-request-headers.js +54 -7
  245. package/dist/utils/project.d.ts +2 -2
  246. package/dist/utils/project.js +3 -16
  247. package/dist/utils/regex.d.ts +5 -0
  248. package/dist/utils/regex.js +11 -1
  249. package/dist/utils/text-stream.d.ts +10 -5
  250. package/dist/utils/text-stream.js +6 -6
  251. package/package.json +2 -1
  252. package/dist/build/layout-classification-types.d.ts +0 -60
  253. package/dist/build/layout-classification-types.js +0 -1
  254. package/dist/build/layout-classification.d.ts +0 -62
  255. package/dist/build/layout-classification.js +0 -98
  256. package/dist/build/route-classification-injector.d.ts +0 -33
  257. package/dist/build/route-classification-injector.js +0 -59
  258. package/dist/build/route-classification-manifest.d.ts +0 -54
  259. package/dist/build/route-classification-manifest.js +0 -143
  260. package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
  261. package/dist/server/app-browser-client-reuse-manifest.js +0 -101
  262. package/dist/server/app-layout-param-observation.d.ts +0 -42
  263. package/dist/server/app-layout-param-observation.js +0 -168
  264. package/dist/server/client-reuse-manifest.d.ts +0 -103
  265. package/dist/server/client-reuse-manifest.js +0 -209
  266. package/dist/server/skip-cache-proof.d.ts +0 -60
  267. package/dist/server/skip-cache-proof.js +0 -168
  268. package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
  269. package/dist/server/static-layout-client-reuse-proof.js +0 -33
  270. package/dist/utils/sorted-array.d.ts +0 -8
  271. package/dist/utils/sorted-array.js +0 -20
@@ -1,5 +1,5 @@
1
- import { VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
2
1
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
2
+ import { VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
3
3
  import { AppRscStateFingerprintInput } from "./app-rsc-state-fingerprint.js";
4
4
  //#region src/server/app-rsc-cache-busting.d.ts
5
5
  /**
@@ -13,10 +13,10 @@ export declare const VINEXT_RSC_BUILD_ID_HEADER = "X-Vinext-RSC-Build-Id";
13
13
  export declare const VINEXT_RSC_COMPATIBILITY_ID_HEADER = "X-Vinext-RSC-Compatibility-Id";
14
14
  export declare const VINEXT_RSC_CONTENT_TYPE = "text/x-component";
15
15
  type CreateRscRequestHeadersOptions = {
16
- clientReuseManifestHeader?: string | null;
17
16
  interceptionContext?: string | null;
18
17
  interceptionId?: string | null;
19
18
  mountedSlotsHeader?: string | null;
19
+ mountedLayoutsHeader?: string | null;
20
20
  includePrefetchHeader?: boolean;
21
21
  renderMode?: AppRscRenderMode;
22
22
  fetchPriority?: "auto" | "high" | "low";
@@ -68,11 +68,6 @@ export declare function stripRscCacheBustingSearchParam(url: URL): void;
68
68
  * are dropped. Other requests keep no `_rsc`, because it selects nothing there.
69
69
  */
70
70
  export declare function keepOnlyValidatedRscCacheBustingSearchParam(url: URL, isRscRequest: boolean): void;
71
- /**
72
- * Remove a trailing `.rsc` suffix from a pathname. Returns the pathname
73
- * unchanged when the suffix is absent.
74
- */
75
- export declare function stripRscSuffix(pathname: string): string;
76
71
  export declare function createCanonicalRscRequestHeaders(deploymentId?: string | null | undefined): Headers;
77
72
  /** Headers for the deterministic loading-boundary prefetch representation. */
78
73
  export declare function createCanonicalLoadingShellRscRequestHeaders(deploymentId?: string | null | undefined): Headers;
@@ -96,13 +91,18 @@ export declare function canonicalizeLoadingShellRscRequestHeaders(headers: Heade
96
91
  * appended to the base instead of resolved against it.
97
92
  */
98
93
  export declare function parseRscRequestPath(href: string): URL;
94
+ /**
95
+ * A pathname as the start of a path-absolute reference. One that begins with
96
+ * "//" would serialize as a protocol-relative URL naming another host, so it
97
+ * keeps a "/." prefix, as the WHATWG URL serializer does. URL resolution drops
98
+ * the dot segment, so the reference still targets the same pathname on the
99
+ * origin it is resolved against.
100
+ */
101
+ export declare function toPathAbsolutePathname(pathname: string): string;
99
102
  /**
100
103
  * Serialize the path-absolute reference callers fetch against the app origin.
101
- * A pathname that begins with "//" would serialize as a protocol-relative URL
102
- * and send the request to another host, so it keeps a "/." prefix, as the
103
- * WHATWG URL serializer does. URL resolution drops the dot segment, so the
104
- * request still targets the same pathname on the app origin, as Next.js's
105
- * full-URL fetch does.
104
+ * A "//" pathname keeps its "/." prefix so the request still targets the same
105
+ * pathname on the app origin, as Next.js's full-URL fetch does.
106
106
  */
107
107
  export declare function formatRscRequestPath(url: URL): string;
108
108
  export declare function createRscRequestUrl(href: string, headers: Headers): Promise<string>;
@@ -1,5 +1,5 @@
1
1
  import { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERCEPTION_ID_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_STATE_FINGERPRINT_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
2
- import { NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER } from "./headers.js";
2
+ import { NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_MOUNTED_LAYOUTS_HEADER } from "./headers.js";
3
3
  import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL, parseAppRscRenderMode } from "./app-rsc-render-mode.js";
4
4
  import { fnv1a64 } from "../utils/hash.js";
5
5
  import { applyDeploymentIdHeader, getDeploymentId } from "../utils/deployment-id.js";
@@ -22,8 +22,10 @@ function encodeBase64Url(bytes) {
22
22
  for (const byte of bytes) binary += String.fromCharCode(byte);
23
23
  return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
24
24
  }
25
- function normalizeHeaderValue(value) {
26
- return value ?? "0";
25
+ function serializeHeaderValue(value) {
26
+ if (value === null) return "0";
27
+ if (value === "0") return "\\0";
28
+ return value.replaceAll("\\", "\\\\").replaceAll(",", "\\,");
27
29
  }
28
30
  function normalizeCompatibilityId(value) {
29
31
  return value && value.length > 0 ? value : null;
@@ -57,9 +59,9 @@ function resolveHardNavigationTargetFromRscResponse(responseUrl, currentHref, or
57
59
  const parsed = new URL(responseUrl, origin);
58
60
  stripRscCacheBustingSearchParam(parsed);
59
61
  const origUrl = new URL(currentHref, origin);
60
- let pathname = stripRscSuffix(parsed.pathname);
62
+ let pathname = parsed.pathname;
61
63
  if (origUrl.pathname.length > 1 && origUrl.pathname.endsWith("/") && !pathname.endsWith("/")) pathname += "/";
62
- let hardNavigationTarget = pathname + parsed.search;
64
+ let hardNavigationTarget = toPathAbsolutePathname(pathname) + parsed.search;
63
65
  if (origUrl.hash) hardNavigationTarget += origUrl.hash;
64
66
  return hardNavigationTarget;
65
67
  }
@@ -74,21 +76,21 @@ function normalizeRenderModeHeaderValue(value) {
74
76
  const renderMode = parseAppRscRenderMode(value);
75
77
  return renderMode === "navigation" ? null : renderMode;
76
78
  }
77
- function createCacheBustingInput(headers, options = {}) {
79
+ function createCacheBustingInput(headers) {
78
80
  const values = [
79
81
  headers.get(NEXT_ROUTER_PREFETCH_HEADER),
80
82
  headers.get(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER),
81
83
  headers.get(NEXT_ROUTER_STATE_TREE_HEADER),
82
84
  headers.get(NEXT_URL_HEADER),
83
85
  headers.get(VINEXT_INTERCEPTION_CONTEXT_HEADER),
84
- ...options.includeInterceptionIdHeader === false ? [] : [headers.get(VINEXT_INTERCEPTION_ID_HEADER)],
86
+ headers.get(VINEXT_INTERCEPTION_ID_HEADER),
85
87
  headers.get(VINEXT_MOUNTED_SLOTS_HEADER),
86
- ...options.includeRenderModeHeader === false ? [] : [normalizeRenderModeHeaderValue(headers.get(VINEXT_RSC_RENDER_MODE_HEADER))]
88
+ normalizeRenderModeHeaderValue(headers.get(VINEXT_RSC_RENDER_MODE_HEADER))
87
89
  ];
88
90
  const stateFingerprint = headers.get(VINEXT_RSC_STATE_FINGERPRINT_HEADER);
89
- if (options.includeStateFingerprintHeader !== false && stateFingerprint !== null) values.push(stateFingerprint);
91
+ if (stateFingerprint !== null) values.push(stateFingerprint);
90
92
  if (values.every((value) => value === null)) return null;
91
- return values.map(normalizeHeaderValue).join(",");
93
+ return values.map(serializeHeaderValue).join(",");
92
94
  }
93
95
  async function sha256CacheBustingHash(input) {
94
96
  const subtle = globalThis.crypto?.subtle;
@@ -147,13 +149,6 @@ function keepOnlyValidatedRscCacheBustingSearchParam(url, isRscRequest) {
147
149
  url.search = "";
148
150
  if (hash !== null) setRscCacheBustingSearchParam(url, hash);
149
151
  }
150
- /**
151
- * Remove a trailing `.rsc` suffix from a pathname. Returns the pathname
152
- * unchanged when the suffix is absent.
153
- */
154
- function stripRscSuffix(pathname) {
155
- return pathname.endsWith(".rsc") ? pathname.slice(0, -4) : pathname;
156
- }
157
152
  function createCanonicalRscRequestHeaders(deploymentId = getDeploymentId()) {
158
153
  const headers = new Headers({
159
154
  Accept: VINEXT_RSC_CONTENT_TYPE,
@@ -183,7 +178,7 @@ function createRscRequestHeaders(options = {}) {
183
178
  if (options.interceptionContext !== void 0 && options.interceptionContext !== null) headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);
184
179
  if (options.interceptionId !== void 0 && options.interceptionId !== null) headers.set(VINEXT_INTERCEPTION_ID_HEADER, options.interceptionId);
185
180
  if (options.mountedSlotsHeader !== void 0 && options.mountedSlotsHeader !== null) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
186
- if (options.clientReuseManifestHeader !== void 0 && options.clientReuseManifestHeader !== null) headers.set(VINEXT_CLIENT_REUSE_MANIFEST_HEADER, options.clientReuseManifestHeader);
181
+ if (options.mountedLayoutsHeader !== void 0 && options.mountedLayoutsHeader !== null) headers.set(VINEXT_MOUNTED_LAYOUTS_HEADER, options.mountedLayoutsHeader);
187
182
  const renderMode = options.renderMode ?? "navigation";
188
183
  if (renderMode !== "navigation") headers.set(VINEXT_RSC_RENDER_MODE_HEADER, renderMode);
189
184
  return headers;
@@ -199,8 +194,8 @@ function canonicalizePrewarmableRscRequestHeaders(headers) {
199
194
  headers.delete(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER);
200
195
  headers.delete(NEXT_ROUTER_STATE_TREE_HEADER);
201
196
  headers.delete(NEXT_URL_HEADER);
197
+ headers.delete(VINEXT_MOUNTED_LAYOUTS_HEADER);
202
198
  headers.delete(VINEXT_RSC_STATE_FINGERPRINT_HEADER);
203
- headers.delete(VINEXT_CLIENT_REUSE_MANIFEST_HEADER);
204
199
  return true;
205
200
  }
206
201
  /**
@@ -214,8 +209,8 @@ function canonicalizeLoadingShellRscRequestHeaders(headers) {
214
209
  headers.set(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, "1");
215
210
  headers.delete(NEXT_ROUTER_STATE_TREE_HEADER);
216
211
  headers.delete(NEXT_URL_HEADER);
212
+ headers.delete(VINEXT_MOUNTED_LAYOUTS_HEADER);
217
213
  headers.delete(VINEXT_RSC_STATE_FINGERPRINT_HEADER);
218
- headers.delete(VINEXT_CLIENT_REUSE_MANIFEST_HEADER);
219
214
  return true;
220
215
  }
221
216
  const RSC_REQUEST_URL_BASE = "http://vinext.local";
@@ -232,15 +227,22 @@ function parseRscRequestPath(href) {
232
227
  return new URL(beforeHash, RSC_REQUEST_URL_BASE);
233
228
  }
234
229
  /**
230
+ * A pathname as the start of a path-absolute reference. One that begins with
231
+ * "//" would serialize as a protocol-relative URL naming another host, so it
232
+ * keeps a "/." prefix, as the WHATWG URL serializer does. URL resolution drops
233
+ * the dot segment, so the reference still targets the same pathname on the
234
+ * origin it is resolved against.
235
+ */
236
+ function toPathAbsolutePathname(pathname) {
237
+ return pathname.startsWith("//") ? `/.${pathname}` : pathname;
238
+ }
239
+ /**
235
240
  * Serialize the path-absolute reference callers fetch against the app origin.
236
- * A pathname that begins with "//" would serialize as a protocol-relative URL
237
- * and send the request to another host, so it keeps a "/." prefix, as the
238
- * WHATWG URL serializer does. URL resolution drops the dot segment, so the
239
- * request still targets the same pathname on the app origin, as Next.js's
240
- * full-URL fetch does.
241
+ * A "//" pathname keeps its "/." prefix so the request still targets the same
242
+ * pathname on the app origin, as Next.js's full-URL fetch does.
241
243
  */
242
244
  function formatRscRequestPath(url) {
243
- return `${url.pathname.startsWith("//") ? `/.${url.pathname}` : url.pathname}${url.search}`;
245
+ return `${toPathAbsolutePathname(url.pathname)}${url.search}`;
244
246
  }
245
247
  async function createRscRequestUrl(href, headers) {
246
248
  const url = parseRscRequestPath(href);
@@ -275,55 +277,12 @@ async function resolveInvalidRscCacheBustingRequest(options) {
275
277
  const url = new URL(options.request.url);
276
278
  const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);
277
279
  const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);
278
- if (actualHash === null && expectedHash === "" && url.pathname.endsWith(".rsc")) return null;
279
- const acceptedHashes = /* @__PURE__ */ new Set([expectedHash]);
280
- if (actualHash !== null && actualHash !== expectedHash) {
281
- acceptedHashes.add(computeLegacyRscCacheBustingSearchParam(options.request.headers));
282
- const compatibilityInputs = [];
283
- const hasInterceptionId = options.request.headers.has(VINEXT_INTERCEPTION_ID_HEADER);
284
- const hasStateFingerprint = options.request.headers.has(VINEXT_RSC_STATE_FINGERPRINT_HEADER);
285
- const hasNormalRenderMode = normalizeRenderModeHeaderValue(options.request.headers.get(VINEXT_RSC_RENDER_MODE_HEADER)) === null;
286
- if (!hasInterceptionId) compatibilityInputs.push({ includeInterceptionIdHeader: false });
287
- if (hasStateFingerprint) {
288
- compatibilityInputs.push({ includeStateFingerprintHeader: false });
289
- if (!hasInterceptionId) compatibilityInputs.push({
290
- includeInterceptionIdHeader: false,
291
- includeStateFingerprintHeader: false
292
- });
293
- }
294
- if (hasNormalRenderMode) {
295
- compatibilityInputs.push({ includeRenderModeHeader: false });
296
- if (!hasInterceptionId) compatibilityInputs.push({
297
- includeInterceptionIdHeader: false,
298
- includeRenderModeHeader: false
299
- });
300
- }
301
- if (hasStateFingerprint && hasNormalRenderMode) {
302
- compatibilityInputs.push({
303
- includeRenderModeHeader: false,
304
- includeStateFingerprintHeader: false
305
- });
306
- if (!hasInterceptionId) compatibilityInputs.push({
307
- includeInterceptionIdHeader: false,
308
- includeRenderModeHeader: false,
309
- includeStateFingerprintHeader: false
310
- });
311
- }
312
- for (const compatibilityOptions of compatibilityInputs) {
313
- const input = createCacheBustingInput(options.request.headers, compatibilityOptions);
314
- if (input === null) acceptedHashes.add("");
315
- else {
316
- acceptedHashes.add(await sha256CacheBustingHash(input));
317
- acceptedHashes.add(fnv1a64(input));
318
- }
319
- }
320
- }
321
- if (actualHash !== null && acceptedHashes.has(actualHash)) return null;
280
+ if (actualHash !== null && (actualHash === expectedHash || actualHash === computeLegacyRscCacheBustingSearchParam(options.request.headers))) return null;
322
281
  setRscCacheBustingSearchParam(url, expectedHash);
323
282
  return new Response(null, {
324
283
  status: 307,
325
- headers: { Location: `${url.pathname}${url.search}` }
284
+ headers: { Location: formatRscRequestPath(url) }
326
285
  });
327
286
  }
328
287
  //#endregion
329
- export { VINEXT_RSC_BUILD_ID_HEADER, VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, computeRscCacheBustingSearchParam, createCanonicalLoadingShellRscRequestHeaders, createCanonicalRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, formatRscRequestPath, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, keepOnlyValidatedRscCacheBustingSearchParam, parseRscRequestPath, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
288
+ export { VINEXT_RSC_BUILD_ID_HEADER, VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, computeRscCacheBustingSearchParam, createCanonicalLoadingShellRscRequestHeaders, createCanonicalRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, formatRscRequestPath, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, keepOnlyValidatedRscCacheBustingSearchParam, parseRscRequestPath, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, toPathAbsolutePathname };
@@ -20,7 +20,8 @@ export type AppRenderErrorContextOverrides = {
20
20
  * the incoming Web `Request`, wires it into a `createRscOnErrorHandler` call,
21
21
  * and binds the configured `reportRequestError` reporter.
22
22
  *
23
- * Pure factory: takes all deps explicitly — no closure over module-level state.
23
+ * Takes all deps explicitly. The only module-level state is the set of errors
24
+ * each request already logged, keyed weakly by its `Request`.
24
25
  */
25
26
  export declare function createAppRscOnErrorHandler(reportRequestError: ReportRequestError, request: Request, pathname: string, routePath: string, overrides?: AppRenderErrorContextOverrides): (error: unknown) => string | undefined;
26
27
  //#endregion
@@ -3,12 +3,14 @@ import "./app-rsc-vary.js";
3
3
  import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
4
4
  import { createRscOnErrorHandler } from "./app-rsc-errors.js";
5
5
  //#region src/server/app-rsc-error-handler.ts
6
+ const loggedErrorsByRequest = /* @__PURE__ */ new WeakMap();
6
7
  /**
7
8
  * Build a per-request RSC error handler that extracts request metadata from
8
9
  * the incoming Web `Request`, wires it into a `createRscOnErrorHandler` call,
9
10
  * and binds the configured `reportRequestError` reporter.
10
11
  *
11
- * Pure factory: takes all deps explicitly — no closure over module-level state.
12
+ * Takes all deps explicitly. The only module-level state is the set of errors
13
+ * each request already logged, keyed weakly by its `Request`.
12
14
  */
13
15
  function createAppRscOnErrorHandler(reportRequestError, request, pathname, routePath, overrides) {
14
16
  const requestHeaders = Object.fromEntries(request.headers.entries());
@@ -21,12 +23,18 @@ function createAppRscOnErrorHandler(reportRequestError, request, pathname, route
21
23
  routerKind: "App Router",
22
24
  routePath: routePath || pathname,
23
25
  routeType: overrides?.routeType ?? "render",
24
- renderSource: overrides?.renderSource ?? (request.headers.get("RSC") === "1" || new URL(request.url).pathname.endsWith(".rsc") ? "react-server-components-payload" : "react-server-components"),
26
+ renderSource: overrides?.renderSource ?? (request.headers.get("RSC") === "1" ? "react-server-components-payload" : "react-server-components"),
25
27
  revalidateReason: isOnDemandRevalidateRequest(request.headers.get("x-prerender-revalidate")) ? "on-demand" : overrides?.revalidateReason
26
28
  };
29
+ let loggedErrors = loggedErrorsByRequest.get(request);
30
+ if (!loggedErrors) {
31
+ loggedErrors = /* @__PURE__ */ new WeakSet();
32
+ loggedErrorsByRequest.set(request, loggedErrors);
33
+ }
27
34
  return createRscOnErrorHandler({
28
35
  attachDigest: errorContext.renderSource !== "server-rendering",
29
36
  errorContext,
37
+ loggedErrors,
30
38
  reportRequestError(error, info, context) {
31
39
  reportRequestError(error, info, context);
32
40
  },
@@ -15,6 +15,14 @@ type RscErrorReporter = (error: unknown, requestInfo: RscRequestInfo, errorConte
15
15
  type CreateRscOnErrorHandlerOptions = {
16
16
  attachDigest?: boolean;
17
17
  errorContext: RscErrorContext | null;
18
+ /**
19
+ * The errors this request already logged, shared by its handlers so an error
20
+ * reaching more than one, such as in the RSC and then the SSR pass, is logged
21
+ * once. Like Next.js, a digest alone does not mean an error was logged: user
22
+ * code can set its own. Request-scoped, as a failed module evaluation throws
23
+ * the same error on every request. Defaults to this handler's own.
24
+ */
25
+ loggedErrors?: WeakSet<object>;
18
26
  nodeEnv?: string;
19
27
  reportRequestError: RscErrorReporter;
20
28
  requestInfo: RscRequestInfo | null;
@@ -1,4 +1,6 @@
1
1
  import { isNavigationSignalError } from "../utils/navigation-signal.js";
2
+ import { logRequestError } from "./request-error-log.js";
3
+ import { rewriteClientHookError } from "../shims/client-hook-error.js";
2
4
  import { resolveAppPageSpecialError } from "./app-page-execution.js";
3
5
  import { isAppRenderAbortError } from "./app-render-abort-error.js";
4
6
  import { getProperError } from "./proper-error.js";
@@ -63,6 +65,13 @@ function sanitizeErrorForClient(error, nodeEnv = process.env.NODE_ENV) {
63
65
  }
64
66
  function createRscOnErrorHandler(options) {
65
67
  let loggedPrerenderErrors;
68
+ const loggedErrors = options.loggedErrors ?? /* @__PURE__ */ new WeakSet();
69
+ const wasLogged = (error) => {
70
+ if (typeof error !== "object" && typeof error !== "function" || error === null) return false;
71
+ if (loggedErrors.has(error)) return true;
72
+ loggedErrors.add(error);
73
+ return false;
74
+ };
66
75
  return (error) => {
67
76
  const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV;
68
77
  const reportableError = error && typeof error === "object" && ORIGINAL_SERVER_ERROR in error ? Reflect.get(error, ORIGINAL_SERVER_ERROR) : error;
@@ -80,6 +89,7 @@ function createRscOnErrorHandler(options) {
80
89
  if (!hasDigest(properError) && (properError !== reportableError || options.attachDigest !== false)) try {
81
90
  Object.assign(properError, { digest });
82
91
  } catch {}
92
+ if (nodeEnv !== "production") rewriteClientHookError(properError);
83
93
  if (options.requestInfo && options.errorContext) options.reportRequestError(properError, options.requestInfo, options.errorContext);
84
94
  if (process.env.VINEXT_PRERENDER === "1" && error) {
85
95
  if (!loggedPrerenderErrors?.has(reportableError)) {
@@ -87,7 +97,7 @@ function createRscOnErrorHandler(options) {
87
97
  const route = options.requestInfo?.path ?? options.errorContext?.routePath ?? "<unknown>";
88
98
  console.error(`[vinext] Error prerendering route ${JSON.stringify(route)}:`, reportableError);
89
99
  }
90
- } else if (nodeEnv !== "production" && !thrownHasDigest) console.error("[vinext] Server render error:", properError);
100
+ } else if (!(reportableError !== error && thrownHasDigest) && !wasLogged(reportableError)) logRequestError("[vinext] Server render error:", properError);
91
101
  return digest;
92
102
  };
93
103
  }
@@ -1,14 +1,13 @@
1
1
  import { VinextCacheabilityProbeMode } from "./multi-stage.js";
2
2
  import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
3
+ import { AppRscRenderMode } from "./app-rsc-render-mode.js";
3
4
  import { ImageConfig } from "./image-optimization.js";
4
5
  import { ExecutionContextLike } from "../shims/request-context.js";
5
6
  import { AppMiddlewareContext, ApplyAppMiddlewareResult } from "./app-middleware.js";
6
- import { ClientReuseManifestParseResult } from "./client-reuse-manifest.js";
7
- import { AppRscRenderMode } from "./app-rsc-render-mode.js";
8
7
  import { RootParams } from "../shims/root-params.js";
9
8
  import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
10
- import { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap } from "./app-prerender-endpoints.js";
11
9
  import { PagesRouteDataKind } from "./pages-route-data-kind.js";
10
+ import { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap } from "./app-prerender-endpoints.js";
12
11
  import { TrustedPrerenderState } from "./prerender-route-params.js";
13
12
  import { AppRouteTreePrefetchRoute, PrefetchInliningConfig } from "./app-route-tree-prefetch.js";
14
13
  import { DispatchAppWorkerResponseStage, RenderAppWorkerResponseStageLocally } from "./app-worker-stages.js";
@@ -52,7 +51,6 @@ type AppRscRouteMatch<TRoute> = {
52
51
  type DispatchMatchedPageOptions<TRoute> = {
53
52
  bypassInterceptionContextCache: boolean;
54
53
  cachePathname: string;
55
- clientReuseManifest: ClientReuseManifestParseResult;
56
54
  cleanPathname: string;
57
55
  displayPathname: string;
58
56
  formState: ReactFormState | null;
@@ -170,7 +168,7 @@ type RenderPagesFallbackOptions = {
170
168
  pattern: string;
171
169
  };
172
170
  } | null;
173
- dispatchPagesResponseStage?: (request: Request, resourceKind: "api" | "page", dataKind?: PagesRouteDataKind, hasRequestAwareDocument?: boolean) => Promise<Response>;
171
+ dispatchPagesResponseStage?: (request: Request, resourceKind: "api" | "page", dataKind?: PagesRouteDataKind, hasRequestAwareDocument?: boolean, runsInitialProps?: boolean) => Promise<Response>;
174
172
  isDataRequest?: boolean;
175
173
  isRscRequest: boolean;
176
174
  initialResponseHeaders?: Headers;
@@ -179,6 +177,8 @@ type RenderPagesFallbackOptions = {
179
177
  pathname?: string;
180
178
  pagesDataRequest?: Request | null;
181
179
  request: Request;
180
+ /** The shared cache entry answers every host; a request-time render is not stored. */
181
+ sharedAcrossHosts?: boolean;
182
182
  url: URL;
183
183
  };
184
184
  type NavigationContextValue = {