vinext 1.0.0-beta.1 → 1.0.0-beta.3

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 (234) hide show
  1. package/README.md +10 -10
  2. package/dist/build/client-build-config.js +8 -1
  3. package/dist/build/report.d.ts +8 -1
  4. package/dist/build/report.js +12 -2
  5. package/dist/check.js +19 -2
  6. package/dist/cli.js +3 -2
  7. package/dist/config/config-matchers.d.ts +13 -37
  8. package/dist/config/config-matchers.js +35 -122
  9. package/dist/config/next-config.d.ts +15 -5
  10. package/dist/config/next-config.js +7 -1
  11. package/dist/config/request-context.d.ts +14 -0
  12. package/dist/config/request-context.js +26 -0
  13. package/dist/entries/app-browser-entry.d.ts +4 -10
  14. package/dist/entries/app-browser-entry.js +20 -4
  15. package/dist/entries/app-rsc-entry.js +30 -9
  16. package/dist/entries/app-rsc-manifest.js +36 -0
  17. package/dist/entries/pages-client-entry.js +0 -1
  18. package/dist/entries/pages-server-entry.js +13 -5
  19. package/dist/index.js +194 -101
  20. package/dist/init-cloudflare.d.ts +3 -1
  21. package/dist/init-cloudflare.js +59 -5
  22. package/dist/init.d.ts +6 -4
  23. package/dist/init.js +20 -22
  24. package/dist/plugins/extensionless-dynamic-import.js +23 -18
  25. package/dist/plugins/ignore-dynamic-requests.js +3 -1
  26. package/dist/plugins/import-meta-url.js +17 -6
  27. package/dist/plugins/og-assets.js +1 -1
  28. package/dist/plugins/require-context.js +20 -15
  29. package/dist/plugins/transform-cache.d.ts +19 -0
  30. package/dist/plugins/transform-cache.js +36 -0
  31. package/dist/routing/app-route-graph.d.ts +27 -11
  32. package/dist/routing/app-route-graph.js +158 -22
  33. package/dist/routing/app-router.js +12 -6
  34. package/dist/routing/file-matcher.d.ts +11 -22
  35. package/dist/routing/file-matcher.js +21 -33
  36. package/dist/routing/pages-router.js +23 -29
  37. package/dist/routing/route-matching.d.ts +14 -1
  38. package/dist/routing/route-matching.js +13 -1
  39. package/dist/routing/route-pattern.d.ts +2 -1
  40. package/dist/routing/route-pattern.js +7 -4
  41. package/dist/routing/route-trie.d.ts +5 -1
  42. package/dist/routing/route-trie.js +5 -2
  43. package/dist/server/api-handler.d.ts +2 -0
  44. package/dist/server/api-handler.js +3 -3
  45. package/dist/server/app-browser-entry.js +110 -37
  46. package/dist/server/app-browser-history-controller.d.ts +1 -1
  47. package/dist/server/app-browser-history-controller.js +3 -3
  48. package/dist/server/app-browser-navigation-controller.d.ts +23 -21
  49. package/dist/server/app-browser-navigation-controller.js +2 -2
  50. package/dist/server/app-browser-state.js +1 -1
  51. package/dist/server/app-browser-visible-commit.js +1 -1
  52. package/dist/server/app-fallback-renderer.d.ts +3 -0
  53. package/dist/server/app-fallback-renderer.js +4 -2
  54. package/dist/server/app-middleware.js +2 -1
  55. package/dist/server/app-page-boundary-render.d.ts +12 -1
  56. package/dist/server/app-page-boundary-render.js +84 -2
  57. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  58. package/dist/server/app-page-cache-finalizer.js +1 -1
  59. package/dist/server/app-page-cache.d.ts +2 -2
  60. package/dist/server/app-page-cache.js +16 -2
  61. package/dist/server/app-page-dispatch.d.ts +19 -2
  62. package/dist/server/app-page-dispatch.js +45 -23
  63. package/dist/server/app-page-element-builder.d.ts +9 -2
  64. package/dist/server/app-page-element-builder.js +144 -33
  65. package/dist/server/app-page-head.d.ts +56 -4
  66. package/dist/server/app-page-head.js +216 -85
  67. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  68. package/dist/server/app-page-http-access-fallback-metadata.js +114 -0
  69. package/dist/server/app-page-probe.d.ts +4 -0
  70. package/dist/server/app-page-probe.js +6 -2
  71. package/dist/server/app-page-render.d.ts +2 -2
  72. package/dist/server/app-page-render.js +1 -1
  73. package/dist/server/app-page-request.d.ts +15 -0
  74. package/dist/server/app-page-request.js +134 -14
  75. package/dist/server/app-page-response.js +1 -1
  76. package/dist/server/app-page-route-wiring.d.ts +16 -0
  77. package/dist/server/app-page-route-wiring.js +254 -52
  78. package/dist/server/app-pages-bridge.d.ts +1 -1
  79. package/dist/server/app-pages-bridge.js +2 -1
  80. package/dist/server/app-post-middleware-context.d.ts +1 -1
  81. package/dist/server/app-post-middleware-context.js +1 -1
  82. package/dist/server/app-route-handler-cache.js +4 -0
  83. package/dist/server/app-route-handler-dispatch.js +40 -20
  84. package/dist/server/app-route-handler-execution.d.ts +6 -1
  85. package/dist/server/app-route-handler-execution.js +42 -16
  86. package/dist/server/app-route-handler-policy.d.ts +2 -0
  87. package/dist/server/app-route-handler-policy.js +3 -3
  88. package/dist/server/app-route-handler-response.js +1 -1
  89. package/dist/server/app-route-module-loader.d.ts +9 -1
  90. package/dist/server/app-route-module-loader.js +4 -0
  91. package/dist/server/app-router-entry.js +6 -3
  92. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  93. package/dist/server/app-rsc-errors.d.ts +1 -1
  94. package/dist/server/app-rsc-errors.js +22 -2
  95. package/dist/server/app-rsc-handler.d.ts +10 -5
  96. package/dist/server/app-rsc-handler.js +73 -33
  97. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  98. package/dist/server/app-rsc-request-normalization.js +8 -2
  99. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  100. package/dist/server/app-rsc-response-finalizer.js +5 -11
  101. package/dist/server/app-rsc-route-matching.d.ts +29 -0
  102. package/dist/server/app-rsc-route-matching.js +93 -11
  103. package/dist/server/app-segment-config.js +13 -3
  104. package/dist/server/app-server-action-execution.d.ts +3 -1
  105. package/dist/server/app-server-action-execution.js +9 -7
  106. package/dist/server/app-ssr-entry.js +6 -6
  107. package/dist/server/app-ssr-stream.d.ts +1 -7
  108. package/dist/server/app-ssr-stream.js +2 -10
  109. package/dist/server/cache-control.d.ts +2 -2
  110. package/dist/server/cache-control.js +2 -1
  111. package/dist/server/config-headers.d.ts +24 -0
  112. package/dist/server/config-headers.js +52 -0
  113. package/dist/server/dev-initial-server-error.d.ts +1 -1
  114. package/dist/server/dev-server.d.ts +3 -1
  115. package/dist/server/dev-server.js +170 -321
  116. package/dist/server/headers.d.ts +2 -2
  117. package/dist/server/headers.js +4 -3
  118. package/dist/server/isr-cache.d.ts +11 -34
  119. package/dist/server/isr-cache.js +33 -43
  120. package/dist/server/isr-decision.d.ts +2 -2
  121. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  122. package/dist/server/middleware-matcher-pattern.js +219 -0
  123. package/dist/server/middleware-matcher.d.ts +2 -7
  124. package/dist/server/middleware-matcher.js +13 -60
  125. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  126. package/dist/server/middleware-path-to-regexp.js +228 -0
  127. package/dist/server/middleware-runtime.js +4 -3
  128. package/dist/server/middleware.d.ts +1 -1
  129. package/dist/server/middleware.js +2 -1
  130. package/dist/server/pages-api-route.d.ts +2 -0
  131. package/dist/server/pages-api-route.js +4 -1
  132. package/dist/server/pages-data-route.d.ts +11 -1
  133. package/dist/server/pages-data-route.js +16 -1
  134. package/dist/server/pages-dev-hydration.js +0 -1
  135. package/dist/server/pages-get-initial-props.d.ts +16 -3
  136. package/dist/server/pages-get-initial-props.js +17 -10
  137. package/dist/server/pages-i18n.js +64 -16
  138. package/dist/server/pages-node-compat.d.ts +2 -0
  139. package/dist/server/pages-node-compat.js +7 -3
  140. package/dist/server/pages-page-data.d.ts +64 -10
  141. package/dist/server/pages-page-data.js +349 -80
  142. package/dist/server/pages-page-handler.d.ts +9 -3
  143. package/dist/server/pages-page-handler.js +131 -36
  144. package/dist/server/pages-page-response.d.ts +5 -3
  145. package/dist/server/pages-page-response.js +24 -27
  146. package/dist/server/pages-readiness.d.ts +3 -3
  147. package/dist/server/pages-request-pipeline.d.ts +8 -0
  148. package/dist/server/pages-request-pipeline.js +30 -12
  149. package/dist/server/pages-revalidate.d.ts +1 -1
  150. package/dist/server/pages-revalidate.js +54 -8
  151. package/dist/server/pages-router-entry.d.ts +1 -0
  152. package/dist/server/pages-router-entry.js +16 -4
  153. package/dist/server/prerender-route-params.js +2 -2
  154. package/dist/server/prod-server.d.ts +3 -5
  155. package/dist/server/prod-server.js +72 -35
  156. package/dist/server/request-pipeline.d.ts +15 -29
  157. package/dist/server/request-pipeline.js +24 -59
  158. package/dist/server/revalidation-host.d.ts +11 -0
  159. package/dist/server/revalidation-host.js +19 -0
  160. package/dist/server/rsc-stream-hints.js +122 -18
  161. package/dist/server/worker-revalidation-context.d.ts +13 -0
  162. package/dist/server/worker-revalidation-context.js +29 -0
  163. package/dist/shims/app.d.ts +1 -1
  164. package/dist/shims/cache-handler.d.ts +1 -1
  165. package/dist/shims/cache-handler.js +10 -7
  166. package/dist/shims/cache-request-state.d.ts +27 -1
  167. package/dist/shims/cache-request-state.js +60 -1
  168. package/dist/shims/cache-runtime.d.ts +18 -1
  169. package/dist/shims/cache-runtime.js +26 -8
  170. package/dist/shims/cache.d.ts +5 -5
  171. package/dist/shims/cache.js +27 -11
  172. package/dist/shims/document.d.ts +42 -83
  173. package/dist/shims/document.js +62 -53
  174. package/dist/shims/dynamic.d.ts +5 -25
  175. package/dist/shims/dynamic.js +29 -8
  176. package/dist/shims/error.d.ts +1 -1
  177. package/dist/shims/error.js +2 -2
  178. package/dist/shims/fetch-cache.js +13 -4
  179. package/dist/shims/font-google-base.d.ts +11 -4
  180. package/dist/shims/font-google-base.js +17 -8
  181. package/dist/shims/font-local.d.ts +10 -3
  182. package/dist/shims/font-local.js +41 -10
  183. package/dist/shims/head.d.ts +13 -2
  184. package/dist/shims/head.js +3 -3
  185. package/dist/shims/headers.d.ts +37 -43
  186. package/dist/shims/headers.js +183 -74
  187. package/dist/shims/image.d.ts +27 -37
  188. package/dist/shims/image.js +21 -14
  189. package/dist/shims/internal/cookie-serialize.d.ts +12 -9
  190. package/dist/shims/internal/cookie-serialize.js +10 -7
  191. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  192. package/dist/shims/internal/interpolate-as.d.ts +15 -1
  193. package/dist/shims/internal/interpolate-as.js +27 -2
  194. package/dist/shims/internal/utils.d.ts +3 -3
  195. package/dist/shims/legacy-image.d.ts +3 -37
  196. package/dist/shims/legacy-image.js +6 -16
  197. package/dist/shims/link.d.ts +15 -22
  198. package/dist/shims/link.js +34 -13
  199. package/dist/shims/metadata.d.ts +7 -17
  200. package/dist/shims/metadata.js +74 -24
  201. package/dist/shims/navigation-context-state.d.ts +1 -1
  202. package/dist/shims/navigation.d.ts +7 -3
  203. package/dist/shims/navigation.js +25 -14
  204. package/dist/shims/navigation.react-server.js +1 -1
  205. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  206. package/dist/shims/next-shims-public.d.ts +1 -0
  207. package/dist/shims/public-shim-map.json.js +103 -0
  208. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  209. package/dist/shims/readonly-url-search-params.js +3 -3
  210. package/dist/shims/request-context.d.ts +4 -1
  211. package/dist/shims/request-state-types.d.ts +1 -1
  212. package/dist/shims/router.d.ts +55 -21
  213. package/dist/shims/router.js +180 -44
  214. package/dist/shims/script.d.ts +6 -10
  215. package/dist/shims/script.js +7 -4
  216. package/dist/shims/server.d.ts +50 -26
  217. package/dist/shims/server.js +193 -55
  218. package/dist/shims/unified-request-context.d.ts +22 -3
  219. package/dist/shims/unified-request-context.js +84 -1
  220. package/dist/shims/url-safety.d.ts +1 -1
  221. package/dist/shims/url-safety.js +2 -2
  222. package/dist/typegen.d.ts +8 -2
  223. package/dist/typegen.js +76 -15
  224. package/dist/utils/cache-control-metadata.d.ts +2 -1
  225. package/dist/utils/cache-control-metadata.js +5 -1
  226. package/dist/utils/domain-locale.d.ts +2 -2
  227. package/dist/utils/external-url.d.ts +5 -0
  228. package/dist/utils/external-url.js +7 -0
  229. package/dist/utils/html-limited-bots.js +1 -1
  230. package/dist/utils/protocol-headers.d.ts +7 -1
  231. package/dist/utils/protocol-headers.js +7 -1
  232. package/dist/utils/regex-safety.d.ts +8 -0
  233. package/dist/utils/regex-safety.js +737 -0
  234. package/package.json +13 -2
@@ -4,6 +4,7 @@ declare function routePatternParts(pathname: string): string[];
4
4
  declare function routePattern(pathname: string): string;
5
5
  declare function fillRoutePatternSegments(pathname: string, params: RoutePatternParams): string | null;
6
6
  declare function matchRoutePattern(urlParts: readonly string[], patternParts: readonly string[]): RoutePatternParams | null;
7
+ declare function matchRoutePatternRaw(urlParts: readonly string[], patternParts: readonly string[]): RoutePatternParams | null;
7
8
  declare function matchRoutePatternPrefix(pathParts: readonly string[], patternParts: readonly string[]): boolean;
8
9
  declare function matchRoutePatternWithOptionalDynamicSegments(pathParts: readonly string[], patternParts: readonly string[]): boolean;
9
10
  /**
@@ -61,4 +62,4 @@ declare function normalizeStaticPathname(pathname: string): string;
61
62
  */
62
63
  declare function normalizeStaticPathsEntry(entry: StaticPathsEntry, routePattern: string): NormalizedStaticPathsEntry;
63
64
  //#endregion
64
- export { RoutePatternParams, StaticPathsEntry, fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
65
+ export { RoutePatternParams, StaticPathsEntry, fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternRaw, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
@@ -56,6 +56,11 @@ function fillRoutePatternSegments(pathname, params) {
56
56
  return resolvedSegments.length > 0 ? `/${resolvedSegments.join("/")}` : "/";
57
57
  }
58
58
  function matchRoutePattern(urlParts, patternParts) {
59
+ const params = matchRoutePatternRaw(urlParts, patternParts);
60
+ if (params) decodeMatchedParams(params);
61
+ return params;
62
+ }
63
+ function matchRoutePatternRaw(urlParts, patternParts) {
59
64
  const params = Object.create(null);
60
65
  function matchFrom(urlIndex, patternIndex) {
61
66
  if (patternIndex === patternParts.length) return urlIndex === urlParts.length;
@@ -83,9 +88,7 @@ function matchRoutePattern(urlParts, patternParts) {
83
88
  if (urlIndex >= urlParts.length || urlParts[urlIndex] !== patternPart) return false;
84
89
  return matchFrom(urlIndex + 1, patternIndex + 1);
85
90
  }
86
- if (!matchFrom(0, 0)) return null;
87
- decodeMatchedParams(params);
88
- return params;
91
+ return matchFrom(0, 0) ? params : null;
89
92
  }
90
93
  function matchRoutePatternPrefix(pathParts, patternParts) {
91
94
  let pathIndex = 0;
@@ -162,4 +165,4 @@ function normalizeStaticPathsEntry(entry, routePattern) {
162
165
  return { params };
163
166
  }
164
167
  //#endregion
165
- export { fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
168
+ export { fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternRaw, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
@@ -63,5 +63,9 @@ declare function trieMatch<R>(root: TrieNode<R>, urlParts: string[]): {
63
63
  route: R;
64
64
  params: Record<string, string | string[]>;
65
65
  } | null;
66
+ declare function trieMatchRaw<R>(root: TrieNode<R>, urlParts: string[]): {
67
+ route: R;
68
+ params: Record<string, string | string[]>;
69
+ } | null;
66
70
  //#endregion
67
- export { TrieNode, buildRouteTrie, trieMatch };
71
+ export { TrieNode, buildRouteTrie, trieMatch, trieMatchRaw };
@@ -92,10 +92,13 @@ function buildRouteTrie(routes) {
92
92
  * @returns Match result with route and extracted params, or null
93
93
  */
94
94
  function trieMatch(root, urlParts) {
95
- const result = match(root, urlParts, 0, []);
95
+ const result = trieMatchRaw(root, urlParts);
96
96
  if (result) decodeMatchedParams(result.params);
97
97
  return result;
98
98
  }
99
+ function trieMatchRaw(root, urlParts) {
100
+ return match(root, urlParts, 0, []);
101
+ }
99
102
  function match(node, urlParts, index, entries) {
100
103
  if (index === urlParts.length) {
101
104
  if (node.route !== null) return {
@@ -140,4 +143,4 @@ function match(node, urlParts, index, entries) {
140
143
  return null;
141
144
  }
142
145
  //#endregion
143
- export { buildRouteTrie, trieMatch };
146
+ export { buildRouteTrie, trieMatch, trieMatchRaw };
@@ -11,6 +11,8 @@ import { IncomingMessage, ServerResponse } from "node:http";
11
11
  declare function handleApiRoute(runner: ModuleImporter, req: IncomingMessage, res: ServerResponse, url: string, apiRoutes: Route[], nextConfig?: {
12
12
  basePath?: string;
13
13
  i18n?: NextI18nConfig | null;
14
+ trustedRevalidateOrigin?: string;
15
+ allowedRevalidateHeaderKeys?: readonly string[];
14
16
  trailingSlash?: boolean;
15
17
  }): Promise<boolean>;
16
18
  //#endregion
@@ -160,7 +160,7 @@ async function writeEdgeApiResponseBody(res, body) {
160
160
  /**
161
161
  * Enhance a Node.js req/res pair with Next.js API route helpers.
162
162
  */
163
- function enhanceApiObjects(req, res, query, body) {
163
+ function enhanceApiObjects(req, res, query, body, trustedRevalidateOrigin, allowedRevalidateHeaderKeys = [], dev = false) {
164
164
  const apiReq = Object.assign(req, {
165
165
  body,
166
166
  query
@@ -202,7 +202,7 @@ function enhanceApiObjects(req, res, query, body) {
202
202
  return this;
203
203
  },
204
204
  async revalidate(urlPath, opts) {
205
- await performOnDemandRevalidate(req, urlPath, opts);
205
+ await performOnDemandRevalidate(req, urlPath, opts, trustedRevalidateOrigin, allowedRevalidateHeaderKeys, dev);
206
206
  }
207
207
  });
208
208
  attachPagesPreviewApi(apiReq, apiRes);
@@ -248,7 +248,7 @@ async function handleApiRoute(runner, req, res, url, apiRoutes, nextConfig) {
248
248
  }
249
249
  const query = mergeRouteParamsIntoQuery(parseQueryString(url), params);
250
250
  const bodyParserConfig = resolveBodyParserConfig(apiModule.config);
251
- const { apiReq, apiRes } = enhanceApiObjects(req, res, query, bodyParserConfig.enabled ? await parseBody(req, bodyParserConfig.sizeLimit) : void 0);
251
+ const { apiReq, apiRes } = enhanceApiObjects(req, res, query, bodyParserConfig.enabled ? await parseBody(req, bodyParserConfig.sizeLimit) : void 0, nextConfig?.trustedRevalidateOrigin, nextConfig?.allowedRevalidateHeaderKeys, true);
252
252
  await handler(apiReq, apiRes);
253
253
  return true;
254
254
  } catch (e) {
@@ -16,16 +16,15 @@ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscR
16
16
  import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
17
17
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
18
18
  import "../client/instrumentation-client.js";
19
+ import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
20
+ import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
21
+ import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
19
22
  import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
20
23
  import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
21
24
  import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
22
25
  import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
23
26
  import { navigationPlanner } from "./navigation-planner.js";
24
- import { resolveHybridClientRewriteHref } from "../shims/internal/hybrid-client-route-owner.js";
25
- import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
26
- import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
27
- import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
28
- import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
27
+ import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, preloadHybridClientRouteOwner, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveLoadedHybridClientRewriteHref, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
29
28
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
30
29
  import { COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, isCompleteAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl } from "./app-browser-state.js";
31
30
  import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
@@ -43,6 +42,7 @@ import { createRoot, hydrateRoot } from "react-dom/client";
43
42
  import { createFromFetch, createFromReadableStream, setServerCallback } from "@vitejs/plugin-rsc/browser";
44
43
  import { hasServerActions, loadServerActionClient } from "virtual:vinext-app-capabilities";
45
44
  //#region src/server/app-browser-entry.ts
45
+ const HAS_CLIENT_REWRITES = process.env.__VINEXT_HAS_CLIENT_REWRITES !== "false";
46
46
  function toActionType(kind) {
47
47
  return kind === "traverse" ? "traverse" : "navigate";
48
48
  }
@@ -302,28 +302,29 @@ function createNavigationCommitEffect(options) {
302
302
  commitClientNavigationState(navId);
303
303
  };
304
304
  }
305
- async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null, restoredBfcacheIds = null, reuseCurrentBfcacheIds = true, visibleCommitMode = "transition", onCommittedState, navigationCommitKind) {
305
+ async function renderNavigationPayload(options) {
306
306
  syncServerActionHttpFallbackHead(null);
307
307
  return browserNavigationController.renderNavigationPayload({
308
- actionType,
308
+ actionType: options.actionType ?? "navigate",
309
309
  createNavigationCommitEffect,
310
- historyUpdateMode,
311
- navigationSnapshot,
312
- nextElements: payload,
313
- operationLane,
314
- payloadOrigin,
315
- params,
316
- pendingRouterState,
317
- previousNextUrl,
318
- scrollIntent,
319
- restoredBfcacheIds,
320
- reuseCurrentBfcacheIds,
321
- targetHistoryIndex: traversalIntent === null ? void 0 : traversalIntent.targetHistoryIndex,
322
- targetHref,
323
- navId,
324
- navigationCommitKind,
325
- visibleCommitMode,
326
- onCommittedState
310
+ historyUpdateMode: options.historyUpdateMode,
311
+ navigationCommitKind: options.navigationCommitKind,
312
+ navigationInitiationState: options.navigationInitiationState,
313
+ navigationSnapshot: options.navigationSnapshot,
314
+ navId: options.navId,
315
+ nextElements: options.payload,
316
+ onCommittedState: options.onCommittedState,
317
+ operationLane: options.operationLane ?? "navigation",
318
+ params: options.params,
319
+ payloadOrigin: options.payloadOrigin,
320
+ pendingRouterState: options.pendingRouterState,
321
+ previousNextUrl: options.previousNextUrl,
322
+ restoredBfcacheIds: options.restoredBfcacheIds ?? null,
323
+ reuseCurrentBfcacheIds: options.reuseCurrentBfcacheIds ?? true,
324
+ scrollIntent: options.scrollIntent ?? null,
325
+ targetHistoryIndex: options.traversalIntent?.targetHistoryIndex,
326
+ targetHref: options.targetHref,
327
+ visibleCommitMode: options.visibleCommitMode ?? "transition"
327
328
  });
328
329
  }
329
330
  async function commitSameUrlNavigatePayload(nextElements, actionInitiation, returnValue, revalidation = "none") {
@@ -725,7 +726,21 @@ function registerServerActionCallback() {
725
726
  const hashIdx = target.href.indexOf("#");
726
727
  const actionScrollIntent = beginAppRouterScrollIntent((hashIdx !== -1 ? target.href.slice(hashIdx) : "") || null);
727
728
  if (target.type === "push") saveScrollPosition();
728
- renderNavigationPayload(Promise.resolve(elements), createClientNavigationRenderSnapshot(target.href, actionInitiation.routerState.navigationSnapshot.params), target.href, actionInitiation.navigationId, target.type === "push" ? "push" : "replace", {}, null, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, target.type === "push" ? "navigate" : "replace", resolveServerActionOperationLane(revalidation), null, actionScrollIntent).catch(() => {
729
+ renderNavigationPayload({
730
+ actionType: target.type === "push" ? "navigate" : "replace",
731
+ historyUpdateMode: target.type === "push" ? "push" : "replace",
732
+ navigationInitiationState: actionInitiation.routerState,
733
+ navigationSnapshot: createClientNavigationRenderSnapshot(target.href, actionInitiation.routerState.navigationSnapshot.params),
734
+ navId: actionInitiation.navigationId,
735
+ operationLane: resolveServerActionOperationLane(revalidation),
736
+ params: {},
737
+ payload: Promise.resolve(elements),
738
+ payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
739
+ pendingRouterState: null,
740
+ previousNextUrl: null,
741
+ scrollIntent: actionScrollIntent,
742
+ targetHref: target.href
743
+ }).catch(() => {
729
744
  browserNavigationController.performHardNavigation(target.href);
730
745
  });
731
746
  },
@@ -738,6 +753,7 @@ async function main() {
738
753
  if (!claimInitialAppRouterBootstrap()) return;
739
754
  if (hasServerActions) registerServerActionCallback();
740
755
  installAppNavigationFailureListeners();
756
+ if (HAS_CLIENT_REWRITES) await preloadHybridClientRouteOwner();
741
757
  let devErrorOverlay = null;
742
758
  if (import.meta.env.DEV) {
743
759
  devErrorOverlay = await import("../client/dev-error-overlay.js");
@@ -869,6 +885,8 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
869
885
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
870
886
  if (shouldUsePendingRouterState) pendingRouterState = beginPendingBrowserRouterState();
871
887
  }
888
+ const navigationInitiationState = getBrowserRouterState();
889
+ const mountedSlotsHeader = getMountedSlotIdsHeader(navigationInitiationState.elements);
872
890
  while (true) {
873
891
  const url = new URL(currentHref, window.location.origin);
874
892
  const requestState = getRequestState(navigationKind, url.pathname, currentPrevNextUrl, activeTraversalIntent?.historyState);
@@ -876,12 +894,9 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
876
894
  const requestPreviousNextUrl = requestState.previousNextUrl;
877
895
  if (navigationKind === "refresh") historyController.syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
878
896
  setPendingPathname(url.pathname, navId);
879
- const routerStateAtNavStart = getBrowserRouterState();
880
- const elementsAtNavStart = routerStateAtNavStart.elements;
881
- const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
882
897
  const earlyIntentDecision = navigationKind === "navigate" ? navigationPlanner.classifyEarlyNavigationIntent({
883
898
  basePath: __basePath,
884
- currentHref: clientNavigationSnapshotHref(routerStateAtNavStart.navigationSnapshot),
899
+ currentHref: clientNavigationSnapshotHref(navigationInitiationState.navigationSnapshot),
885
900
  mode: "push",
886
901
  scroll: false,
887
902
  targetHref: url.href
@@ -892,7 +907,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
892
907
  mountedSlotsHeader
893
908
  });
894
909
  const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
895
- const rewrittenNavigationHref = navigationKind === "navigate" ? resolveHybridClientRewriteHref(currentHref, __basePath) : null;
910
+ const rewrittenNavigationHref = navigationKind === "navigate" && HAS_CLIENT_REWRITES ? resolveLoadedHybridClientRewriteHref(currentHref, __basePath) : null;
896
911
  const additionalPrefetchRscUrls = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [await createRscRequestUrl(rewrittenNavigationHref, requestHeaders)] : [];
897
912
  const visitedResponseCandidate = shouldBypassNavigationCache ? {
898
913
  cacheKey: AppElementsWire.encodeCacheKey(rscUrl, requestInterceptionContext),
@@ -959,7 +974,26 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
959
974
  const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
960
975
  const cachedPayload = cachedRoute.elements ? Promise.resolve(cachedRoute.elements) : decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
961
976
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
962
- if (await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, cachedRoute.elements ? COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN : VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode) === "no-commit") {
977
+ if (await renderNavigationPayload({
978
+ actionType: toActionType(navigationKind),
979
+ historyUpdateMode: currentHistoryMode,
980
+ navigationCommitKind: detachedNavigationCommits ? "authoritative" : void 0,
981
+ navigationInitiationState,
982
+ navigationSnapshot: cachedNavigationSnapshot,
983
+ navId,
984
+ operationLane: toOperationLane(navigationKind),
985
+ params: cachedParams,
986
+ payload: cachedPayload,
987
+ payloadOrigin: cachedRoute.elements ? COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN : VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN,
988
+ pendingRouterState: detachedNavigationCommits ? null : pendingRouterState,
989
+ previousNextUrl: requestPreviousNextUrl,
990
+ restoredBfcacheIds,
991
+ reuseCurrentBfcacheIds,
992
+ scrollIntent,
993
+ targetHref: currentHref,
994
+ traversalIntent: activeTraversalIntent,
995
+ visibleCommitMode
996
+ }) === "no-commit") {
963
997
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
964
998
  deleteVisitedResponse(rscUrl, requestInterceptionContext);
965
999
  continue;
@@ -1015,7 +1049,26 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1015
1049
  if (optimisticPayload !== null) {
1016
1050
  detachedNavigationCommits = true;
1017
1051
  const optimisticNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, optimisticPayload.params);
1018
- renderNavigationPayload(Promise.resolve(optimisticPayload.elements), optimisticNavigationSnapshot, currentHref, navId, currentHistoryMode, optimisticPayload.params, requestPreviousNextUrl, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode, void 0, "detached").catch((error) => {
1052
+ renderNavigationPayload({
1053
+ actionType: toActionType(navigationKind),
1054
+ historyUpdateMode: currentHistoryMode,
1055
+ navigationCommitKind: "detached",
1056
+ navigationInitiationState,
1057
+ navigationSnapshot: optimisticNavigationSnapshot,
1058
+ navId,
1059
+ operationLane: toOperationLane(navigationKind),
1060
+ params: optimisticPayload.params,
1061
+ payload: Promise.resolve(optimisticPayload.elements),
1062
+ payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
1063
+ pendingRouterState: null,
1064
+ previousNextUrl: requestPreviousNextUrl,
1065
+ restoredBfcacheIds,
1066
+ reuseCurrentBfcacheIds,
1067
+ scrollIntent,
1068
+ targetHref: currentHref,
1069
+ traversalIntent: activeTraversalIntent,
1070
+ visibleCommitMode
1071
+ }).catch((error) => {
1019
1072
  if (browserNavigationController.isCurrentNavigation(navId)) console.error("[vinext] Optimistic RSC navigation error:", error);
1020
1073
  });
1021
1074
  }
@@ -1023,7 +1076,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1023
1076
  }
1024
1077
  if (!navResponse) {
1025
1078
  if (navigationKind === "navigate") {
1026
- const clientReuseManifestHeader = createClientReuseManifestHeaderFromVisibleAppState(routerStateAtNavStart);
1079
+ const clientReuseManifestHeader = createClientReuseManifestHeaderFromVisibleAppState(navigationInitiationState);
1027
1080
  if (clientReuseManifestHeader !== null) requestHeaders.set(VINEXT_CLIENT_REUSE_MANIFEST_HEADER, clientReuseManifestHeader);
1028
1081
  }
1029
1082
  navResponse = await fetch(rscUrl, {
@@ -1085,10 +1138,30 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1085
1138
  const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(reactResponse)));
1086
1139
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1087
1140
  let committedState = null;
1088
- if (await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode, (state) => {
1089
- committedState = state;
1090
- if (activeNavigationAbortController === navigationAbortController) activeNavigationAbortController = null;
1091
- }, detachedNavigationCommits ? "authoritative" : void 0) !== "committed") return;
1141
+ if (await renderNavigationPayload({
1142
+ actionType: toActionType(navigationKind),
1143
+ historyUpdateMode: currentHistoryMode,
1144
+ navigationCommitKind: detachedNavigationCommits ? "authoritative" : void 0,
1145
+ navigationInitiationState,
1146
+ navigationSnapshot,
1147
+ navId,
1148
+ onCommittedState: (state) => {
1149
+ committedState = state;
1150
+ if (activeNavigationAbortController === navigationAbortController) activeNavigationAbortController = null;
1151
+ },
1152
+ operationLane: toOperationLane(navigationKind),
1153
+ params: navParams,
1154
+ payload: rscPayload,
1155
+ payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
1156
+ pendingRouterState: detachedNavigationCommits ? null : pendingRouterState,
1157
+ previousNextUrl: requestPreviousNextUrl,
1158
+ restoredBfcacheIds,
1159
+ reuseCurrentBfcacheIds,
1160
+ scrollIntent,
1161
+ targetHref: currentHref,
1162
+ traversalIntent: activeTraversalIntent,
1163
+ visibleCommitMode
1164
+ }) !== "committed") return;
1092
1165
  try {
1093
1166
  const renderedElements = await rscPayload;
1094
1167
  if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
@@ -18,7 +18,7 @@ type AppBrowserHistoryControllerDeps = {
18
18
  readHistoryState: () => unknown; /** Reads `window.location.href`. Injected so the controller stays unit-testable. */
19
19
  readCurrentHref: () => string; /** Wraps `pushHistoryStateWithoutNotify(state, "", href)`. */
20
20
  pushHistoryState: (state: unknown, href: string) => void; /** Wraps `replaceHistoryStateWithoutNotify(state, "", href)`. */
21
- replaceHistoryState: (state: unknown, href: string) => void;
21
+ replaceHistoryState: (state: unknown, href?: string) => void;
22
22
  readVisibleNavigationMetadata: () => VisibleNavigationMetadata | null;
23
23
  };
24
24
  /**
@@ -158,9 +158,9 @@ var AppBrowserHistoryController = class {
158
158
  bfcacheVersion: bfcacheIds === void 0 ? void 0 : this.#restorableClientState.currentBfcacheVersion,
159
159
  previousNextUrl
160
160
  });
161
- this.#replaceHistoryState(nextHistoryState, this.#readCurrentHref());
161
+ this.#replaceHistoryState(nextHistoryState);
162
162
  if (this.#isHistoryStateNavigationMetadataInSync(this.#readHistoryState(), previousNextUrl, bfcacheIds)) return;
163
- this.#replaceHistoryState(nextHistoryState, this.#readCurrentHref());
163
+ this.#replaceHistoryState(nextHistoryState);
164
164
  }
165
165
  #isHistoryStateNavigationMetadataInSync(state, previousNextUrl, bfcacheIds) {
166
166
  return readHistoryStatePreviousNextUrl(state) === previousNextUrl && (bfcacheIds === void 0 || areBfcacheIdMapsEqual(readHistoryStateBfcacheIds(state), bfcacheIds) && this.#restorableClientState.isCurrentBfcacheVersion(state));
@@ -179,7 +179,7 @@ var AppBrowserHistoryController = class {
179
179
  bfcacheVersion: this.#restorableClientState.currentBfcacheVersion,
180
180
  previousNextUrl: options.previousNextUrl,
181
181
  traversalIndex: this.#currentHistoryTraversalIndex
182
- }), this.#readCurrentHref());
182
+ }));
183
183
  }
184
184
  /**
185
185
  * Resolves a restorable snapshot candidate for the given history entry and
@@ -43,6 +43,28 @@ type BrowserNavigationControllerDeps = {
43
43
  getRouteManifest?: () => RouteManifest | null;
44
44
  syncHistoryStatePreviousNextUrl?: (previousNextUrl: string | null, bfcacheIds?: Readonly<Record<string, string>> | null) => void;
45
45
  };
46
+ type BrowserNavigationPayloadOptions = {
47
+ actionType: "navigate" | "replace" | "traverse";
48
+ createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;
49
+ historyUpdateMode: HistoryUpdateMode | undefined;
50
+ navigationCommitKind?: "authoritative" | "detached";
51
+ navigationInitiationState: AppRouterState;
52
+ navigationSnapshot: ClientNavigationRenderSnapshot;
53
+ navId: number;
54
+ nextElements: Promise<AppElements>;
55
+ onCommittedState?: (state: AppRouterState) => void;
56
+ operationLane: OperationLane;
57
+ params: Record<string, string | string[]>;
58
+ payloadOrigin: AppNavigationPayloadOrigin;
59
+ pendingRouterState: PendingBrowserRouterState | null;
60
+ previousNextUrl: string | null;
61
+ restoredBfcacheIds?: Readonly<Record<string, string>> | null;
62
+ reuseCurrentBfcacheIds?: boolean;
63
+ scrollIntent?: AppRouterScrollIntent | null;
64
+ targetHistoryIndex?: number | null;
65
+ targetHref: string;
66
+ visibleCommitMode?: NavigationRuntimeVisibleCommitMode;
67
+ };
46
68
  type BrowserNavigationController = {
47
69
  beginNavigation(): number;
48
70
  getActiveNavigationId(): number;
@@ -60,27 +82,7 @@ type BrowserNavigationController = {
60
82
  state: AppRouterState;
61
83
  targetHref: string;
62
84
  }): boolean;
63
- renderNavigationPayload(options: {
64
- actionType: "navigate" | "replace" | "traverse";
65
- createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;
66
- historyUpdateMode: HistoryUpdateMode | undefined;
67
- navigationSnapshot: ClientNavigationRenderSnapshot;
68
- nextElements: Promise<AppElements>;
69
- operationLane: OperationLane;
70
- payloadOrigin: AppNavigationPayloadOrigin;
71
- params: Record<string, string | string[]>;
72
- pendingRouterState: PendingBrowserRouterState | null;
73
- previousNextUrl: string | null;
74
- scrollIntent?: AppRouterScrollIntent | null;
75
- restoredBfcacheIds?: Readonly<Record<string, string>> | null;
76
- reuseCurrentBfcacheIds?: boolean;
77
- targetHistoryIndex?: number | null;
78
- targetHref: string;
79
- navId: number;
80
- navigationCommitKind?: "authoritative" | "detached";
81
- visibleCommitMode?: NavigationRuntimeVisibleCommitMode;
82
- onCommittedState?: (state: AppRouterState) => void;
83
- }): Promise<NavigationPayloadOutcome>;
85
+ renderNavigationPayload(options: BrowserNavigationPayloadOptions): Promise<NavigationPayloadOutcome>;
84
86
  commitSameUrlNavigatePayload(nextElements: Promise<AppElements>, navigationSnapshot: ClientNavigationRenderSnapshot, returnValue?: {
85
87
  ok: boolean;
86
88
  data: unknown;
@@ -1,8 +1,8 @@
1
1
  import { stripBasePath } from "../utils/base-path.js";
2
2
  import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
3
3
  import { claimAppRouterScrollIntentForCommit, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
4
- import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
5
4
  import { resolveServerActionOperationLane, shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
5
+ import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
6
6
  import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit } from "./app-browser-state.js";
7
7
  import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
8
8
  import { startTransition, useInsertionEffect, useLayoutEffect } from "react";
@@ -349,7 +349,7 @@ function createAppBrowserNavigationController(deps = {}) {
349
349
  let snapshotActivated = false;
350
350
  try {
351
351
  const pending = await createPendingNavigationCommit({
352
- currentState: getBrowserRouterState(),
352
+ currentState: options.navigationInitiationState,
353
353
  navigationCommitKind: options.navigationCommitKind,
354
354
  navigationId: options.navId,
355
355
  nextElements: options.nextElements,
@@ -6,12 +6,12 @@ import { AppElementsWire } from "./app-elements-wire.js";
6
6
  import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
7
7
  import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
8
8
  import { createCacheEntryReuseProof } from "./cache-proof.js";
9
+ import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
9
10
  import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
10
11
  import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
11
12
  import { verifyOperationTokenForCommit } from "./operation-token.js";
12
13
  import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
13
14
  import { createSnapshotPathAndSearch } from "../shims/navigation.js";
14
- import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
15
15
  //#region src/server/app-browser-state.ts
16
16
  const COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "committed-cache" };
17
17
  const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
@@ -1,8 +1,8 @@
1
1
  import { normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
2
2
  import "./app-elements.js";
3
3
  import { mergeElements } from "../shims/slot.js";
4
- import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
5
4
  import { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
5
+ import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
6
6
  import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
7
7
  //#region src/server/app-browser-visible-commit.ts
8
8
  const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
@@ -5,6 +5,7 @@ import { AppPageParams } from "./app-page-boundary.js";
5
5
  import { AppPageFontPreload } from "./app-page-execution.js";
6
6
  import { AppPageMiddlewareContext } from "./app-page-response.js";
7
7
  import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
8
+ import { AppPageInterceptOptions } from "./app-page-element-builder.js";
8
9
  import { AppPageSsrHandler } from "./app-page-stream.js";
9
10
  import { AppPageBoundaryRoute } from "./app-page-boundary-render.js";
10
11
  import { ReactNode } from "react";
@@ -81,6 +82,7 @@ type AppFallbackRendererCallContext = {
81
82
  * render path. Defaults to `false` when no route is matched.
82
83
  */
83
84
  isEdgeRuntime?: boolean;
85
+ routePathname?: string;
84
86
  sourcePageSegments?: readonly string[] | null;
85
87
  };
86
88
  type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
@@ -88,6 +90,7 @@ type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
88
90
  renderHttpAccessFallback: (route: AppPageBoundaryRoute<TModule> | null, statusCode: number, isRscRequest: boolean, request: Request, opts: {
89
91
  boundaryComponent?: AppPageComponent | null;
90
92
  boundaryModule?: TModule | null;
93
+ intercept?: AppPageInterceptOptions<TModule> | null;
91
94
  layouts?: readonly (TModule | null | undefined)[] | null;
92
95
  matchedParams?: AppPageParams;
93
96
  }, scriptNonce: string | undefined, middlewareContext: AppPageMiddlewareContext, callContext?: AppFallbackRendererCallContext) => Promise<Response | null>;
@@ -1,8 +1,8 @@
1
- import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
2
1
  import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
2
+ import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
3
+ import { renderAppPageErrorBoundary, renderAppPageHttpAccessFallback } from "./app-page-boundary-render.js";
3
4
  import { DEFAULT_GLOBAL_NOT_FOUND_MODULE } from "./default-global-not-found-module.js";
4
5
  import { DEFAULT_NOT_FOUND_MODULE } from "./default-not-found-module.js";
5
- import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
6
6
  //#region src/server/app-fallback-renderer.ts
7
7
  const EMPTY_MW_CTX = {
8
8
  headers: null,
@@ -84,6 +84,7 @@ function createAppFallbackRenderer(options) {
84
84
  getAndClearPendingCookies,
85
85
  getNavigationContext,
86
86
  globalErrorModule: effectiveGlobalErrorModule,
87
+ intercept: opts?.intercept ?? null,
87
88
  isEdgeRuntime: callContext?.isEdgeRuntime,
88
89
  isRscRequest,
89
90
  layoutModules: useGlobalNotFound ? [] : opts?.layouts ?? null,
@@ -100,6 +101,7 @@ function createAppFallbackRenderer(options) {
100
101
  rootNotFoundModule: routeMissRootNotFoundModule,
101
102
  rootUnauthorizedModule,
102
103
  route: useGlobalNotFound ? null : route,
104
+ routePathname: callContext?.routePathname,
103
105
  renderToReadableStream: rscRenderer,
104
106
  scriptNonce,
105
107
  serveStreamingMetadata,
@@ -1,7 +1,7 @@
1
1
  import { VINEXT_MW_CTX_HEADER } from "../utils/protocol-headers.js";
2
2
  import { FLIGHT_HEADERS } from "./headers.js";
3
3
  import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
4
- import { isExternalUrl, proxyExternalRequest } from "../config/config-matchers.js";
4
+ import { isExternalUrl } from "../utils/external-url.js";
5
5
  import { internalServerErrorResponse } from "./http-error-responses.js";
6
6
  import { cloneRequestWithHeaders, processMiddlewareHeaders } from "./request-pipeline.js";
7
7
  import { executeMiddleware } from "./middleware-runtime.js";
@@ -58,6 +58,7 @@ async function proxyExternalMiddlewareRewrite(request, rewriteUrl, context) {
58
58
  const proxyRequest = requestWithMiddlewareRequestHeaders(request, context.requestHeaders ?? context.headers);
59
59
  setHeadersContext(null);
60
60
  setNavigationContext(null);
61
+ const { proxyExternalRequest } = await import("../config/config-matchers.js");
61
62
  const proxyResponse = await proxyExternalRequest(proxyRequest, rewriteUrl);
62
63
  const headers = new Headers(proxyResponse.headers);
63
64
  processMiddlewareHeaders(headers);
@@ -5,6 +5,8 @@ import { AppPageParams } from "./app-page-boundary.js";
5
5
  import { AppPageFontPreload } from "./app-page-execution.js";
6
6
  import { AppPageMiddlewareContext } from "./app-page-response.js";
7
7
  import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
8
+ import { AppPageRouteWiringRoute } from "./app-page-route-wiring.js";
9
+ import { AppPageInterceptOptions } from "./app-page-element-builder.js";
8
10
  import { AppPageSsrHandler } from "./app-page-stream.js";
9
11
  import { ComponentType, ReactNode } from "react";
10
12
 
@@ -19,13 +21,20 @@ type AppPageBoundaryRoute<TModule extends AppPageModule = AppPageModule> = {
19
21
  errorPaths?: readonly TModule[] | null;
20
22
  errors?: readonly (TModule | null | undefined)[] | null;
21
23
  forbidden?: TModule | null;
24
+ forbiddenTreePosition?: number | null;
25
+ forbiddens?: readonly (TModule | null | undefined)[] | null;
22
26
  layoutTreePositions?: readonly number[] | null;
23
27
  layouts?: readonly (TModule | null | undefined)[];
24
28
  notFound?: TModule | null;
29
+ notFounds?: readonly (TModule | null | undefined)[] | null;
30
+ notFoundTreePosition?: number | null;
25
31
  params?: AppPageParams;
26
32
  pattern?: string;
27
33
  routeSegments?: readonly string[];
34
+ slots?: AppPageRouteWiringRoute<TModule>["slots"];
28
35
  unauthorized?: TModule | null;
36
+ unauthorizedTreePosition?: number | null;
37
+ unauthorizeds?: readonly (TModule | null | undefined)[] | null;
29
38
  };
30
39
  type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageModule> = {
31
40
  applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
@@ -70,11 +79,13 @@ type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageM
70
79
  type RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppPageModule> = {
71
80
  boundaryComponent?: AppPageComponent | null;
72
81
  boundaryModule?: TModule | null;
82
+ intercept?: AppPageInterceptOptions<TModule> | null;
73
83
  layoutModules?: readonly (TModule | null | undefined)[] | null;
74
84
  matchedParams: AppPageParams;
75
85
  rootForbiddenModule?: TModule | null;
76
86
  rootNotFoundModule?: TModule | null;
77
- rootUnauthorizedModule?: TModule | null;
87
+ rootUnauthorizedModule?: TModule | null; /** Normalized, basePath-free application pathname used for route matching. */
88
+ routePathname?: string;
78
89
  route?: AppPageBoundaryRoute<TModule> | null;
79
90
  /**
80
91
  * When true, the resolved boundary is rendered without wrapping it in the