vinext 1.0.0-beta.0 → 1.0.0-beta.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 (202) hide show
  1. package/README.md +17 -1
  2. package/dist/build/assets-ignore.js +1 -1
  3. package/dist/build/clean-output.js +1 -1
  4. package/dist/build/client-build-config.js +6 -4
  5. package/dist/build/css-url-assets.js +3 -3
  6. package/dist/build/google-fonts/fallback-metrics.js +1 -1
  7. package/dist/build/google-fonts/font-metadata.js +1 -1
  8. package/dist/build/inject-pregenerated-paths.js +1 -1
  9. package/dist/build/inline-css.js +2 -5
  10. package/dist/build/module-dependency-cache.d.ts +4 -0
  11. package/dist/build/module-dependency-cache.js +13 -0
  12. package/dist/build/next-client-runtime-manifests.js +1 -1
  13. package/dist/build/pages-client-assets-module.js +1 -1
  14. package/dist/build/precompress.js +7 -7
  15. package/dist/build/prerender-paths.d.ts +2 -2
  16. package/dist/build/prerender-paths.js +10 -15
  17. package/dist/build/prerender-server-pool.js +2 -2
  18. package/dist/build/prerender.js +1 -1
  19. package/dist/build/preview-credentials.d.ts +11 -0
  20. package/dist/build/preview-credentials.js +19 -0
  21. package/dist/build/report.d.ts +0 -3
  22. package/dist/build/report.js +2 -4
  23. package/dist/build/run-prerender.d.ts +2 -11
  24. package/dist/build/run-prerender.js +2 -10
  25. package/dist/build/server-manifest.js +1 -1
  26. package/dist/build/ssr-manifest.d.ts +4 -0
  27. package/dist/build/ssr-manifest.js +10 -6
  28. package/dist/build/standalone.js +37 -37
  29. package/dist/cache/cache-adapters-virtual.d.ts +1 -17
  30. package/dist/cache/cache-adapters-virtual.js +20 -11
  31. package/dist/check.d.ts +0 -16
  32. package/dist/check.js +12 -34
  33. package/dist/cli.js +58 -53
  34. package/dist/client/instrumentation-client-inject.js +1 -1
  35. package/dist/client/pages-router-link-navigation.js +1 -1
  36. package/dist/config/config-matchers.js +2 -2
  37. package/dist/config/dotenv.js +1 -1
  38. package/dist/config/next-config.d.ts +4 -1
  39. package/dist/config/next-config.js +81 -14
  40. package/dist/config/prerender.d.ts +2 -2
  41. package/dist/config/prerender.js +7 -15
  42. package/dist/config/server-external-packages.js +1 -1
  43. package/dist/config/tsconfig-paths.js +2 -2
  44. package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
  45. package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
  46. package/dist/entries/app-rsc-entry.js +12 -5
  47. package/dist/entries/app-rsc-manifest.js +4 -4
  48. package/dist/entries/pages-client-entry.js +6 -5
  49. package/dist/entries/pages-server-entry.js +15 -26
  50. package/dist/entries/runtime-entry-module.js +2 -2
  51. package/dist/index.js +255 -195
  52. package/dist/init-cloudflare.js +1 -1
  53. package/dist/init-platform.js +1 -1
  54. package/dist/init.js +5 -5
  55. package/dist/plugins/ast-utils.js +1 -1
  56. package/dist/plugins/dynamic-preload-metadata.js +7 -7
  57. package/dist/plugins/extensionless-dynamic-import.js +1 -1
  58. package/dist/plugins/fonts.js +3 -3
  59. package/dist/plugins/ignore-dynamic-requests.js +13 -8
  60. package/dist/plugins/import-meta-url.js +16 -17
  61. package/dist/plugins/middleware-export-validation.js +1 -1
  62. package/dist/plugins/middleware-server-only.js +2 -2
  63. package/dist/plugins/og-asset-ownership.js +7 -6
  64. package/dist/plugins/og-assets.js +4 -5
  65. package/dist/plugins/optimize-imports.js +12 -13
  66. package/dist/plugins/postcss.js +1 -1
  67. package/dist/plugins/remove-console.js +1 -1
  68. package/dist/plugins/require-context.js +1 -1
  69. package/dist/plugins/sass.js +2 -2
  70. package/dist/plugins/server-externals-manifest.js +1 -1
  71. package/dist/plugins/strip-server-exports.js +1 -1
  72. package/dist/plugins/styled-jsx.js +3 -2
  73. package/dist/plugins/typeof-window.js +1 -1
  74. package/dist/routing/app-route-graph.d.ts +3 -10
  75. package/dist/routing/app-route-graph.js +28 -76
  76. package/dist/routing/app-router.d.ts +0 -5
  77. package/dist/routing/app-router.js +0 -5
  78. package/dist/routing/file-matcher.d.ts +2 -6
  79. package/dist/routing/file-matcher.js +10 -11
  80. package/dist/routing/pages-router.js +3 -3
  81. package/dist/server/api-handler.js +41 -33
  82. package/dist/server/app-browser-entry.js +17 -11
  83. package/dist/server/app-browser-navigation-controller.js +5 -3
  84. package/dist/server/app-browser-server-action-client.js +1 -1
  85. package/dist/server/app-browser-state.js +1 -1
  86. package/dist/server/app-browser-visible-commit.js +1 -1
  87. package/dist/server/app-elements-wire.d.ts +2 -1
  88. package/dist/server/app-fallback-renderer.d.ts +8 -0
  89. package/dist/server/app-fallback-renderer.js +13 -1
  90. package/dist/server/app-page-boundary-render.d.ts +14 -1
  91. package/dist/server/app-page-boundary-render.js +107 -54
  92. package/dist/server/app-page-dispatch.d.ts +1 -0
  93. package/dist/server/app-page-dispatch.js +26 -37
  94. package/dist/server/app-page-element-builder.d.ts +2 -1
  95. package/dist/server/app-page-element-builder.js +3 -3
  96. package/dist/server/app-page-execution.d.ts +3 -1
  97. package/dist/server/app-page-execution.js +31 -39
  98. package/dist/server/app-page-request.js +1 -1
  99. package/dist/server/app-page-route-wiring.js +1 -1
  100. package/dist/server/app-route-handler-execution.js +1 -1
  101. package/dist/server/app-route-tree-prefetch.js +1 -1
  102. package/dist/server/app-rsc-cache-busting.js +1 -1
  103. package/dist/server/app-rsc-handler.js +3 -3
  104. package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
  105. package/dist/server/app-rsc-redirect-flight.js +71 -0
  106. package/dist/server/app-segment-config.js +2 -2
  107. package/dist/server/app-server-action-execution.js +1 -1
  108. package/dist/server/app-ssr-entry.js +6 -3
  109. package/dist/server/app-ssr-stream.d.ts +2 -1
  110. package/dist/server/app-ssr-stream.js +4 -1
  111. package/dist/server/cache-proof.js +1 -1
  112. package/dist/server/default-global-error-module.d.ts +3 -1
  113. package/dist/server/default-not-found-module.d.ts +3 -1
  114. package/dist/server/dev-lockfile.js +2 -3
  115. package/dist/server/dev-route-files.js +1 -1
  116. package/dist/server/dev-server.js +253 -161
  117. package/dist/server/dev-stack-sourcemap.js +4 -3
  118. package/dist/server/headers.d.ts +3 -1
  119. package/dist/server/headers.js +3 -1
  120. package/dist/server/image-optimization.js +2 -2
  121. package/dist/server/implicit-tags.js +2 -1
  122. package/dist/server/instrumentation.js +2 -2
  123. package/dist/server/isr-cache.js +1 -1
  124. package/dist/server/metadata-routes.js +4 -4
  125. package/dist/server/middleware-response-headers.js +1 -1
  126. package/dist/server/middleware-runtime.js +1 -1
  127. package/dist/server/middleware.d.ts +1 -0
  128. package/dist/server/middleware.js +1 -1
  129. package/dist/server/navigation-planner.d.ts +2 -0
  130. package/dist/server/navigation-planner.js +8 -2
  131. package/dist/server/next-error-digest.d.ts +9 -24
  132. package/dist/server/next-error-digest.js +23 -15
  133. package/dist/server/operation-token.js +1 -1
  134. package/dist/server/pages-body-parser-config.js +2 -1
  135. package/dist/server/pages-dev-hydration.d.ts +14 -0
  136. package/dist/server/pages-dev-hydration.js +83 -0
  137. package/dist/server/pages-dev-module-url.js +2 -2
  138. package/dist/server/pages-node-compat.d.ts +13 -6
  139. package/dist/server/pages-node-compat.js +44 -45
  140. package/dist/server/pages-page-data.d.ts +1 -1
  141. package/dist/server/pages-page-data.js +4 -3
  142. package/dist/server/pages-page-handler.js +61 -29
  143. package/dist/server/pages-page-response.d.ts +2 -2
  144. package/dist/server/pages-preview.d.ts +26 -0
  145. package/dist/server/pages-preview.js +165 -0
  146. package/dist/server/pages-readiness.d.ts +2 -1
  147. package/dist/server/pages-readiness.js +4 -2
  148. package/dist/server/prod-server.js +9 -8
  149. package/dist/server/request-pipeline.js +1 -1
  150. package/dist/server/seed-cache.js +1 -1
  151. package/dist/server/socket-error-backstop.js +1 -1
  152. package/dist/server/static-file-cache.js +7 -8
  153. package/dist/server/worker-utils.js +1 -1
  154. package/dist/shims/cache.js +2 -1
  155. package/dist/shims/constants.js +1 -1
  156. package/dist/shims/error-boundary.d.ts +4 -4
  157. package/dist/shims/error.d.ts +21 -5
  158. package/dist/shims/error.js +52 -14
  159. package/dist/shims/fetch-cache.js +1 -1
  160. package/dist/shims/font-utils.js +1 -1
  161. package/dist/shims/form.d.ts +1 -1
  162. package/dist/shims/head.js +3 -3
  163. package/dist/shims/headers.js +6 -4
  164. package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
  165. package/dist/shims/layout-segment-context.d.ts +1 -1
  166. package/dist/shims/link.d.ts +3 -1
  167. package/dist/shims/link.js +6 -3
  168. package/dist/shims/navigation-errors.d.ts +2 -1
  169. package/dist/shims/navigation-errors.js +9 -13
  170. package/dist/shims/navigation.d.ts +1 -1
  171. package/dist/shims/navigation.js +5 -5
  172. package/dist/shims/navigation.react-server.js +1 -1
  173. package/dist/shims/router-state.d.ts +1 -0
  174. package/dist/shims/router.d.ts +2 -1
  175. package/dist/shims/router.js +18 -11
  176. package/dist/shims/script.js +1 -1
  177. package/dist/shims/server.js +2 -2
  178. package/dist/shims/slot.d.ts +1 -1
  179. package/dist/shims/thenable-params.js +1 -1
  180. package/dist/typegen.js +9 -11
  181. package/dist/utils/client-build-manifest.js +2 -2
  182. package/dist/utils/client-entry-manifest.js +1 -1
  183. package/dist/utils/client-runtime-metadata.js +1 -1
  184. package/dist/utils/commonjs-loader.js +3 -3
  185. package/dist/utils/mdx-scan.js +1 -1
  186. package/dist/utils/path.d.ts +1 -13
  187. package/dist/utils/path.js +1 -15
  188. package/dist/utils/plugin-options.d.ts +4 -0
  189. package/dist/utils/plugin-options.js +8 -0
  190. package/dist/utils/project.d.ts +0 -6
  191. package/dist/utils/project.js +2 -8
  192. package/dist/utils/public-routes.js +2 -2
  193. package/dist/utils/react-version.js +1 -1
  194. package/dist/utils/redirect-digest.d.ts +9 -0
  195. package/dist/utils/redirect-digest.js +25 -0
  196. package/dist/utils/vinext-root.js +1 -1
  197. package/dist/utils/vite-version.d.ts +5 -2
  198. package/dist/utils/vite-version.js +43 -17
  199. package/package.json +4 -3
  200. /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
  201. /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
  202. /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
@@ -1,5 +1,4 @@
1
- import { addBasePathToPathname } from "../utils/base-path.js";
2
- import { VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
1
+ import { VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER } from "./headers.js";
3
2
  import { runWithConnectionProbe } from "../shims/headers.js";
4
3
  import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, createRscRedirectLocation } from "./app-rsc-cache-busting.js";
5
4
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
@@ -7,28 +6,9 @@ import { applyEdgeRuntimeHeader } from "./app-page-response.js";
7
6
  import { parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
8
7
  import { renderSsrErrorMetaTags } from "./app-ssr-error-meta.js";
9
8
  import { isPromiseLike } from "../utils/promise.js";
9
+ import { formatNextRedirectDigest } from "./app-rsc-redirect-flight.js";
10
10
  //#region src/server/app-page-execution.ts
11
11
  /**
12
- * Builds the canonical `NEXT_REDIRECT;<type>;<url>;<status>;` digest that
13
- * Next.js encodes on `redirect()` / `permanentRedirect()` throws. Used when
14
- * we synthesize a flight payload for an RSC navigation: the digest must
15
- * round-trip through the client's `RedirectErrorBoundary` so the same
16
- * `getURLFromRedirectError` / `getRedirectTypeFromError` helpers decode it.
17
- *
18
- * The URL is included verbatim, not encoded — Next.js's `getRedirectError`
19
- * sets `digest = ${CODE};${type};${url};${status};` with the raw URL, and the
20
- * client decodes via `error.digest.split(';').slice(2, -2).join(';')`. We
21
- * default `type=replace` because `redirect()` is replace-style outside of
22
- * server actions, matching Next.js's `getRedirectError` default.
23
- *
24
- * Reference:
25
- * `.nextjs-ref/packages/next/src/client/components/redirect.ts:20-23`
26
- * `.nextjs-ref/packages/next/src/client/components/redirect-error.ts`
27
- */
28
- function formatNextRedirectDigest(options) {
29
- return `NEXT_REDIRECT;replace;${options.url};${options.statusCode};`;
30
- }
31
- /**
32
12
  * Marker we tag onto a thrown redirect/notFound error when it originates from
33
13
  * `generateMetadata()` (vs. a server component itself). Metadata resolution is
34
14
  * suspended/streamed in Next.js, so a redirect from metadata is not emitted as
@@ -73,12 +53,13 @@ function mergeAppPageSpecialErrorHeaders(response, middlewareContext) {
73
53
  function resolveAppPageSpecialError(error) {
74
54
  if (!(error && typeof error === "object" && "digest" in error)) return null;
75
55
  const digest = String(error.digest);
76
- const fromMetadata = error[APP_PAGE_METADATA_ERROR_MARKER] === true;
56
+ const fromMetadata = Reflect.get(error, APP_PAGE_METADATA_ERROR_MARKER) === true;
77
57
  const redirect = parseNextRedirectDigest(digest);
78
58
  if (redirect) return {
79
59
  kind: "redirect",
80
60
  location: redirect.url,
81
61
  statusCode: redirect.status,
62
+ type: redirect.type === "push" ? "push" : "replace",
82
63
  ...fromMetadata ? { fromMetadata: true } : {}
83
64
  };
84
65
  const httpError = parseNextHttpErrorDigest(digest);
@@ -97,17 +78,15 @@ function resolveAppPageSpecialError(error) {
97
78
  * in `app-render.tsx`: a `redirect("/about")` call from a page mounted at
98
79
  * `/blog` (basePath) produces `Location: /blog/about`.
99
80
  *
100
- * Skips prefixing when:
101
- * - basePath is unset / empty
102
- * - the target is a full URL pointing at a different origin (external redirect)
103
- * - the target already starts with the basePath (caller did the work themselves)
81
+ * Skips prefixing only when basePath is unset or the raw target does not start
82
+ * with `/`, matching Next.js's literal `addPathPrefix()` contract.
104
83
  */
105
- function applyAppPageRedirectBasePath(location, requestUrl, basePath) {
106
- const resolved = new URL(location, requestUrl);
107
- const requestOrigin = new URL(requestUrl).origin;
108
- if (!basePath || resolved.origin !== requestOrigin) return resolved.toString();
109
- resolved.pathname = addBasePathToPathname(resolved.pathname, basePath);
110
- return resolved.toString();
84
+ function applyAppPageRedirectBasePath(location, basePath) {
85
+ if (!basePath || !location.startsWith("/")) return location;
86
+ const queryIndex = location.indexOf("?");
87
+ const hashIndex = location.indexOf("#");
88
+ const suffixIndex = queryIndex === -1 ? hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
89
+ return `${basePath}${suffixIndex === -1 ? location : location.slice(0, suffixIndex)}${suffixIndex === -1 ? "" : location.slice(suffixIndex)}`;
111
90
  }
112
91
  /**
113
92
  * Returns a path-relative form (`/foo?bar`) of an absolute URL when it shares
@@ -141,9 +120,10 @@ function buildMetadataRedirectHtmlResponse(options) {
141
120
  async function buildAppPageSpecialErrorResponse(options) {
142
121
  if (options.specialError.kind === "redirect") {
143
122
  options.clearRequestContext();
144
- const prefixedLocation = applyAppPageRedirectBasePath(options.specialError.location, options.request.url, options.basePath);
123
+ const prefixedLocation = applyAppPageRedirectBasePath(options.specialError.location, options.basePath);
145
124
  const digestUrl = sameOriginPathOrAbsolute(prefixedLocation, options.request.url);
146
125
  const digest = formatNextRedirectDigest({
126
+ type: options.specialError.type ?? "replace",
147
127
  url: digestUrl,
148
128
  statusCode: options.specialError.statusCode
149
129
  });
@@ -155,14 +135,13 @@ async function buildAppPageSpecialErrorResponse(options) {
155
135
  });
156
136
  if (Boolean(options.buildRscRedirectFlightStream) && options.isRscRequest && options.buildRscRedirectFlightStream) {
157
137
  const stream = options.buildRscRedirectFlightStream({ digest });
158
- const headers = new Headers({
159
- "Content-Type": VINEXT_RSC_CONTENT_TYPE,
160
- [VINEXT_RSC_REDIRECT_HEADER]: digestUrl
161
- });
138
+ const headers = new Headers({ "Content-Type": VINEXT_RSC_CONTENT_TYPE });
162
139
  applyEdgeRuntimeHeader(headers, options.isEdgeRuntime);
163
140
  applyRscCompatibilityIdHeader(headers);
164
141
  applyRscDeploymentIdHeader(headers);
165
142
  mergeMiddlewareResponseHeaders(headers, options.middlewareContext?.headers ?? null);
143
+ headers.set(VINEXT_RSC_REDIRECT_HEADER, digestUrl);
144
+ headers.set(VINEXT_RSC_REDIRECT_TYPE_HEADER, options.specialError.type ?? "replace");
166
145
  const pendingCookies = options.getAndClearPendingCookies?.() ?? [];
167
146
  for (const cookie of pendingCookies) headers.append("Set-Cookie", cookie);
168
147
  return new Response(stream, {
@@ -313,6 +292,19 @@ async function readAppPageBinaryStream(stream) {
313
292
  }
314
293
  return buffer.buffer;
315
294
  }
295
+ async function bufferAppPageBinaryStream(stream) {
296
+ const reader = stream.getReader();
297
+ const chunks = [];
298
+ for (;;) {
299
+ const { done, value } = await reader.read();
300
+ if (done) break;
301
+ chunks.push(value);
302
+ }
303
+ return new ReadableStream({ start(controller) {
304
+ for (const chunk of chunks) controller.enqueue(chunk);
305
+ controller.close();
306
+ } });
307
+ }
316
308
  function teeAppPageRscStreamForCapture(stream, shouldCapture) {
317
309
  if (!shouldCapture) return { ssrStream: stream };
318
310
  const [ssrStream, sideStream] = stream.tee();
@@ -326,4 +318,4 @@ function buildAppPageFontLinkHeader(preloads) {
326
318
  return preloads.map((preload) => `<${preload.href}>; rel=preload; as=font; type=${preload.type}; crossorigin`).join(", ");
327
319
  }
328
320
  //#endregion
329
- export { buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, probeAppPageThrownError, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
321
+ export { bufferAppPageBinaryStream, buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, probeAppPageThrownError, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
@@ -57,7 +57,7 @@ function getParallelParentParamNames(routeParamNames, branch, boundaryPosition)
57
57
  return name ? [name] : [];
58
58
  }));
59
59
  const ownerParamNames = slotParamNames.filter((name) => !branchParamNameSet.has(name));
60
- return [...new Set([...ownerParamNames, ...branchParamNames])];
60
+ return [.../* @__PURE__ */ new Set([...ownerParamNames, ...branchParamNames])];
61
61
  }
62
62
  function resolveAppPageGenerateStaticParamsSources(options) {
63
63
  const sources = [];
@@ -213,7 +213,7 @@ function buildAppPageElements(options) {
213
213
  const slotName = slot.name;
214
214
  slotNameCounts.set(slotName, (slotNameCounts.get(slotName) ?? 0) + 1);
215
215
  }
216
- const orderedTreePositions = Array.from(new Set([
216
+ const orderedTreePositions = Array.from(/* @__PURE__ */ new Set([
217
217
  ...layoutEntries.map((entry) => entry.treePosition),
218
218
  ...templateEntries.map((entry) => entry.treePosition),
219
219
  ...errorEntries.map((entry) => entry.treePosition)
@@ -1,6 +1,6 @@
1
1
  import { isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
2
- import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
3
2
  import { runWithRootParamsUsage } from "../shims/root-params.js";
3
+ import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
4
4
  import { applyRouteHandlerMiddlewareContext, applyRouteHandlerRevalidateHeader, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, finalizeRouteHandlerResponse, markRouteHandlerCacheMiss } from "./app-route-handler-response.js";
5
5
  import { createTrackedAppRouteRequest, markKnownDynamicAppRoute } from "./app-route-handler-runtime.js";
6
6
  import { createStaticGenerationHeadersContext, getAppRouteStaticGenerationErrorMessage } from "./app-static-generation.js";
@@ -86,7 +86,7 @@ function modulesByTreePosition(modules, positions) {
86
86
  async function buildTree(route) {
87
87
  const layoutsByPosition = layoutModuleByTreePosition(route);
88
88
  const root = createNode("", layoutsByPosition.get(0));
89
- const nodesByPosition = new Map([[0, root]]);
89
+ const nodesByPosition = /* @__PURE__ */ new Map([[0, root]]);
90
90
  let current = root;
91
91
  for (const [index, segment] of route.routeSegments.entries()) {
92
92
  const position = index + 1;
@@ -189,7 +189,7 @@ async function resolveInvalidRscCacheBustingRequest(options) {
189
189
  const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);
190
190
  const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);
191
191
  if (actualHash === null && expectedHash === "" && url.pathname.endsWith(".rsc")) return null;
192
- const acceptedHashes = new Set([expectedHash]);
192
+ const acceptedHashes = /* @__PURE__ */ new Set([expectedHash]);
193
193
  if (actualHash !== null && actualHash !== expectedHash) {
194
194
  acceptedHashes.add(computeLegacyRscCacheBustingSearchParam(options.request.headers));
195
195
  if (normalizeRenderModeHeaderValue(options.request.headers.get("X-Vinext-Rsc-Render-Mode")) === null) {
@@ -19,17 +19,17 @@ import "./app-page-response.js";
19
19
  import { parseNextHttpErrorDigest } from "./next-error-digest.js";
20
20
  import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
21
21
  import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
22
+ import { flattenErrorCauses } from "../utils/error-cause.js";
23
+ import { pickRootParams, setRootParams } from "../shims/root-params.js";
22
24
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
23
25
  import { buildPageCacheTags } from "./implicit-tags.js";
24
26
  import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
25
- import { pickRootParams, setRootParams } from "../shims/root-params.js";
26
27
  import { createRouteTreePrefetchResponse, isRouteTreePrefetchRequest } from "./app-route-tree-prefetch.js";
27
- import { flattenErrorCauses } from "../utils/error-cause.js";
28
28
  import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
29
29
  import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
30
30
  import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
31
31
  //#region src/server/app-rsc-handler.ts
32
- const STATIC_METADATA_CONFIG_HEADER_OVERRIDES = new Set(["cache-control"]);
32
+ const STATIC_METADATA_CONFIG_HEADER_OVERRIDES = /* @__PURE__ */ new Set(["cache-control"]);
33
33
  function applyMiddlewareContextToResponse(response, middlewareContext) {
34
34
  if (!middlewareContext.headers && middlewareContext.status == null) return response;
35
35
  const headers = new Headers(response.headers);
@@ -0,0 +1,66 @@
1
+ import { ReactNode } from "react";
2
+
3
+ //#region src/server/app-rsc-redirect-flight.d.ts
4
+ /**
5
+ * Encoding of a `redirect()` for RSC transport: the canonical
6
+ * `NEXT_REDIRECT;<type>;<url>;<status>;` digest and the flight payload that
7
+ * carries it. Kept in one module so the digest format and the stream that
8
+ * serializes it have a single owner; `buildAppPageSpecialErrorResponse` and the
9
+ * boundary/dispatch special-error paths all depend on this contract.
10
+ */
11
+ /**
12
+ * Builds the canonical `NEXT_REDIRECT;<type>;<url>;<status>;` digest that
13
+ * Next.js encodes on `redirect()` / `permanentRedirect()` throws. Used when we
14
+ * synthesize a flight payload for an RSC navigation: the digest must round-trip
15
+ * through the client's `RedirectErrorBoundary` so the same
16
+ * `getURLFromRedirectError` / `getRedirectTypeFromError` helpers decode it.
17
+ *
18
+ * The URL is included verbatim, not encoded — Next.js's `getRedirectError`
19
+ * sets `digest = ${CODE};${type};${url};${status};` with the raw URL, and the
20
+ * client decodes via `error.digest.split(';').slice(2, -2).join(';')`. We
21
+ * default `type=replace` because `redirect()` is replace-style outside of
22
+ * server actions, matching Next.js's `getRedirectError` default.
23
+ *
24
+ * Reference:
25
+ * `.nextjs-ref/packages/next/src/client/components/redirect.ts:20-23`
26
+ * `.nextjs-ref/packages/next/src/client/components/redirect-error.ts`
27
+ */
28
+ declare function formatNextRedirectDigest(options: {
29
+ type: "push" | "replace";
30
+ url: string;
31
+ statusCode: number;
32
+ }): string;
33
+ /**
34
+ * The subset of `renderToReadableStream` the redirect-flight encoding needs.
35
+ * Both the boundary and dispatch special-error paths hand in their own
36
+ * environment-specific renderer, which accepts a wider element type; a plain
37
+ * throwing React element satisfies all of them.
38
+ */
39
+ type RedirectFlightStreamRenderer = (element: ReactNode, options: {
40
+ onError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;
41
+ }) => ReadableStream<Uint8Array>;
42
+ /**
43
+ * Builds an RSC flight payload that encodes a `redirect()` as a React error
44
+ * carrying the canonical `NEXT_REDIRECT;<type>;<url>;<status>;` digest. We
45
+ * render a tiny element that throws immediately; `renderToReadableStream`'s
46
+ * `onError` returns the digest, react-server-dom-webpack serializes the error
47
+ * into the stream, and the client's `RedirectErrorBoundary` decodes it via
48
+ * `getURLFromRedirectError` / `getRedirectTypeFromError`. The HTTP response
49
+ * stays 200 because the redirect rides in the flight body, not the status line.
50
+ *
51
+ * Mirrors Next.js's `generateDynamicFlightRenderResult` in `app-render.tsx`,
52
+ * where a redirect thrown during RSC rendering propagates through
53
+ * `renderToFlightStream`'s `onError` into the flight payload.
54
+ *
55
+ * This is the single owner of the redirect-flight encoding: the matched
56
+ * dispatch paths (`renderLayoutSpecialError` / `renderPageSpecialError`) and the
57
+ * route-miss boundary path (`renderBoundarySpecialErrorResponse`) both call it
58
+ * through the `buildRscRedirectFlightStream` option of
59
+ * `buildAppPageSpecialErrorResponse`.
60
+ */
61
+ declare function buildRscRedirectFlightStream(options: {
62
+ renderToReadableStream: RedirectFlightStreamRenderer;
63
+ digest: string;
64
+ }): ReadableStream<Uint8Array>;
65
+ //#endregion
66
+ export { RedirectFlightStreamRenderer, buildRscRedirectFlightStream, formatNextRedirectDigest };
@@ -0,0 +1,71 @@
1
+ import { createElement } from "react";
2
+ //#region src/server/app-rsc-redirect-flight.ts
3
+ /**
4
+ * Encoding of a `redirect()` for RSC transport: the canonical
5
+ * `NEXT_REDIRECT;<type>;<url>;<status>;` digest and the flight payload that
6
+ * carries it. Kept in one module so the digest format and the stream that
7
+ * serializes it have a single owner; `buildAppPageSpecialErrorResponse` and the
8
+ * boundary/dispatch special-error paths all depend on this contract.
9
+ */
10
+ /**
11
+ * Builds the canonical `NEXT_REDIRECT;<type>;<url>;<status>;` digest that
12
+ * Next.js encodes on `redirect()` / `permanentRedirect()` throws. Used when we
13
+ * synthesize a flight payload for an RSC navigation: the digest must round-trip
14
+ * through the client's `RedirectErrorBoundary` so the same
15
+ * `getURLFromRedirectError` / `getRedirectTypeFromError` helpers decode it.
16
+ *
17
+ * The URL is included verbatim, not encoded — Next.js's `getRedirectError`
18
+ * sets `digest = ${CODE};${type};${url};${status};` with the raw URL, and the
19
+ * client decodes via `error.digest.split(';').slice(2, -2).join(';')`. We
20
+ * default `type=replace` because `redirect()` is replace-style outside of
21
+ * server actions, matching Next.js's `getRedirectError` default.
22
+ *
23
+ * Reference:
24
+ * `.nextjs-ref/packages/next/src/client/components/redirect.ts:20-23`
25
+ * `.nextjs-ref/packages/next/src/client/components/redirect-error.ts`
26
+ */
27
+ function formatNextRedirectDigest(options) {
28
+ return `NEXT_REDIRECT;${options.type};${options.url};${options.statusCode};`;
29
+ }
30
+ /**
31
+ * Error thrown by the redirect-flight renderer below. Its `digest` is the
32
+ * canonical `NEXT_REDIRECT;...` string that react-server-dom's `onError`
33
+ * reports so the client's `RedirectErrorBoundary` can decode it. A named
34
+ * subclass keeps `digest` a real field rather than an `as`-cast on a plain
35
+ * `Error`.
36
+ */
37
+ var RscRedirectFlightError = class extends Error {
38
+ digest;
39
+ constructor(digest) {
40
+ super("NEXT_REDIRECT");
41
+ this.digest = digest;
42
+ }
43
+ };
44
+ /**
45
+ * Builds an RSC flight payload that encodes a `redirect()` as a React error
46
+ * carrying the canonical `NEXT_REDIRECT;<type>;<url>;<status>;` digest. We
47
+ * render a tiny element that throws immediately; `renderToReadableStream`'s
48
+ * `onError` returns the digest, react-server-dom-webpack serializes the error
49
+ * into the stream, and the client's `RedirectErrorBoundary` decodes it via
50
+ * `getURLFromRedirectError` / `getRedirectTypeFromError`. The HTTP response
51
+ * stays 200 because the redirect rides in the flight body, not the status line.
52
+ *
53
+ * Mirrors Next.js's `generateDynamicFlightRenderResult` in `app-render.tsx`,
54
+ * where a redirect thrown during RSC rendering propagates through
55
+ * `renderToFlightStream`'s `onError` into the flight payload.
56
+ *
57
+ * This is the single owner of the redirect-flight encoding: the matched
58
+ * dispatch paths (`renderLayoutSpecialError` / `renderPageSpecialError`) and the
59
+ * route-miss boundary path (`renderBoundarySpecialErrorResponse`) both call it
60
+ * through the `buildRscRedirectFlightStream` option of
61
+ * `buildAppPageSpecialErrorResponse`.
62
+ */
63
+ function buildRscRedirectFlightStream(options) {
64
+ const { digest } = options;
65
+ const throwingElement = createElement(function NextRedirectFlightThrower() {
66
+ throw new RscRedirectFlightError(digest);
67
+ });
68
+ return options.renderToReadableStream(throwingElement, { onError: () => digest });
69
+ }
70
+ //#endregion
71
+ export { buildRscRedirectFlightStream, formatNextRedirectDigest };
@@ -1,12 +1,12 @@
1
1
  import { isEdgeApiRuntime } from "./edge-api-runtime.js";
2
2
  //#region src/server/app-segment-config.ts
3
- const DYNAMIC_VALUES = new Set([
3
+ const DYNAMIC_VALUES = /* @__PURE__ */ new Set([
4
4
  "auto",
5
5
  "error",
6
6
  "force-dynamic",
7
7
  "force-static"
8
8
  ]);
9
- const FETCH_CACHE_VALUES = new Set([
9
+ const FETCH_CACHE_VALUES = /* @__PURE__ */ new Set([
10
10
  "auto",
11
11
  "default-cache",
12
12
  "default-no-store",
@@ -13,13 +13,13 @@ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityI
13
13
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
14
14
  import { applyEdgeRuntimeHeader } from "./app-page-response.js";
15
15
  import { getNextErrorDigest, parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
16
+ import { createRootParamsUsageController, pickRootParams, runWithRootParamsScope, runWithRootParamsUsage } from "../shims/root-params.js";
16
17
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage, isServerActionNotFoundError } from "./server-action-not-found.js";
17
18
  import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
18
19
  import "./app-page-stream.js";
19
20
  import { buildAppPageTags } from "./implicit-tags.js";
20
21
  import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
21
22
  import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
22
- import { createRootParamsUsageController, pickRootParams, runWithRootParamsScope, runWithRootParamsUsage } from "../shims/root-params.js";
23
23
  import { getSetCookieName } from "./cookie-utils.js";
24
24
  import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
25
25
  //#region src/server/app-server-action-execution.ts
@@ -16,13 +16,13 @@ import { setPagesClientAssets } from "./pages-client-assets.js";
16
16
  import DefaultGlobalError from "../shims/default-global-error.js";
17
17
  import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
18
18
  import { createSsrErrorMetaRenderer } from "./app-ssr-error-meta.js";
19
- import { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform } from "./app-ssr-stream.js";
19
+ import { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform, waitAtLeastOneReactRenderTask } from "./app-ssr-stream.js";
20
+ import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
21
+ import { runWithRootParamsScope } from "../shims/root-params.js";
20
22
  import { createInitialBfcacheMaps } from "./app-bfcache-identity.js";
21
23
  import { RSC_FORM_STATE_GLOBAL } from "./app-browser-hydration.js";
22
24
  import { createClientReferencePreloader } from "./app-client-reference-preloader.js";
23
25
  import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
24
- import { runWithRootParamsScope } from "../shims/root-params.js";
25
- import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
26
26
  import { renderBeforeInteractiveInlineScripts } from "./before-interactive-head.js";
27
27
  import { createInitialDevServerErrorScript } from "./dev-initial-server-error.js";
28
28
  import { ssrAppRouterInstance } from "./app-ssr-router-instance.js";
@@ -238,6 +238,7 @@ async function handleSsr(rscStream, navContext, fontData, options) {
238
238
  };
239
239
  let htmlStream;
240
240
  let shellErrorRecovered = false;
241
+ let shouldDelayInitialHtmlPull = false;
241
242
  if (pprFallbackShellSignal) {
242
243
  const prerender = await loadStaticPrerender();
243
244
  const htmlAbortController = new AbortController();
@@ -252,6 +253,7 @@ async function handleSsr(rscStream, navContext, fontData, options) {
252
253
  try {
253
254
  streamingHtmlStream = await renderToReadableStream(ssrRoot, { ...renderOptions });
254
255
  if (options?.waitForAllReady === true) await streamingHtmlStream.allReady;
256
+ else shouldDelayInitialHtmlPull = true;
255
257
  htmlStream = streamingHtmlStream;
256
258
  } catch (error) {
257
259
  streamingHtmlStream?.cancel().catch(() => {});
@@ -281,6 +283,7 @@ async function handleSsr(rscStream, navContext, fontData, options) {
281
283
  return buildHeadInjectionHtml(ssrNavigationContext, bootstrapModuleUrl, options?.formState ?? null, insertedHTML + errorMetaHTML + getTraceMetaHTML() + initialDevServerErrorHTML, fontHTML, options?.dynamicStaleTimeSeconds, options?.scriptNonce);
282
284
  };
283
285
  const getBeforeInteractiveHeadHTML = () => renderBeforeInteractiveInlineScripts(beforeInteractiveInlineScripts);
286
+ if (shouldDelayInitialHtmlPull) await waitAtLeastOneReactRenderTask();
284
287
  return {
285
288
  htmlStream: deferUntilStreamConsumed(htmlStream.pipeThrough(createTickBufferedTransform(rscEmbed, getInsertedHTML, getBeforeInteractiveHeadHTML, inlineCssManifest, inlineCssFontStyles, inlineCssFontStyleFallbackHTML, options?.scriptNonce)), cleanup),
286
289
  metadataReady: Promise.resolve(),
@@ -10,6 +10,7 @@ type InitialNavigationCacheMetadata = {
10
10
  kind: "dynamic" | "static";
11
11
  dynamicStaleTimeSeconds?: number;
12
12
  };
13
+ declare function waitAtLeastOneReactRenderTask(): Promise<void>;
13
14
  declare function navigationRuntimeRscBootstrapExpression(): string;
14
15
  declare function createNavigationRuntimeRscMetadataScript(params: Record<string, string | string[]>, nav: {
15
16
  pathname: string;
@@ -61,4 +62,4 @@ declare function fixPreloadAs(html: string): string;
61
62
  */
62
63
  declare function createTickBufferedTransform(rscEmbed: RscEmbedTransform, injectHTML?: HtmlInsertion, injectAfterHeadOpenHTML?: HtmlInsertion, inlineCssManifest?: InlineCssManifest, inlineCssPrependCss?: string, inlineCssPrependFallbackHTML?: string, inlineCssScriptNonce?: string): TransformStream<Uint8Array, Uint8Array>;
63
64
  //#endregion
64
- export { InitialNavigationCacheMetadata, createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform, fixFlightHints, fixPreloadAs, navigationRuntimeRscBootstrapExpression };
65
+ export { InitialNavigationCacheMetadata, createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform, fixFlightHints, fixPreloadAs, navigationRuntimeRscBootstrapExpression, waitAtLeastOneReactRenderTask };
@@ -2,6 +2,9 @@ import { createInlineScriptTag, escapeHtmlAttr, htmlTokenListContains, safeJsonS
2
2
  import { bytesToBase64, concatUint8Arrays } from "./app-rsc-embedded-chunks.js";
3
3
  import { NAVIGATION_RUNTIME_SYMBOL_DESCRIPTION } from "../client/navigation-runtime.js";
4
4
  //#region src/server/app-ssr-stream.ts
5
+ function waitAtLeastOneReactRenderTask() {
6
+ return new Promise((resolve) => setTimeout(resolve, 0));
7
+ }
5
8
  const NAVIGATION_RUNTIME_REFERENCE = `self[Symbol.for(${safeJsonStringify(NAVIGATION_RUNTIME_SYMBOL_DESCRIPTION)})]`;
6
9
  function navigationRuntimeRscBootstrapExpression() {
7
10
  return `((${NAVIGATION_RUNTIME_REFERENCE}??={bootstrap:{routeManifest:null},functions:{}}).bootstrap.rsc??={rsc:[]})`;
@@ -409,4 +412,4 @@ function createTickBufferedTransform(rscEmbed, injectHTML = "", injectAfterHeadO
409
412
  });
410
413
  }
411
414
  //#endregion
412
- export { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform, fixFlightHints, fixPreloadAs, navigationRuntimeRscBootstrapExpression };
415
+ export { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform, fixFlightHints, fixPreloadAs, navigationRuntimeRscBootstrapExpression, waitAtLeastOneReactRenderTask };
@@ -19,7 +19,7 @@ const ALL_RENDER_REQUEST_API_KINDS = [
19
19
  "params",
20
20
  "searchParams"
21
21
  ];
22
- const PUBLIC_UNSAFE_DIMENSION_SOURCES = new Set([
22
+ const PUBLIC_UNSAFE_DIMENSION_SOURCES = /* @__PURE__ */ new Set([
23
23
  "auth",
24
24
  "cookie",
25
25
  "draft-mode",
@@ -1,3 +1,5 @@
1
+ import DefaultGlobalError from "../shims/default-global-error.js";
2
+
1
3
  //#region src/server/default-global-error-module.d.ts
2
4
  /**
3
5
  * Module-shaped wrapper around vinext's built-in default global error
@@ -13,7 +15,7 @@
13
15
  * https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts
14
16
  */
15
17
  declare const DEFAULT_GLOBAL_ERROR_MODULE: {
16
- readonly default: any;
18
+ readonly default: typeof DefaultGlobalError;
17
19
  };
18
20
  //#endregion
19
21
  export { DEFAULT_GLOBAL_ERROR_MODULE };
@@ -1,3 +1,5 @@
1
+ import DefaultNotFound from "../shims/default-not-found.js";
2
+
1
3
  //#region src/server/default-not-found-module.d.ts
2
4
  /**
3
5
  * Module-shaped wrapper around vinext's built-in default not-found component.
@@ -13,7 +15,7 @@
13
15
  * https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts
14
16
  */
15
17
  declare const DEFAULT_NOT_FOUND_MODULE: {
16
- readonly default: any;
18
+ readonly default: typeof DefaultNotFound;
17
19
  };
18
20
  //#endregion
19
21
  export { DEFAULT_NOT_FOUND_MODULE };
@@ -1,6 +1,5 @@
1
- import { normalizePathSeparators } from "../utils/path.js";
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
2
  import fs from "node:fs";
3
- import path from "node:path";
4
3
  //#region src/server/dev-lockfile.ts
5
4
  /**
6
5
  * Dev server lock file.
@@ -99,7 +98,7 @@ function formatAlreadyRunningError(opts) {
99
98
  if (!existing) return [
100
99
  "Another vinext dev server appears to be running in this directory.",
101
100
  "",
102
- `Stale lock file: ${normalizePathSeparators(path.relative(cwd, lockfilePath))}`,
101
+ `Stale lock file: ${path.relative(cwd, lockfilePath)}`,
103
102
  "Remove it manually if no server is running, then re-run `vinext dev`."
104
103
  ].join("\n");
105
104
  const killCommand = process.platform === "win32" ? `taskkill /PID ${existing.pid} /F` : `kill ${existing.pid}`;
@@ -1,5 +1,5 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { METADATA_FILE_MAP, matchMetadataFileBaseName } from "./metadata-routes.js";
2
- import path from "node:path";
3
3
  //#region src/server/dev-route-files.ts
4
4
  const APP_ROUTER_STRUCTURE_FILES = [
5
5
  "page",