vinext 1.2.1 → 1.3.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 (212) hide show
  1. package/README.md +12 -9
  2. package/dist/build/client-build-config.d.ts +64 -3
  3. package/dist/build/client-build-config.js +131 -4
  4. package/dist/build/client-reference-groups.d.ts +163 -0
  5. package/dist/build/client-reference-groups.js +534 -0
  6. package/dist/build/module-dependency-cache.d.ts +31 -0
  7. package/dist/build/module-dependency-cache.js +51 -1
  8. package/dist/build/next-client-runtime-manifests.d.ts +10 -1
  9. package/dist/build/next-client-runtime-manifests.js +19 -4
  10. package/dist/build/nitro-public-files.d.ts +24 -0
  11. package/dist/build/nitro-public-files.js +60 -0
  12. package/dist/build/pages-client-assets-module.js +1 -1
  13. package/dist/build/prerender-paths.js +5 -2
  14. package/dist/build/server-actions-encryption-key.d.ts +23 -0
  15. package/dist/build/server-actions-encryption-key.js +101 -0
  16. package/dist/build/ssr-manifest.d.ts +3 -0
  17. package/dist/build/ssr-manifest.js +10 -1
  18. package/dist/client/client-rewrite-params.d.ts +9 -0
  19. package/dist/client/client-rewrite-params.js +20 -0
  20. package/dist/client/dev-error-overlay.js +2 -1
  21. package/dist/client/navigation-runtime.d.ts +25 -2
  22. package/dist/client/navigation-runtime.js +42 -11
  23. package/dist/client/vinext-next-data.d.ts +0 -1
  24. package/dist/config/config-matchers.d.ts +15 -40
  25. package/dist/config/config-matchers.js +183 -255
  26. package/dist/config/config-source.d.ts +34 -0
  27. package/dist/config/config-source.js +141 -0
  28. package/dist/config/header-params.d.ts +29 -0
  29. package/dist/config/header-params.js +106 -0
  30. package/dist/config/next-config.d.ts +7 -5
  31. package/dist/config/next-config.js +120 -7
  32. package/dist/entries/app-browser-entry.d.ts +14 -1
  33. package/dist/entries/app-browser-entry.js +26 -36
  34. package/dist/entries/app-rsc-entry.d.ts +2 -0
  35. package/dist/entries/app-rsc-entry.js +92 -57
  36. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  37. package/dist/entries/app-rsc-manifest.js +20 -1
  38. package/dist/entries/app-ssr-entry.d.ts +4 -1
  39. package/dist/entries/app-ssr-entry.js +9 -2
  40. package/dist/entries/pages-client-entry.d.ts +1 -0
  41. package/dist/entries/pages-client-entry.js +6 -6
  42. package/dist/entries/pages-server-entry.js +17 -14
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.js +239 -83
  45. package/dist/init.js +17 -0
  46. package/dist/plugins/optimize-imports.d.ts +25 -2
  47. package/dist/plugins/optimize-imports.js +106 -20
  48. package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
  49. package/dist/plugins/rsc-client-reference-loaders.js +336 -18
  50. package/dist/plugins/use-cache-callable.d.ts +5 -0
  51. package/dist/plugins/use-cache-callable.js +30 -8
  52. package/dist/plugins/worker-image-imports.d.ts +1 -0
  53. package/dist/plugins/worker-image-imports.js +1 -1
  54. package/dist/routing/app-route-graph.d.ts +1 -1
  55. package/dist/routing/browser-route-manifest.d.ts +43 -0
  56. package/dist/routing/browser-route-manifest.js +195 -0
  57. package/dist/routing/hashed-route-patterns.d.ts +4 -0
  58. package/dist/routing/hashed-route-patterns.js +22 -0
  59. package/dist/routing/optimistic-route-trie.d.ts +27 -0
  60. package/dist/routing/optimistic-route-trie.js +102 -0
  61. package/dist/routing/route-validation.d.ts +6 -1
  62. package/dist/routing/route-validation.js +26 -10
  63. package/dist/server/app-action-forwarding.d.ts +8 -0
  64. package/dist/server/app-action-forwarding.js +15 -1
  65. package/dist/server/app-browser-entry.js +147 -60
  66. package/dist/server/app-browser-error.d.ts +3 -1
  67. package/dist/server/app-browser-error.js +7 -2
  68. package/dist/server/app-browser-interception-context.d.ts +2 -2
  69. package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
  70. package/dist/server/app-browser-mpa-navigation.js +6 -5
  71. package/dist/server/app-browser-navigation-controller.d.ts +17 -6
  72. package/dist/server/app-browser-navigation-controller.js +88 -26
  73. package/dist/server/app-browser-state.d.ts +2 -2
  74. package/dist/server/app-browser-visible-commit.d.ts +4 -4
  75. package/dist/server/app-client-reference-preloader.d.ts +23 -0
  76. package/dist/server/app-client-reference-preloader.js +30 -7
  77. package/dist/server/app-fallback-renderer.js +2 -1
  78. package/dist/server/app-middleware.d.ts +6 -0
  79. package/dist/server/app-middleware.js +8 -10
  80. package/dist/server/app-optimistic-routing.d.ts +8 -10
  81. package/dist/server/app-optimistic-routing.js +4 -95
  82. package/dist/server/app-page-boundary-render.js +8 -1
  83. package/dist/server/app-page-cache-render.js +1 -0
  84. package/dist/server/app-page-dispatch.js +2 -0
  85. package/dist/server/app-page-render.js +3 -1
  86. package/dist/server/app-page-rsc-render-status.d.ts +1 -0
  87. package/dist/server/app-page-rsc-render-status.js +1 -0
  88. package/dist/server/app-page-search-params-observation.d.ts +1 -4
  89. package/dist/server/app-page-search-params-observation.js +8 -10
  90. package/dist/server/app-page-stream.d.ts +7 -0
  91. package/dist/server/app-page-stream.js +1 -0
  92. package/dist/server/app-pages-bridge.d.ts +2 -1
  93. package/dist/server/app-pages-bridge.js +11 -7
  94. package/dist/server/app-prerender-static-params.js +3 -2
  95. package/dist/server/app-render-dependency.js +42 -2
  96. package/dist/server/app-request-stage-independent-entry.js +2 -2
  97. package/dist/server/app-response-stage-entry.js +3 -3
  98. package/dist/server/app-route-handler-dispatch.js +3 -1
  99. package/dist/server/app-route-handler-execution.d.ts +2 -0
  100. package/dist/server/app-route-handler-execution.js +9 -2
  101. package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
  102. package/dist/server/app-route-handler-middleware-context.js +3 -3
  103. package/dist/server/app-route-handler-response.d.ts +2 -1
  104. package/dist/server/app-route-handler-response.js +2 -2
  105. package/dist/server/app-route-handler-runtime.d.ts +2 -0
  106. package/dist/server/app-route-handler-runtime.js +20 -3
  107. package/dist/server/app-route-module-loader.js +7 -6
  108. package/dist/server/app-route-tree.d.ts +20 -0
  109. package/dist/server/app-route-tree.js +18 -0
  110. package/dist/server/app-router-entry.js +2 -2
  111. package/dist/server/app-rsc-combined-handler.js +8 -1
  112. package/dist/server/app-rsc-errors.d.ts +7 -0
  113. package/dist/server/app-rsc-errors.js +9 -2
  114. package/dist/server/app-rsc-handler.d.ts +4 -1
  115. package/dist/server/app-rsc-handler.js +146 -130
  116. package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
  117. package/dist/server/app-rsc-response-finalizer.js +4 -1
  118. package/dist/server/app-rsc-response-stage.js +3 -1
  119. package/dist/server/app-rsc-route-matching.d.ts +1 -0
  120. package/dist/server/app-rsc-route-matching.js +1 -1
  121. package/dist/server/app-server-action-execution.d.ts +23 -6
  122. package/dist/server/app-server-action-execution.js +50 -56
  123. package/dist/server/app-ssr-entry.d.ts +6 -0
  124. package/dist/server/app-ssr-entry.js +16 -7
  125. package/dist/server/app-ssr-stream.d.ts +7 -0
  126. package/dist/server/app-ssr-stream.js +13 -1
  127. package/dist/server/config-headers.js +12 -3
  128. package/dist/server/isolate-shared-promise.d.ts +10 -0
  129. package/dist/server/isolate-shared-promise.js +33 -0
  130. package/dist/server/isr-cache.js +3 -2
  131. package/dist/server/middleware-matcher-pattern.d.ts +0 -1
  132. package/dist/server/middleware-matcher-pattern.js +11 -140
  133. package/dist/server/middleware-matcher.js +5 -6
  134. package/dist/server/middleware-response-headers.d.ts +31 -0
  135. package/dist/server/middleware-response-headers.js +57 -1
  136. package/dist/server/middleware-runtime.js +26 -13
  137. package/dist/server/navigation-planner.d.ts +2 -2
  138. package/dist/server/nitro-public-files-plugin.d.ts +38 -0
  139. package/dist/server/nitro-public-files-plugin.js +106 -0
  140. package/dist/server/nitro-public-files.d.ts +21 -0
  141. package/dist/server/nitro-public-files.js +39 -0
  142. package/dist/server/pages-asset-tags.d.ts +5 -0
  143. package/dist/server/pages-asset-tags.js +9 -2
  144. package/dist/server/pages-client-assets.d.ts +4 -1
  145. package/dist/server/pages-i18n.d.ts +18 -0
  146. package/dist/server/pages-i18n.js +18 -2
  147. package/dist/server/pages-node-compat.d.ts +5 -3
  148. package/dist/server/pages-node-compat.js +35 -16
  149. package/dist/server/pages-request-pipeline.d.ts +6 -1
  150. package/dist/server/pages-request-pipeline.js +31 -35
  151. package/dist/server/pages-request-stage-entry.js +16 -6
  152. package/dist/server/pages-response-stage-entry.js +1 -1
  153. package/dist/server/pages-revalidate.js +1 -0
  154. package/dist/server/pages-router-entry.js +1 -1
  155. package/dist/server/prod-server.d.ts +2 -2
  156. package/dist/server/prod-server.js +71 -33
  157. package/dist/server/proxy-trust.d.ts +6 -0
  158. package/dist/server/proxy-trust.js +12 -6
  159. package/dist/server/request-pipeline.d.ts +5 -0
  160. package/dist/server/request-pipeline.js +12 -1
  161. package/dist/server/server-reference-loader.js +10 -1
  162. package/dist/server/static-file-cache.js +15 -3
  163. package/dist/server/worker-utils.js +1 -1
  164. package/dist/shims/cache-handler.js +3 -2
  165. package/dist/shims/cache-request-state.d.ts +40 -3
  166. package/dist/shims/cache-request-state.js +70 -5
  167. package/dist/shims/cache-runtime.js +47 -19
  168. package/dist/shims/cache.d.ts +2 -2
  169. package/dist/shims/cache.js +17 -8
  170. package/dist/shims/cdn-purge-routes.d.ts +24 -0
  171. package/dist/shims/cdn-purge-routes.js +77 -0
  172. package/dist/shims/dynamic.js +17 -4
  173. package/dist/shims/form.js +8 -3
  174. package/dist/shims/image-props.d.ts +93 -0
  175. package/dist/shims/image-props.js +323 -0
  176. package/dist/shims/image.d.ts +4 -18
  177. package/dist/shims/image.js +4 -319
  178. package/dist/shims/internal/headers-state.d.ts +7 -0
  179. package/dist/shims/internal/headers-state.js +14 -2
  180. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
  181. package/dist/shims/internal/hybrid-client-route-owner-direct.js +31 -14
  182. package/dist/shims/internal/hybrid-client-route-owner.js +8 -8
  183. package/dist/shims/link.js +5 -3
  184. package/dist/shims/navigation.d.ts +1 -1
  185. package/dist/shims/navigation.js +17 -5
  186. package/dist/shims/og.js +35 -10
  187. package/dist/shims/request-context.d.ts +13 -0
  188. package/dist/shims/router.js +19 -40
  189. package/dist/shims/server.d.ts +31 -4
  190. package/dist/shims/server.js +58 -10
  191. package/dist/shims/thenable-params.d.ts +6 -1
  192. package/dist/shims/thenable-params.js +11 -2
  193. package/dist/shims/unified-request-context.d.ts +5 -0
  194. package/dist/shims/unified-request-context.js +2 -0
  195. package/dist/utils/asset-prefix.d.ts +7 -0
  196. package/dist/utils/asset-prefix.js +10 -1
  197. package/dist/utils/client-build-manifest.js +12 -5
  198. package/dist/utils/client-runtime-metadata.d.ts +1 -0
  199. package/dist/utils/client-runtime-metadata.js +15 -2
  200. package/dist/utils/lazy-chunks.d.ts +4 -0
  201. package/dist/utils/manifest-paths.d.ts +14 -0
  202. package/dist/utils/manifest-paths.js +22 -1
  203. package/dist/utils/path-to-regexp.d.ts +21 -0
  204. package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
  205. package/dist/utils/plugin-react-version.d.ts +15 -0
  206. package/dist/utils/plugin-react-version.js +64 -0
  207. package/dist/utils/public-routes.d.ts +2 -0
  208. package/dist/utils/public-routes.js +18 -7
  209. package/package.json +1 -1
  210. package/dist/server/middleware-path-to-regexp.d.ts +0 -13
  211. package/dist/utils/regex-safety.d.ts +0 -17
  212. package/dist/utils/regex-safety.js +0 -789
@@ -1,7 +1,7 @@
1
1
  import { isBotUserAgent } from "../utils/html-limited-bots.js";
2
2
  import { isExternalUrl } from "../utils/external-url.js";
3
3
  import { stripBasePath } from "../utils/base-path.js";
4
- import { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER } from "../server/app-rsc-vary.js";
4
+ import { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER } from "../server/app-rsc-vary.js";
5
5
  import { NEXT_ROUTER_STALE_TIME_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_RSC_COMPLETION_METADATA_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER, VINEXT_STALE_TIME_PENDING_HEADER } from "../server/headers.js";
6
6
  import { assertSafeNavigationUrl } from "./url-safety.js";
7
7
  import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "../server/app-rsc-render-mode.js";
@@ -19,7 +19,7 @@ import { clearAppNavigationFailureTarget, stageAppNavigationFailureTarget } from
19
19
  import { beginAppRouterScrollIntent, clearAppRouterScrollIntent, consumeAppRouterScrollIntent, getPendingAppRouterScrollIntent, isLatestAppRouterScrollIntent } from "./app-router-scroll-state.js";
20
20
  import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, formatRscRequestPath, parseRscRequestPath, stripRscCacheBustingSearchParam, stripRscSuffix } from "../server/app-rsc-cache-busting.js";
21
21
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
22
- import { getNavigationRuntime, hasAppNavigationRuntime } from "../client/navigation-runtime.js";
22
+ import { getNavigationRuntime, hasAppNavigationRuntime, loadNavigationRuntimeRouteManifest } from "../client/navigation-runtime.js";
23
23
  import { UnrecognizedActionError, unstable_isUnrecognizedActionError } from "./unrecognized-action-error.js";
24
24
  import { PUBLIC_INITIAL_BFCACHE_ID } from "../server/app-bfcache-id.js";
25
25
  import { resolveManifestNavigationInterceptionContext } from "../server/app-browser-interception-context.js";
@@ -117,7 +117,7 @@ function getCurrentInterceptionContext() {
117
117
  if (isServer) return null;
118
118
  return stripBasePath(window.location.pathname, __basePath);
119
119
  }
120
- function getPrefetchInterceptionContext(targetHref) {
120
+ function getPrefetchInterceptionContext(targetHref, currentPathname) {
121
121
  if (isServer) return null;
122
122
  let targetUrl;
123
123
  try {
@@ -127,7 +127,7 @@ function getPrefetchInterceptionContext(targetHref) {
127
127
  }
128
128
  return resolveManifestNavigationInterceptionContext({
129
129
  basePath: __basePath,
130
- currentPathname: window.location.pathname,
130
+ currentPathname: currentPathname ?? window.location.pathname,
131
131
  routeManifest: getNavigationRuntime()?.bootstrap.routeManifest ?? null,
132
132
  targetPathname: targetUrl.pathname
133
133
  });
@@ -1465,6 +1465,11 @@ async function navigateClientSide(href, mode, scroll, programmaticTransition = f
1465
1465
  const fullHref = toCanonicalBrowserNavigationHref(normalizedHref, window.location.href, __basePath, __trailingSlash);
1466
1466
  notifyAppRouterTransitionStart(fullHref, mode);
1467
1467
  if (mode === "push") saveScrollPosition();
1468
+ const mpaNavigate = getNavigationRuntime()?.functions.navigateExternal;
1469
+ if (mpaNavigate) {
1470
+ await mpaNavigate(fullHref, mode);
1471
+ return;
1472
+ }
1468
1473
  hardNavigateTo(fullHref, mode);
1469
1474
  await new Promise(() => {});
1470
1475
  return;
@@ -1607,7 +1612,8 @@ const _appRouter = {
1607
1612
  if (prefetchHref == null) return;
1608
1613
  const fullHref = toAppPrefetchDestination(prefetchHref);
1609
1614
  if (fullHref === null) return;
1610
- const interceptionContext = getPrefetchInterceptionContext(fullHref);
1615
+ const currentPathname = window.location.pathname;
1616
+ let interceptionContext = getPrefetchInterceptionContext(fullHref, currentPathname);
1611
1617
  const mountedSlotsHeader = getMountedSlotsHeader();
1612
1618
  const headers = createAppPrefetchRequestHeaders({
1613
1619
  fetchPriority: "low",
@@ -1616,6 +1622,12 @@ const _appRouter = {
1616
1622
  });
1617
1623
  const setup = beginPrefetchSetup(fullHref);
1618
1624
  (async () => {
1625
+ const routeManifestLoad = loadNavigationRuntimeRouteManifest();
1626
+ if (routeManifestLoad !== null) {
1627
+ if (!await routeManifestLoad || setup.cancelled) return;
1628
+ interceptionContext = getPrefetchInterceptionContext(fullHref, currentPathname);
1629
+ if (interceptionContext !== null) headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, interceptionContext);
1630
+ }
1619
1631
  if (HAS_CLIENT_REWRITES) await preloadHybridClientRouteOwner();
1620
1632
  const hybridOwner = resolveHybridClientRouteOwner(fullHref);
1621
1633
  if (hybridOwner === "pages" || hybridOwner === "document") return;
package/dist/shims/og.js CHANGED
@@ -1,4 +1,6 @@
1
+ import { shareIsolatePromise } from "../server/isolate-shared-promise.js";
1
2
  //#region src/shims/og.tsx
3
+ let vercelOg;
2
4
  const CACHE_HEADERS = {
3
5
  noCache: "no-cache, no-store",
4
6
  revalidate: "public, max-age=0, must-revalidate"
@@ -13,21 +15,43 @@ const CACHE_HEADERS = {
13
15
  var ImageResponse = class extends Response {
14
16
  static displayName = "ImageResponse";
15
17
  constructor(element, options) {
18
+ let startRendering;
19
+ const constructed = new Promise((resolve) => {
20
+ startRendering = resolve;
21
+ });
16
22
  const readable = new ReadableStream({ async start(controller) {
17
- const { ImageResponse: VercelImageResponse } = await import("@vercel/og");
18
- const imageResponse = new VercelImageResponse(element, options);
19
- if (!imageResponse.body) {
20
- controller.close();
21
- return;
23
+ await constructed;
24
+ if (options === null) throw new TypeError("Cannot read properties of null (reading 'headers')");
25
+ let settleInitialization;
26
+ if (!vercelOg) {
27
+ const loading = import("@vercel/og");
28
+ vercelOg = loading;
29
+ loading.catch(() => {
30
+ if (vercelOg === loading) vercelOg = void 0;
31
+ });
32
+ shareIsolatePromise(new Promise((resolve) => {
33
+ settleInitialization = resolve;
34
+ }));
22
35
  }
23
- const reader = imageResponse.body.getReader();
24
- while (true) {
25
- const { done, value } = await reader.read();
26
- if (done) {
36
+ try {
37
+ const { ImageResponse: VercelImageResponse } = await vercelOg;
38
+ const imageResponse = new VercelImageResponse(element, options);
39
+ if (!imageResponse.body) {
27
40
  controller.close();
28
41
  return;
29
42
  }
30
- controller.enqueue(value);
43
+ const reader = imageResponse.body.getReader();
44
+ while (true) {
45
+ const { done, value } = await reader.read();
46
+ settleInitialization?.();
47
+ if (done) {
48
+ controller.close();
49
+ return;
50
+ }
51
+ controller.enqueue(value);
52
+ }
53
+ } finally {
54
+ settleInitialization?.();
31
55
  }
32
56
  } });
33
57
  const headers = new Headers({
@@ -42,6 +66,7 @@ var ImageResponse = class extends Response {
42
66
  status: options?.status,
43
67
  statusText: options?.statusText
44
68
  });
69
+ startRendering();
45
70
  }
46
71
  };
47
72
  //#endregion
@@ -38,6 +38,19 @@ export type ExecutionContextLike = {
38
38
  cache?: unknown;
39
39
  /** Server-owned origin for credential-bearing Pages revalidation loopbacks. */
40
40
  trustedRevalidateOrigin?: string;
41
+ /**
42
+ * Node production server signal that aborts when the client disconnects
43
+ * before the response finishes. Its Request only follows this signal, so the
44
+ * App RSC handler takes it from here (UnifiedRequestContext.requestSignal).
45
+ */
46
+ requestSignal?: AbortSignal;
47
+ /**
48
+ * Server-owned origin middleware runs against. Set by the Node production
49
+ * server, whose request URL comes from the client's Host header. Without it
50
+ * middleware uses the request URL's origin, which Workers can trust because
51
+ * the platform routes by hostname.
52
+ */
53
+ middlewareOrigin?: string;
41
54
  /** Worker-owned in-process dispatcher for authenticated Pages revalidation. */
42
55
  dispatchPagesRevalidate?: (request: Request) => Promise<Response>;
43
56
  /** Marks a request currently executing through the internal revalidation dispatcher. */
@@ -1,4 +1,5 @@
1
1
  import { isUnknownRecord } from "../utils/record.js";
2
+ import { execConfigSource } from "../config/config-source.js";
2
3
  import { parseCookieHeader } from "../utils/parse-cookie.js";
3
4
  import { isExternalUrl } from "../utils/external-url.js";
4
5
  import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
@@ -28,6 +29,7 @@ import { formatUrlObject, formatUrlObjectWithValidation } from "./internal/forma
28
29
  import { normalizeRouterHref, resolvePagesRouterHref } from "./internal/normalize-router-href.js";
29
30
  import { getCurrentRoutePathnameForWarning } from "./internal/route-pattern-for-warning.js";
30
31
  import { getCurrentBrowserLocale } from "./client-locale.js";
32
+ import { clientRewriteAppendsParams } from "../client/client-rewrite-params.js";
31
33
  import { Component, Fragment, StrictMode, createElement, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
32
34
  //#region src/shims/router.ts
33
35
  /**
@@ -975,7 +977,8 @@ function hasClientRedirectRules() {
975
977
  }
976
978
  function hasClientAppRouteManifest() {
977
979
  const routes = window.__VINEXT_LINK_PREFETCH_ROUTES__;
978
- return Array.isArray(routes) && routes.length > 0;
980
+ const routeHandlers = window.__VINEXT_APP_ROUTE_HANDLERS__;
981
+ return Array.isArray(routes) && routes.length > 0 || Array.isArray(routeHandlers) && routeHandlers.length > 0;
979
982
  }
980
983
  function getClientConfigRouteContext(href) {
981
984
  let parsed;
@@ -1029,40 +1032,14 @@ function shouldEvaluateClientConfigRule(ruleBasePath, state) {
1029
1032
  if (!state.basePath) return true;
1030
1033
  return ruleBasePath === false ? !state.hadBasePath : state.hadBasePath;
1031
1034
  }
1032
- function matchSimpleClientConfigPattern(pathname, source) {
1033
- if (source.includes("(") || source.includes("\\") || /:[\w-]+[*+][^/]/.test(source)) return;
1034
- const sourceParts = removeTrailingSlash(source).split("/");
1035
- const pathParts = removeTrailingSlash(pathname).split("/");
1036
- const params = {};
1037
- let pathIndex = 0;
1038
- for (let sourceIndex = 0; sourceIndex < sourceParts.length; sourceIndex++) {
1039
- const sourcePart = sourceParts[sourceIndex];
1040
- const pathPart = pathParts[pathIndex];
1041
- if (sourcePart.startsWith(":")) {
1042
- const catchAll = sourcePart.match(/^:([\w-]+)([*+])$/);
1043
- if (catchAll) {
1044
- const rest = pathParts.slice(pathIndex).join("/");
1045
- if (catchAll[2] === "+" && rest === "") return null;
1046
- params[catchAll[1]] = rest;
1047
- return sourceIndex === sourceParts.length - 1 ? params : void 0;
1048
- }
1049
- if (pathPart === void 0) return null;
1050
- params[sourcePart.slice(1)] = pathPart;
1051
- pathIndex++;
1052
- continue;
1053
- }
1054
- if (pathPart !== sourcePart) return null;
1055
- pathIndex++;
1035
+ function isSerializedRewriteDestination(destination) {
1036
+ if (!destination.startsWith("/") || destination.startsWith("//")) return true;
1037
+ try {
1038
+ const parsed = new URL(destination, "http://n");
1039
+ return parsed.pathname + parsed.search + parsed.hash === destination;
1040
+ } catch {
1041
+ return false;
1056
1042
  }
1057
- return pathIndex === pathParts.length ? params : null;
1058
- }
1059
- function simpleClientConfigSourceCouldMatch(pathname, source) {
1060
- const wildcardIndex = source.search(/[:(\\*+?]/);
1061
- const literalPrefix = wildcardIndex === -1 ? source : source.slice(0, wildcardIndex);
1062
- const normalizedPrefix = removeTrailingSlash(literalPrefix);
1063
- if (!normalizedPrefix || normalizedPrefix === "/") return true;
1064
- const normalizedPathname = removeTrailingSlash(pathname);
1065
- return normalizedPathname === normalizedPrefix || normalizedPathname.startsWith(`${normalizedPrefix}/`);
1066
1043
  }
1067
1044
  function isExternalClientConfigUrl(url) {
1068
1045
  return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith("//");
@@ -1074,8 +1051,7 @@ function clientConfigRedirectCouldMatch(href) {
1074
1051
  if (!routeContext) return false;
1075
1052
  for (const redirect of redirects) {
1076
1053
  if (!shouldEvaluateClientConfigRule(redirect.basePath, routeContext.basePathState)) continue;
1077
- if (!simpleClientConfigSourceCouldMatch(routeContext.pathname, redirect.source)) continue;
1078
- if (matchSimpleClientConfigPattern(routeContext.pathname, redirect.source) !== null) return true;
1054
+ if (execConfigSource(routeContext.pathname, redirect.source) !== null) return true;
1079
1055
  }
1080
1056
  return false;
1081
1057
  }
@@ -1088,12 +1064,15 @@ function resolveClientConfigRewriteSync(href) {
1088
1064
  const routeContext = getClientConfigRouteContext(currentHref);
1089
1065
  if (!routeContext) return null;
1090
1066
  if (!shouldEvaluateClientConfigRule(rewrite.basePath, routeContext.basePathState)) continue;
1091
- if (!simpleClientConfigSourceCouldMatch(routeContext.pathname, rewrite.source)) continue;
1067
+ const match = execConfigSource(routeContext.pathname, rewrite.source);
1068
+ if (match === null) continue;
1092
1069
  if (rewrite.has || rewrite.requiresServerEvaluation) return void 0;
1093
- const params = matchSimpleClientConfigPattern(routeContext.pathname, rewrite.source);
1094
- if (params === void 0) return void 0;
1095
- if (params === null) continue;
1070
+ if (match.unmatched.length > 0) return void 0;
1071
+ const { params } = match;
1072
+ if (!isSerializedRewriteDestination(rewrite.destination)) return void 0;
1073
+ if (clientRewriteAppendsParams(rewrite.destination, params)) return void 0;
1096
1074
  const rewritten = substituteDestinationParams(rewrite.destination, params, "rewrite");
1075
+ if (!/^(?:https?:\/\/|\/(?![\\/\t\n\r]))/.test(rewritten)) return void 0;
1097
1076
  if (isExternalClientConfigUrl(rewritten)) return { kind: "document" };
1098
1077
  currentHref = mergeRewriteQuery(currentHref, rewritten);
1099
1078
  matched = true;
@@ -28,6 +28,11 @@ export type RequestInit = globalThis.RequestInit & {
28
28
  trailingSlash?: boolean;
29
29
  skipTrailingSlashRedirect?: boolean;
30
30
  };
31
+ /**
32
+ * vinext-internal: the host the request was made to, when the URL carries
33
+ * the server's own origin instead. It picks the i18n domain locale.
34
+ */
35
+ requestHost?: string;
31
36
  signal?: AbortSignal;
32
37
  duplex?: "half";
33
38
  };
@@ -100,6 +105,11 @@ export declare class NextResponse<_Body = unknown> extends Response {
100
105
  }
101
106
  export type NextURLConfig = {
102
107
  basePath?: string;
108
+ /**
109
+ * Request headers. As in Next.js's `getHostname`, a Host header decides the
110
+ * domain locale before the URL's own hostname.
111
+ */
112
+ headers?: Record<string, string | string[] | undefined>;
103
113
  nextConfig?: {
104
114
  i18n?: {
105
115
  locales: string[];
@@ -146,6 +156,12 @@ export declare class NextURL {
146
156
  private _locales;
147
157
  private _domains;
148
158
  private _domainLocale;
159
+ private _headers;
160
+ private _buildId;
161
+ /** First page segment of a raw data pathname, where its locale sits. */
162
+ private _dataPathSegment;
163
+ /** The locale parsed from that segment, if it is one. */
164
+ private _dataPathLocale;
149
165
  constructor(input: string | URL, base?: string | URL, config?: NextURLConfig);
150
166
  /**
151
167
  * With `skipTrailingSlashRedirect`, take the slash from the parsed pathname
@@ -164,9 +180,20 @@ export declare class NextURL {
164
180
  * middleware-base-path's "should execute from absolute paths" case.
165
181
  */
166
182
  private _stripBasePath;
183
+ /**
184
+ * Take the build ID from a raw `/_next/data/<buildId>/….json` pathname, as
185
+ * getNextPathnameInfo does. Middleware only sees one when proxy URL
186
+ * normalization is skipped; the pathname is left as is.
187
+ */
188
+ private _parseBuildId;
167
189
  /** Extract locale from pathname, stripping it from the internal URL. */
168
190
  private _detectPathnameLocale;
169
191
  private _analyzeI18n;
192
+ /**
193
+ * A raw data pathname keeps its locale segment, replaced by the current
194
+ * locale once it has been changed.
195
+ */
196
+ private _formatDataPathLocale;
170
197
  /**
171
198
  * Reconstruct the full pathname with basePath + locale prefix and apply
172
199
  * the configured trailingSlash policy.
@@ -214,10 +241,10 @@ export declare class NextURL {
214
241
  toString(): string;
215
242
  toJSON(): string;
216
243
  /**
217
- * The build ID of the Next.js application.
218
- * Set from `generateBuildId` in next.config.js, or a random UUID if not configured.
219
- * Can be used in middleware to detect deployment skew between client and server.
220
- * Matches the Next.js API: `request.nextUrl.buildId`.
244
+ * Matches the Next.js API: `request.nextUrl.buildId`. Next.js derives it
245
+ * from the URL (only `/_next/data/<buildId>/…` paths carry one) and never
246
+ * from the deployment, so a Client Component reads the same value on the
247
+ * server and in the browser.
221
248
  */
222
249
  get buildId(): string | undefined;
223
250
  }
@@ -117,7 +117,7 @@ var NextRequest = class extends Request {
117
117
  _cookies;
118
118
  constructor(input, init) {
119
119
  validateURL(typeof input !== "string" && "url" in input ? input.url : String(input));
120
- const { nextConfig: _nextConfig, ...plainInit } = init ?? {};
120
+ const { nextConfig: _nextConfig, requestHost, ...plainInit } = init ?? {};
121
121
  const requestInit = init instanceof Request ? requestInitFromRequest(init) : plainInit;
122
122
  if (input instanceof Request) {
123
123
  super(input, initWithoutInputBody(input, requestInit));
@@ -143,6 +143,7 @@ var NextRequest = class extends Request {
143
143
  } : void 0;
144
144
  const urlConfig = _nextConfig ? {
145
145
  basePath: _nextConfig.basePath,
146
+ headers: requestHost === void 0 ? void 0 : { host: requestHost },
146
147
  nextConfig: {
147
148
  i18n,
148
149
  trailingSlash: _nextConfig.trailingSlash,
@@ -293,6 +294,9 @@ var NextResponse = class NextResponse extends Response {
293
294
  });
294
295
  }
295
296
  };
297
+ function isRawDataPathname(pathname) {
298
+ return pathname.startsWith("/_next/data/") && pathname.endsWith(".json");
299
+ }
296
300
  var NextURL = class NextURL {
297
301
  /** Internal URL stores the pathname WITHOUT basePath or locale prefix. */
298
302
  _url;
@@ -312,8 +316,15 @@ var NextURL = class NextURL {
312
316
  _locales;
313
317
  _domains;
314
318
  _domainLocale;
319
+ _headers;
320
+ _buildId;
321
+ /** First page segment of a raw data pathname, where its locale sits. */
322
+ _dataPathSegment;
323
+ /** The locale parsed from that segment, if it is one. */
324
+ _dataPathLocale;
315
325
  constructor(input, base, config) {
316
326
  this._url = new URL(input.toString(), base);
327
+ this._headers = config?.headers;
317
328
  this._configBasePath = config?.basePath ?? "";
318
329
  this._basePath = this._configBasePath;
319
330
  this._configTrailingSlash = config?.nextConfig?.trailingSlash ?? false;
@@ -321,6 +332,7 @@ var NextURL = class NextURL {
321
332
  this._trailingSlash = this._configTrailingSlash;
322
333
  this._analyzeTrailingSlash();
323
334
  this._stripBasePath();
335
+ this._parseBuildId();
324
336
  const i18n = config?.nextConfig?.i18n;
325
337
  if (i18n) {
326
338
  this._locales = [...i18n.locales];
@@ -361,6 +373,22 @@ var NextURL = class NextURL {
361
373
  this._basePath = this._configBasePath;
362
374
  this._url.pathname = stripBasePath(this._url.pathname, this._configBasePath);
363
375
  }
376
+ /**
377
+ * Take the build ID from a raw `/_next/data/<buildId>/….json` pathname, as
378
+ * getNextPathnameInfo does. Middleware only sees one when proxy URL
379
+ * normalization is skipped; the pathname is left as is.
380
+ */
381
+ _parseBuildId() {
382
+ const { pathname } = this._url;
383
+ if (!isRawDataPathname(pathname)) {
384
+ this._buildId = void 0;
385
+ this._dataPathSegment = void 0;
386
+ return;
387
+ }
388
+ const [buildId, pageSegment] = pathname.slice(12, -5).split("/");
389
+ this._buildId = buildId;
390
+ this._dataPathSegment = pageSegment === "index" ? void 0 : pageSegment;
391
+ }
364
392
  /** Extract locale from pathname, stripping it from the internal URL. */
365
393
  _detectPathnameLocale(locales) {
366
394
  const segments = this._url.pathname.split("/");
@@ -372,11 +400,29 @@ var NextURL = class NextURL {
372
400
  _analyzeI18n() {
373
401
  if (!this._locales || !this._configDefaultLocale) return;
374
402
  const detectedLocale = this._detectPathnameLocale(this._locales);
403
+ this._dataPathLocale = void 0;
404
+ if (!detectedLocale && this._buildId && this._dataPathSegment) {
405
+ const candidate = this._dataPathSegment.toLowerCase();
406
+ this._dataPathLocale = this._locales.find((l) => l.toLowerCase() === candidate);
407
+ }
375
408
  const detectedLocaleLower = detectedLocale?.toLowerCase();
376
- const hostname = this._url.hostname.toLowerCase();
409
+ const hostHeader = this._headers?.host;
410
+ const hostname = (typeof hostHeader === "string" && hostHeader ? hostHeader.split(":", 1)[0] : this._url.hostname).toLowerCase();
377
411
  this._domainLocale = this._domains?.find((domain) => domain.domain.split(":", 1)[0].toLowerCase() === hostname || detectedLocaleLower === domain.defaultLocale.toLowerCase() || domain.locales?.some((locale) => locale.toLowerCase() === detectedLocaleLower));
378
412
  this._defaultLocale = this._domainLocale?.defaultLocale ?? this._configDefaultLocale;
379
- this._locale = detectedLocale ?? this._defaultLocale;
413
+ this._locale = detectedLocale ?? this._dataPathLocale ?? this._defaultLocale;
414
+ }
415
+ /**
416
+ * A raw data pathname keeps its locale segment, replaced by the current
417
+ * locale once it has been changed.
418
+ */
419
+ _formatDataPathLocale(pathname) {
420
+ if (!this._dataPathLocale || this._locale === this._dataPathLocale) return pathname;
421
+ if (!this._locale || !isRawDataPathname(pathname)) return pathname;
422
+ const segments = pathname.slice(12, -5).split("/");
423
+ if (segments[1]?.toLowerCase() !== this._dataPathLocale.toLowerCase()) return pathname;
424
+ segments[1] = this._locale;
425
+ return "/_next/data/" + segments.join("/") + ".json";
380
426
  }
381
427
  /**
382
428
  * Reconstruct the full pathname with basePath + locale prefix and apply
@@ -385,9 +431,9 @@ var NextURL = class NextURL {
385
431
  */
386
432
  _formatPathname() {
387
433
  let prefix = this._basePath;
388
- const inner = this._url.pathname;
434
+ const inner = this._formatDataPathLocale(this._url.pathname);
389
435
  const innerLower = inner.toLowerCase();
390
- if (!(innerLower === "/api" || innerLower.startsWith("/api/")) && this._locale && this._locale !== this._defaultLocale) prefix += "/" + this._locale;
436
+ if (!(innerLower === "/api" || innerLower.startsWith("/api/")) && !isRawDataPathname(inner) && this._locale && this._locale !== this._defaultLocale) prefix += "/" + this._locale;
391
437
  const composed = !prefix ? inner : inner === "/" ? prefix : prefix + inner;
392
438
  return this._applyTrailingSlash(composed);
393
439
  }
@@ -415,6 +461,7 @@ var NextURL = class NextURL {
415
461
  this._url.href = value;
416
462
  this._analyzeTrailingSlash();
417
463
  this._stripBasePath();
464
+ this._parseBuildId();
418
465
  this._analyzeI18n();
419
466
  }
420
467
  get origin() {
@@ -526,6 +573,7 @@ var NextURL = class NextURL {
526
573
  } else if (this._trailingSlash) nextConfig.trailingSlash = true;
527
574
  const config = {
528
575
  basePath: this._configBasePath,
576
+ headers: this._headers,
529
577
  nextConfig: Object.keys(nextConfig).length > 0 ? nextConfig : void 0
530
578
  };
531
579
  return new NextURL(this.href, void 0, config);
@@ -537,13 +585,13 @@ var NextURL = class NextURL {
537
585
  return this.href;
538
586
  }
539
587
  /**
540
- * The build ID of the Next.js application.
541
- * Set from `generateBuildId` in next.config.js, or a random UUID if not configured.
542
- * Can be used in middleware to detect deployment skew between client and server.
543
- * Matches the Next.js API: `request.nextUrl.buildId`.
588
+ * Matches the Next.js API: `request.nextUrl.buildId`. Next.js derives it
589
+ * from the URL (only `/_next/data/<buildId>/…` paths carry one) and never
590
+ * from the deployment, so a Client Component reads the same value on the
591
+ * server and in the browser.
544
592
  */
545
593
  get buildId() {
546
- return process.env.__VINEXT_BUILD_ID ?? void 0;
594
+ return this._buildId;
547
595
  }
548
596
  };
549
597
  var RequestCookies = class {
@@ -3,7 +3,12 @@ import { WellKnownProperty } from "./internal/thenable-well-known-properties.js"
3
3
  export type ThenableParams<T extends Record<string, unknown>> = Promise<T> & Omit<T, WellKnownProperty>;
4
4
  export type ThenableParamsObserver = Readonly<{
5
5
  observeParamAccess: (keys: readonly string[]) => void;
6
- observeReactPromiseStatus?: boolean;
6
+ /**
7
+ * Runs when `then` is read, and when `catch` or `finally` is called (they
8
+ * read `then` on a native promise). Throwing here fails the read itself
9
+ * before React counts any pending work, as Next.js does.
10
+ */
11
+ observeThenRead?: () => void;
7
12
  }>;
8
13
  /** Serialize backing values without reading a framework fallback-key proxy. */
9
14
  export declare function getFallbackParamsSnapshot(value: unknown): Promise<Record<string, unknown>> | undefined;
@@ -117,14 +117,20 @@ function createThenableParams(obj, observer, fallbackShellState) {
117
117
  const params = createThenableParamsProxy(promise, {
118
118
  get(target, prop, receiver) {
119
119
  if (isPromiseContinuation(prop)) {
120
+ if (prop === "then") observer?.observeThenRead?.();
120
121
  const value = Reflect.get(target, prop, receiver);
121
122
  if (typeof value !== "function") return value;
122
123
  return (...args) => {
123
- if (!fallbackParamNames) observeAllParamKeys(observer, plain);
124
+ if (prop !== "then") observer?.observeThenRead?.();
125
+ if (!fallbackParamNames) try {
126
+ observeAllParamKeys(observer, plain);
127
+ } catch (error) {
128
+ return Reflect.apply(value, Promise.reject(error), args);
129
+ }
124
130
  return Reflect.apply(value, target, args);
125
131
  };
126
132
  }
127
- if (prop === "status" && observer?.observeReactPromiseStatus === true) observeAllParamKeys(observer, plain);
133
+ if (prop === "reason" && Object.hasOwn(target, prop)) return Reflect.get(target, prop);
128
134
  if (typeof prop === "string" && !isWellKnownProperty(prop)) observeParamKeys(observer, [prop]);
129
135
  if (!isWellKnownProperty(prop) && hasParamProperty(plain, prop)) {
130
136
  if (isFallbackParam(prop)) {
@@ -164,6 +170,9 @@ function createThenableParams(obj, observer, fallbackShellState) {
164
170
  ownKeys() {
165
171
  observeReadableParamKeys(observer, plain);
166
172
  return Reflect.ownKeys(plain).filter((prop) => !isWellKnownProperty(prop));
173
+ },
174
+ set(target, prop, value) {
175
+ return Reflect.set(target, prop, value);
167
176
  }
168
177
  });
169
178
  paramsState.set(params, {
@@ -21,6 +21,11 @@ import "./request-state-types.js";
21
21
  export type UnifiedRequestContext = {
22
22
  /** Cloudflare Workers ExecutionContext, or null on Node.js dev. */
23
23
  executionContext: ExecutionContextLike | null;
24
+ /**
25
+ * The host's client-connection signal for the incoming request, before any
26
+ * clone follows it. Null for requests vinext creates itself (regeneration).
27
+ */
28
+ requestSignal: AbortSignal | null;
24
29
  /** Per-request cache for cacheForRequest(). Keyed by factory function reference. */
25
30
  requestCache: WeakMap<(...args: any[]) => any, unknown>;
26
31
  /** Shared lifecycle state for work deferred until the response closes. */
@@ -18,6 +18,7 @@ function createRequestContext(opts) {
18
18
  headersContext: null,
19
19
  actionRevalidationKind: 0,
20
20
  cacheLifeSink: null,
21
+ pendingCdnTagInvalidations: [],
21
22
  pendingRevalidatedTags: /* @__PURE__ */ new Set(),
22
23
  pendingRevalidations: /* @__PURE__ */ new Set(),
23
24
  dynamicUsageDetected: false,
@@ -50,6 +51,7 @@ function createRequestContext(opts) {
50
51
  currentFetchDedupeEntries: /* @__PURE__ */ new Map(),
51
52
  nextFetchId: 1,
52
53
  executionContext: _getInheritedExecutionContext(),
54
+ requestSignal: null,
53
55
  requestCache: /* @__PURE__ */ new WeakMap(),
54
56
  afterContext: {
55
57
  callbacks: [],
@@ -92,4 +92,11 @@ export declare function assetPrefixPathname(assetPrefix: string): string;
92
92
  * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/router-server.ts
93
93
  */
94
94
  export declare function isNextStaticPath(pathname: string, basePath: string, assetPathPrefix: string): boolean;
95
+ /**
96
+ * Whether `pathname` is a build asset under a path `assetPrefix`. Next.js adds
97
+ * a built-in beforeFiles rewrite from `${assetPrefix}/_next/:path+` into the
98
+ * basePath (`loadRewrites` in `packages/next/src/lib/load-custom-routes.ts`),
99
+ * so such a path resolves even when it lies outside the basePath.
100
+ */
101
+ export declare function isAssetPrefixBuildAsset(pathname: string, assetPathPrefix: string): boolean;
95
102
  //#endregion
@@ -118,5 +118,14 @@ function isNextStaticPath(pathname, basePath, assetPathPrefix) {
118
118
  if (assetPathPrefix && (p === assetPathPrefix || p.startsWith(assetPathPrefix + "/"))) p = p.slice(assetPathPrefix.length) || "/";
119
119
  return p.startsWith(`/${ASSET_PREFIX_URL_DIR}/`);
120
120
  }
121
+ /**
122
+ * Whether `pathname` is a build asset under a path `assetPrefix`. Next.js adds
123
+ * a built-in beforeFiles rewrite from `${assetPrefix}/_next/:path+` into the
124
+ * basePath (`loadRewrites` in `packages/next/src/lib/load-custom-routes.ts`),
125
+ * so such a path resolves even when it lies outside the basePath.
126
+ */
127
+ function isAssetPrefixBuildAsset(pathname, assetPathPrefix) {
128
+ return !!assetPathPrefix && (pathname === assetPathPrefix || pathname.startsWith(assetPathPrefix + "/")) && isNextStaticPath(pathname, "", assetPathPrefix);
129
+ }
121
130
  //#endregion
122
- export { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix, isNextStaticPath, resolveAssetUrlPrefix, resolveAssetsDir };
131
+ export { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix, isAssetPrefixBuildAsset, isNextStaticPath, resolveAssetUrlPrefix, resolveAssetsDir };
@@ -19,6 +19,8 @@ function readClientBuildManifest(manifestPath) {
19
19
  const assets = readStringArray(entry.assets);
20
20
  manifest[key] = {
21
21
  file: entry.file,
22
+ ...typeof entry.src === "string" ? { src: entry.src } : {},
23
+ ...typeof entry.name === "string" ? { name: entry.name } : {},
22
24
  ...entry.isEntry === true ? { isEntry: true } : {},
23
25
  ...entry.isDynamicEntry === true ? { isDynamicEntry: true } : {},
24
26
  ...imports ? { imports } : {},
@@ -39,14 +41,19 @@ function findPagesClientEntryFileFromManifest(buildManifest, assetBase) {
39
41
  return findEntryFileFromManifest(buildManifest, assetBase, PAGES_CLIENT_ENTRY_MARKERS, false);
40
42
  }
41
43
  function findEntryFileFromManifest(buildManifest, assetBase, markers, fallbackToFirstEntry) {
42
- const entries = Object.values(buildManifest).filter((entry) => entry.isEntry && entry.file);
43
- for (const marker of markers) {
44
- const markedEntry = entries.find((entry) => entry.file.includes(marker));
45
- if (markedEntry) return manifestFileWithBase(markedEntry.file, assetBase);
44
+ const entries = Object.entries(buildManifest).filter(([, entry]) => entry.isEntry && entry.file);
45
+ const matchers = [(marker, key, entry) => entry.name === marker || isVirtualEntryId(key, marker) || entry.src !== void 0 && isVirtualEntryId(entry.src, marker), (marker, _key, entry) => entry.file.includes(marker)];
46
+ for (const matches of matchers) for (const marker of markers) {
47
+ const markedEntry = entries.find(([key, entry]) => matches(marker, key, entry));
48
+ if (markedEntry) return manifestFileWithBase(markedEntry[1].file, assetBase);
46
49
  }
47
- const chosen = fallbackToFirstEntry ? entries[0] : void 0;
50
+ const chosen = fallbackToFirstEntry ? entries[0]?.[1] : void 0;
48
51
  return chosen ? manifestFileWithBase(chosen.file, assetBase) : void 0;
49
52
  }
53
+ function isVirtualEntryId(id, marker) {
54
+ const virtualId = `virtual:${marker}`;
55
+ return id === virtualId || id.endsWith(`/${virtualId}`);
56
+ }
50
57
  function listFilesRecursive(dir) {
51
58
  const out = [];
52
59
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
@@ -8,6 +8,7 @@ type ClientRuntimeMetadata = {
8
8
  }>;
9
9
  lazyChunks?: string[];
10
10
  dynamicPreloads?: Record<string, string[]>;
11
+ sharedChunks?: string[];
11
12
  };
12
13
  /**
13
14
  * Read the client build manifest and compute runtime metadata used by