vinext 1.0.0-beta.11 → 1.0.0-beta.13

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 (170) hide show
  1. package/README.md +39 -12
  2. package/dist/build/action-owner-manifest.js +23 -5
  3. package/dist/build/lifecycle.d.ts +42 -0
  4. package/dist/build/lifecycle.js +246 -0
  5. package/dist/build/nitro-route-rules.js +1 -1
  6. package/dist/build/pages-client-assets-module.d.ts +0 -3
  7. package/dist/build/pages-client-assets-module.js +1 -13
  8. package/dist/build/precompress.js +1 -1
  9. package/dist/build/prerender-paths.d.ts +1 -1
  10. package/dist/build/prerender-paths.js +6 -6
  11. package/dist/build/prerender-server-pool.js +1 -1
  12. package/dist/build/prerender.d.ts +1 -1
  13. package/dist/build/prerender.js +5 -5
  14. package/dist/build/preview-credentials.d.ts +1 -1
  15. package/dist/build/preview-credentials.js +2 -2
  16. package/dist/build/report.js +1 -1
  17. package/dist/build/run-prerender.d.ts +2 -2
  18. package/dist/build/run-prerender.js +5 -5
  19. package/dist/build/standalone.js +2 -2
  20. package/dist/cli-args.d.ts +5 -13
  21. package/dist/cli-args.js +2 -45
  22. package/dist/cli-dev-config.d.ts +6 -2
  23. package/dist/cli-dev-config.js +160 -3
  24. package/dist/cli.js +104 -439
  25. package/dist/config/config-matchers.js +1 -1
  26. package/dist/config/next-config.d.ts +2 -2
  27. package/dist/config/next-config.js +5 -5
  28. package/dist/config/prerender.d.ts +3 -0
  29. package/dist/config/prerender.js +8 -2
  30. package/dist/entries/app-browser-entry.js +1 -1
  31. package/dist/entries/app-rsc-entry.d.ts +2 -0
  32. package/dist/entries/app-rsc-entry.js +25 -5
  33. package/dist/entries/pages-client-entry.d.ts +1 -0
  34. package/dist/entries/pages-client-entry.js +17 -2
  35. package/dist/index.d.ts +6 -8
  36. package/dist/index.js +282 -105
  37. package/dist/init-cloudflare.d.ts +3 -2
  38. package/dist/init-cloudflare.js +117 -5
  39. package/dist/init-platform.d.ts +2 -0
  40. package/dist/init-platform.js +9 -3
  41. package/dist/init.d.ts +7 -5
  42. package/dist/init.js +41 -22
  43. package/dist/plugins/dynamic-preload-metadata.js +1 -1
  44. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  45. package/dist/plugins/fonts.js +1 -1
  46. package/dist/plugins/ignore-dynamic-requests.js +1 -1
  47. package/dist/plugins/import-meta-url.js +1 -1
  48. package/dist/plugins/instrumentation-client.js +1 -1
  49. package/dist/plugins/og-assets.js +32 -13
  50. package/dist/plugins/og-harfbuzz.d.ts +24 -0
  51. package/dist/plugins/og-harfbuzz.js +260 -0
  52. package/dist/plugins/optimize-imports.js +1 -1
  53. package/dist/plugins/require-condition-resolution.js +2 -2
  54. package/dist/plugins/require-context.js +2 -2
  55. package/dist/plugins/typeof-window.js +1 -1
  56. package/dist/plugins/use-cache-callable.d.ts +0 -2
  57. package/dist/plugins/use-cache-callable.js +40 -22
  58. package/dist/plugins/worker-image-imports.js +1 -1
  59. package/dist/routing/app-route-graph.js +1 -1
  60. package/dist/routing/app-router.js +1 -1
  61. package/dist/routing/pages-router.js +1 -1
  62. package/dist/server/app-action-forwarding.js +1 -1
  63. package/dist/server/app-browser-entry.js +1 -0
  64. package/dist/server/app-browser-error.js +1 -1
  65. package/dist/server/app-elements-wire.js +2 -2
  66. package/dist/server/app-middleware.js +1 -1
  67. package/dist/server/app-optimistic-routing.js +1 -1
  68. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  69. package/dist/server/app-page-cache-finalizer.js +14 -2
  70. package/dist/server/app-page-dispatch.js +1 -1
  71. package/dist/server/app-page-element-builder.js +3 -2
  72. package/dist/server/app-page-probe.js +3 -3
  73. package/dist/server/app-page-render.js +1 -0
  74. package/dist/server/app-page-request.d.ts +2 -0
  75. package/dist/server/app-page-request.js +16 -12
  76. package/dist/server/app-request-stage-dispatch.js +1 -1
  77. package/dist/server/app-request-stage-independent-entry.js +2 -2
  78. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  79. package/dist/server/app-route-handler-dispatch.js +3 -2
  80. package/dist/server/app-route-handler-execution.d.ts +1 -0
  81. package/dist/server/app-route-handler-execution.js +2 -2
  82. package/dist/server/app-route-handler-runtime.js +1 -1
  83. package/dist/server/app-router-entry.js +2 -2
  84. package/dist/server/app-rsc-handler.d.ts +9 -2
  85. package/dist/server/app-rsc-handler.js +30 -10
  86. package/dist/server/app-rsc-response-stage.js +6 -3
  87. package/dist/server/app-rsc-route-matching.js +1 -1
  88. package/dist/server/app-server-action-execution.js +35 -6
  89. package/dist/server/app-ssr-entry.js +7 -2
  90. package/dist/server/app-ssr-stream.js +25 -6
  91. package/dist/server/app-worker-stages.d.ts +4 -1
  92. package/dist/server/app-worker-stages.js +4 -4
  93. package/dist/server/artifact-compatibility.js +1 -1
  94. package/dist/server/client-reuse-manifest.js +1 -1
  95. package/dist/server/dev-lockfile.d.ts +1 -1
  96. package/dist/server/dev-lockfile.js +4 -1
  97. package/dist/server/dev-server.d.ts +1 -1
  98. package/dist/server/dev-server.js +28 -6
  99. package/dist/server/dev-stack-sourcemap.js +1 -1
  100. package/dist/server/html.d.ts +0 -20
  101. package/dist/server/html.js +16 -1
  102. package/dist/server/instrumentation.d.ts +4 -9
  103. package/dist/server/instrumentation.js +10 -15
  104. package/dist/server/isr-cache.js +3 -3
  105. package/dist/server/metadata-route-response.d.ts +1 -0
  106. package/dist/server/metadata-route-response.js +65 -0
  107. package/dist/server/middleware-runtime.js +3 -3
  108. package/dist/server/pages-asset-tags.d.ts +1 -0
  109. package/dist/server/pages-asset-tags.js +37 -2
  110. package/dist/server/pages-client-assets.d.ts +7 -0
  111. package/dist/server/pages-data-route.js +1 -1
  112. package/dist/server/pages-dev-hydration.d.ts +6 -0
  113. package/dist/server/pages-dev-hydration.js +19 -7
  114. package/dist/server/pages-document-initial-props.d.ts +1 -0
  115. package/dist/server/pages-document-initial-props.js +1 -1
  116. package/dist/server/pages-page-data.js +2 -2
  117. package/dist/server/pages-page-handler.js +5 -2
  118. package/dist/server/pages-page-response.d.ts +1 -0
  119. package/dist/server/pages-page-response.js +3 -2
  120. package/dist/server/pages-request-pipeline.js +3 -3
  121. package/dist/server/pages-request-stage-entry.js +3 -3
  122. package/dist/server/pages-revalidate.js +1 -1
  123. package/dist/server/prerender-route-params.js +1 -1
  124. package/dist/server/prod-server.js +19 -13
  125. package/dist/server/request-pipeline.js +2 -2
  126. package/dist/server/rsc-stream-hints.d.ts +12 -0
  127. package/dist/server/rsc-stream-hints.js +70 -35
  128. package/dist/server/seed-cache.js +3 -4
  129. package/dist/server/socket-error-backstop.js +1 -1
  130. package/dist/shims/cache-callable-runtime.d.ts +38 -0
  131. package/dist/shims/cache-callable-runtime.js +162 -11
  132. package/dist/shims/cache-runtime.d.ts +6 -8
  133. package/dist/shims/cache-runtime.js +89 -24
  134. package/dist/shims/constants.js +1 -1
  135. package/dist/shims/dynamic-preload-chunks.js +6 -2
  136. package/dist/shims/font-local.js +1 -1
  137. package/dist/shims/form.js +1 -1
  138. package/dist/shims/head.js +1 -1
  139. package/dist/shims/headers.js +2 -2
  140. package/dist/shims/image-config.js +2 -0
  141. package/dist/shims/internal/app-page-props-cache-key.d.ts +29 -0
  142. package/dist/shims/internal/app-page-props-cache-key.js +53 -1
  143. package/dist/shims/internal/format-url-object.d.ts +7 -0
  144. package/dist/shims/internal/format-url-object.js +53 -0
  145. package/dist/shims/internal/normalize-router-href.d.ts +15 -0
  146. package/dist/shims/internal/normalize-router-href.js +41 -0
  147. package/dist/shims/internal/pages-data-target.d.ts +4 -1
  148. package/dist/shims/internal/pages-data-target.js +28 -35
  149. package/dist/shims/internal/route-pattern-for-warning.d.ts +2 -2
  150. package/dist/shims/internal/route-pattern-for-warning.js +3 -3
  151. package/dist/shims/link.js +31 -92
  152. package/dist/shims/metadata.js +5 -4
  153. package/dist/shims/navigation.js +2 -2
  154. package/dist/shims/router-state.js +1 -1
  155. package/dist/shims/router.d.ts +8 -7
  156. package/dist/shims/router.js +312 -148
  157. package/dist/shims/script-nonce-context.d.ts +4 -1
  158. package/dist/shims/script-nonce-context.js +15 -6
  159. package/dist/shims/server.js +3 -3
  160. package/dist/utils/built-asset-url.js +1 -1
  161. package/dist/utils/client-runtime-metadata.d.ts +6 -0
  162. package/dist/utils/client-runtime-metadata.js +16 -0
  163. package/dist/utils/lazy-chunks.js +1 -1
  164. package/dist/utils/project.d.ts +1 -11
  165. package/dist/utils/project.js +20 -29
  166. package/dist/utils/react-version.d.ts +3 -1
  167. package/dist/utils/react-version.js +19 -1
  168. package/dist/utils/vite-cli-invocation.d.ts +21 -0
  169. package/dist/utils/vite-cli-invocation.js +144 -0
  170. package/package.json +10 -2
@@ -1,14 +1,18 @@
1
1
  import { markFullyBufferedBody } from "./fully-buffered-response.js";
2
2
  import { closeAfterResponse, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
3
+ import { decodeMatchedParams } from "../routing/utils.js";
3
4
  import { getRequestExecutionContext } from "../shims/request-context.js";
4
5
  import { VINEXT_METADATA_ROUTE_CACHE_HEADER } from "./headers.js";
5
6
  import { notFoundResponse } from "./http-error-responses.js";
7
+ import { beginRouteCacheability, markRouteCacheabilityExplicitResponsePolicy } from "../shims/cacheability-classification.js";
8
+ import { hasCdnResponsePolicy, hasExplicitNonCacheableResponsePolicy } from "./cache-control.js";
6
9
  import { isrCacheControl } from "./isr-cache.js";
7
10
  import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
8
11
  import { _consumeRequestScopedCacheLife, cacheLifeProfiles } from "../shims/cache-request-state.js";
9
12
  import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
10
13
  import { isValidMetadataImageId, manifestToJson, matchMetadataRoutePattern, robotsToText, sitemapToXml } from "./metadata-routes.js";
11
14
  import { applyPrerenderCacheLifeHeader, applyPrerenderCacheTagsHeader } from "./prerender-cache-life-header.js";
15
+ import { canonicalizeAppPageParams } from "./app-page-segment-state.js";
12
16
  import { buildPageCacheTags } from "./implicit-tags.js";
13
17
  import { buildAppRouteCacheValue, buildRouteHandlerCachedResponse } from "./app-route-handler-response.js";
14
18
  import { isMetadataResponseCacheable } from "./metadata-route-cache-policy.js";
@@ -50,6 +54,7 @@ function metadataRouteCacheHeader(route) {
50
54
  return CACHE_HEADERS.revalidate;
51
55
  }
52
56
  function withMetadataRouteCacheHeader(response, route) {
57
+ if (hasCdnResponsePolicy(response.headers) && !hasExplicitNonCacheableResponsePolicy(response.headers)) markRouteCacheabilityExplicitResponsePolicy();
53
58
  const headers = new Headers(response.headers);
54
59
  if (!headers.has("Cache-Control")) headers.set("Cache-Control", metadataRouteCacheHeader(route));
55
60
  return new Response(response.body, {
@@ -58,13 +63,18 @@ function withMetadataRouteCacheHeader(response, route) {
58
63
  statusText: response.statusText
59
64
  });
60
65
  }
66
+ function beginMetadataRouteCacheability(route) {
67
+ beginRouteCacheability("app-route", route.patternParts ? `/${route.patternParts.join("/")}` : route.servedUrl);
68
+ }
61
69
  function getMetadataRouteFunctions(route) {
62
70
  const cached = routeFunctionCache.get(route);
63
71
  if (cached) return cached;
64
72
  const generateImageMetadata = route.isDynamic && isImageMetadataRoute(route) ? readFunction(route.module, "generateImageMetadata") : null;
65
73
  const functions = {
66
74
  defaultExport: route.isDynamic ? readFunction(route.module, "default") : null,
75
+ dynamicParams: route.isDynamic && typeof route.module?.dynamicParams === "boolean" ? route.module.dynamicParams : void 0,
67
76
  generateImageMetadata,
77
+ generateStaticParams: route.isDynamic ? readFunction(route.module, "generateStaticParams") : null,
68
78
  generateSitemaps: route.type === "sitemap" && route.isDynamic ? readFunction(route.module, "generateSitemaps") : null,
69
79
  hasGeneratedImageMetadata: route.isDynamic && isImageMetadataRoute(route) && Boolean(generateImageMetadata)
70
80
  };
@@ -256,6 +266,39 @@ function matchMetadataRoute(route, cleanPathname, functions, getUrlParts) {
256
266
  imageId: null
257
267
  } : null;
258
268
  }
269
+ function metadataRouteParamNames(patternParts) {
270
+ return patternParts.flatMap((part) => {
271
+ if (!part.startsWith(":")) return [];
272
+ return [part.slice(1, part.endsWith("+") || part.endsWith("*") ? -1 : void 0)];
273
+ });
274
+ }
275
+ function metadataRouteOptionalCatchAllParamNames(patternParts) {
276
+ return patternParts.flatMap((part) => part.startsWith(":") && part.endsWith("*") ? [part.slice(1, -1)] : []);
277
+ }
278
+ function metadataRouteRawParams(route, match, routePathname) {
279
+ const urlParts = routePathname.split("/").filter(Boolean);
280
+ if (match.imageId !== null) urlParts.pop();
281
+ const params = Object.create(null);
282
+ let urlIndex = 0;
283
+ for (const part of route.patternParts ?? []) {
284
+ if (!part.startsWith(":")) {
285
+ urlIndex++;
286
+ continue;
287
+ }
288
+ const isCatchAll = part.endsWith("+") || part.endsWith("*");
289
+ const name = part.slice(1, isCatchAll ? -1 : void 0);
290
+ if (!isCatchAll) {
291
+ const value = urlParts[urlIndex++];
292
+ if (value !== void 0) params[name] = value;
293
+ continue;
294
+ }
295
+ const matchedValue = match.params?.[name];
296
+ const valueCount = Array.isArray(matchedValue) ? matchedValue.length : matchedValue ? 1 : 0;
297
+ if (valueCount > 0) params[name] = urlParts.slice(urlIndex, urlIndex + valueCount);
298
+ urlIndex += valueCount;
299
+ }
300
+ return params;
301
+ }
259
302
  function findGeneratedSitemapId(entries, rawId) {
260
303
  if (!Array.isArray(entries)) return null;
261
304
  for (const entry of entries) {
@@ -386,6 +429,7 @@ async function handleMetadataRouteRequest(options) {
386
429
  if (route.type === "sitemap" && route.isDynamic) {
387
430
  if (functions.generateSitemaps) {
388
431
  if (isGeneratedSitemapPath(route, options.cleanPathname)) {
432
+ beginMetadataRouteCacheability(route);
389
433
  const render = async () => {
390
434
  setCurrentFetchSoftTags(buildMetadataRouteTags(route, options.cleanPathname, []));
391
435
  const response = await handleGeneratedSitemap(route, options.cleanPathname, functions);
@@ -404,6 +448,27 @@ async function handleMetadataRouteRequest(options) {
404
448
  }
405
449
  const match = matchMetadataRoute(route, options.cleanPathname, functions, getUrlParts);
406
450
  if (!match) continue;
451
+ beginMetadataRouteCacheability(route);
452
+ const rawParams = route.patternParts ? metadataRouteRawParams(route, match, options.routePathname ?? options.cleanPathname) : Object.create(null);
453
+ if (route.patternParts) {
454
+ const runtimeParams = { ...rawParams };
455
+ decodeMatchedParams(runtimeParams);
456
+ match.params = runtimeParams;
457
+ }
458
+ if (route.isDynamic && isImageMetadataRoute(route) && functions.dynamicParams === false) {
459
+ const validationParams = { ...rawParams };
460
+ canonicalizeAppPageParams(validationParams);
461
+ const { validateAppPageDynamicParams } = await import("./app-page-request.js");
462
+ const dynamicParamsResponse = await validateAppPageDynamicParams({
463
+ enforceStaticParamsOnly: true,
464
+ generateStaticParams: functions.generateStaticParams,
465
+ isDynamicRoute: Boolean(route.patternParts),
466
+ optionalCatchAllParamNames: metadataRouteOptionalCatchAllParamNames(route.patternParts ?? []),
467
+ params: validationParams,
468
+ requiredParamNames: metadataRouteParamNames(route.patternParts ?? [])
469
+ });
470
+ if (dynamicParamsResponse) return dynamicParamsResponse;
471
+ }
407
472
  const render = async () => {
408
473
  setCurrentFetchSoftTags(buildMetadataRouteTags(route, options.cleanPathname, []));
409
474
  return captureRenderedMetadataRoute(route.isDynamic ? await callDynamicMetadataRoute(route, match, options.makeThenableParams, functions) : serveStaticMetadataRoute(route));
@@ -1,12 +1,12 @@
1
1
  import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import "../utils/protocol-headers.js";
3
+ import { shouldKeepMiddlewareHeader } from "../utils/middleware-request-headers.js";
4
+ import { normalizeHost } from "../config/request-context.js";
2
5
  import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
3
6
  import { addBasePathToPathname, hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
4
7
  import { getRequestExecutionContext, runWithExecutionContext } from "../shims/request-context.js";
5
8
  import "./server-globals.js";
6
- import { normalizeHost } from "../config/request-context.js";
7
- import "../utils/protocol-headers.js";
8
9
  import { MIDDLEWARE_REWRITE_HEADER } from "./headers.js";
9
- import { shouldKeepMiddlewareHeader } from "../utils/middleware-request-headers.js";
10
10
  import { NextFetchEvent, NextRequest } from "../shims/server.js";
11
11
  import { normalizePath } from "./normalize-path.js";
12
12
  import { matchesMiddleware, matchesMiddlewarePathname } from "./middleware-matcher.js";
@@ -59,6 +59,7 @@ type CollectAssetTagsOptions = {
59
59
  assetPrefix?: string;
60
60
  deploymentId?: string;
61
61
  crossOrigin?: string;
62
+ initialStylesheetHrefs?: Set<string>;
62
63
  };
63
64
  /**
64
65
  * Build the HTML `<link>` and `<script>` tag string for the SSR response.
@@ -34,6 +34,30 @@ function getManifestFilesForModule(manifest, moduleId) {
34
34
  for (const key in manifest) if (moduleId.endsWith("/" + key) || moduleId === key) return manifest[key];
35
35
  return null;
36
36
  }
37
+ function collectGraphOrderedCss(graph, moduleIds) {
38
+ const ordered = [];
39
+ const emitted = /* @__PURE__ */ new Set();
40
+ const visited = /* @__PURE__ */ new Set();
41
+ function findKey(moduleId) {
42
+ if (!moduleId) return void 0;
43
+ if (graph[moduleId]) return moduleId;
44
+ for (const key in graph) if (moduleId === key || moduleId.endsWith("/" + key)) return key;
45
+ }
46
+ function visit(key) {
47
+ if (!key || visited.has(key)) return;
48
+ visited.add(key);
49
+ const chunk = graph[key];
50
+ if (!chunk) return;
51
+ for (const importedKey of chunk.imports ?? []) visit(importedKey);
52
+ for (const file of chunk.css ?? []) {
53
+ if (emitted.has(file)) continue;
54
+ emitted.add(file);
55
+ ordered.push(file);
56
+ }
57
+ }
58
+ for (const moduleId of moduleIds) visit(findKey(moduleId));
59
+ return ordered;
60
+ }
37
61
  /**
38
62
  * Find the first `.js` file in the manifest for `moduleId` and return the URL it
39
63
  * is actually SERVED from. Used to resolve the client-navigation / hydration URL
@@ -87,6 +111,14 @@ function collectAssetTags(options) {
87
111
  tags.push("<link rel=\"modulepreload\"" + nonceAttr + " href=\"" + href(clientEntry) + "\"" + preloadCrossOriginAttr + " />");
88
112
  tags.push("<script type=\"module\"" + deferAttr + nonceAttr + " src=\"" + href(clientEntry) + "\"" + scriptCrossOriginAttr + "><\/script>");
89
113
  }
114
+ if (runtimeAssets.cssGraph) for (let file of collectGraphOrderedCss(runtimeAssets.cssGraph, options.moduleIds)) {
115
+ if (file.charAt(0) === "/") file = file.slice(1);
116
+ if (seen.has(file)) continue;
117
+ seen.add(file);
118
+ const stylesheetHref = href(file);
119
+ options.initialStylesheetHrefs?.add(stylesheetHref);
120
+ tags.push("<link rel=\"stylesheet\"" + nonceAttr + " href=\"" + stylesheetHref + "\" />");
121
+ }
90
122
  if (m) {
91
123
  const allFiles = [];
92
124
  const moduleIds = options.moduleIds;
@@ -114,8 +146,11 @@ function collectAssetTags(options) {
114
146
  if (tf.charAt(0) === "/") tf = tf.slice(1);
115
147
  if (seen.has(tf)) continue;
116
148
  seen.add(tf);
117
- if (tf.endsWith(".css")) tags.push("<link rel=\"stylesheet\"" + nonceAttr + " href=\"" + href(tf) + "\" />");
118
- else if (tf.endsWith(".js")) {
149
+ if (tf.endsWith(".css")) {
150
+ const stylesheetHref = href(tf);
151
+ options.initialStylesheetHrefs?.add(stylesheetHref);
152
+ tags.push("<link rel=\"stylesheet\"" + nonceAttr + " href=\"" + stylesheetHref + "\" />");
153
+ } else if (tf.endsWith(".js")) {
119
154
  if (lazySet && lazySet.has(tf)) continue;
120
155
  tags.push("<link rel=\"modulepreload\"" + nonceAttr + " href=\"" + href(tf) + "\"" + preloadCrossOriginAttr + " />");
121
156
  tags.push("<script type=\"module\"" + deferAttr + nonceAttr + " src=\"" + href(tf) + "\"" + scriptCrossOriginAttr + "><\/script>");
@@ -1,10 +1,17 @@
1
1
  //#region src/server/pages-client-assets.d.ts
2
+ export type AssetCrossOrigin = "" | "anonymous" | "use-credentials";
2
3
  export type PagesClientAssets = {
3
4
  clientEntry?: string;
4
5
  appBootstrapPreinitModules?: string[];
5
6
  ssrManifest?: Record<string, string[]>;
7
+ cssGraph?: Record<string, {
8
+ imports?: string[];
9
+ css?: string[];
10
+ }>;
6
11
  lazyChunks?: string[];
7
12
  dynamicPreloads?: Record<string, string[]>;
13
+ /** next.config crossOrigin, defaulting to anonymous for Vite's CORS-fetched assets. */
14
+ crossOrigin?: AssetCrossOrigin;
8
15
  };
9
16
  export declare function setPagesClientAssets(assets: PagesClientAssets | undefined): void;
10
17
  export declare function getPagesClientAssets(): PagesClientAssets;
@@ -1,5 +1,5 @@
1
- import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
2
1
  import { MIDDLEWARE_SKIP_HEADER } from "../utils/protocol-headers.js";
2
+ import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
3
3
  import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
4
4
  //#region src/server/pages-data-route.ts
5
5
  /**
@@ -4,6 +4,12 @@ export type PagesDevHydrationOptions = {
4
4
  forceRouterReady?: boolean;
5
5
  normalizePageProps?: boolean;
6
6
  pageModuleSource: string;
7
+ /** Lazily importable page routes, matching the production client manifest. */
8
+ pageLoaders?: readonly {
9
+ pattern: string;
10
+ moduleSource: string;
11
+ dataKind?: "static" | "server" | "none";
12
+ }[];
7
13
  reactStrictMode: boolean;
8
14
  replaceFallbackRoute?: boolean;
9
15
  scriptNonce?: string;
@@ -1,11 +1,17 @@
1
1
  import { resolveClientRuntimeModule } from "../entries/runtime-entry-module.js";
2
- import { createNonceAttribute } from "./html.js";
2
+ import { createNonceAttribute, safeJsonStringify } from "./html.js";
3
3
  //#region src/server/pages-dev-hydration.ts
4
4
  function createPagesDevHydrationScript(options) {
5
5
  const nonceAttr = createNonceAttribute(options.scriptNonce);
6
6
  const reactInstanceBootstrapPath = resolveClientRuntimeModule("react-instance-bootstrap");
7
7
  const initializeRouter = options.forceRouterReady ? "_initializePagesRouterReadyFromNextData(nextData, true);" : "_initializePagesRouterReadyFromNextData(nextData);";
8
- const pagePatterns = options.setPagePatternsFromNextData ? "window.__VINEXT_PAGE_PATTERNS__ = [nextData.page];" : "";
8
+ const pagePatterns = options.setPagePatternsFromNextData ? options.pageLoaders ? "window.__VINEXT_PAGE_PATTERNS__ = Object.keys(window.__VINEXT_PAGE_LOADERS__);" : "window.__VINEXT_PAGE_PATTERNS__ = [nextData.page];" : "";
9
+ const pageLoaders = `{ ${[...options.pageLoaders?.map(({ pattern, moduleSource }) => {
10
+ const importer = moduleSource === "next/error" ? "import(\"next/error\")" : `loadDevPage(import.meta.env.BASE_URL + ${safeJsonStringify(moduleSource.slice(1))})`;
11
+ return `${safeJsonStringify(pattern)}: () => ${importer}`;
12
+ }) ?? [], `[nextData.page]: () => import(${safeJsonStringify(options.pageModuleSource)})`].join(", ")} }`;
13
+ const ssgPatterns = options.pageLoaders?.filter((route) => route.dataKind === "static").map((route) => route.pattern);
14
+ const sspPatterns = options.pageLoaders?.filter((route) => route.dataKind === "server").map((route) => route.pattern);
9
15
  const pageProps = options.normalizePageProps === false ? "const pageProps = rawPageProps ?? {};" : "const pageProps = rawPageProps && typeof rawPageProps === \"object\" ? rawPageProps : {};";
10
16
  const hydrationQueryUpdate = options.replaceFallbackRoute ? `
11
17
  const initialMatchesMiddleware =
@@ -19,7 +25,7 @@ function createPagesDevHydrationScript(options) {
19
25
  await Router.replace(routeUrl || currentUrl, routeUrl ? currentUrl : undefined, { _h: 1, scroll: false, shallow: !nextData.isFallback && !initialMatchesMiddleware });
20
26
  }` : "";
21
27
  const createElement = options.appModuleSource ? `
22
- const appModule = await import(${JSON.stringify(options.appModuleSource)});
28
+ const appModule = await import(${safeJsonStringify(options.appModuleSource)});
23
29
  const AppComponent = appModule.default;
24
30
  window.__VINEXT_APP__ = AppComponent;
25
31
  const appRouter = ${options.forceRouterReady ? "{ ...Router, isReady: true }" : "Router"};
@@ -33,7 +39,7 @@ function createPagesDevHydrationScript(options) {
33
39
  `;
34
40
  return `
35
41
  <script type="module"${nonceAttr}>
36
- import ${JSON.stringify(reactInstanceBootstrapPath)};
42
+ import ${safeJsonStringify(reactInstanceBootstrapPath)};
37
43
  import "vinext/instrumentation-client";
38
44
  import React from "react";
39
45
  import { hydrateRoot } from "react-dom/client";
@@ -47,13 +53,19 @@ if (nextDataElement?.textContent) {
47
53
  window.__VINEXT_DEFAULT_LOCALE__ = window.__NEXT_DATA__.defaultLocale;
48
54
  }
49
55
  const nextData = window.__NEXT_DATA__;
56
+ window.__VINEXT_MIDDLEWARE_MATCHER__ = nextData.__vinext?.clientMiddlewareMatcher;
50
57
  ${initializeRouter}
51
58
  const props = nextData.props && typeof nextData.props === "object" ? nextData.props : {};
52
59
  const rawPageProps = props.pageProps;
53
60
  ${pageProps}
54
- window.__VINEXT_PAGE_LOADERS__ = { [nextData.page]: () => import(${JSON.stringify(options.pageModuleSource)}) };
61
+ // Other pages must not become static dependencies of this page's HMR proxy.
62
+ // Vite adds ?import to variable imports, so source URLs are bare and base-qualified here.
63
+ const loadDevPage = (source) => import(/* @vite-ignore */ source);
64
+ window.__VINEXT_PAGE_LOADERS__ = ${pageLoaders};
55
65
  ${pagePatterns}
56
- window.__VINEXT_APP_LOADER__ = ${options.appModuleSource ? `() => import(${JSON.stringify(options.appModuleSource)})` : "undefined"};
66
+ ${ssgPatterns ? `window.__VINEXT_PAGES_SSG_PATTERNS__ = ${safeJsonStringify(ssgPatterns)};` : ""}
67
+ ${sspPatterns ? `window.__VINEXT_PAGES_SSP_PATTERNS__ = ${safeJsonStringify(sspPatterns)};` : ""}
68
+ window.__VINEXT_APP_LOADER__ = ${options.appModuleSource ? `() => import(${safeJsonStringify(options.appModuleSource)})` : "undefined"};
57
69
  window.__VINEXT_REACT_STRICT_MODE__ = ${JSON.stringify(options.reactStrictMode)};
58
70
 
59
71
  async function hydrate() {
@@ -69,7 +81,7 @@ async function hydrate() {
69
81
  };
70
82
  }
71
83
 
72
- const pageModule = await import(${JSON.stringify(options.pageModuleSource)});
84
+ const pageModule = await import(${safeJsonStringify(options.pageModuleSource)});
73
85
  const PageComponent = pageModule.default;
74
86
  let element;
75
87
  ${createElement}
@@ -23,6 +23,7 @@ type DocumentRenderPageInput = {
23
23
  renderStylesToString: (element: React.ReactElement) => Promise<string>;
24
24
  /** Per-request CSP nonce applied to the enhanced page tree, if any. */
25
25
  scriptNonce?: string | undefined;
26
+ initialStylesheetHrefs?: ReadonlySet<string> | undefined;
26
27
  /** Extra `DocumentContext` fields (pathname/query/asPath). */
27
28
  context?: Record<string, unknown> | undefined;
28
29
  };
@@ -75,7 +75,7 @@ async function runDocumentRenderPage(input) {
75
75
  const enhancePageElement = input.enhancePageElement;
76
76
  const renderPage = async (opts = {}) => {
77
77
  const enhancedElement = enhancePageElement(typeof opts === "function" ? { enhanceComponent: opts } : opts);
78
- const wrapped = withScriptNonce(enhancedElement, input.scriptNonce);
78
+ const wrapped = withScriptNonce(enhancedElement, input.scriptNonce, input.initialStylesheetHrefs);
79
79
  const stream = await input.renderToReadableStream(wrapped);
80
80
  return {
81
81
  html: await readStreamAsText(stream),
@@ -1,14 +1,14 @@
1
+ import { isUnknownRecord } from "../utils/record.js";
2
+ import { isBotUserAgent } from "../utils/html-limited-bots.js";
1
3
  import { normalizePathnameForRouteMatch } from "../routing/utils.js";
2
4
  import { NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
3
5
  import { isDangerousScheme } from "../shims/url-safety.js";
4
6
  import { applyCdnResponseHeaders } from "./cache-control.js";
5
7
  import { buildMissIsrCacheControl, decideIsr } from "./isr-decision.js";
6
- import { isUnknownRecord } from "../utils/record.js";
7
8
  import { buildPagesCacheValue, isrCacheControl } from "./isr-cache.js";
8
9
  import { encodeCacheTag } from "../utils/encode-cache-tag.js";
9
10
  import { normalizeStaticPathname } from "../routing/route-pattern.js";
10
11
  import { buildCacheStateHeaders } from "./cache-headers.js";
11
- import { isBotUserAgent } from "../utils/html-limited-bots.js";
12
12
  import { matchesIfNoneMatch } from "./http-conditional.js";
13
13
  import { buildPagesNextDataScript, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
14
14
  import { createPagesGetInitialPropsRouter, hasPagesGetInitialProps, isResponseSent, loadPagesGetInitialProps } from "./pages-get-initial-props.js";
@@ -1,8 +1,8 @@
1
1
  import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
2
2
  import { closeAfterResponse, closeAfterResponseWithBody, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
3
+ import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
3
4
  import { patternToNextFormat } from "../routing/route-validation.js";
4
5
  import { getRequestExecutionContext } from "../shims/request-context.js";
5
- import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
6
6
  import { NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_CACHE_HEADER, VINEXT_REVALIDATED_CACHE_TAG_HEADER } from "./headers.js";
7
7
  import { extractLocaleFromUrl, resolvePagesI18nRequest } from "./pages-i18n.js";
8
8
  import { reportRequestError } from "./instrumentation.js";
@@ -492,6 +492,7 @@ function createPagesPageHandler(opts) {
492
492
  const pageModuleIds = [];
493
493
  if (appAssetPath) pageModuleIds.push(appAssetPath);
494
494
  if (route.filePath) pageModuleIds.push(route.filePath);
495
+ const initialStylesheetHrefs = /* @__PURE__ */ new Set();
495
496
  let pageResponse = await renderTracedPagesPageResponse({
496
497
  assetTags: collectAssetTags({
497
498
  manifest,
@@ -501,7 +502,8 @@ function createPagesPageHandler(opts) {
501
502
  basePath: vinextConfig.basePath,
502
503
  assetPrefix: vinextConfig.assetPrefix,
503
504
  deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID,
504
- crossOrigin: vinextConfig.crossOrigin
505
+ crossOrigin: vinextConfig.crossOrigin,
506
+ initialStylesheetHrefs
505
507
  }),
506
508
  buildId,
507
509
  clearSsrContext() {
@@ -549,6 +551,7 @@ function createPagesPageHandler(opts) {
549
551
  routeUrl: renderRouteUrl,
550
552
  safeJsonStringify,
551
553
  scriptNonce,
554
+ initialStylesheetHrefs,
552
555
  crossOrigin: vinextConfig.crossOrigin,
553
556
  disableOptimizedLoading: vinextConfig.disableOptimizedLoading,
554
557
  statusCode: renderStatusCode,
@@ -112,6 +112,7 @@ type RenderPagesPageResponseOptions = {
112
112
  routeUrl: string;
113
113
  safeJsonStringify: (value: unknown) => string;
114
114
  scriptNonce?: string;
115
+ initialStylesheetHrefs?: ReadonlySet<string>;
115
116
  crossOrigin?: string;
116
117
  disableOptimizedLoading: boolean;
117
118
  statusCode?: number;
@@ -1,3 +1,4 @@
1
+ import { isBotUserAgent } from "../utils/html-limited-bots.js";
1
2
  import { getRequestExecutionContext } from "../shims/request-context.js";
2
3
  import { NEXTJS_CACHE_HEADER, VINEXT_REVALIDATED_CACHE_TAG_HEADER } from "./headers.js";
3
4
  import { reportRequestError } from "./instrumentation.js";
@@ -15,7 +16,6 @@ import { setCacheStateHeaders } from "./cache-headers.js";
15
16
  import { readStreamAsText } from "../utils/text-stream.js";
16
17
  import { loadUserDocumentInitialProps, runDocumentRenderPage } from "./pages-document-initial-props.js";
17
18
  import { callDocumentGetInitialProps } from "./document-initial-head.js";
18
- import { isBotUserAgent } from "../utils/html-limited-bots.js";
19
19
  import { matchesIfNoneMatch } from "./http-conditional.js";
20
20
  import React from "react";
21
21
  //#region src/server/pages-page-response.ts
@@ -189,6 +189,7 @@ async function renderPagesPageResponse(options) {
189
189
  renderToReadableStream: options.renderToReadableStream,
190
190
  renderStylesToString: async (element) => readStreamAsText(await options.renderToReadableStream(element)),
191
191
  scriptNonce: options.scriptNonce,
192
+ initialStylesheetHrefs: options.initialStylesheetHrefs,
192
193
  context: {
193
194
  err: options.err,
194
195
  req: options.documentReqRes?.req,
@@ -208,7 +209,7 @@ async function renderPagesPageResponse(options) {
208
209
  controller.close();
209
210
  } });
210
211
  else {
211
- const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(renderProps)), options.scriptNonce);
212
+ const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(renderProps)), options.scriptNonce, options.initialStylesheetHrefs);
212
213
  bodyStream = await options.renderToReadableStream(pageElement);
213
214
  }
214
215
  if (documentRenderPage.status === "skipped") await callDocumentGetInitialProps(options.DocumentComponent, options.setDocumentInitialHead);
@@ -1,9 +1,9 @@
1
- import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
2
- import { patternToNextFormat } from "../routing/route-validation.js";
3
- import { requestContextFromRequest } from "../config/request-context.js";
4
1
  import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
2
+ import { requestContextFromRequest } from "../config/request-context.js";
5
3
  import { isExternalUrl } from "../utils/external-url.js";
6
4
  import { applyMiddlewareRequestHeaders, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, sanitizeDestination } from "../config/config-matchers.js";
5
+ import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
6
+ import { patternToNextFormat } from "../routing/route-validation.js";
7
7
  import { methodNotAllowedResponse, sanitizeMethodNotAllowedHeaders } from "./http-error-responses.js";
8
8
  import { cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
9
9
  import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
@@ -1,8 +1,9 @@
1
+ import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
+ import { requestContextFromRequest } from "../config/request-context.js";
3
+ import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
1
4
  import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
2
5
  import { hasBasePath, stripBasePath } from "../utils/base-path.js";
3
6
  import { runWithExecutionContext } from "../shims/request-context.js";
4
- import { requestContextFromRequest } from "../config/request-context.js";
5
- import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
6
7
  import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM, VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./headers.js";
7
8
  import { notFoundStaticAssetResponse } from "./http-error-responses.js";
8
9
  import { isOpenRedirectShaped } from "./open-redirect.js";
@@ -11,7 +12,6 @@ import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
11
12
  import { CACHEABILITY_REQUEST_STATE } from "../shims/cacheability-classification.js";
12
13
  import { applyCdnResponseIdentityHeaders, captureCdnResponsePolicyOverrides, reconcileCdnResponseHeadersAfterOuterPolicy, validateCdnRequest } from "./cache-control.js";
13
14
  import { registerLazyDataCacheHandler } from "../shims/cache-handler.js";
14
- import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
15
15
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
16
16
  import { traceFrameworkRequest } from "./request-tracing.js";
17
17
  import { resolveResponseStageCachePolicy } from "./config-headers.js";
@@ -1,5 +1,5 @@
1
- import { getRequestExecutionContext } from "../shims/request-context.js";
2
1
  import { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
+ import { getRequestExecutionContext } from "../shims/request-context.js";
3
3
  import { VINEXT_REVALIDATED_CACHE_TAG_HEADER } from "./headers.js";
4
4
  import { normalizeDomainHostname } from "../utils/domain-locale.js";
5
5
  import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
@@ -1,6 +1,6 @@
1
+ import { isUnknownRecord } from "../utils/record.js";
1
2
  import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
2
3
  import "./headers.js";
3
- import { isUnknownRecord } from "../utils/record.js";
4
4
  //#region src/server/prerender-route-params.ts
5
5
  function isPrerenderRouteParams(value) {
6
6
  if (!isUnknownRecord(value)) return false;
@@ -1,23 +1,23 @@
1
1
  import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { isUnknownRecord } from "../utils/record.js";
3
+ import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
4
+ import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
5
+ import { StaticFileCache, contentTypeForPath, etagFromFilenameHash } from "./static-file-cache.js";
2
6
  import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
3
7
  import { hasBasePath, stripBasePath } from "../utils/base-path.js";
4
- import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
5
8
  import { VINEXT_PRERENDER_RENDER_ERROR_HEADER } from "./headers.js";
6
9
  import { normalizePath } from "./normalize-path.js";
7
10
  import { notFoundResponse } from "./http-error-responses.js";
8
11
  import { isOpenRedirectShaped } from "./open-redirect.js";
9
12
  import { readStaticFileSignal } from "./static-file-signal.js";
10
13
  import { canonicalizeRequestPathname, filterInternalHeaders } from "./request-pipeline.js";
11
- import { isUnknownRecord } from "../utils/record.js";
12
14
  import { parseHttpDate } from "./http-date.js";
13
15
  import { evaluateStaticPreconditions } from "./http-conditional.js";
14
16
  import { buildNextDataNotFoundResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath } from "./pages-data-route.js";
15
- import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
16
17
  import { setPagesClientAssets } from "./pages-client-assets.js";
17
18
  import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
18
19
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, isSafeImageContentType, parseImageParams } from "./image-optimization.js";
19
20
  import { installSocketErrorBackstop } from "./socket-error-backstop.js";
20
- import { StaticFileCache, contentTypeForPath, etagFromFilenameHash } from "./static-file-cache.js";
21
21
  import { collectInlineCssManifest } from "../build/inline-css.js";
22
22
  import { readTrustedRevalidationHostname } from "./revalidation-host.js";
23
23
  import { traceFrameworkRequest } from "./request-tracing.js";
@@ -32,8 +32,8 @@ import { ifRangeAllowsRange, parseByteRange } from "./http-range.js";
32
32
  import { createRequire } from "node:module";
33
33
  import { AsyncLocalStorage } from "node:async_hooks";
34
34
  import fs from "node:fs";
35
- import fsp from "node:fs/promises";
36
35
  import { pathToFileURL } from "node:url";
36
+ import fsp from "node:fs/promises";
37
37
  import { Readable, pipeline } from "node:stream";
38
38
  import zlib from "node:zlib";
39
39
  import { createServer } from "node:http";
@@ -41,7 +41,7 @@ import { createServer } from "node:http";
41
41
  /**
42
42
  * Production server for vinext.
43
43
  *
44
- * Serves the built output from `vinext build`. Handles:
44
+ * Serves the built output from `vite build`. Handles:
45
45
  * - Static asset serving from client build output
46
46
  * - Pages Router: SSR rendering + API route handling
47
47
  * - App Router: RSC/SSR rendering, route handlers, server actions
@@ -315,7 +315,7 @@ const OMIT_METHOD_NOT_ALLOWED_HEADERS = /* @__PURE__ */ new Set([
315
315
  "content-type",
316
316
  "transfer-encoding"
317
317
  ]);
318
- function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
318
+ function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix, crossOrigin) {
319
319
  const metadata = computeClientRuntimeMetadata({
320
320
  clientDir,
321
321
  assetBase,
@@ -324,7 +324,8 @@ function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
324
324
  setPagesClientAssets({
325
325
  appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
326
326
  lazyChunks: metadata.lazyChunks,
327
- dynamicPreloads: metadata.dynamicPreloads
327
+ dynamicPreloads: metadata.dynamicPreloads,
328
+ crossOrigin
328
329
  });
329
330
  }
330
331
  function isNoBodyResponseStatus(status) {
@@ -841,7 +842,7 @@ async function startProdServer(options = {}) {
841
842
  const isAppRouter = fs.existsSync(rscEntryPath);
842
843
  if (!isAppRouter && !fs.existsSync(serverEntryPath)) {
843
844
  console.error(`[vinext] No build output found in ${outDir}`);
844
- console.error("Run `vinext build` first.");
845
+ console.error("Run `vite build` first.");
845
846
  process.exit(1);
846
847
  }
847
848
  if (isAppRouter) return startAppRouterServer({
@@ -980,8 +981,10 @@ function installPagesClientAssets(options) {
980
981
  clientEntry: metadata.clientEntryFile,
981
982
  appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
982
983
  ssrManifest: Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0,
984
+ cssGraph: metadata.cssGraph,
983
985
  lazyChunks: metadata.lazyChunks,
984
- dynamicPreloads: metadata.dynamicPreloads
986
+ dynamicPreloads: metadata.dynamicPreloads,
987
+ crossOrigin: options.crossOrigin
985
988
  });
986
989
  return ssrManifest;
987
990
  }
@@ -1011,6 +1014,7 @@ async function startAppRouterServer(options) {
1011
1014
  const workerEntry = rscModule.default && typeof rscModule.default === "object" ? rscModule.default : void 0;
1012
1015
  const ensureInstrumentation = typeof workerEntry?.__ensureInstrumentation === "function" ? () => workerEntry.__ensureInstrumentation() : typeof rscModule.__ensureInstrumentation === "function" ? () => rscModule.__ensureInstrumentation() : () => void 0;
1013
1016
  const appRouterAssetPrefix = typeof rscModule.__assetPrefix === "string" ? rscModule.__assetPrefix : "";
1017
+ const appRouterCrossOrigin = rscModule.__crossOrigin === "anonymous" || rscModule.__crossOrigin === "use-credentials" ? rscModule.__crossOrigin : "";
1014
1018
  const appRouterBasePath = typeof rscModule.__basePath === "string" ? rscModule.__basePath : "";
1015
1019
  const appRouterInlineCss = rscModule.__inlineCss === true;
1016
1020
  const appRouterHasPagesDir = rscModule.__hasPagesDir === true;
@@ -1031,9 +1035,10 @@ async function startAppRouterServer(options) {
1031
1035
  clientDir,
1032
1036
  assetPrefix: appRouterAssetPrefix,
1033
1037
  assetBase: appAssetBase,
1034
- clientEntryLookup: "pages-client-entry"
1038
+ clientEntryLookup: "pages-client-entry",
1039
+ crossOrigin: appRouterCrossOrigin
1035
1040
  });
1036
- else installClientBuildManifestGlobals(clientDir, appAssetBase, appRouterAssetPrefix);
1041
+ else installClientBuildManifestGlobals(clientDir, appAssetBase, appRouterAssetPrefix, appRouterCrossOrigin);
1037
1042
  const seedPrerenderedRoutes = resolveAppRouterPrerenderSeeder(rscModule);
1038
1043
  const seededRoutes = await runWithServerEntryRequire(rscEntryRequire, () => seedPrerenderedRoutes(serverDir));
1039
1044
  if (seededRoutes > 0) console.log(`[vinext] Seeded ${seededRoutes} pre-rendered route${seededRoutes !== 1 ? "s" : ""} into memory cache`);
@@ -1230,7 +1235,8 @@ async function startPagesRouterServer(options) {
1230
1235
  clientDir,
1231
1236
  assetPrefix,
1232
1237
  assetBase,
1233
- clientEntryLookup: "any-client-entry"
1238
+ clientEntryLookup: "any-client-entry",
1239
+ crossOrigin: vinextConfig?.crossOrigin ?? ""
1234
1240
  });
1235
1241
  const staticCache = await StaticFileCache.create(clientDir);
1236
1242
  const handleRequest = async (req, res) => {
@@ -1,7 +1,7 @@
1
- import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
2
1
  import "../utils/protocol-headers.js";
3
- import { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS } from "./headers.js";
4
2
  import { getUnconsumedMiddlewareRequestHeaders } from "../utils/middleware-request-headers.js";
3
+ import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
4
+ import { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS } from "./headers.js";
5
5
  import { forbiddenResponse, methodNotAllowedResponse, notFoundResponse } from "./http-error-responses.js";
6
6
  import { isOpenRedirectShaped } from "./open-redirect.js";
7
7
  import { createStaticFileSignal } from "./static-file-signal.js";
@@ -1,4 +1,16 @@
1
1
  //#region src/server/rsc-stream-hints.d.ts
2
+ /**
3
+ * Rewrite stylesheet preload hints in a React Flight stream.
4
+ *
5
+ * The rewrite is byte-length preserving, so this transform keeps React's
6
+ * text chunk boundaries instead of re-emitting one chunk per Flight row. Every
7
+ * downstream consumer (the tee, the SSR Flight client, the inline RSC embed,
8
+ * RSC response wrappers) pays a per-chunk cost, and splitting per row
9
+ * multiplied the chunk count roughly 8x on content-heavy pages. Chunks with
10
+ * no stylesheet hint are forwarded as-is without copying; only rows whose
11
+ * tag is `HL` are decoded and inspected. Length-prefixed bodies remain separate
12
+ * so binary bytes do not force adjacent text through the embed's base64 path.
13
+ */
2
14
  export declare function normalizeReactFlightPreloadHints(stream: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;
3
15
  export type RscRawRenderer = (model: unknown, options?: unknown) => ReadableStream<Uint8Array>;
4
16
  export type RscRawPrerenderer = (model: unknown, options?: unknown) => Promise<{