vinext 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/README.md +22 -10
  2. package/dist/build/client-build-config.d.ts +10 -0
  3. package/dist/build/client-build-config.js +18 -2
  4. package/dist/build/output-root-externals.d.ts +21 -0
  5. package/dist/build/output-root-externals.js +40 -0
  6. package/dist/build/pages-client-assets-module.d.ts +8 -0
  7. package/dist/build/pages-client-assets-module.js +21 -1
  8. package/dist/build/prerender-paths.js +6 -4
  9. package/dist/build/prerender.js +1 -1
  10. package/dist/build/run-prerender.js +1 -1
  11. package/dist/build/ssr-manifest.d.ts +2 -0
  12. package/dist/build/ssr-manifest.js +6 -2
  13. package/dist/check.js +12 -12
  14. package/dist/cli-dev-config.js +3 -3
  15. package/dist/cli.js +3 -2
  16. package/dist/client/client-redirect-matcher.d.ts +14 -0
  17. package/dist/client/client-redirect-matcher.js +37 -0
  18. package/dist/client/client-redirects.d.ts +27 -0
  19. package/dist/client/client-redirects.js +28 -0
  20. package/dist/client/client-rewrites.d.ts +2 -1
  21. package/dist/client/client-rewrites.js +1 -1
  22. package/dist/config/config-matchers.d.ts +26 -11
  23. package/dist/config/config-matchers.js +90 -88
  24. package/dist/config/destination-params.d.ts +47 -0
  25. package/dist/config/destination-params.js +116 -0
  26. package/dist/config/next-config.d.ts +7 -0
  27. package/dist/config/next-config.js +3 -0
  28. package/dist/entries/app-rsc-entry.d.ts +4 -0
  29. package/dist/entries/app-rsc-entry.js +20 -6
  30. package/dist/entries/pages-client-entry.js +3 -1
  31. package/dist/entries/pages-server-entry.js +13 -37
  32. package/dist/index.d.ts +3 -1
  33. package/dist/index.js +246 -136
  34. package/dist/init-cloudflare.d.ts +9 -0
  35. package/dist/init-cloudflare.js +107 -31
  36. package/dist/init-platform.d.ts +4 -0
  37. package/dist/init-platform.js +27 -2
  38. package/dist/init.d.ts +2 -1
  39. package/dist/init.js +153 -9
  40. package/dist/plugins/ast-scope.d.ts +7 -0
  41. package/dist/plugins/ast-scope.js +59 -3
  42. package/dist/plugins/ast-utils.d.ts +53 -2
  43. package/dist/plugins/ast-utils.js +90 -2
  44. package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
  45. package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
  46. package/dist/plugins/commonjs-esm-facade.js +2 -2
  47. package/dist/plugins/css-module-imports.js +13 -20
  48. package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
  49. package/dist/plugins/dynamic-preload-metadata.js +11 -11
  50. package/dist/plugins/extensionless-dynamic-import.js +2 -3
  51. package/dist/plugins/fonts.d.ts +1 -1
  52. package/dist/plugins/fonts.js +3 -3
  53. package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
  54. package/dist/plugins/ignore-dynamic-requests.js +5 -7
  55. package/dist/plugins/import-meta-url.js +3 -4
  56. package/dist/plugins/instrumentation-client.js +3 -2
  57. package/dist/plugins/middleware-export-validation.js +2 -3
  58. package/dist/plugins/middleware-server-only.d.ts +5 -4
  59. package/dist/plugins/middleware-server-only.js +8 -5
  60. package/dist/plugins/og-harfbuzz.js +2 -3
  61. package/dist/plugins/optimize-imports.js +3 -4
  62. package/dist/plugins/pages-node-externals.js +3 -4
  63. package/dist/plugins/remove-console.js +2 -18
  64. package/dist/plugins/require-condition-resolution.js +3 -3
  65. package/dist/plugins/require-context.js +2 -3
  66. package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
  67. package/dist/plugins/rsc-scan-glob-imports.js +50 -0
  68. package/dist/plugins/strip-server-exports.js +265 -102
  69. package/dist/plugins/styled-jsx.js +2 -3
  70. package/dist/plugins/transform-result.d.ts +9 -5
  71. package/dist/plugins/transitive-externals.js +1 -1
  72. package/dist/plugins/typeof-window.d.ts +2 -2
  73. package/dist/plugins/use-cache-callable.d.ts +21 -2
  74. package/dist/plugins/use-cache-callable.js +84 -35
  75. package/dist/plugins/worker-image-imports.js +30 -33
  76. package/dist/plugins/worker-server-only-imports.d.ts +20 -0
  77. package/dist/plugins/worker-server-only-imports.js +31 -0
  78. package/dist/plugins/worker-use-server.d.ts +25 -0
  79. package/dist/plugins/worker-use-server.js +153 -0
  80. package/dist/server/api-handler.d.ts +1 -0
  81. package/dist/server/api-handler.js +3 -2
  82. package/dist/server/app-action-forwarding.js +2 -2
  83. package/dist/server/app-browser-action-result.d.ts +1 -1
  84. package/dist/server/app-browser-action-result.js +9 -2
  85. package/dist/server/app-browser-entry.js +3 -3
  86. package/dist/server/app-browser-interception-context.js +1 -1
  87. package/dist/server/app-browser-navigation-controller.js +1 -1
  88. package/dist/server/app-browser-prefetch-response.js +2 -2
  89. package/dist/server/app-browser-server-action-client.js +1 -1
  90. package/dist/server/app-browser-state.js +1 -1
  91. package/dist/server/app-browser-supplemental-refresh.js +1 -1
  92. package/dist/server/app-middleware.d.ts +11 -0
  93. package/dist/server/app-middleware.js +17 -2
  94. package/dist/server/app-optimistic-routing.js +1 -1
  95. package/dist/server/app-page-cache.d.ts +1 -1
  96. package/dist/server/app-page-cache.js +1 -1
  97. package/dist/server/app-page-dispatch.d.ts +3 -1
  98. package/dist/server/app-page-dispatch.js +5 -4
  99. package/dist/server/app-page-ppr-runtime.js +1 -1
  100. package/dist/server/app-page-render-observation.js +1 -1
  101. package/dist/server/app-page-render.js +1 -1
  102. package/dist/server/app-page-request.js +53 -15
  103. package/dist/server/app-page-route-wiring.js +2 -2
  104. package/dist/server/app-pages-bridge.d.ts +1 -1
  105. package/dist/server/app-pages-bridge.js +3 -4
  106. package/dist/server/app-prerender-endpoints.js +9 -6
  107. package/dist/server/app-render-abort-error.d.ts +19 -0
  108. package/dist/server/app-render-abort-error.js +31 -1
  109. package/dist/server/app-request-stage-dispatch.js +6 -2
  110. package/dist/server/app-request-stage-independent-entry.js +29 -9
  111. package/dist/server/app-response-stage-entry.js +11 -3
  112. package/dist/server/app-route-handler-cache.d.ts +1 -0
  113. package/dist/server/app-route-handler-cache.js +1 -0
  114. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  115. package/dist/server/app-route-handler-dispatch.js +5 -2
  116. package/dist/server/app-route-handler-execution.d.ts +1 -0
  117. package/dist/server/app-route-handler-execution.js +1 -0
  118. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  119. package/dist/server/app-route-handler-runtime.js +46 -25
  120. package/dist/server/app-router-entry.js +29 -10
  121. package/dist/server/app-rsc-cache-busting.d.ts +16 -0
  122. package/dist/server/app-rsc-cache-busting.js +30 -13
  123. package/dist/server/app-rsc-errors.js +20 -16
  124. package/dist/server/app-rsc-handler.d.ts +7 -0
  125. package/dist/server/app-rsc-handler.js +89 -39
  126. package/dist/server/app-rsc-request-normalization.js +3 -3
  127. package/dist/server/app-rsc-response-stage.js +5 -3
  128. package/dist/server/app-segment-config.d.ts +2 -1
  129. package/dist/server/app-server-action-execution.d.ts +2 -1
  130. package/dist/server/app-server-action-execution.js +62 -23
  131. package/dist/server/app-ssr-entry.js +7 -5
  132. package/dist/server/app-visited-response-cache.js +2 -2
  133. package/dist/server/app-worker-stages.d.ts +5 -0
  134. package/dist/server/app-worker-stages.js +1 -1
  135. package/dist/server/cacheability-request.js +2 -2
  136. package/dist/server/client-build-files.d.ts +16 -0
  137. package/dist/server/client-build-files.js +36 -0
  138. package/dist/server/client-reuse-manifest.js +1 -1
  139. package/dist/server/config-headers.js +1 -1
  140. package/dist/server/defer-until-stream-consumed.d.ts +2 -1
  141. package/dist/server/defer-until-stream-consumed.js +3 -1
  142. package/dist/server/dev-server.js +39 -28
  143. package/dist/server/dev-stack-sourcemap.js +18 -23
  144. package/dist/server/document-initial-head.d.ts +0 -11
  145. package/dist/server/document-initial-head.js +1 -1
  146. package/dist/server/forwarded-middleware-context.d.ts +5 -0
  147. package/dist/server/forwarded-middleware-context.js +22 -0
  148. package/dist/server/headers.d.ts +4 -1
  149. package/dist/server/headers.js +4 -1
  150. package/dist/server/http-conditional.d.ts +11 -0
  151. package/dist/server/http-conditional.js +10 -1
  152. package/dist/server/http-error-responses.d.ts +1 -1
  153. package/dist/server/image-optimization.d.ts +38 -0
  154. package/dist/server/image-optimization.js +94 -4
  155. package/dist/server/isr-cache.d.ts +10 -0
  156. package/dist/server/isr-cache.js +41 -6
  157. package/dist/server/metadata-route-response.js +11 -10
  158. package/dist/server/middleware-matcher.d.ts +2 -0
  159. package/dist/server/middleware-matcher.js +23 -2
  160. package/dist/server/middleware-path-to-regexp.js +1 -1
  161. package/dist/server/middleware-runtime.d.ts +13 -0
  162. package/dist/server/middleware-runtime.js +38 -25
  163. package/dist/server/middleware.d.ts +1 -1
  164. package/dist/server/middleware.js +3 -1
  165. package/dist/server/multi-stage.d.ts +11 -0
  166. package/dist/server/navigation-planner.js +1 -1
  167. package/dist/server/normalize-path.d.ts +0 -13
  168. package/dist/server/normalize-path.js +1 -34
  169. package/dist/server/open-redirect.d.ts +11 -4
  170. package/dist/server/open-redirect.js +11 -4
  171. package/dist/server/pages-api-route.d.ts +3 -2
  172. package/dist/server/pages-api-route.js +6 -5
  173. package/dist/server/pages-cache-tag.d.ts +12 -0
  174. package/dist/server/pages-cache-tag.js +19 -0
  175. package/dist/server/pages-client-assets.d.ts +2 -0
  176. package/dist/server/pages-data-route.d.ts +10 -0
  177. package/dist/server/pages-data-route.js +21 -3
  178. package/dist/server/pages-document-asset-props.d.ts +5 -1
  179. package/dist/server/pages-document-asset-props.js +13 -5
  180. package/dist/server/pages-document-splice.d.ts +19 -0
  181. package/dist/server/pages-document-splice.js +55 -0
  182. package/dist/server/pages-i18n.d.ts +12 -1
  183. package/dist/server/pages-i18n.js +18 -4
  184. package/dist/server/pages-node-compat.d.ts +16 -5
  185. package/dist/server/pages-node-compat.js +20 -12
  186. package/dist/server/pages-page-data.d.ts +32 -24
  187. package/dist/server/pages-page-data.js +51 -121
  188. package/dist/server/pages-page-handler.d.ts +0 -6
  189. package/dist/server/pages-page-handler.js +189 -127
  190. package/dist/server/pages-page-response.d.ts +12 -6
  191. package/dist/server/pages-page-response.js +42 -35
  192. package/dist/server/pages-request-pipeline.d.ts +10 -2
  193. package/dist/server/pages-request-pipeline.js +41 -22
  194. package/dist/server/pages-request-stage-entry.d.ts +6 -0
  195. package/dist/server/pages-request-stage-entry.js +75 -16
  196. package/dist/server/pages-response-stage-entry.js +4 -0
  197. package/dist/server/pages-revalidate.js +3 -3
  198. package/dist/server/pages-router-entry.js +5 -4
  199. package/dist/server/prerender-manifest.d.ts +3 -3
  200. package/dist/server/prerender-manifest.js +4 -3
  201. package/dist/server/prerender-work-unit-setup.js +4 -0
  202. package/dist/server/prod-server.d.ts +12 -0
  203. package/dist/server/prod-server.js +204 -74
  204. package/dist/server/proper-error.d.ts +4 -0
  205. package/dist/server/proper-error.js +31 -0
  206. package/dist/server/request-pipeline.d.ts +4 -1
  207. package/dist/server/request-pipeline.js +3 -2
  208. package/dist/server/revalidation-request.d.ts +1 -0
  209. package/dist/server/revalidation-request.js +1 -1
  210. package/dist/server/rsc-stream-hints.d.ts +1 -1
  211. package/dist/server/rsc-stream-hints.js +52 -5
  212. package/dist/server/seed-cache.d.ts +1 -0
  213. package/dist/server/seed-cache.js +5 -4
  214. package/dist/server/server-reference-loader.d.ts +4 -0
  215. package/dist/server/server-reference-loader.js +29 -0
  216. package/dist/server/socket-error-backstop.d.ts +9 -1
  217. package/dist/server/socket-error-backstop.js +46 -17
  218. package/dist/server/static-file-signal.d.ts +15 -4
  219. package/dist/server/static-file-signal.js +46 -12
  220. package/dist/server/worker-image-optimization.d.ts +34 -0
  221. package/dist/server/worker-image-optimization.js +99 -0
  222. package/dist/server/worker-stages.d.ts +1 -1
  223. package/dist/server/worker-stages.js +2 -2
  224. package/dist/server/worker-utils.d.ts +8 -3
  225. package/dist/server/worker-utils.js +12 -7
  226. package/dist/shims/app-router-scroll.js +4 -1
  227. package/dist/shims/app-router-tree-context.d.ts +5 -0
  228. package/dist/shims/app-router-tree-context.js +27 -0
  229. package/dist/shims/cache-callable-runtime.d.ts +4 -2
  230. package/dist/shims/cache-callable-runtime.js +21 -12
  231. package/dist/shims/cache-handler.js +1 -9
  232. package/dist/shims/cache-runtime.d.ts +6 -1
  233. package/dist/shims/cache-runtime.js +2 -1
  234. package/dist/shims/cache.d.ts +2 -2
  235. package/dist/shims/cache.js +40 -13
  236. package/dist/shims/cdn-cache.d.ts +8 -0
  237. package/dist/shims/cdn-cache.js +17 -1
  238. package/dist/shims/disable-smooth-scroll.d.ts +3 -0
  239. package/dist/shims/disable-smooth-scroll.js +36 -0
  240. package/dist/shims/document-placeholders.d.ts +19 -0
  241. package/dist/shims/document-placeholders.js +45 -0
  242. package/dist/shims/document.js +21 -5
  243. package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
  244. package/dist/shims/dynamic-preload-chunks.js +13 -9
  245. package/dist/shims/dynamic.d.ts +1 -1
  246. package/dist/shims/dynamic.js +60 -8
  247. package/dist/shims/fetch-cache-state.d.ts +66 -0
  248. package/dist/shims/fetch-cache-state.js +92 -0
  249. package/dist/shims/fetch-cache.d.ts +3 -67
  250. package/dist/shims/fetch-cache.js +160 -125
  251. package/dist/shims/head.d.ts +10 -6
  252. package/dist/shims/head.js +16 -14
  253. package/dist/shims/headers.js +2 -2
  254. package/dist/shims/image.js +2 -1
  255. package/dist/shims/internal/hybrid-client-route-owner-direct.js +1 -1
  256. package/dist/shims/internal/hybrid-client-route-owner.js +1 -0
  257. package/dist/shims/internal/work-store-scope.d.ts +5 -0
  258. package/dist/shims/internal/work-store-scope.js +24 -0
  259. package/dist/shims/link-prefetch.js +5 -4
  260. package/dist/shims/link.js +2 -2
  261. package/dist/shims/navigation.js +34 -9
  262. package/dist/shims/request-context.d.ts +2 -0
  263. package/dist/shims/request-state-types.d.ts +2 -1
  264. package/dist/shims/router.js +21 -32
  265. package/dist/shims/server.d.ts +27 -4
  266. package/dist/shims/server.js +65 -9
  267. package/dist/shims/unified-request-context.d.ts +1 -1
  268. package/dist/shims/url-utils.d.ts +9 -0
  269. package/dist/shims/url-utils.js +15 -4
  270. package/dist/utils/client-runtime-metadata.js +1 -1
  271. package/dist/utils/domain-locale.js +1 -1
  272. package/dist/utils/hash.d.ts +7 -0
  273. package/dist/utils/hash.js +11 -1
  274. package/dist/utils/package-name.d.ts +6 -0
  275. package/dist/utils/package-name.js +12 -1
  276. package/dist/utils/plugin-rsc-version.d.ts +6 -0
  277. package/dist/utils/plugin-rsc-version.js +41 -0
  278. package/dist/utils/prerender-output-paths.js +15 -4
  279. package/dist/utils/public-file-path.d.ts +10 -2
  280. package/dist/utils/public-file-path.js +13 -9
  281. package/dist/utils/public-routes.js +2 -2
  282. package/dist/utils/react-version.d.ts +10 -0
  283. package/dist/utils/react-version.js +39 -16
  284. package/package.json +11 -7
  285. package/dist/build/nitro-route-rules.d.ts +0 -47
  286. package/dist/build/nitro-route-rules.js +0 -79
  287. package/dist/plugins/cache-flight-codec.d.ts +0 -19
  288. package/dist/plugins/cache-flight-codec.js +0 -68
@@ -1,9 +1,9 @@
1
1
  import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { parseProgramAsync } from "./ast-utils.js";
2
3
  import { magicStringTransformResult } from "./transform-result.js";
3
4
  import { NODE_MODULES_PATH_RE } from "../utils/path.js";
4
5
  import { createRequire } from "node:module";
5
6
  import { pathToFileURL } from "node:url";
6
- import { parseAstAsync } from "vite";
7
7
  import { createHmac, randomBytes } from "node:crypto";
8
8
  //#region src/plugins/use-cache-callable.ts
9
9
  const PLUGIN_NAME = "vinext:server-function-directives";
@@ -72,9 +72,46 @@ function getFunctionDirectiveExportNames(transforms, ast, directive) {
72
72
  }
73
73
  function getCacheWrapperOptions(meta) {
74
74
  const argumentCount = getArgumentCount(meta);
75
+ const captureCount = "bindVars" in meta ? meta.bindVars.length : 0;
75
76
  return {
76
77
  acceptsSecondArgument: acceptsSecondArgument(meta),
77
- ...argumentCount === void 0 ? {} : { argumentCount }
78
+ ...argumentCount === void 0 ? {} : { argumentCount },
79
+ ...captureCount === 0 ? {} : { captureCount }
80
+ };
81
+ }
82
+ /**
83
+ * Compile a module for a browser graph: module-level cache functions become
84
+ * server references, and inline ones are rejected as in Next.js Client
85
+ * Components. Returns undefined when the module is unchanged.
86
+ */
87
+ function transformBrowserModule(transforms, code, ast, id, moduleDirective, options) {
88
+ if (!moduleDirective) {
89
+ transforms.transformHoistInlineDirective(code, ast, {
90
+ directive: USE_CACHE_DIRECTIVE_CANDIDATE,
91
+ rejectNonAsyncFunction: true,
92
+ runtime: (_value, _name, meta) => {
93
+ matchUseCacheDirective(meta.directiveMatch[0]);
94
+ throw new Error(`It is not allowed to define inline "use cache" annotated functions in Client Components. Export them from a separate file with a module-level "use cache" or "use server" directive, or pass them down through props from a Server Component. (${options.environmentName}: ${id})`);
95
+ }
96
+ });
97
+ return;
98
+ }
99
+ const useServerExportNames = getFunctionDirectiveExportNames(transforms, ast, "use server");
100
+ const referenceName = (name) => useServerExportNames.has(name) ? name : options.secureExportName(name);
101
+ const result = transforms.transformDirectiveProxyExport(ast, {
102
+ code,
103
+ directive: moduleDirective,
104
+ filter: (name, meta) => {
105
+ if (!shouldTransformModuleExport(name, id, meta)) return false;
106
+ validateModuleExport(transforms, meta);
107
+ return true;
108
+ },
109
+ runtime: (name) => options.createReference(`${options.reference.referenceKey}#${referenceName(name)}`, name)
110
+ });
111
+ if (!result?.output.hasChanged()) return;
112
+ return {
113
+ output: result.output,
114
+ referenceNames: result.exportNames.map(referenceName)
78
115
  };
79
116
  }
80
117
  async function createUseCacheCallablePlugin(options) {
@@ -84,8 +121,39 @@ async function createUseCacheCallablePlugin(options) {
84
121
  const transforms = await import(pathToFileURL(transformsPath).href);
85
122
  const referenceSecret = randomBytes(32);
86
123
  let manager;
124
+ async function analyzeModule(manager, code, id) {
125
+ const ast = await parseProgramAsync(code);
126
+ const moduleDirective = findModuleUseCacheDirective(ast);
127
+ const useServerBoundary = transforms.hasDirective(ast.body, "use server");
128
+ if (moduleDirective && useServerBoundary) throw new Error(`A module cannot contain both ${JSON.stringify(moduleDirective)} and "use server" directives.`);
129
+ const reference = manager.serverReferences.resolve(id, "rsc");
130
+ const relativeImportId = manager.toRelativeId(reference.importId);
131
+ const secureExportName = (name) => `$$vinext_cache_${createHmac("sha256", referenceSecret).update(relativeImportId).update("\0").update(name).digest("hex")}`;
132
+ return {
133
+ ast,
134
+ moduleDirective,
135
+ useServerBoundary,
136
+ reference,
137
+ secureExportName
138
+ };
139
+ }
87
140
  return {
88
141
  name: PLUGIN_NAME,
142
+ api: { async transformWorkerModule(code, id, createReference) {
143
+ if (!code.includes("use cache")) return;
144
+ if (!manager) {
145
+ if (findModuleUseCacheDirective(await parseProgramAsync(code))) throw new Error("vinext: cannot compile a \"use cache\" module in a Web Worker without @vitejs/plugin-rsc.");
146
+ return;
147
+ }
148
+ const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, code, id);
149
+ if (useServerBoundary) return;
150
+ return transformBrowserModule(transforms, code, ast, id, moduleDirective, {
151
+ environmentName: "worker",
152
+ reference,
153
+ secureExportName,
154
+ createReference
155
+ })?.output;
156
+ } },
89
157
  configResolved(config) {
90
158
  const pluginApi = rscModule.getPluginApi(config);
91
159
  const hasRscPlugin = config.plugins.some((plugin) => plugin.name === "rsc");
@@ -109,48 +177,25 @@ async function createUseCacheCallablePlugin(options) {
109
177
  manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
110
178
  return;
111
179
  }
112
- const ast = await parseAstAsync(code);
113
- const moduleDirective = findModuleUseCacheDirective(ast);
114
- const useServerBoundary = transforms.hasDirective(ast.body, "use server");
115
- if (moduleDirective && useServerBoundary) throw new Error(`A module cannot contain both ${JSON.stringify(moduleDirective)} and "use server" directives.`);
116
- const reference = manager.serverReferences.resolve(id, "rsc");
117
- const relativeImportId = manager.toRelativeId(reference.importId);
118
- const secureExportName = (name) => `$$vinext_cache_${createHmac("sha256", referenceSecret).update(relativeImportId).update("\0").update(name).digest("hex")}`;
180
+ const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, code, id);
119
181
  if (!(this.environment.name === "rsc")) {
120
182
  if (useServerBoundary) {
121
183
  manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
122
184
  return;
123
185
  }
124
- if (!moduleDirective) {
125
- transforms.transformHoistInlineDirective(code, ast, {
126
- directive: USE_CACHE_DIRECTIVE_CANDIDATE,
127
- rejectNonAsyncFunction: true,
128
- runtime: (_value, _name, meta) => {
129
- matchUseCacheDirective(meta.directiveMatch[0]);
130
- throw new Error(`It is not allowed to define inline "use cache" annotated functions in Client Components. Export them from a separate file with a module-level "use cache" or "use server" directive, or pass them down through props from a Server Component. (${this.environment.name}: ${id})`);
131
- }
132
- });
133
- manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
134
- return;
135
- }
136
- const useServerExportNames = getFunctionDirectiveExportNames(transforms, ast, "use server");
137
- const result = transforms.transformDirectiveProxyExport(ast, {
138
- code,
139
- directive: moduleDirective,
140
- filter: (name, meta) => {
141
- if (!shouldTransformModuleExport(name, id, meta)) return false;
142
- validateModuleExport(transforms, meta);
143
- return true;
144
- },
145
- runtime: (name) => `$$ReactClient.createServerReference(${JSON.stringify(`${reference.referenceKey}#${useServerExportNames.has(name) ? name : secureExportName(name)}`)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
186
+ const result = transformBrowserModule(transforms, code, ast, id, moduleDirective, {
187
+ environmentName: this.environment.name,
188
+ reference,
189
+ secureExportName,
190
+ createReference: (referenceId, name) => `$$ReactClient.createServerReference(${JSON.stringify(referenceId)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
146
191
  });
147
- if (!result?.output.hasChanged()) {
192
+ if (!result) {
148
193
  manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
149
194
  return;
150
195
  }
151
196
  manager.serverReferences.replaceClaim(PLUGIN_NAME, id, {
152
197
  ...reference,
153
- exportNames: result.exportNames.map((name) => useServerExportNames.has(name) ? name : secureExportName(name))
198
+ exportNames: result.referenceNames
154
199
  });
155
200
  const runtimeEnvironment = this.environment.name === "client" ? "browser" : "ssr";
156
201
  result.output.prepend(`import * as $$ReactClient from "@vitejs/plugin-rsc/react/${runtimeEnvironment}";\n`);
@@ -190,7 +235,11 @@ async function createUseCacheCallablePlugin(options) {
190
235
  hoistRuntime: true,
191
236
  noExport: true,
192
237
  runtime: (value, name, meta) => runtime(value, name, matchUseCacheDirective(meta.directiveMatch[0]), meta),
193
- encode: (value) => `$$cacheRuntime.encryptCacheCaptures(${value})`,
238
+ encode: (value, name) => {
239
+ if (name === void 0) throw new Error("vinext: inline \"use cache\" functions require @vitejs/plugin-rsc 0.5.37 or newer.");
240
+ const referenceId = `${reference.referenceKey}#${secureExportName(name)}`;
241
+ return `$$cacheRuntime.encryptCacheCaptures(${JSON.stringify(referenceId)}, ${value})`;
242
+ },
194
243
  decode: (value) => value
195
244
  });
196
245
  if (!result.output.hasChanged()) {
@@ -217,4 +266,4 @@ async function createUseCacheCallablePlugin(options) {
217
266
  };
218
267
  }
219
268
  //#endregion
220
- export { createUseCacheCallablePlugin };
269
+ export { PLUGIN_NAME as USE_CACHE_PLUGIN_NAME, createUseCacheCallablePlugin };
@@ -1,10 +1,9 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
- import { staticStringValue, walkAst } from "./ast-utils.js";
2
+ import { parseModuleRecord, quotedStringAt } from "./ast-utils.js";
3
3
  import { magicStringTransformResult } from "./transform-result.js";
4
4
  import { appendDeploymentIdQuery } from "../utils/deployment-id.js";
5
5
  import { NODE_MODULES_PATH_RE, stripViteModuleQuery } from "../utils/path.js";
6
6
  import fs from "node:fs";
7
- import { parseAst } from "vite";
8
7
  import MagicString from "magic-string";
9
8
  //#region src/plugins/worker-image-imports.ts
10
9
  const WORKER_IMAGE_METADATA_PREFIX = "\0vinext-worker-image-meta:";
@@ -70,24 +69,19 @@ function createWorkerImageImportsPlugin(options = {}) {
70
69
  },
71
70
  async handler(code, id) {
72
71
  const sourceId = toSlash(stripViteModuleQuery(id));
73
- let ast;
74
- try {
75
- ast = parseAst(code, { lang: /\.(?:[cm]?ts)$/.test(sourceId) ? "ts" : "tsx" });
76
- } catch {
77
- return null;
78
- }
72
+ const record = parseModuleRecord(code, /\.(?:[cm]?ts)$/.test(sourceId) ? "ts" : "tsx");
73
+ if (!record) return null;
79
74
  const output = new MagicString(code);
80
75
  const imageImports = [];
81
- walkAst(ast, (node) => {
82
- if (node.type === "ImportExpression" && node.source.type === "Literal" && typeof node.source.value === "string" && WORKER_IMAGE_EXTENSION_RE.test(node.source.value)) {
83
- imageImports.push({
84
- end: node.end,
85
- importPath: node.source.value,
86
- start: node.start
87
- });
88
- return false;
89
- }
90
- });
76
+ for (const dynamicImport of record.dynamicImports) {
77
+ const importPath = quotedStringAt(code, dynamicImport.moduleRequest);
78
+ if (importPath === null || !WORKER_IMAGE_EXTENSION_RE.test(importPath)) continue;
79
+ imageImports.push({
80
+ end: dynamicImport.end,
81
+ importPath,
82
+ start: dynamicImport.start
83
+ });
84
+ }
91
85
  let changed = false;
92
86
  for (const imageImport of imageImports) {
93
87
  const resolved = await this.resolve(imageImport.importPath, sourceId, { skipSelf: true });
@@ -107,23 +101,26 @@ function createWorkerImageImportsPlugin(options = {}) {
107
101
  if (!options.deploymentId) return null;
108
102
  const chunkSpecifiers = new Set([...chunk.imports, ...chunk.dynamicImports].map((target) => workerChunkSpecifier(chunk.fileName, target)));
109
103
  if (chunkSpecifiers.size === 0) return null;
110
- let ast;
111
- try {
112
- ast = parseAst(code);
113
- } catch {
114
- return null;
115
- }
104
+ const record = parseModuleRecord(code, "js");
105
+ if (!record) return null;
106
+ const sources = [
107
+ ...record.staticImports.map((statement) => statement.moduleRequest),
108
+ ...record.staticExports.flatMap((statement) => statement.entries[0]?.moduleRequest ?? []),
109
+ ...record.dynamicImports.map((dynamicImport) => {
110
+ const value = quotedStringAt(code, dynamicImport.moduleRequest);
111
+ return value === null ? [] : {
112
+ ...dynamicImport.moduleRequest,
113
+ value
114
+ };
115
+ })
116
+ ].flat();
116
117
  const output = new MagicString(code);
117
118
  let changed = false;
118
- walkAst(ast, (node) => {
119
- const source = node.type === "ImportExpression" || node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration" ? node.source : null;
120
- const specifier = staticStringValue(source);
121
- if (specifier !== null && chunkSpecifiers.has(specifier) && source) {
122
- output.overwrite(source.start, source.end, JSON.stringify(appendDeploymentIdQuery(specifier, options.deploymentId)));
123
- changed = true;
124
- return false;
125
- }
126
- });
119
+ for (const source of sources) {
120
+ if (!chunkSpecifiers.has(source.value)) continue;
121
+ output.overwrite(source.start, source.end, JSON.stringify(appendDeploymentIdQuery(source.value, options.deploymentId)));
122
+ changed = true;
123
+ }
127
124
  if (!changed) return null;
128
125
  return magicStringTransformResult(output);
129
126
  }
@@ -0,0 +1,20 @@
1
+ import { Plugin } from "vite";
2
+ //#region src/plugins/worker-server-only-imports.d.ts
3
+ export declare const SERVER_ONLY_SPECIFIER_RE: RegExp;
4
+ /**
5
+ * Reject `server-only` imports inside browser Web Worker bundles.
6
+ *
7
+ * Vite bundles every worker in a fresh plugin container built from
8
+ * `worker.plugins`, so neither `vinext:validate-server-only-client-imports`
9
+ * nor @vitejs/plugin-rsc's `rsc:validate-imports` sees worker modules in
10
+ * production builds. Next.js compiles workers as part of the browser graph
11
+ * and fails the build for these imports with both webpack and Turbopack.
12
+ *
13
+ * Like `rsc:validate-imports`, this guards resolution rather than scanning
14
+ * source, so every specifier form (static, dynamic, re-export, require) is
15
+ * caught before vinext's no-op `server-only` alias applies. `"use server"`
16
+ * modules need no exemption: `vinext:worker-use-server` replaces them with
17
+ * Server Function references, so their imports are never resolved.
18
+ */
19
+ export declare function createWorkerServerOnlyImportsPlugin(): Plugin;
20
+ //#endregion
@@ -0,0 +1,31 @@
1
+ //#region src/plugins/worker-server-only-imports.ts
2
+ const SERVER_ONLY_SPECIFIER_RE = /^server-only$/;
3
+ /**
4
+ * Reject `server-only` imports inside browser Web Worker bundles.
5
+ *
6
+ * Vite bundles every worker in a fresh plugin container built from
7
+ * `worker.plugins`, so neither `vinext:validate-server-only-client-imports`
8
+ * nor @vitejs/plugin-rsc's `rsc:validate-imports` sees worker modules in
9
+ * production builds. Next.js compiles workers as part of the browser graph
10
+ * and fails the build for these imports with both webpack and Turbopack.
11
+ *
12
+ * Like `rsc:validate-imports`, this guards resolution rather than scanning
13
+ * source, so every specifier form (static, dynamic, re-export, require) is
14
+ * caught before vinext's no-op `server-only` alias applies. `"use server"`
15
+ * modules need no exemption: `vinext:worker-use-server` replaces them with
16
+ * Server Function references, so their imports are never resolved.
17
+ */
18
+ function createWorkerServerOnlyImportsPlugin() {
19
+ return {
20
+ name: "vinext:worker-validate-server-only-imports",
21
+ resolveId: {
22
+ order: "pre",
23
+ filter: { id: SERVER_ONLY_SPECIFIER_RE },
24
+ handler(_source, importer) {
25
+ throw new Error(`You're importing a module that depends on "server-only". This API is only available in Server Components in the App Router, but ${importer ?? "this module"} is reachable from a browser Web Worker bundle.`);
26
+ }
27
+ }
28
+ };
29
+ }
30
+ //#endregion
31
+ export { SERVER_ONLY_SPECIFIER_RE, createWorkerServerOnlyImportsPlugin };
@@ -0,0 +1,25 @@
1
+ import { Plugin } from "vite";
2
+ //#region src/plugins/worker-use-server.d.ts
3
+ type RscPluginModule = typeof import("@vitejs/plugin-rsc");
4
+ /**
5
+ * Replace `"use server"` modules in browser Web Worker bundles with Server
6
+ * Function reference proxies.
7
+ *
8
+ * Vite bundles every worker in a fresh plugin container built from
9
+ * `worker.plugins`, so @vitejs/plugin-rsc's `rsc:use-server` transform never
10
+ * sees worker modules in production builds and the module bodies would be
11
+ * emitted verbatim. Next.js compiles workers as part of the browser graph,
12
+ * where `"use server"` exports become `createServerReference(...)` proxies.
13
+ * This mirrors the client-environment branch of `rsc:use-server` with the
14
+ * same reference keys, without claiming references.
15
+ *
16
+ * The worker realm has no router to dispatch Server Function calls. Next.js's
17
+ * `callServer` dispatches inside `startTransition`, so the dispatch error is
18
+ * reported globally and the call's promise never settles; the worker
19
+ * references reproduce that instead of reaching the server.
20
+ */
21
+ export declare function createWorkerUseServerPlugins(options: {
22
+ rscPluginModule: Promise<RscPluginModule>;
23
+ rscPluginPath: string;
24
+ }): Promise<Plugin[]>;
25
+ //#endregion
@@ -0,0 +1,153 @@
1
+ import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { escapeRegExp } from "../utils/regex.js";
3
+ import { parseProgramAsync } from "./ast-utils.js";
4
+ import { magicStringTransformResult } from "./transform-result.js";
5
+ import { USE_CACHE_PLUGIN_NAME as PLUGIN_NAME } from "./use-cache-callable.js";
6
+ import { createRequire } from "node:module";
7
+ import fs from "node:fs";
8
+ import { pathToFileURL } from "node:url";
9
+ import { isCSSRequest, transformWithOxc } from "vite";
10
+ //#region src/plugins/worker-use-server.ts
11
+ const WORKER_REFERENCE_RUNTIME_ID = "\0vinext:worker-server-reference";
12
+ const WORKER_REFERENCE_RUNTIME_ID_RE = /^\0vinext:worker-server-reference$/;
13
+ function workerReferenceRuntime(browserRuntime) {
14
+ return `import { createServerReference } from ${JSON.stringify(browserRuntime)};
15
+
16
+ function callServer() {
17
+ return new Promise(() => {
18
+ reportError(new Error("Server Functions cannot be called from a browser Web Worker."));
19
+ });
20
+ }
21
+
22
+ export function createWorkerServerReference(id, name) {
23
+ return createServerReference(id, callServer, undefined, undefined, name);
24
+ }
25
+ `;
26
+ }
27
+ /** A module-local binding that cannot collide with any name in `code`. */
28
+ function uniqueBinding(code, base) {
29
+ let binding = base;
30
+ while (code.includes(binding)) binding += "_";
31
+ return binding;
32
+ }
33
+ function isPlainFilePath(id) {
34
+ return !/[\0?#]/.test(id) && fs.existsSync(id);
35
+ }
36
+ function withPositionedError(ctx, run) {
37
+ return Promise.resolve().then(run).catch((error) => {
38
+ if (error instanceof Error && "pos" in error && typeof error.pos === "number") ctx.error(error.message, error.pos);
39
+ throw error;
40
+ });
41
+ }
42
+ /**
43
+ * Replace `"use server"` modules in browser Web Worker bundles with Server
44
+ * Function reference proxies.
45
+ *
46
+ * Vite bundles every worker in a fresh plugin container built from
47
+ * `worker.plugins`, so @vitejs/plugin-rsc's `rsc:use-server` transform never
48
+ * sees worker modules in production builds and the module bodies would be
49
+ * emitted verbatim. Next.js compiles workers as part of the browser graph,
50
+ * where `"use server"` exports become `createServerReference(...)` proxies.
51
+ * This mirrors the client-environment branch of `rsc:use-server` with the
52
+ * same reference keys, without claiming references.
53
+ *
54
+ * The worker realm has no router to dispatch Server Function calls. Next.js's
55
+ * `callServer` dispatches inside `startTransition`, so the dispatch error is
56
+ * reported globally and the call's promise never settles; the worker
57
+ * references reproduce that instead of reaching the server.
58
+ */
59
+ async function createWorkerUseServerPlugins(options) {
60
+ const rscRequire = createRequire(options.rscPluginPath);
61
+ const importRscModule = (specifier) => import(pathToFileURL(rscRequire.resolve(specifier)).href);
62
+ const browserRuntime = pathToFileURL(rscRequire.resolve("@vitejs/plugin-rsc/react/browser")).href;
63
+ const [transforms, rscCore] = await Promise.all([importRscModule("@vitejs/plugin-rsc/transforms"), importRscModule("@vitejs/plugin-rsc/core/plugin")]);
64
+ let manager;
65
+ let useCacheApi;
66
+ const useServerPlugin = {
67
+ name: "vinext:worker-use-server",
68
+ async configResolved(config) {
69
+ // @vitejs/plugin-rsc's plugin API (and its reference manager) lives.
70
+ const mainConfig = config.mainConfig;
71
+ manager = (await options.rscPluginModule).getPluginApi(mainConfig ?? config)?.manager;
72
+ useCacheApi = (mainConfig ?? config).plugins.find((plugin) => plugin.name === PLUGIN_NAME)?.api;
73
+ },
74
+ resolveId: {
75
+ filter: { id: WORKER_REFERENCE_RUNTIME_ID_RE },
76
+ handler: (source) => source
77
+ },
78
+ load: {
79
+ filter: { id: WORKER_REFERENCE_RUNTIME_ID_RE },
80
+ handler: () => workerReferenceRuntime(browserRuntime)
81
+ },
82
+ transform: {
83
+ filter: { code: "use server" },
84
+ async handler(code, id) {
85
+ let ast = await parseProgramAsync(code);
86
+ if (!transforms.hasDirective(ast.body, "use server")) return null;
87
+ if (!manager) throw new Error("vinext: cannot compile a \"use server\" module in a Web Worker without @vitejs/plugin-rsc.");
88
+ const expanded = await withPositionedError(this, () => transforms.transformExpandExportAll({
89
+ code,
90
+ ast,
91
+ importer: id,
92
+ resolve: async (source, importer) => (await this.resolve(source, importer))?.id,
93
+ load: async (target) => {
94
+ if (!isPlainFilePath(target)) throw new Error(`vinext: a "use server" module imported by a Web Worker cannot \`export *\` from ${JSON.stringify(target)}; re-export its names explicitly.`);
95
+ this.addWatchFile(target);
96
+ const source = await fs.promises.readFile(target, "utf-8");
97
+ return parseProgramAsync((await transformWithOxc(source, target, { sourcemap: false })).code);
98
+ }
99
+ }));
100
+ if (expanded) {
101
+ code = expanded.code;
102
+ ast = await parseProgramAsync(code);
103
+ }
104
+ const { referenceKey } = manager.serverReferences.resolve(id, "rsc");
105
+ const runtime = uniqueBinding(code, "$$vinextWorkerReference");
106
+ const result = await withPositionedError(this, () => transforms.transformDirectiveProxyExport(ast, {
107
+ code,
108
+ directive: "use server",
109
+ rejectNonAsyncFunction: true,
110
+ runtime: (name) => `${runtime}(${JSON.stringify(`${referenceKey}#${name}`)}, ${JSON.stringify(name)})`
111
+ }));
112
+ if (!result?.output.hasChanged()) return null;
113
+ result.output.prepend(`import { createWorkerServerReference as ${runtime} } from ${JSON.stringify(WORKER_REFERENCE_RUNTIME_ID)};\n`);
114
+ return magicStringTransformResult(result.output);
115
+ }
116
+ }
117
+ };
118
+ const useCachePlugin = {
119
+ name: "vinext:worker-use-cache",
120
+ transform: {
121
+ filter: { code: "use cache" },
122
+ async handler(code, id) {
123
+ if (isCSSRequest(id)) return null;
124
+ const api = useCacheApi;
125
+ if (!api) throw new Error("vinext: cannot compile a \"use cache\" module in a Web Worker without vinext's \"use cache\" plugin.");
126
+ const runtime = uniqueBinding(code, "$$vinextWorkerReference");
127
+ const output = await withPositionedError(this, () => api.transformWorkerModule(code, id, (referenceId, name) => `${runtime}(${JSON.stringify(referenceId)}, ${JSON.stringify(name)})`));
128
+ if (!output) return null;
129
+ output.prepend(`import { createWorkerServerReference as ${runtime} } from ${JSON.stringify(WORKER_REFERENCE_RUNTIME_ID)};\n`);
130
+ return magicStringTransformResult(output);
131
+ }
132
+ }
133
+ };
134
+ const patchHook = rscCore.default().find((plugin) => plugin.name === "rsc:patch-react-server-dom-webpack")?.transform;
135
+ if (!patchHook || typeof patchHook !== "object") throw new Error("vinext: @vitejs/plugin-rsc no longer exposes its Flight client patch plugin.");
136
+ const flightClientDir = path.dirname(rscRequire.resolve("@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"));
137
+ return [
138
+ {
139
+ name: "vinext:worker-patch-react-server-dom",
140
+ transform: {
141
+ filter: {
142
+ id: new RegExp(`^${escapeRegExp(`${toSlash(flightClientDir)}/`)}`),
143
+ code: "__webpack_require__"
144
+ },
145
+ handler: patchHook.handler
146
+ }
147
+ },
148
+ useCachePlugin,
149
+ useServerPlugin
150
+ ];
151
+ }
152
+ //#endregion
153
+ export { createWorkerUseServerPlugins };
@@ -13,5 +13,6 @@ export declare function handleApiRoute(runner: ModuleImporter, req: IncomingMess
13
13
  trustedRevalidateOrigin?: string;
14
14
  allowedRevalidateHeaderKeys?: readonly string[];
15
15
  trailingSlash?: boolean;
16
+ skipTrailingSlashRedirect?: boolean;
16
17
  }): Promise<boolean>;
17
18
  //#endregion
@@ -1,13 +1,13 @@
1
1
  import { hasBasePath } from "../utils/base-path.js";
2
2
  import { matchRoute } from "../routing/pages-router.js";
3
3
  import "./server-globals.js";
4
+ import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
4
5
  import { NextRequest } from "../shims/server.js";
5
6
  import { importModule, reportRequestError } from "./instrumentation.js";
6
7
  import { mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
7
8
  import { tracePagesApiHandler } from "./pages-execution-tracing.js";
8
9
  import { DEFAULT_PAGES_API_BODY_SIZE_LIMIT, resolveBodyParserConfig } from "./pages-body-parser-config.js";
9
10
  import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
10
- import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
11
11
  import { performOnDemandRevalidate } from "./pages-revalidate.js";
12
12
  import { attachPagesPreviewApi, attachPagesRequestCookies } from "./pages-node-compat.js";
13
13
  import { finalizeEdgeApiResponse, isEdgeApiRuntime } from "./edge-api-runtime.js";
@@ -237,7 +237,8 @@ async function handleApiRoute(runner, req, res, url, apiRoutes, nextConfig) {
237
237
  const nextRequest = new NextRequest(createEdgeApiRequest(req, res, url, params, nextConfig), nextConfig ? { nextConfig: {
238
238
  basePath: nextConfig.basePath,
239
239
  i18n: nextConfig.i18n ?? void 0,
240
- trailingSlash: nextConfig.trailingSlash
240
+ trailingSlash: nextConfig.trailingSlash,
241
+ skipTrailingSlashRedirect: nextConfig.skipTrailingSlashRedirect
241
242
  } } : void 0);
242
243
  const handlerResponse = await tracePagesApiHandler(route.pattern, () => apiModule.default(nextRequest));
243
244
  if (!(handlerResponse instanceof Response)) throw new Error("Edge API route did not return a Response");
@@ -1,8 +1,8 @@
1
1
  import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
2
- import { patternToNextFormat } from "../routing/route-validation.js";
3
2
  import "./headers.js";
4
- import { RequestCookies, ResponseCookies } from "../shims/server.js";
5
3
  import { attachRequestCfMetadata, processMiddlewareHeaders, validateCsrfOrigin } from "./request-pipeline.js";
4
+ import { patternToNextFormat } from "../routing/route-validation.js";
5
+ import { RequestCookies, ResponseCookies } from "../shims/server.js";
6
6
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
7
7
  import { getSetCookieName } from "./cookie-utils.js";
8
8
  import "../shims/internal/cookies.js";
@@ -25,7 +25,7 @@ export declare function isServerActionResult<TRoot>(value: unknown): value is Ap
25
25
  export declare function shouldClearClientNavigationCachesForServerActionResult<TRoot>(result: AppBrowserServerActionResult<TRoot> | TRoot, revalidation?: ServerActionRevalidationKind): boolean;
26
26
  export declare function parseServerActionRevalidationHeader(headers: Pick<Headers, "get">): ServerActionRevalidationKind;
27
27
  export declare function resolveServerActionOperationLane(revalidation: ServerActionRevalidationKind): Extract<OperationLane, "refresh" | "server-action">;
28
- export declare function normalizeServerActionThrownValue(data: unknown, responseStatus: number): unknown;
28
+ export declare function normalizeServerActionThrownValue(data: unknown, responseStatus: number): Promise<unknown>;
29
29
  export declare function shouldSyncServerActionHttpFallbackHead<TRoot>(result: AppBrowserServerActionResult<TRoot> | TRoot): boolean;
30
30
  export declare function readInvalidServerActionResponseError(response: Pick<Response, "headers" | "status" | "text">, hasRedirectLocation: boolean): Promise<Error | null>;
31
31
  export type ServerActionResultResponseFactsInput = {
@@ -41,8 +41,15 @@ function createServerActionHttpFallbackError(status) {
41
41
  const error = /* @__PURE__ */ new Error(status === 404 ? "NEXT_NOT_FOUND" : `NEXT_HTTP_ERROR_FALLBACK;${status}`);
42
42
  return Object.assign(error, { digest });
43
43
  }
44
- function normalizeServerActionThrownValue(data, responseStatus) {
45
- return createServerActionHttpFallbackError(responseStatus) ?? data;
44
+ async function normalizeServerActionThrownValue(data, responseStatus) {
45
+ const fallbackError = createServerActionHttpFallbackError(responseStatus);
46
+ if (fallbackError) return fallbackError;
47
+ try {
48
+ await data;
49
+ } catch (error) {
50
+ return error;
51
+ }
52
+ return data;
46
53
  }
47
54
  function shouldSyncServerActionHttpFallbackHead(result) {
48
55
  if (!isServerActionResult(result) || result.root !== void 0) return false;
@@ -1,6 +1,6 @@
1
- import { splitPathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { addBasePathToPathname, stripBasePath } from "../utils/base-path.js";
3
2
  import { VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER } from "./headers.js";
3
+ import { splitPathnameForRouteMatch } from "../routing/utils.js";
4
4
  import { AppRouterContext } from "../shims/internal/app-router-context.js";
5
5
  import { matchRoutePattern } from "../routing/route-pattern.js";
6
6
  import { installWindowNext, setWindowNextInternalSourcePage } from "../client/window-next.js";
@@ -15,7 +15,7 @@ import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../s
15
15
  import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
16
16
  import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
17
17
  import { BfcacheIdentityMapContext, ElementsContext, Slot, bindAppElementsRenderedSearch, setAppElementsRenderedSearch } from "../shims/slot.js";
18
- import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
18
+ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, formatRscRequestPath, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
19
19
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
20
20
  import "../client/instrumentation-client.js";
21
21
  import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
@@ -1122,7 +1122,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1122
1122
  }
1123
1123
  });
1124
1124
  const rewrittenNavigationHref = navigationKind === "navigate" && HAS_CLIENT_REWRITES ? resolveLoadedHybridClientRewriteHref(currentHref, __basePath) : null;
1125
- const targetPathAndSearch = url.pathname + url.search;
1125
+ const targetPathAndSearch = formatRscRequestPath(url);
1126
1126
  const additionalPrefetchPathAndSearch = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [rewrittenNavigationHref] : [];
1127
1127
  const settledPrefetchedResponse = peekSettledPrefetchResponseForNavigation({
1128
1128
  additionalRscUrls: additionalPrefetchPathAndSearch,
@@ -1,5 +1,5 @@
1
- import { normalizePathnameForRouteMatch, splitPathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { stripBasePath } from "../utils/base-path.js";
2
+ import { normalizePathnameForRouteMatch, splitPathnameForRouteMatch } from "../routing/utils.js";
3
3
  import { normalizePath } from "./normalize-path.js";
4
4
  import { matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments } from "../routing/route-pattern.js";
5
5
  //#region src/server/app-browser-interception-context.ts
@@ -583,7 +583,7 @@ function createAppBrowserNavigationController(deps = {}) {
583
583
  } else notifyDiscardedServerActionRevalidation(lifecycleOptions);
584
584
  } else if (decision.disposition === "no-commit") notifyDiscardedServerActionRevalidation(lifecycleOptions);
585
585
  if (returnValue) {
586
- if (!returnValue.ok) throw returnValue.data;
586
+ if (!returnValue.ok) throw await returnValue.data;
587
587
  return returnValue.data;
588
588
  }
589
589
  }
@@ -1,4 +1,4 @@
1
- import { stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
1
+ import { formatRscRequestPath, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
2
2
  import { peekPrefetchResponseForNavigation } from "../shims/navigation.js";
3
3
  //#region src/server/app-browser-prefetch-response.ts
4
4
  function peekSettledPrefetchResponseForNavigation(options) {
@@ -25,7 +25,7 @@ function isSameOriginBrowserRscUrl(url, origin) {
25
25
  function canonicalizeBrowserRscResponseUrl(responseUrl, origin) {
26
26
  try {
27
27
  const parsed = new URL(responseUrl, origin);
28
- if (parsed.origin === new URL(origin).origin) return `${parsed.pathname}${parsed.search}`;
28
+ if (parsed.origin === new URL(origin).origin) return formatRscRequestPath(parsed);
29
29
  } catch {}
30
30
  return responseUrl;
31
31
  }
@@ -123,7 +123,7 @@ async function invokeClientServerAction(id, args, actionInitiation, deps) {
123
123
  return deps.commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result.root)), actionInitiation, returnValue, revalidation, renderedPathAndSearch);
124
124
  }
125
125
  if (result.returnValue) {
126
- if (!result.returnValue.ok) throw normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
126
+ if (!result.returnValue.ok) throw await normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
127
127
  return result.returnValue.data;
128
128
  }
129
129
  return;