vinext 1.0.1 → 1.1.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 (159) hide show
  1. package/README.md +72 -1
  2. package/dist/build/app-page-static-eligibility.d.ts +15 -0
  3. package/dist/build/app-page-static-eligibility.js +82 -0
  4. package/dist/build/prerender-paths.js +3 -78
  5. package/dist/build/prerender.js +33 -8
  6. package/dist/build/server-manifest.d.ts +7 -0
  7. package/dist/build/server-manifest.js +11 -1
  8. package/dist/cache/cache-adapters-virtual.d.ts +7 -1
  9. package/dist/cache/cache-adapters-virtual.js +3 -3
  10. package/dist/client/navigation-runtime.d.ts +11 -0
  11. package/dist/client/navigation-runtime.js +1 -1
  12. package/dist/config/config-matchers.js +3 -1
  13. package/dist/config/next-config.d.ts +7 -0
  14. package/dist/config/next-config.js +18 -3
  15. package/dist/entries/app-rsc-entry.d.ts +2 -0
  16. package/dist/entries/app-rsc-entry.js +64 -43
  17. package/dist/index.d.ts +4 -1
  18. package/dist/index.js +59 -30
  19. package/dist/plugins/cache-flight-codec.d.ts +19 -0
  20. package/dist/plugins/cache-flight-codec.js +68 -0
  21. package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
  22. package/dist/plugins/commonjs-esm-facade.js +80 -0
  23. package/dist/plugins/fonts.d.ts +8 -11
  24. package/dist/plugins/fonts.js +71 -34
  25. package/dist/routing/file-matcher.d.ts +1 -0
  26. package/dist/routing/file-matcher.js +1 -1
  27. package/dist/server/api-handler.js +17 -7
  28. package/dist/server/app-browser-entry.js +11 -7
  29. package/dist/server/app-browser-history-controller.d.ts +2 -0
  30. package/dist/server/app-browser-history-controller.js +8 -0
  31. package/dist/server/app-browser-interception-context.js +26 -2
  32. package/dist/server/app-browser-navigation-controller.d.ts +7 -1
  33. package/dist/server/app-browser-navigation-controller.js +93 -10
  34. package/dist/server/app-fallback-renderer.d.ts +2 -0
  35. package/dist/server/app-fallback-renderer.js +1 -0
  36. package/dist/server/app-history-state.d.ts +3 -0
  37. package/dist/server/app-history-state.js +7 -0
  38. package/dist/server/app-middleware.js +2 -1
  39. package/dist/server/app-optimistic-routing.js +1 -1
  40. package/dist/server/app-page-boundary-render.d.ts +5 -0
  41. package/dist/server/app-page-boundary-render.js +6 -4
  42. package/dist/server/app-page-cache-finalizer.d.ts +11 -0
  43. package/dist/server/app-page-cache-finalizer.js +41 -7
  44. package/dist/server/app-page-cache-render.d.ts +18 -0
  45. package/dist/server/app-page-cache-render.js +63 -43
  46. package/dist/server/app-page-cache.d.ts +5 -0
  47. package/dist/server/app-page-cache.js +27 -7
  48. package/dist/server/app-page-dispatch.d.ts +9 -1
  49. package/dist/server/app-page-dispatch.js +47 -30
  50. package/dist/server/app-page-element-builder.d.ts +7 -0
  51. package/dist/server/app-page-element-builder.js +27 -42
  52. package/dist/server/app-page-execution.d.ts +15 -12
  53. package/dist/server/app-page-execution.js +30 -40
  54. package/dist/server/app-page-head.d.ts +5 -0
  55. package/dist/server/app-page-head.js +9 -3
  56. package/dist/server/app-page-probe.d.ts +0 -109
  57. package/dist/server/app-page-probe.js +3 -136
  58. package/dist/server/app-page-render-identity.d.ts +0 -1
  59. package/dist/server/app-page-render-identity.js +1 -1
  60. package/dist/server/app-page-render-observation.js +2 -2
  61. package/dist/server/app-page-render.d.ts +13 -5
  62. package/dist/server/app-page-render.js +219 -119
  63. package/dist/server/app-page-request.d.ts +0 -1
  64. package/dist/server/app-page-request.js +1 -2
  65. package/dist/server/app-page-response.d.ts +4 -3
  66. package/dist/server/app-page-response.js +4 -3
  67. package/dist/server/app-page-route-wiring.d.ts +17 -5
  68. package/dist/server/app-page-route-wiring.js +55 -33
  69. package/dist/server/app-page-rsc-render-status.d.ts +48 -0
  70. package/dist/server/app-page-rsc-render-status.js +54 -0
  71. package/dist/server/app-page-stream.d.ts +15 -8
  72. package/dist/server/app-page-stream.js +6 -0
  73. package/dist/server/app-request-stage-dispatch.js +1 -1
  74. package/dist/server/app-request-stage-independent-entry.js +4 -4
  75. package/dist/server/app-response-header-provenance.d.ts +2 -0
  76. package/dist/server/app-response-header-provenance.js +10 -4
  77. package/dist/server/app-route-handler-dispatch.js +1 -1
  78. package/dist/server/app-router-entry.js +3 -3
  79. package/dist/server/app-rsc-handler.d.ts +4 -0
  80. package/dist/server/app-rsc-handler.js +212 -96
  81. package/dist/server/app-rsc-request-normalization.d.ts +3 -1
  82. package/dist/server/app-rsc-request-normalization.js +4 -2
  83. package/dist/server/app-rsc-response-stage.d.ts +1 -1
  84. package/dist/server/app-rsc-response-stage.js +6 -4
  85. package/dist/server/app-rsc-route-matching.d.ts +9 -1
  86. package/dist/server/app-rsc-route-matching.js +36 -19
  87. package/dist/server/app-server-action-execution.js +1 -1
  88. package/dist/server/app-ssr-entry.d.ts +3 -2
  89. package/dist/server/app-ssr-entry.js +6 -4
  90. package/dist/server/app-ssr-stream.d.ts +6 -1
  91. package/dist/server/app-ssr-stream.js +34 -15
  92. package/dist/server/app-worker-stages.d.ts +2 -2
  93. package/dist/server/app-worker-stages.js +3 -3
  94. package/dist/server/cacheability-request.js +9 -5
  95. package/dist/server/config-headers.js +2 -0
  96. package/dist/server/dev-server.js +12 -2
  97. package/dist/server/headers.d.ts +14 -0
  98. package/dist/server/headers.js +15 -1
  99. package/dist/server/image-optimization.d.ts +16 -0
  100. package/dist/server/image-optimization.js +26 -6
  101. package/dist/server/isr-cache.js +2 -2
  102. package/dist/server/middleware-matcher-pattern.js +8 -4
  103. package/dist/server/middleware-response-headers.js +2 -0
  104. package/dist/server/multi-stage.d.ts +8 -0
  105. package/dist/server/navigation-planner.js +1 -1
  106. package/dist/server/node-response-signal.d.ts +16 -0
  107. package/dist/server/node-response-signal.js +26 -0
  108. package/dist/server/open-redirect.d.ts +47 -0
  109. package/dist/server/open-redirect.js +74 -1
  110. package/dist/server/pages-page-handler.js +21 -4
  111. package/dist/server/pages-request-stage-entry.js +8 -4
  112. package/dist/server/prod-server.d.ts +8 -7
  113. package/dist/server/prod-server.js +153 -69
  114. package/dist/server/request-pipeline.d.ts +20 -8
  115. package/dist/server/request-pipeline.js +21 -7
  116. package/dist/server/response-compression.d.ts +43 -0
  117. package/dist/server/response-compression.js +111 -0
  118. package/dist/server/seed-cache.js +10 -7
  119. package/dist/server/socket-error-backstop.d.ts +14 -0
  120. package/dist/server/socket-error-backstop.js +27 -4
  121. package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
  122. package/dist/shims/cache-adapter-instantiate.js +118 -0
  123. package/dist/shims/cache-callable-runtime.d.ts +2 -40
  124. package/dist/shims/cache-callable-runtime.js +50 -168
  125. package/dist/shims/cache-flight-arguments.d.ts +22 -0
  126. package/dist/shims/cache-flight-arguments.js +56 -0
  127. package/dist/shims/cache-request-state.d.ts +15 -0
  128. package/dist/shims/cache-request-state.js +31 -8
  129. package/dist/shims/cache-runtime.d.ts +6 -19
  130. package/dist/shims/cache-runtime.js +165 -225
  131. package/dist/shims/cache.d.ts +2 -2
  132. package/dist/shims/cache.js +5 -4
  133. package/dist/shims/cacheability-classification.d.ts +7 -0
  134. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  135. package/dist/shims/error-boundary-navigation.js +19 -1
  136. package/dist/shims/error-boundary.d.ts +10 -10
  137. package/dist/shims/error-boundary.js +26 -7
  138. package/dist/shims/fetch-cache.d.ts +6 -0
  139. package/dist/shims/fetch-cache.js +19 -1
  140. package/dist/shims/form.js +1 -1
  141. package/dist/shims/headers.d.ts +13 -0
  142. package/dist/shims/headers.js +47 -4
  143. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
  144. package/dist/shims/internal/app-page-props-cache-key.js +24 -15
  145. package/dist/shims/internal/headers-state.d.ts +0 -1
  146. package/dist/shims/metadata.js +3 -3
  147. package/dist/shims/navigation-errors.d.ts +6 -0
  148. package/dist/shims/navigation-errors.js +11 -1
  149. package/dist/shims/navigation.d.ts +7 -0
  150. package/dist/shims/navigation.js +14 -4
  151. package/dist/shims/request-context.d.ts +9 -0
  152. package/dist/shims/thenable-params.d.ts +4 -0
  153. package/dist/shims/thenable-params.js +25 -3
  154. package/dist/shims/unified-request-context.js +1 -0
  155. package/dist/utils/mdx-scan.d.ts +5 -0
  156. package/dist/utils/mdx-scan.js +8 -1
  157. package/dist/utils/regex-safety.d.ts +10 -0
  158. package/dist/utils/regex-safety.js +70 -18
  159. package/package.json +3 -3
@@ -2,11 +2,12 @@ import { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index
2
2
  import { appRouteHasMainTreeLoadingBoundary } from "../routing/app-router.js";
3
3
  import { resolveEntryPath } from "./runtime-entry-module.js";
4
4
  import { isProxyFile } from "../server/middleware.js";
5
- import { extractExportConstString } from "../build/report.js";
5
+ import { extractExportConstString, getAppRouteRenderEntryPath } from "../build/report.js";
6
6
  import { routePatternParts } from "../routing/route-pattern.js";
7
7
  import { safeJsonStringify } from "../server/html.js";
8
8
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES } from "../server/image-optimization.js";
9
9
  import { buildAppRscManifestCode } from "./app-rsc-manifest.js";
10
+ import { classifyAppPageRouteStaticEligibility } from "../build/app-page-static-eligibility.js";
10
11
  import { generateDevOriginCheckCode } from "../server/dev-origin-check.js";
11
12
  import { ACTION_OWNER_MANIFEST_ID } from "../plugins/action-owner-manifest.js";
12
13
  import fs from "node:fs";
@@ -38,7 +39,6 @@ const appPageExecutionPath = resolveEntryPath("../server/app-page-execution.js",
38
39
  const appFallbackRendererPath = resolveEntryPath("../server/app-fallback-renderer.js", import.meta.url);
39
40
  const appElementsPath = resolveEntryPath("../server/app-elements.js", import.meta.url);
40
41
  const appPageRouteWiringPath = resolveEntryPath("../server/app-page-route-wiring.js", import.meta.url);
41
- const appPageProbePath = resolveEntryPath("../server/app-page-probe.js", import.meta.url);
42
42
  const appPageDispatchPath = resolveEntryPath("../server/app-page-dispatch.js", import.meta.url);
43
43
  const appPagePprRuntimePath = resolveEntryPath("../server/app-page-ppr-runtime.js", import.meta.url);
44
44
  const fileBasedMetadataPath = resolveEntryPath("../server/file-based-metadata.js", import.meta.url);
@@ -63,10 +63,10 @@ const appHookWarningSuppressionPath = resolveEntryPath("../server/app-hook-warni
63
63
  const serverGlobalsPath = resolveEntryPath("../server/server-globals.js", import.meta.url);
64
64
  const appPagesBridgePath = resolveEntryPath("../server/app-pages-bridge.js", import.meta.url);
65
65
  const routePatternPath = resolveEntryPath("../routing/route-pattern.js", import.meta.url);
66
- function buildAppRequestRouteMetadata(routes) {
66
+ function createSegmentSourceReader() {
67
67
  const sourceCache = /* @__PURE__ */ new Map();
68
- const forcesDynamic = (filePath) => {
69
- if (!filePath) return false;
68
+ return (filePath) => {
69
+ if (!filePath) return null;
70
70
  let source = sourceCache.get(filePath);
71
71
  if (source === void 0) {
72
72
  try {
@@ -76,19 +76,57 @@ function buildAppRequestRouteMetadata(routes) {
76
76
  }
77
77
  sourceCache.set(filePath, source);
78
78
  }
79
+ return source;
80
+ };
81
+ }
82
+ /** Segment config files of the tree a direct request to a page route renders. */
83
+ function appPageSegmentConfigPaths(route) {
84
+ return [
85
+ ...route.layouts,
86
+ route.pagePath,
87
+ ...route.parallelSlots.flatMap((slot) => [
88
+ slot.layoutPath,
89
+ ...slot.configLayoutPaths ?? [],
90
+ slot.pagePath ?? slot.defaultPath
91
+ ])
92
+ ];
93
+ }
94
+ /**
95
+ * Patterns of the static App pages that answer a request whose raw pathname
96
+ * reaches a dynamic sibling but whose segment-decoded pathname names them, so
97
+ * `/%61` and `/caf%C3%A9` render `/a` and `/café` rather than `/[slug]`.
98
+ *
99
+ * Next.js serves those requests from the response cached under the decoded
100
+ * pathname, which exists only for a page it prerendered. The prerender listing
101
+ * classifies those: a page whose effective segment config renders it
102
+ * dynamically (`dynamic = "force-dynamic"`, `revalidate = 0` or the edge
103
+ * runtime on any segment) and a Route Handler have no such entry, so the
104
+ * dynamic sibling renders. So does a page whose sources can't be read here;
105
+ * its sibling's render stays out of the shared caches. A cacheComponents
106
+ * build lists every page route, as the prerender listing does.
107
+ */
108
+ function buildAppDecodedPathnamePatterns(routes, config) {
109
+ const isPrerenderedPage = (route) => {
110
+ if (config?.cacheComponents) return true;
111
+ try {
112
+ return classifyAppPageRouteStaticEligibility(route, config?.readMdxEsm ?? null) === "eligible";
113
+ } catch {
114
+ return false;
115
+ }
116
+ };
117
+ return routes.filter((route) => !route.isDynamic && !route.routePath && getAppRouteRenderEntryPath(route) !== null && isPrerenderedPage(route)).map((route) => route.pattern);
118
+ }
119
+ function buildAppRequestRouteMetadata(routes) {
120
+ const readSource = createSegmentSourceReader();
121
+ const forcesDynamic = (filePath) => {
122
+ const source = readSource(filePath);
79
123
  return source !== null && extractExportConstString(source, "dynamic") === "force-dynamic";
80
124
  };
81
125
  return routes.map((route) => ({
82
126
  canUseCanonicalLoadingShell: appRouteHasMainTreeLoadingBoundary(route),
83
127
  forceDynamic: route.routePath ? forcesDynamic(route.routePath) : [
84
- ...route.layouts,
85
- route.pagePath,
86
- ...route.parallelSlots.flatMap((slot) => [
87
- slot.layoutPath,
88
- ...slot.configLayoutPaths ?? [],
89
- slot.pagePath ?? slot.defaultPath,
90
- ...slot.interceptingRoutes.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])
91
- ]),
128
+ ...appPageSegmentConfigPaths(route),
129
+ ...route.parallelSlots.flatMap((slot) => slot.interceptingRoutes.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])),
92
130
  ...route.siblingIntercepts.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])
93
131
  ].some(forcesDynamic),
94
132
  ids: route.ids ?? null,
@@ -201,11 +239,12 @@ export const __imageConfig = ${JSON.stringify({
201
239
  contentSecurityPolicy: config?.imageConfig?.contentSecurityPolicy
202
240
  })};
203
241
  const __routes = ${JSON.stringify(requestRoutes)};
204
- const __routeMatcher = __createAppRscRouteMatcher(__routes);
242
+ const __routeMatcher = __createAppRscRouteMatcher(__routes, ${JSON.stringify(buildAppDecodedPathnamePatterns(routes, config))});
205
243
  const __metadataRouteMatchers = ${JSON.stringify(metadataRouteMatchers)};
206
244
 
207
245
  function matchRoute(pathname) { return __routeMatcher.matchRoute(pathname); }
208
246
  function matchRequestRoute(pathname) { return __routeMatcher.matchRequestRoute(pathname); }
247
+ function matchRawRequestRoute(pathname) { return __routeMatcher.matchRawRequestRoute(pathname); }
209
248
  function hasInterceptionId(interceptionId) { return __routeMatcher.hasInterceptionId(interceptionId); }
210
249
  function __isMetadataPath(pathname) {
211
250
  const parts = pathname.split("/").filter(Boolean);
@@ -262,6 +301,7 @@ const __requestHandler = createAppRscRequestHandler({
262
301
  hasInterceptionId,
263
302
  matchRoute,
264
303
  matchRequestRoute,
304
+ matchRawRequestRoute,
265
305
  matchInterceptRoute(pathname, sourcePathname, interceptionId) {
266
306
  const intercept = __routeMatcher.findIntercept(pathname, sourcePathname, interceptionId);
267
307
  if (!intercept) return null;
@@ -513,7 +553,6 @@ import {
513
553
  resolveAppPageChildSegments as __resolveAppPageChildSegments,
514
554
  } from ${JSON.stringify(appPageRouteWiringPath)};
515
555
  import { buildPageElements as __buildPageElements } from ${JSON.stringify(appPageElementBuilderPath)};
516
- import { buildAppPageProbes as __buildAppPageProbes } from ${JSON.stringify(appPageProbePath)};
517
556
  import {
518
557
  dispatchAppPage as __dispatchAppPage,
519
558
  } from ${JSON.stringify(appPageDispatchPath)};
@@ -566,7 +605,7 @@ import { suppressHookWarningAls } from ${JSON.stringify(appHookWarningSuppressio
566
605
  import { clearAppRequestContext as __clearRequestContext, setAppNavigationContext as setNavigationContext } from ${JSON.stringify(appRequestContextPath)};
567
606
  __configureMemoryCacheHandler({ cacheMaxMemorySize: ${JSON.stringify(cacheMaxMemorySize)} });
568
607
  import { createAppPrerenderStaticParamsResolver as __createAppPrerenderStaticParamsResolver } from ${JSON.stringify(appPrerenderStaticParamsPath)};
569
- import { ensureAppRouteModulesLoaded as __ensureRouteLoaded, loadAppInterceptPage as __loadAppInterceptPage } from ${JSON.stringify(appRouteModuleLoaderPath)};
608
+ import { ensureAppRouteModulesLoaded as __ensureRouteLoaded } from ${JSON.stringify(appRouteModuleLoaderPath)};
570
609
  import {
571
610
  getRenderedConcreteUrlPathsForRoute as __getRenderedConcreteUrlPathsForRoute,
572
611
  initPregeneratedPathsFromGlobals as __initPregeneratedPathsFromGlobals,
@@ -744,7 +783,7 @@ function __VINEXT_CLASS_REASONS(routeIdx) {
744
783
  const routes = [
745
784
  ${routeEntries.join(",\n")}
746
785
  ];
747
- const __routeMatcher = __createAppRscRouteMatcher(routes);
786
+ const __routeMatcher = __createAppRscRouteMatcher(routes, ${JSON.stringify(buildAppDecodedPathnamePatterns(routes, config))});
748
787
 
749
788
  ${instrumentationPath ? "let metadataRoutes;" : `const metadataRoutes = [
750
789
  ${metaRouteEntries.join(",\n")}
@@ -841,6 +880,10 @@ function matchRequestRoute(url) {
841
880
  return __routeMatcher.matchRequestRoute(url);
842
881
  }
843
882
 
883
+ function matchRawRequestRoute(url) {
884
+ return __routeMatcher.matchRawRequestRoute(url);
885
+ }
886
+
844
887
  /**
845
888
  * Check if a pathname matches any intercepting route.
846
889
  * Returns the match info or null.
@@ -1000,6 +1043,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1000
1043
  scriptNonce,
1001
1044
  searchParams,
1002
1045
  renderMode,
1046
+ renderWholeDocument,
1003
1047
  }) {
1004
1048
  const PageComponent = route.page?.default;
1005
1049
  const __segmentConfigBranches = __resolveRouteSegmentConfigBranches(route);
@@ -1021,7 +1065,6 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1021
1065
  routePatternParts: route.patternParts,
1022
1066
  routeSegments: route.routeSegments,
1023
1067
  });
1024
- const _asyncRouteParams = makeThenableParams(params);
1025
1068
  return __dispatchAppPage({
1026
1069
  basePath: __basePath,
1027
1070
  bypassInterceptionContextCache,
@@ -1040,6 +1083,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1040
1083
  observePageSearchParamsAccess: buildOptions?.observePageSearchParamsAccess === true,
1041
1084
  isForceStatic: buildOptions?.isForceStatic === true,
1042
1085
  serveStreamingMetadata: buildOptions?.serveStreamingMetadata,
1086
+ placeStreamedMetadataInHead: buildOptions?.placeStreamedMetadataInHead === true,
1043
1087
  isProduction: process.env.NODE_ENV === "production",
1044
1088
  }, layoutParamAccess, displayPathname, scriptNonce);
1045
1089
  },
@@ -1127,31 +1171,6 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1127
1171
  route,
1128
1172
  });
1129
1173
  },
1130
- async probePage(probeSearchParams = searchParams) {
1131
- const __probeIntercept = findIntercept(
1132
- interceptionPathname,
1133
- interceptionContext,
1134
- interceptionId,
1135
- );
1136
- // The intercepting-route page module is lazy (page: null + __pageLoader).
1137
- // Resolve it before probing so buildAppPageProbes inspects the real page
1138
- // component for dynamic bailout — matching the render path, which also
1139
- // hydrates it (resolveAppPageInterceptState). Without this the intercept
1140
- // probe branch silently inspects an undefined component and never
1141
- // observes the page's searchParams/headers access. Shared loader, so
1142
- // the import is isolated from the request context here too.
1143
- if (__probeIntercept) await __loadAppInterceptPage(__probeIntercept);
1144
- return Promise.all(__buildAppPageProbes({
1145
- route,
1146
- pageComponent: PageComponent,
1147
- asyncRouteParams: _asyncRouteParams,
1148
- searchParams: probeSearchParams,
1149
- intercept: __probeIntercept,
1150
- isRscRequest,
1151
- matchedParams: params,
1152
- makeThenableParams,
1153
- }));
1154
- },
1155
1174
  renderErrorBoundaryPage(renderErr, errorOrigin) {
1156
1175
  const __activeIntercept = findIntercept(
1157
1176
  interceptionPathname,
@@ -1210,6 +1229,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1210
1229
  searchParams,
1211
1230
  setNavigationContext,
1212
1231
  renderMode,
1232
+ renderWholeDocument,
1213
1233
  });
1214
1234
  },
1215
1235
  async dispatchMatchedRouteHandler({
@@ -1564,6 +1584,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1564
1584
  },` : ""}
1565
1585
  matchRoute,
1566
1586
  matchRequestRoute,
1587
+ matchRawRequestRoute,
1567
1588
  hasInterceptionId,
1568
1589
  matchInterceptRoute(pathname, sourcePathname, interceptionId) {
1569
1590
  const intercept = findIntercept(pathname, sourcePathname, interceptionId);
package/dist/index.d.ts CHANGED
@@ -106,7 +106,10 @@ export type VinextOptions = {
106
106
  * Configure cache handlers declaratively, so you don't need a custom worker
107
107
  * entry that calls `setDataCacheHandler()` / `setCdnCacheAdapter()`. Each slot
108
108
  * is a `{ adapter, options }` descriptor pointing at an adapter module whose
109
- * default export is a factory; the plugin registers them automatically on the
109
+ * default export is a factory function or a class; either receives one
110
+ * `{ env, options }` argument (classes are invoked with `new`, other
111
+ * functions are called; see `CacheAdapterDescriptor.adapter` for how
112
+ * classes are recognised). The plugin registers them automatically on the
110
113
  * first request, passing the host `env` (Worker bindings) so adapters that
111
114
  * need a binding — e.g. a KV namespace — can read it.
112
115
  *
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import { matchesRewriteSource, proxyExternalRequest } from "./config/config-matc
14
14
  import { omitUnusedBuildSourcemap } from "./plugins/transform-result.js";
15
15
  import { assetPrefixPathname, isNextStaticPath, resolveAssetsDir } from "./utils/asset-prefix.js";
16
16
  import { RESOLVED_VIRTUAL_GOOGLE_FONTS, VIRTUAL_GOOGLE_FONTS, createGoogleFontsPlugin, createLocalFontsPlugin, generateGoogleFontsVirtualModule, parseStaticObjectLiteral } from "./plugins/fonts.js";
17
- import { VINEXT_NEXT_CONFIG_PLUGIN_PROPERTY, createRscCompatibilityId, findNextConfigPath, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "./config/next-config.js";
17
+ import { VINEXT_NEXT_CONFIG_PLUGIN_PROPERTY, createRscCompatibilityId, findNextConfigPath, lightningCssFeatureNamesToMask, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "./config/next-config.js";
18
18
  import { normalizePathnameForRouteMatchStrict } from "./routing/utils.js";
19
19
  import { hasBasePath, stripBasePath } from "./utils/base-path.js";
20
20
  import { appRouteGraph, appRouter, invalidateAppRouteCache, matchAppRoute } from "./routing/app-router.js";
@@ -25,7 +25,7 @@ import { INTERNAL_HEADERS, NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_INTERNAL_HEADERS,
25
25
  import { normalizePath as normalizePath$1 } from "./server/normalize-path.js";
26
26
  import { validateMiddlewareMatcherPatterns } from "./server/middleware-matcher-pattern.js";
27
27
  import { methodNotAllowedResponse, notFoundStaticAssetResponse } from "./server/http-error-responses.js";
28
- import { isOpenRedirectShaped } from "./server/open-redirect.js";
28
+ import { isOpenRedirectShaped, sendRepeatedSlashRedirect } from "./server/open-redirect.js";
29
29
  import { canonicalizeRequestUrlPathname, filterInternalHeaders, normalizeTrailingSlash } from "./server/request-pipeline.js";
30
30
  import { resolvePagesI18nRequest, stripI18nLocaleForApiRoute } from "./server/pages-i18n.js";
31
31
  import { findInstrumentationClientFile, findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
@@ -33,16 +33,17 @@ import { findMiddlewareFile, isProxyFile, runMiddleware } from "./server/middlew
33
33
  import { extractMiddlewareMatcherConfig, extractMiddlewareMatcherConfigValue, hasExportedName } from "./build/report.js";
34
34
  import { generatePagesRequestEntry, generatePagesResponseEntry, generateServerEntry } from "./entries/pages-server-entry.js";
35
35
  import { compileClientMiddlewareMatchers, generateClientEntry } from "./entries/pages-client-entry.js";
36
+ import { isPathInside, isPathInsideOrEqual, stripJsExtension, stripViteModuleQuery } from "./utils/path.js";
36
37
  import { logRequest, now } from "./server/request-log.js";
37
38
  import { encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath } from "./server/pages-data-route.js";
38
39
  import { getPagesPreviewModeId } from "./server/pages-preview.js";
39
40
  import { createSSRHandler } from "./server/dev-server.js";
41
+ import { signalFromNodeResponse } from "./server/node-response-signal.js";
40
42
  import { handleApiRoute } from "./server/api-handler.js";
41
43
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, resolveDevImageRedirect } from "./server/image-optimization.js";
42
44
  import { CACHEABILITY_MANIFEST_MODULE, CACHEABILITY_REQUEST_PROJECTION_MODULE } from "./server/cacheability-manifest.js";
43
45
  import { PREGENERATED_CONCRETE_PATHS_MODULE } from "./server/pregenerated-concrete-paths.js";
44
46
  import { installSocketErrorBackstop } from "./server/socket-error-backstop.js";
45
- import { isPathInside, isPathInsideOrEqual, stripJsExtension, stripViteModuleQuery } from "./utils/path.js";
46
47
  import { invalidateMetadataFileCache, scanMetadataFiles } from "./server/metadata-routes.js";
47
48
  import { shouldInvalidateAppRouteFile } from "./server/dev-route-files.js";
48
49
  import { createDirectRunner } from "./server/dev-module-runner.js";
@@ -94,6 +95,7 @@ import { createTransformCache } from "./plugins/transform-cache.js";
94
95
  import { createOgHarfbuzzPlugin } from "./plugins/og-harfbuzz.js";
95
96
  import { createOgAssetsPlugin, createOgInlineFetchAssetsPlugin } from "./plugins/og-assets.js";
96
97
  import { createUseCacheCallablePlugin } from "./plugins/use-cache-callable.js";
98
+ import { cacheFlightCodecPlugin } from "./plugins/cache-flight-codec.js";
97
99
  import { SSR_EXTERNAL_REACT_ENTRIES, VINEXT_OPTIMIZE_DEPS_EXCLUDE, mergeOptimizeDepsExclude } from "./plugins/rsc-client-shim-excludes.js";
98
100
  import { createServerExternalsManifestPlugin } from "./plugins/server-externals-manifest.js";
99
101
  import { createTransitiveExternalsPlugin } from "./plugins/transitive-externals.js";
@@ -110,12 +112,13 @@ import { removeConsoleCalls } from "./plugins/remove-console.js";
110
112
  import { createImportMetaUrlPlugin } from "./plugins/import-meta-url.js";
111
113
  import { createWorkerImageImportsPlugin } from "./plugins/worker-image-imports.js";
112
114
  import { createRequireContextPlugin } from "./plugins/require-context.js";
115
+ import { commonJsEsmFacadeOptimizeDepsPlugin, stripEsmCommonJsExportFacade } from "./plugins/commonjs-esm-facade.js";
113
116
  import { COMMONJS_SYNTAX_CODE_FILTER } from "./plugins/commonjs-syntax.js";
114
117
  import { createRequireConditionResolutionPlugin, isConditionalRequireScriptModuleId } from "./plugins/require-condition-resolution.js";
115
118
  import { createExtensionlessDynamicImportPlugin } from "./plugins/extensionless-dynamic-import.js";
116
119
  import { createWasmModuleImportPlugin } from "./plugins/wasm-module-import.js";
117
120
  import { consumerEnvironmentConditionFilter, getTypeofWindowReplacement, mayFoldChangeScannedImports, replaceConsumerEnvironmentConditions } from "./plugins/typeof-window.js";
118
- import { hasMdxFiles } from "./utils/mdx-scan.js";
121
+ import { hasMdxFiles, loadMdxEsmReader, pageExtensionsIncludeMdx } from "./utils/mdx-scan.js";
119
122
  import { publicFilePathVariants } from "./utils/public-file-path.js";
120
123
  import { scanPublicFileRoutes } from "./utils/public-routes.js";
121
124
  import { createIgnoreDynamicRequestsPlugin } from "./plugins/ignore-dynamic-requests.js";
@@ -1015,7 +1018,7 @@ function vinext(options = {}) {
1015
1018
  });
1016
1019
  const useServerIndex = plugins.findIndex((plugin) => plugin.name === "rsc:use-server");
1017
1020
  if (useServerIndex === -1) throw new Error("vinext: Failed to locate @vitejs/plugin-rsc use-server plugin.");
1018
- plugins.splice(useServerIndex, 0, useCachePlugin);
1021
+ plugins.splice(useServerIndex, 0, cacheFlightCodecPlugin(), useCachePlugin);
1019
1022
  return plugins.map(scopeRscPlugin);
1020
1023
  }).catch((cause) => {
1021
1024
  throw new Error("vinext: Failed to load @vitejs/plugin-rsc.", { cause });
@@ -1160,12 +1163,21 @@ function vinext(options = {}) {
1160
1163
  const previous = transformBundledCommonJsDependencies;
1161
1164
  transformProjectLocalCommonJs = projectLocal && isDev;
1162
1165
  transformBundledCommonJsDependencies = bundledDependency;
1166
+ let result;
1163
1167
  try {
1164
- return commonJsTransform.call(this, code, id, ...args);
1168
+ result = commonJsTransform.call(this, code, id, ...args);
1165
1169
  } finally {
1166
1170
  transformProjectLocalCommonJs = previousProjectLocal;
1167
1171
  transformBundledCommonJsDependencies = previous;
1168
1172
  }
1173
+ return Promise.resolve(result).then((transformed) => {
1174
+ if (typeof transformed !== "object" || typeof transformed?.code !== "string") return transformed;
1175
+ const stripped = stripEsmCommonJsExportFacade(transformed.code);
1176
+ return stripped === void 0 ? transformed : {
1177
+ ...transformed,
1178
+ code: stripped
1179
+ };
1180
+ });
1169
1181
  };
1170
1182
  commonJsPlugin.transform = {
1171
1183
  filter: { code: { include: COMMONJS_SYNTAX_CODE_FILTER } },
@@ -1643,7 +1655,8 @@ function vinext(options = {}) {
1643
1655
  transformer: "lightningcss",
1644
1656
  lightningcss: {
1645
1657
  ...nextConfig.lightningCssFeatures.include ? { include: nextConfig.lightningCssFeatures.include } : {},
1646
- ...nextConfig.lightningCssFeatures.exclude ? { exclude: nextConfig.lightningCssFeatures.exclude } : {}
1658
+ ...nextConfig.lightningCssFeatures.exclude ? { exclude: nextConfig.lightningCssFeatures.exclude } : {},
1659
+ ...(nextConfig.lightningCssFeatures.include & ~nextConfig.lightningCssFeatures.exclude & lightningCssFeatureNamesToMask(["custom-media-queries"])) !== 0 ? { drafts: { customMedia: true } } : {}
1647
1660
  }
1648
1661
  } : {},
1649
1662
  ...postcssOverride ? { postcss: postcssOverride } : {},
@@ -1693,7 +1706,7 @@ function vinext(options = {}) {
1693
1706
  ...depOptimizeNodeEnvOptions,
1694
1707
  rolldownOptions: {
1695
1708
  ...depOptimizeNodeEnvOptions.rolldownOptions,
1696
- plugins: [depOptimizeAliasPlugin]
1709
+ plugins: [depOptimizeAliasPlugin, commonJsEsmFacadeOptimizeDepsPlugin]
1697
1710
  }
1698
1711
  };
1699
1712
  pagesOptimizeEntries = !hasAppDir ? [...hasPagesDir ? [toRelativeFileEntry(root, pagesDir) + "/**/*.{tsx,ts,jsx,js}"] : [], ...[instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : [])] : [];
@@ -2199,6 +2212,7 @@ function vinext(options = {}) {
2199
2212
  inlineCss: nextConfig?.inlineCss,
2200
2213
  globalNotFound: nextConfig?.globalNotFound,
2201
2214
  cacheComponents: nextConfig?.cacheComponents,
2215
+ readMdxEsm: !nextConfig?.cacheComponents && pageExtensionsIncludeMdx(nextConfig?.pageExtensions ?? []) ? await loadMdxEsmReader(root) : null,
2202
2216
  prefetchInlining: nextConfig?.prefetchInlining,
2203
2217
  hasServerActions,
2204
2218
  actionOwners: this.environment.config.command === "build" ? void 0 : null,
@@ -2587,19 +2601,6 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
2587
2601
  delete req.headers[VINEXT_MW_CTX_HEADER];
2588
2602
  next();
2589
2603
  });
2590
- server.middlewares.use((req, _res, next) => {
2591
- try {
2592
- assertNoPublicNextRequestConflict({
2593
- root: server.config.root,
2594
- publicDir: server.config.publicDir === "" ? null : server.config.publicDir,
2595
- basePath: nextConfig.basePath ?? "",
2596
- requestUrl: req.url ?? "/"
2597
- });
2598
- next();
2599
- } catch (error) {
2600
- next(error);
2601
- }
2602
- });
2603
2604
  const pageExtensions = fileMatcher.extensionRegex;
2604
2605
  let pagesRunner = null;
2605
2606
  const getTrustedDevRevalidateOrigin = () => {
@@ -2896,6 +2897,22 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
2896
2897
  }
2897
2898
  next();
2898
2899
  });
2900
+ server.middlewares.use((req, res, next) => {
2901
+ if (!sendRepeatedSlashRedirect(req.url ?? "/", res)) next();
2902
+ });
2903
+ server.middlewares.use((req, _res, next) => {
2904
+ try {
2905
+ assertNoPublicNextRequestConflict({
2906
+ root: server.config.root,
2907
+ publicDir: server.config.publicDir === "" ? null : server.config.publicDir,
2908
+ basePath: nextConfig.basePath ?? "",
2909
+ requestUrl: req.url ?? "/"
2910
+ });
2911
+ next();
2912
+ } catch (error) {
2913
+ next(error);
2914
+ }
2915
+ });
2899
2916
  server.middlewares.use((req, res, next) => {
2900
2917
  if (!hasPagesDir || !handlePagesMiddleware || !isUnsupportedDevPublicRequest(req)) return next();
2901
2918
  handlePagesMiddleware(req, res, next).catch(next);
@@ -3181,7 +3198,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3181
3198
  const method = req.method ?? "GET";
3182
3199
  const webRequest = new Request(new URL(routeUrl, requestOrigin), {
3183
3200
  method,
3184
- headers: nodeRequestHeaders
3201
+ headers: nodeRequestHeaders,
3202
+ signal: signalFromNodeResponse(res)
3185
3203
  });
3186
3204
  const applyRequestHeadersToNodeRequest = (nextRequestHeaders) => {
3187
3205
  for (const key of Object.keys(req.headers)) delete req.headers[key];
@@ -3192,7 +3210,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3192
3210
  const mwOrigin = `${rawProto === "https" || rawProto === "http" ? rawProto : "http"}://${requestHost}`;
3193
3211
  const middlewareRequest = new Request(new URL(middlewareUrl, mwOrigin), {
3194
3212
  method: req.method,
3195
- headers: nodeRequestHeaders
3213
+ headers: nodeRequestHeaders,
3214
+ signal: webRequest.signal
3196
3215
  });
3197
3216
  const result = await runMiddleware(getPagesRunner(), capturedMiddlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath, nextConfig?.trailingSlash, opts.isDataRequest, pathname);
3198
3217
  if (hasAppDir && result.continue) {
@@ -3256,7 +3275,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3256
3275
  const hasBody = externalMethod !== "GET" && externalMethod !== "HEAD";
3257
3276
  const externalInit = {
3258
3277
  method: externalMethod,
3259
- headers: currentRequest.headers
3278
+ headers: currentRequest.headers,
3279
+ signal: currentRequest.signal
3260
3280
  };
3261
3281
  if (hasBody) {
3262
3282
  const { Readable } = await import("node:stream");
@@ -3774,6 +3794,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3774
3794
  }
3775
3795
  const manifest = {
3776
3796
  prerenderSecret,
3797
+ compress: nextConfig?.compress !== false,
3777
3798
  ...serverRuntimeOutputDirs.size === 0 ? {} : { runtimeOutputDirs: [...serverRuntimeOutputDirs].map((runtimeOutputDir) => path.relative(root, runtimeOutputDir) || ".").sort() }
3778
3799
  };
3779
3800
  const source = JSON.stringify(manifest);
@@ -4124,7 +4145,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
4124
4145
  if (rscPluginPromise) {
4125
4146
  plugins.push(createRscReferenceValidationNormalizerPlugin());
4126
4147
  plugins.push(createRscClientReferenceLoadersPlugin());
4127
- } else if (manualUseCachePluginPromise) plugins.push(manualUseCachePluginPromise);
4148
+ } else if (manualUseCachePluginPromise) plugins.push(cacheFlightCodecPlugin(), manualUseCachePluginPromise);
4128
4149
  plugins.push({
4129
4150
  name: "vinext:plain-pages-build-config",
4130
4151
  apply: "build",
@@ -4162,6 +4183,10 @@ function getNextPublicEnvDefines() {
4162
4183
  * Handles multi-value headers (Set-Cookie) correctly.
4163
4184
  */
4164
4185
  async function writeWebResponseToNodeRes(res, response) {
4186
+ if (res.destroyed) {
4187
+ response.body?.cancel().catch(() => {});
4188
+ return;
4189
+ }
4165
4190
  const nodeHeaders = {};
4166
4191
  response.headers.forEach((value, key) => {
4167
4192
  if (key === "set-cookie") return;
@@ -4174,13 +4199,17 @@ async function writeWebResponseToNodeRes(res, response) {
4174
4199
  if (response.statusText) res.writeHead(response.status, response.statusText, nodeHeaders);
4175
4200
  else res.writeHead(response.status, nodeHeaders);
4176
4201
  if (response.body) {
4177
- const { Readable } = await import("node:stream");
4202
+ const { Readable, pipeline } = await import("node:stream");
4178
4203
  const nodeStream = Readable.fromWeb(response.body);
4204
+ let clientDisconnected = false;
4205
+ res.once("close", () => {
4206
+ clientDisconnected = !res.writableFinished && !nodeStream.errored;
4207
+ });
4179
4208
  await new Promise((resolve, reject) => {
4180
- nodeStream.on("error", reject);
4181
- res.on("error", reject);
4182
- nodeStream.pipe(res);
4183
- nodeStream.on("end", resolve);
4209
+ pipeline(nodeStream, res, (error) => {
4210
+ if (error && !(clientDisconnected && error.code === "ERR_STREAM_PREMATURE_CLOSE")) reject(error);
4211
+ else resolve();
4212
+ });
4184
4213
  });
4185
4214
  } else res.end();
4186
4215
  }
@@ -0,0 +1,19 @@
1
+ import { MagicStringTransformResult } from "./transform-result.js";
2
+ import { Plugin } from "vite";
3
+ //#region src/plugins/cache-flight-codec.d.ts
4
+ /**
5
+ * Version of the Flight codec package that owns `id`. plugin-rsc resolves the
6
+ * app's own react-server-dom-webpack when installed and its vendored copy
7
+ * otherwise; reading the codec file's own package.json follows that choice.
8
+ */
9
+ export declare function readFlightCodecVersion(id: string): string;
10
+ /**
11
+ * Backport React 19.3's root-element temporary reference branch to older Flight
12
+ * codecs, so a "use cache" argument like `Promise<ReactElement>` encodes as a
13
+ * temporary reference instead of throwing. Remove it once React 19.3 is the
14
+ * minimum supported version.
15
+ * https://github.com/facebook/react/blob/v19.3.0/packages/react-client/src/ReactFlightReplyClient.js#L486
16
+ */
17
+ export declare function patchCacheFlightCodec(code: string, id: string, version?: string): MagicStringTransformResult | null;
18
+ export declare function cacheFlightCodecPlugin(): Plugin;
19
+ //#endregion
@@ -0,0 +1,68 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { magicStringTransformResult } from "./transform-result.js";
3
+ import fs from "node:fs";
4
+ import MagicString from "magic-string";
5
+ //#region src/plugins/cache-flight-codec.ts
6
+ const CLIENT_CODEC = /\/react-server-dom-(?:webpack|turbopack)-client\.edge\.(?:development|production)\.js$/;
7
+ const ELEMENT_CASE = /case REACT_ELEMENT_TYPE:[\s\S]*?throw Error\(\s*"React Element cannot be passed/;
8
+ /**
9
+ * Version of the Flight codec package that owns `id`. plugin-rsc resolves the
10
+ * app's own react-server-dom-webpack when installed and its vendored copy
11
+ * otherwise; reading the codec file's own package.json follows that choice.
12
+ */
13
+ function readFlightCodecVersion(id) {
14
+ for (let dir = path.dirname(id);; dir = path.dirname(dir)) {
15
+ const manifest = path.join(dir, "package.json");
16
+ if (fs.existsSync(manifest)) {
17
+ const pkg = JSON.parse(fs.readFileSync(manifest, "utf8"));
18
+ if (/^react-server-dom-(?:webpack|turbopack)$/.test(pkg.name ?? "") && pkg.version) return pkg.version;
19
+ }
20
+ if (path.dirname(dir) === dir) throw new Error(`vinext: cannot find the react-server-dom package version for ${id}`);
21
+ }
22
+ }
23
+ /** React 19.3 ships the branch; 0.0.0-* experimental builds track main. */
24
+ function needsElementTemporaryReferenceBackport(version) {
25
+ const match = /^(\d+)\.(\d+)\./.exec(version);
26
+ if (!match || version.startsWith("0.0.0-")) return false;
27
+ const [major, minor] = [Number(match[1]), Number(match[2])];
28
+ return major < 19 || major === 19 && minor < 3;
29
+ }
30
+ /**
31
+ * Backport React 19.3's root-element temporary reference branch to older Flight
32
+ * codecs, so a "use cache" argument like `Promise<ReactElement>` encodes as a
33
+ * temporary reference instead of throwing. Remove it once React 19.3 is the
34
+ * minimum supported version.
35
+ * https://github.com/facebook/react/blob/v19.3.0/packages/react-client/src/ReactFlightReplyClient.js#L486
36
+ */
37
+ function patchCacheFlightCodec(code, id, version = readFlightCodecVersion(id)) {
38
+ if (!needsElementTemporaryReferenceBackport(version)) return null;
39
+ const elementCase = ELEMENT_CASE.exec(code);
40
+ if (!elementCase) throw new Error(`vinext: react-server-dom-webpack ${version} (${id}) is not supported. Upgrade react, react-dom, and react-server-dom-webpack to 19.3 or later. If your app does not depend on react-server-dom-webpack directly, upgrade @vitejs/plugin-rsc to 0.5.35 or later instead.`);
41
+ const output = new MagicString(code);
42
+ output.appendLeft(elementCase.index + elementCase[0].lastIndexOf("throw Error("), "if (void 0 !== temporaryReferences && modelRoot === value) return (modelRoot = null), \"$T\";\n");
43
+ return magicStringTransformResult(output, {
44
+ hires: "boundary",
45
+ source: id
46
+ });
47
+ }
48
+ function cacheFlightCodecPlugin() {
49
+ const transform = {
50
+ filter: { id: CLIENT_CODEC },
51
+ handler: (code, id) => patchCacheFlightCodec(code, id)
52
+ };
53
+ return {
54
+ name: "vinext:cache-flight-codec",
55
+ enforce: "pre",
56
+ applyToEnvironment: (environment) => environment.name === "rsc",
57
+ configEnvironment(name) {
58
+ if (name !== "rsc") return;
59
+ return { optimizeDeps: { rolldownOptions: { plugins: [{
60
+ name: "vinext:cache-flight-codec-optimizer",
61
+ transform
62
+ }] } } };
63
+ },
64
+ transform
65
+ };
66
+ }
67
+ //#endregion
68
+ export { cacheFlightCodecPlugin, patchCacheFlightCodec, readFlightCodecVersion };
@@ -0,0 +1,35 @@
1
+ import { Plugin } from "vite";
2
+ //#region src/plugins/commonjs-esm-facade.d.ts
3
+ /**
4
+ * Removes the export facade vite-plugin-commonjs appended to `output` when the
5
+ * module it transformed is ESM. Returns `undefined` when there is nothing to
6
+ * remove.
7
+ *
8
+ * Next.js treats a module with ESM syntax as ESM: `require()` still works, but
9
+ * `module` / `exports` never become its exports. The plugin's analyzer is not
10
+ * scope-aware, so for bundled ESM that inlines CommonJS wrappers
11
+ * (`__commonJS((exports, module) => …)`) it exports the wrappers' assignments
12
+ * too, which duplicates the module's own exports. Its `require()` rewrite and
13
+ * its local `module` / `exports` polyfill stay, so free CommonJS assignments
14
+ * still run without becoming exports.
15
+ *
16
+ * Besides the facade, the plugin only prepends imports and its polyfill and
17
+ * rewrites `require()` calls, so the module's own top-level exports are still
18
+ * in `output`. Classifying the output rather than rereading the source keeps
19
+ * the decision tied to the exact code the plugin transformed.
20
+ *
21
+ * The facade is appended after the module's code (only dynamic-require
22
+ * runtimes, which have no source mappings, may follow it), so removing it
23
+ * leaves the plugin's source map valid.
24
+ */
25
+ export declare function stripEsmCommonJsExportFacade(output: string): string | undefined;
26
+ /**
27
+ * Applies {@link stripEsmCommonJsExportFacade} in the client dependency
28
+ * optimizer's Rolldown builds (scan and pre-bundle). vite-plugin-commonjs's
29
+ * pre-bundle plugin loads and converts files there without vinext's transform
30
+ * wrapper, so its output reaches this hook as the loaded code. That code is
31
+ * the optimizer's source, so the removal needs its own map for anything the
32
+ * plugin appended after the facade.
33
+ */
34
+ export declare const commonJsEsmFacadeOptimizeDepsPlugin: Plugin;
35
+ //#endregion