vinext 0.1.7 → 0.2.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 (279) hide show
  1. package/README.md +51 -30
  2. package/dist/build/inject-pregenerated-paths.d.ts +4 -0
  3. package/dist/build/inject-pregenerated-paths.js +18 -0
  4. package/dist/build/layout-classification.js +1 -1
  5. package/dist/build/nitro-route-rules.js +1 -1
  6. package/dist/build/pages-client-assets-module.d.ts +11 -0
  7. package/dist/build/pages-client-assets-module.js +27 -0
  8. package/dist/build/prerender.d.ts +2 -1
  9. package/dist/build/prerender.js +13 -6
  10. package/dist/build/report.d.ts +13 -2
  11. package/dist/build/report.js +99 -2
  12. package/dist/build/run-prerender.d.ts +7 -0
  13. package/dist/build/run-prerender.js +10 -1
  14. package/dist/build/standalone.js +2 -0
  15. package/dist/cache/cache-adapters-virtual.js +3 -3
  16. package/dist/check.d.ts +18 -0
  17. package/dist/check.js +77 -19
  18. package/dist/cli-args.d.ts +1 -2
  19. package/dist/cli-args.js +1 -1
  20. package/dist/cli-dev-config.d.ts +12 -0
  21. package/dist/cli-dev-config.js +23 -0
  22. package/dist/cli.js +113 -97
  23. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  24. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  25. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  26. package/dist/{server → client}/dev-error-overlay.js +2 -2
  27. package/dist/client/navigation-runtime.d.ts +2 -0
  28. package/dist/client/navigation-runtime.js +3 -1
  29. package/dist/client/window-next.d.ts +2 -1
  30. package/dist/cloudflare/index.d.ts +2 -2
  31. package/dist/cloudflare/index.js +2 -2
  32. package/dist/config/config-matchers.js +14 -10
  33. package/dist/config/next-config.d.ts +6 -3
  34. package/dist/config/next-config.js +47 -1
  35. package/dist/config/prerender.d.ts +34 -0
  36. package/dist/config/prerender.js +55 -0
  37. package/dist/config/server-external-packages.d.ts +4 -0
  38. package/dist/config/server-external-packages.js +91 -0
  39. package/dist/entries/app-rsc-entry.d.ts +2 -1
  40. package/dist/entries/app-rsc-entry.js +89 -15
  41. package/dist/entries/app-rsc-manifest.js +10 -0
  42. package/dist/entries/pages-client-entry.d.ts +3 -0
  43. package/dist/entries/pages-client-entry.js +16 -1
  44. package/dist/entries/pages-server-entry.js +6 -2
  45. package/dist/image/image-adapters-virtual.d.ts +59 -0
  46. package/dist/image/image-adapters-virtual.js +59 -0
  47. package/dist/index.d.ts +33 -0
  48. package/dist/index.js +211 -118
  49. package/dist/init-cloudflare.d.ts +43 -0
  50. package/dist/init-cloudflare.js +839 -0
  51. package/dist/init-platform.d.ts +40 -0
  52. package/dist/init-platform.js +195 -0
  53. package/dist/init.d.ts +16 -38
  54. package/dist/init.js +208 -97
  55. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  56. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  57. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  58. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  59. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
  60. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  61. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  62. package/dist/packages/cloudflare/src/deploy.js +276 -0
  63. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  64. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
  65. package/dist/plugins/ast-scope.d.ts +16 -0
  66. package/dist/plugins/ast-scope.js +62 -0
  67. package/dist/plugins/ast-utils.d.ts +27 -1
  68. package/dist/plugins/ast-utils.js +32 -1
  69. package/dist/plugins/css-module-imports.d.ts +14 -0
  70. package/dist/plugins/css-module-imports.js +59 -0
  71. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  72. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  73. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  74. package/dist/plugins/middleware-server-only.d.ts +8 -6
  75. package/dist/plugins/middleware-server-only.js +8 -7
  76. package/dist/plugins/optimize-imports.js +1 -1
  77. package/dist/plugins/typeof-window.d.ts +1 -1
  78. package/dist/plugins/typeof-window.js +28 -56
  79. package/dist/routing/app-route-graph.d.ts +29 -4
  80. package/dist/routing/app-route-graph.js +182 -40
  81. package/dist/routing/app-router.d.ts +5 -0
  82. package/dist/routing/app-router.js +5 -0
  83. package/dist/routing/file-matcher.d.ts +8 -0
  84. package/dist/routing/file-matcher.js +10 -1
  85. package/dist/routing/pages-router.js +2 -2
  86. package/dist/server/api-handler.js +9 -14
  87. package/dist/server/app-browser-action-result.d.ts +4 -1
  88. package/dist/server/app-browser-action-result.js +8 -1
  89. package/dist/server/app-browser-entry.js +194 -190
  90. package/dist/server/app-browser-history-controller.d.ts +2 -1
  91. package/dist/server/app-browser-history-controller.js +6 -2
  92. package/dist/server/app-browser-interception-context.d.ts +1 -0
  93. package/dist/server/app-browser-interception-context.js +4 -2
  94. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  95. package/dist/server/app-browser-navigation-controller.js +60 -31
  96. package/dist/server/app-browser-server-action-client.d.ts +32 -0
  97. package/dist/server/app-browser-server-action-client.js +127 -0
  98. package/dist/server/app-browser-state.d.ts +11 -1
  99. package/dist/server/app-browser-state.js +25 -8
  100. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  101. package/dist/server/app-browser-visible-commit.js +43 -25
  102. package/dist/server/app-elements-wire.d.ts +9 -2
  103. package/dist/server/app-elements-wire.js +8 -1
  104. package/dist/server/app-elements.d.ts +2 -2
  105. package/dist/server/app-elements.js +4 -3
  106. package/dist/server/app-fallback-renderer.d.ts +5 -2
  107. package/dist/server/app-fallback-renderer.js +15 -7
  108. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  109. package/dist/server/app-hydration-cache-publication.js +43 -0
  110. package/dist/server/app-middleware.d.ts +4 -3
  111. package/dist/server/app-middleware.js +8 -3
  112. package/dist/server/app-optimistic-routing.js +11 -4
  113. package/dist/server/app-page-boundary-render.d.ts +3 -0
  114. package/dist/server/app-page-boundary-render.js +14 -3
  115. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  116. package/dist/server/app-page-cache-finalizer.js +10 -3
  117. package/dist/server/app-page-cache-render.d.ts +1 -0
  118. package/dist/server/app-page-cache-render.js +8 -4
  119. package/dist/server/app-page-cache.d.ts +1 -0
  120. package/dist/server/app-page-cache.js +5 -2
  121. package/dist/server/app-page-dispatch.d.ts +33 -4
  122. package/dist/server/app-page-dispatch.js +63 -90
  123. package/dist/server/app-page-element-builder.d.ts +9 -2
  124. package/dist/server/app-page-element-builder.js +114 -23
  125. package/dist/server/app-page-head.d.ts +16 -1
  126. package/dist/server/app-page-head.js +44 -22
  127. package/dist/server/app-page-params.d.ts +2 -1
  128. package/dist/server/app-page-params.js +8 -1
  129. package/dist/server/app-page-ppr-runtime.d.ts +7 -0
  130. package/dist/server/app-page-ppr-runtime.js +70 -0
  131. package/dist/server/app-page-probe.d.ts +1 -0
  132. package/dist/server/app-page-probe.js +6 -1
  133. package/dist/server/app-page-render-identity.d.ts +1 -0
  134. package/dist/server/app-page-render-identity.js +1 -1
  135. package/dist/server/app-page-render.d.ts +4 -1
  136. package/dist/server/app-page-render.js +26 -3
  137. package/dist/server/app-page-request.d.ts +22 -1
  138. package/dist/server/app-page-request.js +92 -15
  139. package/dist/server/app-page-route-wiring.d.ts +14 -2
  140. package/dist/server/app-page-route-wiring.js +61 -25
  141. package/dist/server/app-page-search-params-observation.d.ts +4 -2
  142. package/dist/server/app-page-search-params-observation.js +11 -7
  143. package/dist/server/app-page-segment-state.d.ts +2 -1
  144. package/dist/server/app-page-segment-state.js +3 -1
  145. package/dist/server/app-page-stream.d.ts +5 -0
  146. package/dist/server/app-page-stream.js +3 -1
  147. package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
  148. package/dist/server/app-route-handler-dispatch.js +1 -0
  149. package/dist/server/app-route-handler-execution.js +7 -2
  150. package/dist/server/app-route-handler-response.js +1 -0
  151. package/dist/server/app-route-handler-runtime.js +1 -1
  152. package/dist/server/app-route-module-loader.d.ts +2 -0
  153. package/dist/server/app-route-module-loader.js +1 -0
  154. package/dist/server/app-router-entry.js +16 -8
  155. package/dist/server/app-rsc-errors.js +7 -1
  156. package/dist/server/app-rsc-handler.d.ts +3 -1
  157. package/dist/server/app-rsc-handler.js +67 -39
  158. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  159. package/dist/server/app-rsc-request-normalization.js +6 -3
  160. package/dist/server/app-rsc-route-matching.d.ts +7 -0
  161. package/dist/server/app-rsc-route-matching.js +36 -3
  162. package/dist/server/app-segment-config.d.ts +12 -0
  163. package/dist/server/app-segment-config.js +91 -5
  164. package/dist/server/app-server-action-execution.d.ts +5 -0
  165. package/dist/server/app-server-action-execution.js +94 -33
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +19 -8
  168. package/dist/server/app-ssr-stream.d.ts +7 -3
  169. package/dist/server/app-ssr-stream.js +10 -6
  170. package/dist/server/app-static-generation.d.ts +1 -0
  171. package/dist/server/app-static-generation.js +1 -0
  172. package/dist/server/app-visited-response-cache.d.ts +6 -0
  173. package/dist/server/app-visited-response-cache.js +3 -1
  174. package/dist/server/client-trace-metadata.js +26 -0
  175. package/dist/server/default-global-not-found-module.d.ts +14 -0
  176. package/dist/server/default-global-not-found-module.js +14 -0
  177. package/dist/server/dev-route-files.js +4 -0
  178. package/dist/server/dev-server.js +19 -18
  179. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  180. package/dist/server/dev-stack-sourcemap.js +1 -1
  181. package/dist/server/fetch-handler.d.ts +2 -0
  182. package/dist/server/fetch-handler.js +18 -0
  183. package/dist/server/headers.d.ts +5 -15
  184. package/dist/server/headers.js +4 -15
  185. package/dist/server/image-optimization.d.ts +51 -1
  186. package/dist/server/image-optimization.js +52 -2
  187. package/dist/server/implicit-tags.js +1 -1
  188. package/dist/server/isr-cache.d.ts +1 -1
  189. package/dist/server/isr-cache.js +2 -2
  190. package/dist/server/metadata-routes.d.ts +3 -1
  191. package/dist/server/metadata-routes.js +12 -2
  192. package/dist/server/middleware-runtime.js +6 -1
  193. package/dist/server/navigation-planner.d.ts +1 -0
  194. package/dist/server/navigation-planner.js +14 -3
  195. package/dist/server/pages-api-route.js +2 -2
  196. package/dist/server/pages-asset-tags.d.ts +4 -6
  197. package/dist/server/pages-asset-tags.js +12 -12
  198. package/dist/server/pages-client-assets.d.ts +12 -0
  199. package/dist/server/pages-client-assets.js +10 -0
  200. package/dist/server/pages-node-compat.d.ts +8 -1
  201. package/dist/server/pages-node-compat.js +32 -4
  202. package/dist/server/pages-page-data.d.ts +24 -1
  203. package/dist/server/pages-page-data.js +45 -24
  204. package/dist/server/pages-page-handler.d.ts +2 -1
  205. package/dist/server/pages-page-handler.js +19 -12
  206. package/dist/server/pages-page-response.d.ts +7 -0
  207. package/dist/server/pages-page-response.js +4 -1
  208. package/dist/server/pages-request-pipeline.d.ts +2 -0
  209. package/dist/server/pages-request-pipeline.js +25 -1
  210. package/dist/server/pages-router-entry.d.ts +30 -0
  211. package/dist/server/pages-router-entry.js +108 -0
  212. package/dist/server/prerender-manifest.d.ts +3 -1
  213. package/dist/server/prerender-route-params.js +1 -1
  214. package/dist/server/prod-server.d.ts +1 -1
  215. package/dist/server/prod-server.js +48 -26
  216. package/dist/server/request-pipeline.js +1 -0
  217. package/dist/server/seed-cache.js +4 -4
  218. package/dist/server/worker-utils.d.ts +2 -1
  219. package/dist/server/worker-utils.js +7 -1
  220. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  221. package/dist/shims/app-router-scroll-state.js +1 -0
  222. package/dist/shims/app-router-scroll.js +2 -1
  223. package/dist/shims/cache.js +19 -15
  224. package/dist/shims/cdn-cache.js +1 -1
  225. package/dist/shims/dynamic-preload-chunks.js +2 -1
  226. package/dist/shims/error-boundary.d.ts +19 -1
  227. package/dist/shims/error-boundary.js +11 -1
  228. package/dist/shims/form.d.ts +3 -1
  229. package/dist/shims/form.js +37 -43
  230. package/dist/shims/headers.d.ts +9 -1
  231. package/dist/shims/headers.js +31 -6
  232. package/dist/shims/image.js +75 -14
  233. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  234. package/dist/shims/internal/app-route-detection.js +4 -17
  235. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  236. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  237. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
  238. package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
  239. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
  240. package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
  241. package/dist/shims/internal/pages-data-target.d.ts +10 -9
  242. package/dist/shims/internal/pages-data-target.js +91 -12
  243. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  244. package/dist/shims/internal/pages-router-components.js +13 -0
  245. package/dist/shims/layout-segment-context.d.ts +4 -1
  246. package/dist/shims/layout-segment-context.js +18 -4
  247. package/dist/shims/link.js +70 -37
  248. package/dist/shims/metadata.d.ts +3 -2
  249. package/dist/shims/metadata.js +8 -4
  250. package/dist/shims/navigation.d.ts +5 -1
  251. package/dist/shims/navigation.js +45 -10
  252. package/dist/shims/navigation.react-server.js +1 -1
  253. package/dist/shims/root-params.d.ts +15 -1
  254. package/dist/shims/root-params.js +21 -1
  255. package/dist/shims/router.d.ts +5 -7
  256. package/dist/shims/router.js +374 -94
  257. package/dist/shims/server.js +3 -2
  258. package/dist/shims/slot.js +3 -6
  259. package/dist/typegen.js +6 -5
  260. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  261. package/dist/utils/client-runtime-metadata.js +31 -22
  262. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  263. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  264. package/dist/utils/domain-locale.d.ts +6 -3
  265. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  266. package/dist/{server → utils}/middleware-request-headers.js +2 -2
  267. package/dist/utils/path.d.ts +2 -1
  268. package/dist/utils/path.js +1 -1
  269. package/dist/utils/project.d.ts +52 -2
  270. package/dist/utils/project.js +230 -5
  271. package/dist/utils/protocol-headers.d.ts +17 -0
  272. package/dist/utils/protocol-headers.js +17 -0
  273. package/dist/utils/react-version.d.ts +4 -0
  274. package/dist/utils/react-version.js +44 -0
  275. package/package.json +53 -4
  276. package/dist/deploy.d.ts +0 -190
  277. package/dist/deploy.js +0 -1033
  278. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  279. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -31,6 +31,8 @@ type AppRscInterceptForMatching = {
31
31
  sourceMatchPattern?: string;
32
32
  sourcePageSegments?: readonly string[];
33
33
  interceptLayouts: readonly unknown[];
34
+ interceptLayoutSegments?: readonly (readonly string[])[];
35
+ interceptBranchSegments?: readonly string[];
34
36
  __loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
35
37
  page: unknown;
36
38
  __pageLoader?: (() => Promise<unknown>) | null;
@@ -46,6 +48,8 @@ type AppRscSiblingInterceptForMatching = {
46
48
  sourcePageSegments?: readonly string[];
47
49
  slotId: string | null;
48
50
  interceptLayouts: readonly unknown[];
51
+ interceptLayoutSegments?: readonly (readonly string[])[];
52
+ interceptBranchSegments?: readonly string[];
49
53
  __loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
50
54
  page: unknown;
51
55
  __pageLoader?: (() => Promise<unknown>) | null;
@@ -59,6 +63,7 @@ type AppRscRouteForMatching = {
59
63
  };
60
64
  type AppRscInterceptMatch = AppRscInterceptLookupEntry & {
61
65
  matchedParams: AppRscRouteParams;
66
+ sourceMatchedParams: AppRscRouteParams;
62
67
  };
63
68
  type AppRscInterceptLoadState = {
64
69
  page: unknown;
@@ -74,6 +79,8 @@ type AppRscInterceptLookupEntry = {
74
79
  sourceMatchPatternParts: string[] | null;
75
80
  sourcePageSegments: readonly string[] | null;
76
81
  interceptLayouts: readonly unknown[];
82
+ interceptLayoutSegments?: readonly (readonly string[])[];
83
+ interceptBranchSegments?: readonly string[];
77
84
  __loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
78
85
  page: unknown;
79
86
  __pageLoader?: (() => Promise<unknown>) | null;
@@ -36,12 +36,13 @@ function createAppRscRouteMatcher(routes) {
36
36
  const sourceRoute = routes[concreteSourceRouteIndex];
37
37
  const matchedSourceParams = matchedSourceRoute && entry.sourceMatchPatternParts !== null ? matchedSourceRoute.params : sourceRoute ? matchAppRscRoutePattern(sourceParts, sourceRoute.patternParts) : null;
38
38
  if (matchedSourceParams === null && entry.sourceMatchPatternParts === null) continue;
39
- const sourceParams = matchedSourceParams ?? createRouteParams();
39
+ const sourceParams = matchedSourceParams && entry.sourceMatchPatternParts !== null ? pickPatternParams(matchedSourceParams, entry.sourceMatchPatternParts) : matchedSourceParams ?? createRouteParams();
40
40
  return {
41
41
  ...entry,
42
42
  page: entry.__loadState.page,
43
43
  sourceRouteIndex: concreteSourceRouteIndex,
44
- matchedParams: mergeMatchedParams(sourceParams, params)
44
+ matchedParams: mergeMatchedParams(sourceParams, params),
45
+ sourceMatchedParams: matchedSourceParams ?? createRouteParams()
45
46
  };
46
47
  }
47
48
  return null;
@@ -64,6 +65,24 @@ function matchInterceptSource(sourceParts, entry) {
64
65
  if (patternParts.length === 0) return true;
65
66
  return matchRoutePatternPrefix(sourceParts, patternParts);
66
67
  }
68
+ function interceptSegmentPrecedence(segment) {
69
+ if (!segment.startsWith(":")) return 0;
70
+ if (segment.endsWith("*")) return 3;
71
+ if (segment.endsWith("+")) return 2;
72
+ return 1;
73
+ }
74
+ function compareInterceptTargetPatterns(a, b) {
75
+ const sharedLength = Math.min(a.targetPatternParts.length, b.targetPatternParts.length);
76
+ for (let index = 0; index < sharedLength; index++) {
77
+ const aSegment = a.targetPatternParts[index];
78
+ const bSegment = b.targetPatternParts[index];
79
+ const precedence = interceptSegmentPrecedence(aSegment) - interceptSegmentPrecedence(bSegment);
80
+ if (precedence !== 0) return precedence;
81
+ if (aSegment !== bSegment) return aSegment.localeCompare(bSegment);
82
+ }
83
+ const lengthDifference = a.targetPatternParts.length - b.targetPatternParts.length;
84
+ return lengthDifference !== 0 ? lengthDifference : a.targetPattern.localeCompare(b.targetPattern);
85
+ }
67
86
  function createInterceptLookup(routes) {
68
87
  const patternToIndex = new Map(routes.map((r, i) => [r.pattern, i]));
69
88
  const interceptLookup = [];
@@ -85,6 +104,8 @@ function createInterceptLookup(routes) {
85
104
  sourceMatchPatternParts,
86
105
  sourcePageSegments: intercept.sourcePageSegments ?? null,
87
106
  interceptLayouts: intercept.interceptLayouts,
107
+ interceptLayoutSegments: intercept.interceptLayoutSegments,
108
+ interceptBranchSegments: intercept.interceptBranchSegments,
88
109
  __loadInterceptLayouts: intercept.__loadInterceptLayouts,
89
110
  page: intercept.page,
90
111
  __pageLoader: intercept.__pageLoader,
@@ -110,6 +131,8 @@ function createInterceptLookup(routes) {
110
131
  sourceMatchPatternParts,
111
132
  sourcePageSegments: intercept.sourcePageSegments ?? null,
112
133
  interceptLayouts: intercept.interceptLayouts,
134
+ interceptLayoutSegments: intercept.interceptLayoutSegments,
135
+ interceptBranchSegments: intercept.interceptBranchSegments,
113
136
  __loadInterceptLayouts: intercept.__loadInterceptLayouts,
114
137
  page: intercept.page,
115
138
  __pageLoader: intercept.__pageLoader,
@@ -122,7 +145,7 @@ function createInterceptLookup(routes) {
122
145
  });
123
146
  }
124
147
  }
125
- return interceptLookup;
148
+ return interceptLookup.sort(compareInterceptTargetPatterns);
126
149
  }
127
150
  function matchAppRscRoutePattern(urlParts, patternParts) {
128
151
  return matchRoutePattern(urlParts, patternParts);
@@ -130,5 +153,15 @@ function matchAppRscRoutePattern(urlParts, patternParts) {
130
153
  function mergeMatchedParams(sourceParams, targetParams) {
131
154
  return Object.assign(createRouteParams(), sourceParams, targetParams);
132
155
  }
156
+ function pickPatternParams(params, patternParts) {
157
+ const picked = createRouteParams();
158
+ for (const patternPart of patternParts) {
159
+ if (!patternPart.startsWith(":")) continue;
160
+ const paramName = patternPart.endsWith("+") || patternPart.endsWith("*") ? patternPart.slice(1, -1) : patternPart.slice(1);
161
+ const value = params[paramName];
162
+ if (value !== void 0) picked[paramName] = value;
163
+ }
164
+ return picked;
165
+ }
133
166
  //#endregion
134
167
  export { SIBLING_PAGE_INTERCEPT_SLOT_KEY, createAppRscRouteMatcher, matchAppRscRoutePattern };
@@ -6,6 +6,7 @@ type AppRouteSegmentConfigModule = {
6
6
  dynamic?: unknown;
7
7
  dynamicParams?: unknown;
8
8
  fetchCache?: unknown;
9
+ generateStaticParams?: unknown;
9
10
  revalidate?: unknown;
10
11
  runtime?: unknown;
11
12
  unstable_dynamicStaleTime?: unknown;
@@ -18,10 +19,21 @@ type EffectiveAppPageSegmentConfig = {
18
19
  revalidateSeconds: number | null;
19
20
  runtime?: "edge" | "experimental-edge" | "nodejs";
20
21
  };
22
+ type ParallelAppPageSegmentConfigBranch = {
23
+ configLayouts?: readonly (AppRouteSegmentConfigModule | null | undefined)[] | null;
24
+ configLayoutTreePositions?: readonly number[] | null;
25
+ layout?: AppRouteSegmentConfigModule | null;
26
+ page?: AppRouteSegmentConfigModule | null;
27
+ routeSegments?: readonly string[] | null;
28
+ };
21
29
  type ResolveAppPageSegmentConfigOptions = {
22
30
  layouts?: readonly (AppRouteSegmentConfigModule | null | undefined)[];
31
+ layoutTreePositions?: readonly number[];
23
32
  page?: AppRouteSegmentConfigModule | null;
33
+ parallelBranches?: readonly (ParallelAppPageSegmentConfigBranch | null | undefined)[];
24
34
  parallelPages?: readonly (AppRouteSegmentConfigModule | null | undefined)[];
35
+ parallelSegments?: readonly (AppRouteSegmentConfigModule | null | undefined)[];
36
+ routeSegments?: readonly string[];
25
37
  };
26
38
  /**
27
39
  * Resolve the route segment config that applies to an App page route.
@@ -37,6 +37,65 @@ function resolveDynamicStaleTimeSeconds(current, value) {
37
37
  if (typeof value !== "number" || !Number.isInteger(value) || value < 0) return current;
38
38
  return current === void 0 ? value : Math.min(current, value);
39
39
  }
40
+ function isDynamicSegment(segment) {
41
+ return segment.startsWith("[") && segment.endsWith("]");
42
+ }
43
+ function getParallelSegments(options) {
44
+ if (!options.parallelBranches) return options.parallelSegments ?? [];
45
+ return options.parallelBranches.flatMap((branch) => branch ? [
46
+ branch.layout,
47
+ ...branch.configLayouts ?? [],
48
+ branch.page
49
+ ] : []);
50
+ }
51
+ function resolveDynamicParamsConfig(options) {
52
+ const parallelSegments = getParallelSegments(options);
53
+ const segments = [
54
+ ...options.layouts ?? [],
55
+ options.page,
56
+ ...parallelSegments
57
+ ];
58
+ let dynamicParamsConfig;
59
+ for (const segment of segments) if (segment?.dynamicParams === false) dynamicParamsConfig = false;
60
+ else if (segment?.dynamicParams === true && dynamicParamsConfig !== false) dynamicParamsConfig = true;
61
+ if (dynamicParamsConfig !== false || !options.routeSegments) return dynamicParamsConfig;
62
+ let lastDynamicPosition = -1;
63
+ for (let index = options.routeSegments.length - 1; index >= 0; index--) if (isDynamicSegment(options.routeSegments[index])) {
64
+ lastDynamicPosition = index;
65
+ break;
66
+ }
67
+ if (lastDynamicPosition < 0) return dynamicParamsConfig;
68
+ const layouts = options.layouts ?? [];
69
+ const layoutPositions = options.layoutTreePositions ?? [];
70
+ let lastDynamicSegmentIsStaticOnly = false;
71
+ let lastDynamicSegmentHasStaticParams = false;
72
+ layouts.forEach((layout, index) => {
73
+ if ((layoutPositions[index] ?? 0) - 1 !== lastDynamicPosition) return;
74
+ if (layout?.dynamicParams === false) lastDynamicSegmentIsStaticOnly = true;
75
+ if (typeof layout?.generateStaticParams === "function") lastDynamicSegmentHasStaticParams = true;
76
+ });
77
+ if (options.page?.dynamicParams === false) lastDynamicSegmentIsStaticOnly = true;
78
+ if (typeof options.page?.generateStaticParams === "function") lastDynamicSegmentHasStaticParams = true;
79
+ for (const branch of options.parallelBranches ?? []) {
80
+ if (!branch) continue;
81
+ const branchStartPosition = options.routeSegments.length - (branch.routeSegments?.length ?? 0);
82
+ const checkSegment = (segment, ownerPosition) => {
83
+ if (ownerPosition !== lastDynamicPosition) return;
84
+ if (segment?.dynamicParams === false) lastDynamicSegmentIsStaticOnly = true;
85
+ if (typeof segment?.generateStaticParams === "function") lastDynamicSegmentHasStaticParams = true;
86
+ };
87
+ checkSegment(branch.layout, branchStartPosition - 1);
88
+ branch.configLayouts?.forEach((layout, index) => {
89
+ checkSegment(layout, branchStartPosition + (branch.configLayoutTreePositions?.[index] ?? 0) - 1);
90
+ });
91
+ checkSegment(branch.page, branchStartPosition + (branch.routeSegments?.length ?? 0) - 1);
92
+ }
93
+ if (!options.parallelBranches) for (const segment of parallelSegments) {
94
+ if (segment?.dynamicParams === false) lastDynamicSegmentIsStaticOnly = true;
95
+ if (typeof segment?.generateStaticParams === "function") lastDynamicSegmentHasStaticParams = true;
96
+ }
97
+ return lastDynamicSegmentIsStaticOnly || lastDynamicSegmentHasStaticParams ? false : void 0;
98
+ }
40
99
  function isCacheFetchCacheMode(value) {
41
100
  return value === "default-cache" || value === "force-cache" || value === "only-cache";
42
101
  }
@@ -53,18 +112,22 @@ function describeFetchCacheConflict(value) {
53
112
  */
54
113
  function resolveAppPageSegmentConfig(options) {
55
114
  const segments = [...options.layouts ?? [], options.page];
115
+ const parallelSegments = getParallelSegments(options);
56
116
  const config = { revalidateSeconds: null };
117
+ config.dynamicParamsConfig = resolveDynamicParamsConfig(options);
57
118
  let hasForceCache = false;
58
119
  let hasForceNoStore = false;
59
120
  let hasOnlyCache = false;
60
121
  let hasOnlyNoStore = false;
61
122
  let hasParentDefaultNoStore = false;
123
+ let hasForceDynamic = false;
62
124
  for (const segment of segments) {
63
125
  if (!segment) continue;
64
- if (isRouteSegmentDynamic(segment.dynamic)) config.dynamicConfig = segment.dynamic;
126
+ if (isRouteSegmentDynamic(segment.dynamic)) {
127
+ if (segment.dynamic === "force-dynamic") hasForceDynamic = true;
128
+ config.dynamicConfig = hasForceDynamic ? "force-dynamic" : segment.dynamic;
129
+ }
65
130
  if (isRouteSegmentRuntime(segment.runtime)) config.runtime = segment.runtime;
66
- if (segment.dynamicParams === false) config.dynamicParamsConfig = false;
67
- else if (segment.dynamicParams === true && config.dynamicParamsConfig !== false) config.dynamicParamsConfig = true;
68
131
  if (isRouteSegmentFetchCache(segment.fetchCache)) {
69
132
  const fetchCache = segment.fetchCache;
70
133
  if (hasParentDefaultNoStore && (fetchCache === "auto" || isCacheFetchCacheMode(fetchCache))) throw new Error(describeFetchCacheConflict(fetchCache));
@@ -72,7 +135,7 @@ function resolveAppPageSegmentConfig(options) {
72
135
  if (fetchCache === "force-no-store") hasForceNoStore = true;
73
136
  if (fetchCache === "only-cache") hasOnlyCache = true;
74
137
  if (fetchCache === "only-no-store") hasOnlyNoStore = true;
75
- if ((hasForceCache || hasOnlyCache) && (hasForceNoStore || hasOnlyNoStore)) throw new Error(describeFetchCacheConflict(fetchCache));
138
+ if (hasForceCache && hasForceNoStore || !hasForceCache && !hasForceNoStore && hasOnlyCache && hasOnlyNoStore) throw new Error(describeFetchCacheConflict(fetchCache));
76
139
  if (fetchCache === "default-no-store") hasParentDefaultNoStore = true;
77
140
  if (hasForceCache) config.fetchCache = "force-cache";
78
141
  else if (hasForceNoStore) config.fetchCache = "force-no-store";
@@ -82,6 +145,30 @@ function resolveAppPageSegmentConfig(options) {
82
145
  }
83
146
  config.revalidateSeconds = resolveRevalidateSeconds(config.revalidateSeconds, segment.revalidate);
84
147
  }
148
+ for (const segment of parallelSegments) {
149
+ if (!segment) continue;
150
+ if (segment.dynamic === "force-dynamic") {
151
+ hasForceDynamic = true;
152
+ config.dynamicConfig = "force-dynamic";
153
+ } else if (config.dynamicConfig === void 0 && isRouteSegmentDynamic(segment.dynamic)) config.dynamicConfig = segment.dynamic;
154
+ if (config.runtime === void 0 && isRouteSegmentRuntime(segment.runtime)) config.runtime = segment.runtime;
155
+ if (isRouteSegmentFetchCache(segment.fetchCache)) {
156
+ const fetchCache = segment.fetchCache;
157
+ if (hasParentDefaultNoStore && (fetchCache === "auto" || isCacheFetchCacheMode(fetchCache))) throw new Error(describeFetchCacheConflict(fetchCache));
158
+ if (fetchCache === "force-cache") hasForceCache = true;
159
+ if (fetchCache === "force-no-store") hasForceNoStore = true;
160
+ if (fetchCache === "only-cache") hasOnlyCache = true;
161
+ if (fetchCache === "only-no-store") hasOnlyNoStore = true;
162
+ if (hasForceCache && hasForceNoStore || !hasForceCache && !hasForceNoStore && hasOnlyCache && hasOnlyNoStore) throw new Error(describeFetchCacheConflict(fetchCache));
163
+ if (fetchCache === "default-no-store") hasParentDefaultNoStore = true;
164
+ if (hasForceCache) config.fetchCache = "force-cache";
165
+ else if (hasForceNoStore) config.fetchCache = "force-no-store";
166
+ else if (hasOnlyCache) config.fetchCache = "only-cache";
167
+ else if (hasOnlyNoStore) config.fetchCache = "only-no-store";
168
+ else if (config.fetchCache === void 0) config.fetchCache = fetchCache;
169
+ }
170
+ config.revalidateSeconds = resolveRevalidateSeconds(config.revalidateSeconds, segment.revalidate);
171
+ }
85
172
  for (const segment of [options.page, ...options.parallelPages ?? []]) {
86
173
  if (!segment) continue;
87
174
  config.dynamicStaleTimeSeconds = resolveDynamicStaleTimeSeconds(config.dynamicStaleTimeSeconds, segment.unstable_dynamicStaleTime);
@@ -90,7 +177,6 @@ function resolveAppPageSegmentConfig(options) {
90
177
  if (config.fetchCache === void 0) {
91
178
  if (config.dynamicConfig === "error") config.fetchCache = "only-cache";
92
179
  }
93
- if (config.dynamicParamsConfig === void 0 && (config.dynamicConfig === "error" || config.dynamicConfig === "force-static")) config.dynamicParamsConfig = false;
94
180
  return config;
95
181
  }
96
182
  function resolveAppPageFetchCacheMode(options) {
@@ -29,6 +29,7 @@ type AppServerActionReturnValue = {
29
29
  type AppServerActionRoute = {
30
30
  page?: unknown;
31
31
  pattern: string;
32
+ rootParamNames?: readonly string[];
32
33
  routeHandler?: unknown;
33
34
  routeSegments?: readonly string[];
34
35
  params?: readonly string[] | null;
@@ -76,6 +77,7 @@ type AppServerActionMatch<TRoute extends AppServerActionRoute> = {
76
77
  };
77
78
  type AppServerActionIntercept<TPage = unknown> = {
78
79
  matchedParams: AppPageParams;
80
+ sourceMatchedParams?: AppPageParams;
79
81
  page: TPage;
80
82
  slotId?: string | null;
81
83
  slotKey: string;
@@ -91,6 +93,8 @@ type BuildServerActionPageElementOptions<TRoute extends AppServerActionRoute, TI
91
93
  route: TRoute;
92
94
  searchParams: URLSearchParams;
93
95
  renderMode: AppRscRenderMode;
96
+ observeMetadataSearchParamsAccess?: boolean;
97
+ observePageSearchParamsAccess?: boolean;
94
98
  };
95
99
  type AppServerActionRscModel<TElement> = {
96
100
  /**
@@ -148,6 +152,7 @@ type HandleServerActionRscRequestOptions<TElement, TRoute extends AppServerActio
148
152
  createRscOnErrorHandler: (request: Request, pathname: string, pattern: string) => (error: unknown) => unknown;
149
153
  createTemporaryReferenceSet: () => TTemporaryReferences;
150
154
  decodeReply: (body: string | FormData, options: DecodeServerActionReplyOptions<TTemporaryReferences>) => Promise<unknown[]> | unknown[];
155
+ draftModeSecret: string;
151
156
  /**
152
157
  * Hydrate a route's lazy page/route-handler modules before reading
153
158
  * `route.page` / `route.routeHandler` on action redirect targets and
@@ -5,7 +5,7 @@ import { isExternalUrl } from "../config/config-matchers.js";
5
5
  import { internalServerErrorResponse, payloadTooLargeResponse } from "./http-error-responses.js";
6
6
  import { validateCsrfOrigin, validateServerActionPayload } from "./request-pipeline.js";
7
7
  import { APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI } from "./app-rsc-render-mode.js";
8
- import { headersContextFromRequest, setHeadersContext } from "../shims/headers.js";
8
+ import { headersContextFromRequest, isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
9
9
  import { getAndClearActionRevalidationKind } from "../shims/cache-request-state.js";
10
10
  import { setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
11
11
  import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
@@ -19,8 +19,31 @@ import "./app-page-stream.js";
19
19
  import { buildAppPageTags } from "./implicit-tags.js";
20
20
  import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
21
21
  import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
22
+ import { createRootParamsUsageController, pickRootParams, runWithRootParamsScope, runWithRootParamsUsage } from "../shims/root-params.js";
22
23
  import { getSetCookieName } from "./cookie-utils.js";
24
+ import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
23
25
  //#region src/server/app-server-action-execution.ts
26
+ function prepareActionPageRerenderContext(options) {
27
+ if (options.dynamicConfig === "force-static" || options.dynamicConfig === "error") setHeadersContext(createStaticGenerationHeadersContext({
28
+ draftModeEnabled: isDraftModeRequest(createActionRerenderRequest({
29
+ draftModeCookie: options.draftModeCookie,
30
+ request: options.request
31
+ }), options.draftModeSecret),
32
+ draftModeSecret: options.draftModeSecret,
33
+ dynamicConfig: options.dynamicConfig,
34
+ routeKind: "page",
35
+ routePattern: options.routePattern
36
+ }));
37
+ return options.dynamicConfig === "force-static" ? new URLSearchParams() : options.searchParams;
38
+ }
39
+ function createActionRerenderRequest(options) {
40
+ if (!options.draftModeCookie) return options.request;
41
+ const headers = new Headers(options.request.headers);
42
+ const cookieHeader = applySetCookieMutationsToRequestCookieHeader(headers.get("cookie"), [options.draftModeCookie]);
43
+ if (cookieHeader === null) headers.delete("cookie");
44
+ else headers.set("cookie", cookieHeader);
45
+ return new Request(options.request.url, { headers });
46
+ }
24
47
  /**
25
48
  * Matches Next.js' server action argument cap to prevent stack overflow in
26
49
  * Function.prototype.apply when decoding hostile action payloads.
@@ -351,11 +374,14 @@ async function handleProgressiveServerActionRequest(options) {
351
374
  let actionRedirect = null;
352
375
  let actionError = void 0;
353
376
  let actionFailed = false;
377
+ let actionThrew = false;
354
378
  let actionResult;
379
+ const rootParamsUsage = createRootParamsUsageController();
355
380
  const previousHeadersPhase = options.setHeadersAccessPhase("action");
356
381
  try {
357
- actionResult = await action();
382
+ actionResult = await runWithRootParamsUsage({ kind: "server-action" }, action, rootParamsUsage);
358
383
  } catch (error) {
384
+ actionThrew = true;
359
385
  actionRedirect = getActionRedirect(error);
360
386
  if (!actionRedirect) {
361
387
  actionError = error;
@@ -375,8 +401,10 @@ async function handleProgressiveServerActionRequest(options) {
375
401
  }
376
402
  } finally {
377
403
  options.setHeadersAccessPhase(previousHeadersPhase);
404
+ if (actionThrew) rootParamsUsage.transitionToRender();
378
405
  }
379
406
  if (!actionRedirect) {
407
+ if (!actionThrew) rootParamsUsage.transitionToRender();
380
408
  const actionPendingCookies = dedupePendingCookies(options.getAndClearPendingCookies());
381
409
  const actionDraftCookie = options.getDraftModeCookieHeader();
382
410
  const revalidationKind = resolveActionRevalidationKind(actionPendingCookies.length > 0 || Boolean(actionDraftCookie));
@@ -544,16 +572,19 @@ async function handleServerActionRscRequest(options) {
544
572
  let returnValue;
545
573
  let actionRedirect = null;
546
574
  let actionStatus = 200;
575
+ let actionThrew = false;
547
576
  const actionWasForwarded = Boolean(options.request.headers.get(ACTION_FORWARDED_HEADER));
577
+ const rootParamsUsage = createRootParamsUsageController();
548
578
  const previousHeadersPhase = options.setHeadersAccessPhase("action");
549
579
  try {
550
580
  try {
551
581
  validateServerActionArgs(args);
552
582
  returnValue = {
553
583
  ok: true,
554
- data: await action.apply(null, args)
584
+ data: await runWithRootParamsUsage({ kind: "server-action" }, () => action.apply(null, args), rootParamsUsage)
555
585
  };
556
586
  } catch (error) {
587
+ actionThrew = true;
557
588
  actionRedirect = getActionRedirect(error);
558
589
  if (actionRedirect) returnValue = {
559
590
  ok: true,
@@ -568,6 +599,7 @@ async function handleServerActionRscRequest(options) {
568
599
  data: error
569
600
  };
570
601
  } else {
602
+ actionStatus = 500;
571
603
  console.error("[vinext] Server action error:", error);
572
604
  returnValue = {
573
605
  ok: false,
@@ -578,6 +610,7 @@ async function handleServerActionRscRequest(options) {
578
610
  }
579
611
  } finally {
580
612
  options.setHeadersAccessPhase(previousHeadersPhase);
613
+ if (actionThrew && !actionWasForwarded) rootParamsUsage.transitionToRender();
581
614
  }
582
615
  if (actionRedirect) {
583
616
  const actionPendingCookies = dedupePendingCookies(options.getAndClearPendingCookies());
@@ -622,35 +655,48 @@ async function handleServerActionRscRequest(options) {
622
655
  request: options.request,
623
656
  url: redirectTarget
624
657
  });
625
- setHeadersContext(headersContextFromRequest(redirectRenderRequest));
658
+ setHeadersContext(headersContextFromRequest(redirectRenderRequest, { draftModeSecret: options.draftModeSecret }));
659
+ const redirectDynamicConfig = options.resolveRouteDynamicConfig?.(targetMatch.route);
660
+ const redirectSearchParams = prepareActionPageRerenderContext({
661
+ draftModeCookie: actionDraftCookie,
662
+ draftModeSecret: options.draftModeSecret,
663
+ dynamicConfig: redirectDynamicConfig,
664
+ request: redirectRenderRequest,
665
+ routePattern: targetMatch.route.pattern,
666
+ searchParams: redirectTarget.searchParams
667
+ });
626
668
  const redirectNavigationParams = resolveAppPageNavigationParams(targetMatch.route, targetMatch.params, targetPathname, null);
627
669
  options.setNavigationContext({
628
670
  pathname: targetPathname,
629
- searchParams: redirectTarget.searchParams,
671
+ searchParams: redirectSearchParams,
630
672
  params: redirectNavigationParams
631
673
  });
632
674
  setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(targetMatch.route) ?? null);
633
- setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(targetMatch.route) === "force-dynamic");
675
+ setCurrentForceDynamicFetchDefault(redirectDynamicConfig === "force-dynamic");
634
676
  setCurrentFetchSoftTags(buildServerActionPageTags(targetMatch.route, targetPathname));
635
- const element = options.buildPageElement({
636
- cleanPathname: targetPathname,
637
- interceptOpts: void 0,
638
- isRscRequest: true,
639
- mountedSlotsHeader: null,
640
- params: targetMatch.params,
641
- request: redirectRenderRequest,
642
- route: targetMatch.route,
643
- searchParams: redirectTarget.searchParams,
644
- renderMode: APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI
645
- });
646
- const onRenderError = options.createRscOnErrorHandler(redirectRenderRequest, targetPathname, targetMatch.route.pattern);
647
- return createServerActionRscResponse(await options.renderToReadableStream({
648
- root: element,
649
- returnValue
650
- }, {
651
- temporaryReferences,
652
- onError: onRenderError
653
- }), {
677
+ return createServerActionRscResponse(await runWithRootParamsScope(pickRootParams(targetMatch.params, targetMatch.route.rootParamNames), () => runWithRootParamsUsage({ kind: "route" }, async () => {
678
+ const element = options.buildPageElement({
679
+ cleanPathname: targetPathname,
680
+ interceptOpts: void 0,
681
+ isRscRequest: true,
682
+ mountedSlotsHeader: null,
683
+ params: targetMatch.params,
684
+ request: redirectRenderRequest,
685
+ route: targetMatch.route,
686
+ searchParams: redirectSearchParams,
687
+ renderMode: APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI,
688
+ observeMetadataSearchParamsAccess: redirectDynamicConfig !== "force-static",
689
+ observePageSearchParamsAccess: redirectDynamicConfig !== "force-static"
690
+ });
691
+ const onRenderError = options.createRscOnErrorHandler(redirectRenderRequest, targetPathname, targetMatch.route.pattern);
692
+ return options.renderToReadableStream({
693
+ root: element,
694
+ returnValue
695
+ }, {
696
+ temporaryReferences,
697
+ onError: onRenderError
698
+ });
699
+ })), {
654
700
  status: shouldUseForwardedActionRedirectStatus({
655
701
  actionWasForwarded,
656
702
  currentPathname: options.cleanPathname,
@@ -665,7 +711,8 @@ async function handleServerActionRscRequest(options) {
665
711
  const actionPendingCookies = dedupePendingCookies(options.getAndClearPendingCookies());
666
712
  const actionDraftCookie = options.getDraftModeCookieHeader();
667
713
  const actionRevalidationKind = resolveActionRevalidationKind(actionPendingCookies.length > 0 || Boolean(actionDraftCookie));
668
- if (actionWasForwarded || actionStatus === 200 && actionRevalidationKind === ACTION_DID_NOT_REVALIDATE) {
714
+ const isHttpFallback = actionStatus === 401 || actionStatus === 403 || actionStatus === 404;
715
+ if (!isHttpFallback && (actionWasForwarded || actionRevalidationKind === ACTION_DID_NOT_REVALIDATE)) {
669
716
  const onRenderError = options.createRscOnErrorHandler(options.request, options.cleanPathname, options.cleanPathname);
670
717
  const rscStream = await options.renderToReadableStream({ returnValue }, {
671
718
  temporaryReferences,
@@ -686,6 +733,7 @@ async function handleServerActionRscRequest(options) {
686
733
  headers: actionHeaders
687
734
  }, options.clearRequestContext);
688
735
  }
736
+ if (!actionThrew) rootParamsUsage.transitionToRender();
689
737
  const match = options.matchRoute(options.cleanPathname);
690
738
  let element;
691
739
  let errorPattern = match ? match.route.pattern : options.cleanPathname;
@@ -702,16 +750,25 @@ async function handleServerActionRscRequest(options) {
702
750
  toInterceptOpts: options.toInterceptOpts
703
751
  });
704
752
  const resolvedActionNavigationParams = resolveAppPageNavigationParams(actionRerenderTarget.route, actionRerenderTarget.navigationParams, options.cleanPathname, actionRerenderTarget.interceptOpts);
753
+ await options.ensureRouteLoaded?.(actionRerenderTarget.route);
754
+ const actionRerenderDynamicConfig = options.resolveRouteDynamicConfig?.(actionRerenderTarget.route);
755
+ const actionRerenderSearchParams = prepareActionPageRerenderContext({
756
+ draftModeCookie: actionDraftCookie,
757
+ draftModeSecret: options.draftModeSecret,
758
+ dynamicConfig: actionRerenderDynamicConfig,
759
+ request: options.request,
760
+ routePattern: actionRerenderTarget.route.pattern,
761
+ searchParams: options.searchParams
762
+ });
705
763
  options.setNavigationContext({
706
764
  pathname: options.cleanPathname,
707
- searchParams: options.searchParams,
765
+ searchParams: actionRerenderSearchParams,
708
766
  params: resolvedActionNavigationParams
709
767
  });
710
- await options.ensureRouteLoaded?.(actionRerenderTarget.route);
711
768
  setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(actionRerenderTarget.route) ?? null);
712
- setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(actionRerenderTarget.route) === "force-dynamic");
769
+ setCurrentForceDynamicFetchDefault(actionRerenderDynamicConfig === "force-dynamic");
713
770
  setCurrentFetchSoftTags(buildServerActionPageTags(actionRerenderTarget.route, options.cleanPathname));
714
- element = options.buildPageElement({
771
+ const buildActionRerenderElement = () => options.buildPageElement({
715
772
  cleanPathname: options.cleanPathname,
716
773
  interceptOpts: actionRerenderTarget.interceptOpts,
717
774
  isRscRequest: options.isRscRequest,
@@ -719,22 +776,26 @@ async function handleServerActionRscRequest(options) {
719
776
  params: actionRerenderTarget.params,
720
777
  request: options.request,
721
778
  route: actionRerenderTarget.route,
722
- searchParams: options.searchParams,
723
- renderMode: APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI
779
+ searchParams: actionRerenderSearchParams,
780
+ renderMode: APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI,
781
+ observeMetadataSearchParamsAccess: actionRerenderDynamicConfig !== "force-static",
782
+ observePageSearchParamsAccess: actionRerenderDynamicConfig !== "force-static"
724
783
  });
784
+ element = actionWasForwarded && isHttpFallback ? await runWithRootParamsUsage({ kind: "route" }, async () => buildActionRerenderElement()) : buildActionRerenderElement();
725
785
  errorPattern = actionRerenderTarget.route.pattern;
726
786
  } else {
727
787
  const actionRouteId = options.createPayloadRouteId(options.cleanPathname, null);
728
788
  element = options.createNotFoundElement(actionRouteId);
729
789
  }
730
790
  const onRenderError = options.createRscOnErrorHandler(options.request, options.cleanPathname, errorPattern);
731
- const rscStream = await options.renderToReadableStream({
791
+ const renderActionRerender = () => options.renderToReadableStream({
732
792
  root: element,
733
793
  returnValue
734
794
  }, {
735
795
  temporaryReferences,
736
796
  onError: onRenderError
737
797
  });
798
+ const rscStream = await (actionWasForwarded && isHttpFallback ? runWithRootParamsUsage({ kind: "route" }, renderActionRerender) : renderActionRerender());
738
799
  const actionHeaders = new Headers({
739
800
  "Content-Type": VINEXT_RSC_CONTENT_TYPE,
740
801
  Vary: VINEXT_RSC_VARY_HEADER
@@ -1,5 +1,6 @@
1
1
  import { NavigationContext } from "../shims/navigation-context-state.js";
2
2
  import { RootParams } from "../shims/root-params.js";
3
+ import { InitialNavigationCacheMetadata } from "./app-ssr-stream.js";
3
4
  import { AppSsrRenderResult } from "./app-page-stream.js";
4
5
  import { ReactFormState } from "react-dom/client";
5
6
 
@@ -44,6 +45,8 @@ declare function handleSsr(rscStream: ReadableStream<Uint8Array>, navContext: Na
44
45
  * and ISR cache writes to avoid caching fallback content. */
45
46
  waitForAllReady?: boolean;
46
47
  fallbackToErrorDocumentOnShellError?: boolean;
48
+ dynamicStaleTimeSeconds?: number;
49
+ getInitialNavigationCacheMetadata?: () => InitialNavigationCacheMetadata;
47
50
  }): Promise<AppSsrRenderResult>;
48
51
  declare const _default: {
49
52
  fetch(request: Request): Promise<Response>;