vinext 0.0.50 → 0.0.51

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 (309) hide show
  1. package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
  2. package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
  3. package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
  4. package/dist/build/google-fonts/fallback-metrics.js +46 -0
  5. package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
  6. package/dist/build/precompress.d.ts +13 -2
  7. package/dist/build/precompress.js +12 -3
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +1 -1
  10. package/dist/build/prerender.js +44 -14
  11. package/dist/build/prerender.js.map +1 -1
  12. package/dist/build/report.d.ts +5 -4
  13. package/dist/build/report.js +196 -348
  14. package/dist/build/report.js.map +1 -1
  15. package/dist/check.js +1 -0
  16. package/dist/check.js.map +1 -1
  17. package/dist/cli.js +60 -3
  18. package/dist/cli.js.map +1 -1
  19. package/dist/client/window-next.d.ts +3 -1
  20. package/dist/client/window-next.js.map +1 -1
  21. package/dist/config/dotenv.d.ts +11 -1
  22. package/dist/config/dotenv.js.map +1 -1
  23. package/dist/config/next-config.d.ts +87 -3
  24. package/dist/config/next-config.js +222 -6
  25. package/dist/config/next-config.js.map +1 -1
  26. package/dist/config/tsconfig-paths.d.ts +13 -0
  27. package/dist/config/tsconfig-paths.js +117 -0
  28. package/dist/config/tsconfig-paths.js.map +1 -0
  29. package/dist/deploy.js +3 -2
  30. package/dist/deploy.js.map +1 -1
  31. package/dist/entries/app-browser-entry.d.ts +2 -2
  32. package/dist/entries/app-browser-entry.js +26 -1
  33. package/dist/entries/app-browser-entry.js.map +1 -1
  34. package/dist/entries/app-rsc-entry.d.ts +19 -1
  35. package/dist/entries/app-rsc-entry.js +38 -12
  36. package/dist/entries/app-rsc-entry.js.map +1 -1
  37. package/dist/entries/app-rsc-manifest.d.ts +9 -0
  38. package/dist/entries/app-rsc-manifest.js +4 -1
  39. package/dist/entries/app-rsc-manifest.js.map +1 -1
  40. package/dist/entries/pages-client-entry.js +3 -5
  41. package/dist/entries/pages-client-entry.js.map +1 -1
  42. package/dist/entries/pages-server-entry.js +19 -1
  43. package/dist/entries/pages-server-entry.js.map +1 -1
  44. package/dist/index.js +130 -37
  45. package/dist/index.js.map +1 -1
  46. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  47. package/dist/plugins/client-reference-dedup.js +138 -16
  48. package/dist/plugins/client-reference-dedup.js.map +1 -1
  49. package/dist/plugins/fonts.d.ts +2 -2
  50. package/dist/plugins/fonts.js +15 -6
  51. package/dist/plugins/fonts.js.map +1 -1
  52. package/dist/plugins/sass.d.ts +34 -0
  53. package/dist/plugins/sass.js +22 -0
  54. package/dist/plugins/sass.js.map +1 -0
  55. package/dist/routing/app-route-graph.d.ts +31 -2
  56. package/dist/routing/app-route-graph.js +82 -10
  57. package/dist/routing/app-route-graph.js.map +1 -1
  58. package/dist/routing/route-pattern.d.ts +56 -1
  59. package/dist/routing/route-pattern.js +60 -1
  60. package/dist/routing/route-pattern.js.map +1 -1
  61. package/dist/server/app-browser-action-result.d.ts +27 -2
  62. package/dist/server/app-browser-action-result.js +63 -2
  63. package/dist/server/app-browser-action-result.js.map +1 -1
  64. package/dist/server/app-browser-entry.js +262 -108
  65. package/dist/server/app-browser-entry.js.map +1 -1
  66. package/dist/server/app-browser-hydration.d.ts +13 -1
  67. package/dist/server/app-browser-hydration.js +9 -1
  68. package/dist/server/app-browser-hydration.js.map +1 -1
  69. package/dist/server/app-browser-navigation-controller.d.ts +14 -1
  70. package/dist/server/app-browser-navigation-controller.js +28 -9
  71. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  72. package/dist/server/app-browser-popstate.d.ts +16 -0
  73. package/dist/server/app-browser-popstate.js +17 -0
  74. package/dist/server/app-browser-popstate.js.map +1 -0
  75. package/dist/server/app-browser-rsc-redirect.d.ts +28 -0
  76. package/dist/server/app-browser-rsc-redirect.js +37 -0
  77. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  78. package/dist/server/app-browser-state.d.ts +11 -7
  79. package/dist/server/app-browser-state.js +45 -27
  80. package/dist/server/app-browser-state.js.map +1 -1
  81. package/dist/server/app-browser-stream.d.ts +5 -4
  82. package/dist/server/app-browser-stream.js +5 -6
  83. package/dist/server/app-browser-stream.js.map +1 -1
  84. package/dist/server/app-browser-visible-commit.d.ts +5 -0
  85. package/dist/server/app-browser-visible-commit.js +38 -5
  86. package/dist/server/app-browser-visible-commit.js.map +1 -1
  87. package/dist/server/app-elements-wire.d.ts +38 -6
  88. package/dist/server/app-elements-wire.js +106 -6
  89. package/dist/server/app-elements-wire.js.map +1 -1
  90. package/dist/server/app-elements.d.ts +2 -2
  91. package/dist/server/app-elements.js +2 -2
  92. package/dist/server/app-elements.js.map +1 -1
  93. package/dist/server/app-fallback-renderer.d.ts +10 -1
  94. package/dist/server/app-fallback-renderer.js +37 -1
  95. package/dist/server/app-fallback-renderer.js.map +1 -1
  96. package/dist/server/app-history-state.d.ts +26 -0
  97. package/dist/server/app-history-state.js +53 -0
  98. package/dist/server/app-history-state.js.map +1 -0
  99. package/dist/server/app-page-boundary-render.d.ts +10 -1
  100. package/dist/server/app-page-boundary-render.js +13 -6
  101. package/dist/server/app-page-boundary-render.js.map +1 -1
  102. package/dist/server/app-page-boundary.js +3 -2
  103. package/dist/server/app-page-boundary.js.map +1 -1
  104. package/dist/server/app-page-cache.d.ts +13 -0
  105. package/dist/server/app-page-cache.js +25 -8
  106. package/dist/server/app-page-cache.js.map +1 -1
  107. package/dist/server/app-page-dispatch.d.ts +5 -0
  108. package/dist/server/app-page-dispatch.js +68 -11
  109. package/dist/server/app-page-dispatch.js.map +1 -1
  110. package/dist/server/app-page-element-builder.d.ts +7 -0
  111. package/dist/server/app-page-element-builder.js +32 -4
  112. package/dist/server/app-page-element-builder.js.map +1 -1
  113. package/dist/server/app-page-execution.js +2 -3
  114. package/dist/server/app-page-execution.js.map +1 -1
  115. package/dist/server/app-page-head.d.ts +7 -0
  116. package/dist/server/app-page-head.js +2 -1
  117. package/dist/server/app-page-head.js.map +1 -1
  118. package/dist/server/app-page-probe.d.ts +23 -1
  119. package/dist/server/app-page-probe.js +29 -1
  120. package/dist/server/app-page-probe.js.map +1 -1
  121. package/dist/server/app-page-render-observation.d.ts +35 -0
  122. package/dist/server/app-page-render-observation.js +68 -0
  123. package/dist/server/app-page-render-observation.js.map +1 -0
  124. package/dist/server/app-page-render.d.ts +5 -1
  125. package/dist/server/app-page-render.js +79 -3
  126. package/dist/server/app-page-render.js.map +1 -1
  127. package/dist/server/app-page-request.d.ts +1 -0
  128. package/dist/server/app-page-request.js.map +1 -1
  129. package/dist/server/app-page-response.js +3 -2
  130. package/dist/server/app-page-response.js.map +1 -1
  131. package/dist/server/app-page-route-wiring.d.ts +3 -1
  132. package/dist/server/app-page-route-wiring.js +42 -14
  133. package/dist/server/app-page-route-wiring.js.map +1 -1
  134. package/dist/server/app-page-stream.d.ts +2 -0
  135. package/dist/server/app-page-stream.js +1 -0
  136. package/dist/server/app-page-stream.js.map +1 -1
  137. package/dist/server/app-router-entry.js +1 -13
  138. package/dist/server/app-router-entry.js.map +1 -1
  139. package/dist/server/app-rsc-cache-busting.d.ts +19 -1
  140. package/dist/server/app-rsc-cache-busting.js +36 -1
  141. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  142. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  143. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  144. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  145. package/dist/server/app-rsc-errors.d.ts +4 -1
  146. package/dist/server/app-rsc-errors.js +1 -1
  147. package/dist/server/app-rsc-errors.js.map +1 -1
  148. package/dist/server/app-rsc-handler.d.ts +12 -4
  149. package/dist/server/app-rsc-handler.js +6 -1
  150. package/dist/server/app-rsc-handler.js.map +1 -1
  151. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  152. package/dist/server/app-rsc-route-matching.js +45 -23
  153. package/dist/server/app-rsc-route-matching.js.map +1 -1
  154. package/dist/server/app-server-action-execution.d.ts +35 -3
  155. package/dist/server/app-server-action-execution.js +87 -33
  156. package/dist/server/app-server-action-execution.js.map +1 -1
  157. package/dist/server/app-ssr-entry.d.ts +1 -0
  158. package/dist/server/app-ssr-entry.js +37 -13
  159. package/dist/server/app-ssr-entry.js.map +1 -1
  160. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  161. package/dist/server/app-ssr-error-meta.js +50 -0
  162. package/dist/server/app-ssr-error-meta.js.map +1 -0
  163. package/dist/server/app-ssr-stream.d.ts +1 -1
  164. package/dist/server/app-ssr-stream.js +9 -12
  165. package/dist/server/app-ssr-stream.js.map +1 -1
  166. package/dist/server/artifact-compatibility.d.ts +12 -2
  167. package/dist/server/artifact-compatibility.js +12 -8
  168. package/dist/server/artifact-compatibility.js.map +1 -1
  169. package/dist/server/cache-proof.d.ts +124 -5
  170. package/dist/server/cache-proof.js +416 -18
  171. package/dist/server/cache-proof.js.map +1 -1
  172. package/dist/server/dev-lockfile.d.ts +110 -0
  173. package/dist/server/dev-lockfile.js +180 -0
  174. package/dist/server/dev-lockfile.js.map +1 -0
  175. package/dist/server/dev-server.js +15 -5
  176. package/dist/server/dev-server.js.map +1 -1
  177. package/dist/server/file-based-metadata.d.ts +13 -0
  178. package/dist/server/file-based-metadata.js +49 -2
  179. package/dist/server/file-based-metadata.js.map +1 -1
  180. package/dist/server/headers.d.ts +3 -1
  181. package/dist/server/headers.js +5 -2
  182. package/dist/server/headers.js.map +1 -1
  183. package/dist/server/html.js +1 -1
  184. package/dist/server/html.js.map +1 -1
  185. package/dist/server/http-error-responses.d.ts +10 -0
  186. package/dist/server/http-error-responses.js +11 -1
  187. package/dist/server/http-error-responses.js.map +1 -1
  188. package/dist/server/isr-cache.d.ts +2 -1
  189. package/dist/server/isr-cache.js +4 -2
  190. package/dist/server/isr-cache.js.map +1 -1
  191. package/dist/server/metadata-route-response.js +22 -5
  192. package/dist/server/metadata-route-response.js.map +1 -1
  193. package/dist/server/metadata-routes.js +27 -8
  194. package/dist/server/metadata-routes.js.map +1 -1
  195. package/dist/server/middleware-runtime.js +1 -0
  196. package/dist/server/middleware-runtime.js.map +1 -1
  197. package/dist/server/middleware.d.ts +12 -0
  198. package/dist/server/middleware.js +12 -0
  199. package/dist/server/middleware.js.map +1 -1
  200. package/dist/server/navigation-planner.d.ts +19 -5
  201. package/dist/server/navigation-planner.js +278 -17
  202. package/dist/server/navigation-planner.js.map +1 -1
  203. package/dist/server/navigation-trace.d.ts +8 -1
  204. package/dist/server/navigation-trace.js +7 -0
  205. package/dist/server/navigation-trace.js.map +1 -1
  206. package/dist/server/normalize-path.d.ts +2 -1
  207. package/dist/server/normalize-path.js +4 -1
  208. package/dist/server/normalize-path.js.map +1 -1
  209. package/dist/server/pages-api-route.js +1 -0
  210. package/dist/server/pages-api-route.js.map +1 -1
  211. package/dist/server/pages-page-data.d.ts +3 -2
  212. package/dist/server/pages-page-data.js +22 -3
  213. package/dist/server/pages-page-data.js.map +1 -1
  214. package/dist/server/pages-page-response.js +1 -1
  215. package/dist/server/prod-server.d.ts +28 -1
  216. package/dist/server/prod-server.js +62 -9
  217. package/dist/server/prod-server.js.map +1 -1
  218. package/dist/server/server-action-not-found.d.ts +16 -3
  219. package/dist/server/server-action-not-found.js +19 -1
  220. package/dist/server/server-action-not-found.js.map +1 -1
  221. package/dist/server/server-globals.d.ts +5 -0
  222. package/dist/server/server-globals.js +37 -0
  223. package/dist/server/server-globals.js.map +1 -0
  224. package/dist/server/static-file-cache.js +1 -1
  225. package/dist/server/static-file-cache.js.map +1 -1
  226. package/dist/shims/cache-runtime.d.ts +19 -2
  227. package/dist/shims/cache-runtime.js +67 -11
  228. package/dist/shims/cache-runtime.js.map +1 -1
  229. package/dist/shims/cache.d.ts +5 -18
  230. package/dist/shims/cache.js +2 -0
  231. package/dist/shims/cache.js.map +1 -1
  232. package/dist/shims/error-boundary.js +6 -8
  233. package/dist/shims/error-boundary.js.map +1 -1
  234. package/dist/shims/error.d.ts +18 -1
  235. package/dist/shims/error.js +56 -1
  236. package/dist/shims/error.js.map +1 -1
  237. package/dist/shims/fetch-cache.d.ts +4 -1
  238. package/dist/shims/fetch-cache.js +40 -5
  239. package/dist/shims/fetch-cache.js.map +1 -1
  240. package/dist/shims/font-google-base.d.ts +22 -8
  241. package/dist/shims/font-google-base.js +41 -71
  242. package/dist/shims/font-google-base.js.map +1 -1
  243. package/dist/shims/font-local.d.ts +3 -20
  244. package/dist/shims/font-local.js +23 -75
  245. package/dist/shims/font-local.js.map +1 -1
  246. package/dist/shims/font-utils.d.ts +51 -0
  247. package/dist/shims/font-utils.js +97 -0
  248. package/dist/shims/font-utils.js.map +1 -0
  249. package/dist/shims/hash-scroll.d.ts +7 -0
  250. package/dist/shims/hash-scroll.js +30 -0
  251. package/dist/shims/hash-scroll.js.map +1 -0
  252. package/dist/shims/headers.d.ts +8 -11
  253. package/dist/shims/headers.js +22 -2
  254. package/dist/shims/headers.js.map +1 -1
  255. package/dist/shims/image.d.ts +1 -0
  256. package/dist/shims/image.js +144 -78
  257. package/dist/shims/image.js.map +1 -1
  258. package/dist/shims/internal/app-router-context.d.ts +6 -6
  259. package/dist/shims/internal/app-router-context.js +17 -6
  260. package/dist/shims/internal/app-router-context.js.map +1 -1
  261. package/dist/shims/link-prefetch.d.ts +9 -1
  262. package/dist/shims/link-prefetch.js +11 -6
  263. package/dist/shims/link-prefetch.js.map +1 -1
  264. package/dist/shims/link.d.ts +12 -2
  265. package/dist/shims/link.js +78 -32
  266. package/dist/shims/link.js.map +1 -1
  267. package/dist/shims/metadata.d.ts +16 -30
  268. package/dist/shims/metadata.js +87 -28
  269. package/dist/shims/metadata.js.map +1 -1
  270. package/dist/shims/navigation.d.ts +158 -17
  271. package/dist/shims/navigation.js +324 -74
  272. package/dist/shims/navigation.js.map +1 -1
  273. package/dist/shims/navigation.react-server.d.ts +3 -2
  274. package/dist/shims/navigation.react-server.js +5 -2
  275. package/dist/shims/navigation.react-server.js.map +1 -1
  276. package/dist/shims/pages-router-runtime.d.ts +7 -0
  277. package/dist/shims/pages-router-runtime.js +16 -0
  278. package/dist/shims/pages-router-runtime.js.map +1 -0
  279. package/dist/shims/router.d.ts +32 -6
  280. package/dist/shims/router.js +197 -242
  281. package/dist/shims/router.js.map +1 -1
  282. package/dist/shims/script.js +110 -32
  283. package/dist/shims/script.js.map +1 -1
  284. package/dist/shims/server.js +2 -1
  285. package/dist/shims/server.js.map +1 -1
  286. package/dist/shims/slot.d.ts +1 -0
  287. package/dist/shims/slot.js +41 -1
  288. package/dist/shims/slot.js.map +1 -1
  289. package/dist/shims/unified-request-context.js +2 -0
  290. package/dist/shims/unified-request-context.js.map +1 -1
  291. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  292. package/dist/shims/unrecognized-action-error.js +41 -0
  293. package/dist/shims/unrecognized-action-error.js.map +1 -0
  294. package/dist/shims/url-utils.d.ts +21 -1
  295. package/dist/shims/url-utils.js +67 -3
  296. package/dist/shims/url-utils.js.map +1 -1
  297. package/dist/utils/asset-prefix.d.ts +69 -0
  298. package/dist/utils/asset-prefix.js +91 -0
  299. package/dist/utils/asset-prefix.js.map +1 -0
  300. package/dist/utils/base-path.d.ts +7 -1
  301. package/dist/utils/base-path.js +10 -1
  302. package/dist/utils/base-path.js.map +1 -1
  303. package/dist/utils/navigation-signal.d.ts +1 -2
  304. package/dist/utils/navigation-signal.js +1 -1
  305. package/dist/utils/navigation-signal.js.map +1 -1
  306. package/dist/utils/sorted-array.d.ts +9 -0
  307. package/dist/utils/sorted-array.js +22 -0
  308. package/dist/utils/sorted-array.js.map +1 -0
  309. package/package.json +3 -3
@@ -1,12 +1,16 @@
1
1
  import { stripBasePath } from "../utils/base-path.js";
2
2
  import { VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER } from "../server/headers.js";
3
3
  import { assertSafeNavigationUrl } from "./url-safety.js";
4
- import { isHashOnlyBrowserUrlChange, toBrowserNavigationHref, toSameOriginAppPath } from "./url-utils.js";
4
+ import { isAbsoluteOrProtocolRelativeUrl, isHashOnlyBrowserUrlChange, toBrowserNavigationHref, toSameOriginAppPath } from "./url-utils.js";
5
+ import { scrollToHashTarget } from "./hash-scroll.js";
5
6
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
6
7
  import { AppElementsWire } from "../server/app-elements-wire.js";
7
8
  import "../server/app-elements.js";
8
- import { createRscRequestHeaders, createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
9
+ import { createExternalHistoryStatePreservingMetadata } from "../server/app-history-state.js";
10
+ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
9
11
  import { ReadonlyURLSearchParams } from "./readonly-url-search-params.js";
12
+ import { AppRouterContext } from "./internal/app-router-context.js";
13
+ import { UnrecognizedActionError, unstable_isUnrecognizedActionError } from "./unrecognized-action-error.js";
10
14
  import * as React$1 from "react";
11
15
  //#region src/shims/navigation.ts
12
16
  /**
@@ -103,6 +107,16 @@ function _registerStateAccessors(accessors) {
103
107
  _getInsertedHTMLCallbacks = accessors.getInsertedHTMLCallbacks;
104
108
  _clearInsertedHTMLCallbacks = accessors.clearInsertedHTMLCallbacks;
105
109
  }
110
+ const PAGES_NAVIGATION_ACCESSOR_KEY = Symbol.for("vinext.navigation.pagesNavigationContextAccessor");
111
+ function _getPagesNavigationContext() {
112
+ const accessor = globalThis[PAGES_NAVIGATION_ACCESSOR_KEY];
113
+ if (!accessor) return null;
114
+ try {
115
+ return accessor();
116
+ } catch {
117
+ return null;
118
+ }
119
+ }
106
120
  /**
107
121
  * Get the navigation context for the current SSR/RSC render.
108
122
  * Reads from AsyncLocalStorage when available (concurrent-safe),
@@ -157,18 +171,80 @@ function evictPrefetchCacheIfNeeded() {
157
171
  if (cache.size < 50) return;
158
172
  const now = Date.now();
159
173
  const prefetched = getPrefetchedUrls();
160
- for (const [key, entry] of cache) if (now - entry.timestamp >= 3e4) {
161
- cache.delete(key);
162
- prefetched.delete(key);
163
- }
174
+ for (const [key, entry] of cache) if (now - entry.timestamp >= 3e4) deletePrefetchCacheEntry(cache, prefetched, key, entry, true);
164
175
  while (cache.size >= 50) {
165
176
  const oldest = cache.keys().next().value;
166
177
  if (oldest !== void 0) {
167
- cache.delete(oldest);
168
- prefetched.delete(oldest);
178
+ const entry = cache.get(oldest);
179
+ if (entry) deletePrefetchCacheEntry(cache, prefetched, oldest, entry, true);
180
+ else {
181
+ cache.delete(oldest);
182
+ prefetched.delete(oldest);
183
+ }
169
184
  } else break;
170
185
  }
171
186
  }
187
+ function clearPrefetchInvalidation(entry) {
188
+ if (entry.invalidationTimer !== void 0) {
189
+ clearTimeout(entry.invalidationTimer);
190
+ entry.invalidationTimer = void 0;
191
+ }
192
+ }
193
+ function notifyPrefetchInvalidated(entry) {
194
+ clearPrefetchInvalidation(entry);
195
+ const callbacks = entry.onInvalidateCallbacks;
196
+ entry.onInvalidateCallbacks = void 0;
197
+ if (callbacks === void 0) return;
198
+ for (const onInvalidate of callbacks) try {
199
+ onInvalidate();
200
+ } catch (error) {
201
+ if (typeof reportError === "function") reportError(error);
202
+ else console.error(error);
203
+ }
204
+ }
205
+ function deletePrefetchCacheEntry(cache, prefetched, cacheKey, entry, notify) {
206
+ cache.delete(cacheKey);
207
+ prefetched.delete(cacheKey);
208
+ if (notify) notifyPrefetchInvalidated(entry);
209
+ else {
210
+ clearPrefetchInvalidation(entry);
211
+ entry.onInvalidateCallbacks = void 0;
212
+ }
213
+ }
214
+ function invalidatePrefetchCacheEntry(cacheKey) {
215
+ const cache = getPrefetchCache();
216
+ const entry = cache.get(cacheKey);
217
+ if (!entry) return;
218
+ deletePrefetchCacheEntry(cache, getPrefetchedUrls(), cacheKey, entry, true);
219
+ }
220
+ function schedulePrefetchInvalidation(cacheKey, entry) {
221
+ if (entry.onInvalidateCallbacks === void 0 || entry.onInvalidateCallbacks.size === 0) return;
222
+ clearPrefetchInvalidation(entry);
223
+ const elapsed = Date.now() - entry.timestamp;
224
+ const delay = Math.max(0, PREFETCH_CACHE_TTL - elapsed);
225
+ entry.invalidationTimer = setTimeout(() => {
226
+ invalidatePrefetchCacheEntry(cacheKey);
227
+ }, delay);
228
+ }
229
+ function addPrefetchInvalidationCallback(entry, onInvalidate) {
230
+ if (onInvalidate === void 0) return;
231
+ if (entry.onInvalidateCallbacks === void 0) entry.onInvalidateCallbacks = /* @__PURE__ */ new Set();
232
+ entry.onInvalidateCallbacks.add(onInvalidate);
233
+ }
234
+ function attachPrefetchInvalidationCallback(cacheKey, onInvalidate) {
235
+ if (onInvalidate === void 0) return;
236
+ const entry = getPrefetchCache().get(cacheKey);
237
+ if (!entry) return;
238
+ addPrefetchInvalidationCallback(entry, onInvalidate);
239
+ if (entry.outcome === "cache-seeded") schedulePrefetchInvalidation(cacheKey, entry);
240
+ }
241
+ function invalidatePrefetchCache() {
242
+ const cache = getPrefetchCache();
243
+ const prefetched = getPrefetchedUrls();
244
+ for (const [cacheKey, entry] of cache) deletePrefetchCacheEntry(cache, prefetched, cacheKey, entry, true);
245
+ prefetched.clear();
246
+ if (!isServer) window.__VINEXT_PING_VISIBLE_LINKS__?.();
247
+ }
172
248
  /**
173
249
  * Store a prefetched RSC response in the cache by snapshotting it to an
174
250
  * ArrayBuffer. The snapshot completes asynchronously; during that window
@@ -185,37 +261,45 @@ function evictPrefetchCacheIfNeeded() {
185
261
  * NB: Caller is responsible for managing getPrefetchedUrls() — this
186
262
  * function only stores the response in the prefetch cache.
187
263
  */
188
- function storePrefetchResponse(rscUrl, response, interceptionContext = null) {
264
+ function storePrefetchResponse(rscUrl, response, interceptionContext = null, options) {
189
265
  const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
190
266
  evictPrefetchCacheIfNeeded();
191
267
  const entry = {
192
268
  outcome: "pending",
193
269
  timestamp: Date.now()
194
270
  };
271
+ addPrefetchInvalidationCallback(entry, options?.onInvalidate);
195
272
  entry.pending = snapshotRscResponse(response).then((snapshot) => {
196
273
  entry.snapshot = snapshot;
197
274
  }).catch(() => {
198
- getPrefetchCache().delete(cacheKey);
275
+ deletePrefetchCacheEntry(getPrefetchCache(), getPrefetchedUrls(), cacheKey, entry, false);
199
276
  }).finally(() => {
200
277
  entry.pending = void 0;
201
- if (entry.snapshot) entry.outcome = "cache-seeded";
278
+ if (entry.snapshot) {
279
+ entry.outcome = "cache-seeded";
280
+ schedulePrefetchInvalidation(cacheKey, entry);
281
+ }
202
282
  });
203
283
  getPrefetchCache().set(cacheKey, entry);
204
284
  }
205
- /**
206
- * Snapshot an RSC response to an ArrayBuffer for caching and replay.
207
- * Consumes the response body and stores it with content-type and URL metadata.
208
- */
209
- async function snapshotRscResponse(response) {
285
+ function createCachedRscResponseSnapshot(response, buffer, responseUrl = null) {
210
286
  return {
211
- buffer: await response.arrayBuffer(),
287
+ compatibilityIdHeader: response.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
288
+ buffer,
212
289
  contentType: response.headers.get("content-type") ?? "text/x-component",
213
290
  mountedSlotsHeader: response.headers.get(VINEXT_MOUNTED_SLOTS_HEADER),
214
291
  paramsHeader: response.headers.get(VINEXT_PARAMS_HEADER),
215
- url: response.url
292
+ url: responseUrl ?? response.url
216
293
  };
217
294
  }
218
295
  /**
296
+ * Snapshot an RSC response to an ArrayBuffer for caching and replay.
297
+ * Consumes the response body and stores it with content-type and URL metadata.
298
+ */
299
+ async function snapshotRscResponse(response) {
300
+ return createCachedRscResponseSnapshot(response, await response.arrayBuffer());
301
+ }
302
+ /**
219
303
  * Reconstruct a Response from a cached RSC snapshot.
220
304
  * Creates a new Response with the original ArrayBuffer so createFromFetch
221
305
  * can consume the stream from scratch.
@@ -233,6 +317,7 @@ async function snapshotRscResponse(response) {
233
317
  function restoreRscResponse(cached, copy = true) {
234
318
  const headers = new Headers({ "content-type": cached.contentType });
235
319
  if (cached.mountedSlotsHeader != null) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, cached.mountedSlotsHeader);
320
+ if (cached.compatibilityIdHeader != null) headers.set(VINEXT_RSC_COMPATIBILITY_ID_HEADER, cached.compatibilityIdHeader);
236
321
  if (cached.paramsHeader != null) headers.set(VINEXT_PARAMS_HEADER, cached.paramsHeader);
237
322
  return new Response(copy ? cached.buffer.slice(0) : cached.buffer, {
238
323
  status: 200,
@@ -246,7 +331,7 @@ function restoreRscResponse(cached, copy = true) {
246
331
  * Enforces a maximum cache size to prevent unbounded memory growth on
247
332
  * link-heavy pages.
248
333
  */
249
- function prefetchRscResponse(rscUrl, fetchPromise, interceptionContext = null, mountedSlotsHeader = null) {
334
+ function prefetchRscResponse(rscUrl, fetchPromise, interceptionContext = null, mountedSlotsHeader = null, options) {
250
335
  const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
251
336
  const cache = getPrefetchCache();
252
337
  const prefetched = getPrefetchedUrls();
@@ -254,21 +339,21 @@ function prefetchRscResponse(rscUrl, fetchPromise, interceptionContext = null, m
254
339
  outcome: "pending",
255
340
  timestamp: Date.now()
256
341
  };
342
+ addPrefetchInvalidationCallback(entry, options?.onInvalidate);
257
343
  entry.pending = fetchPromise.then(async (response) => {
258
344
  if (response.ok) entry.snapshot = {
259
345
  ...await snapshotRscResponse(response),
260
346
  mountedSlotsHeader
261
347
  };
262
- else {
263
- prefetched.delete(cacheKey);
264
- cache.delete(cacheKey);
265
- }
348
+ else deletePrefetchCacheEntry(cache, prefetched, cacheKey, entry, false);
266
349
  }).catch(() => {
267
- prefetched.delete(cacheKey);
268
- cache.delete(cacheKey);
350
+ deletePrefetchCacheEntry(cache, prefetched, cacheKey, entry, false);
269
351
  }).finally(() => {
270
352
  entry.pending = void 0;
271
- if (entry.snapshot) entry.outcome = "cache-seeded";
353
+ if (entry.snapshot) {
354
+ entry.outcome = "cache-seeded";
355
+ schedulePrefetchInvalidation(cacheKey, entry);
356
+ }
272
357
  });
273
358
  cache.set(cacheKey, entry);
274
359
  evictPrefetchCacheIfNeeded();
@@ -284,8 +369,7 @@ function consumePrefetchResponse(rscUrl, interceptionContext = null, mountedSlot
284
369
  const entry = cache.get(cacheKey);
285
370
  if (!entry) return null;
286
371
  if (entry.pending || entry.outcome !== "cache-seeded") return null;
287
- cache.delete(cacheKey);
288
- getPrefetchedUrls().delete(cacheKey);
372
+ deletePrefetchCacheEntry(cache, getPrefetchedUrls(), cacheKey, entry, false);
289
373
  if (entry.snapshot) {
290
374
  if ((entry.snapshot.mountedSlotsHeader ?? null) !== mountedSlotsHeader) return null;
291
375
  if (Date.now() - entry.timestamp >= 3e4) return null;
@@ -379,6 +463,8 @@ function syncCommittedUrlStateFromLocation() {
379
463
  function getServerSearchParamsSnapshot() {
380
464
  const ctx = _getServerContext();
381
465
  if (!ctx) {
466
+ const pagesCtx = _getPagesNavigationContext();
467
+ if (pagesCtx) return new ReadonlyURLSearchParams(pagesCtx.searchParams);
382
468
  if (_cachedEmptyServerSearchParams === null) _cachedEmptyServerSearchParams = new ReadonlyURLSearchParams();
383
469
  return _cachedEmptyServerSearchParams;
384
470
  }
@@ -488,10 +574,16 @@ function clearPendingPathname(navId) {
488
574
  }
489
575
  }
490
576
  function getClientParamsSnapshot() {
491
- return getClientNavigationState()?.clientParams ?? _EMPTY_PARAMS;
577
+ const state = getClientNavigationState();
578
+ if (state && Object.keys(state.clientParams).length > 0) return state.clientParams;
579
+ const pagesCtx = _getPagesNavigationContext();
580
+ if (pagesCtx) return pagesCtx.params;
581
+ return state?.clientParams ?? _EMPTY_PARAMS;
492
582
  }
493
583
  function getServerParamsSnapshot() {
494
- return _getServerContext()?.params ?? _EMPTY_PARAMS;
584
+ const ctx = _getServerContext();
585
+ if (ctx) return ctx.params;
586
+ return _getPagesNavigationContext()?.params ?? _EMPTY_PARAMS;
495
587
  }
496
588
  function subscribeToNavigation(cb) {
497
589
  const state = getClientNavigationState();
@@ -506,9 +598,13 @@ function subscribeToNavigation(cb) {
506
598
  * Server: from request context. Client: from window.location.
507
599
  */
508
600
  function usePathname() {
509
- if (isServer) return _getServerContext()?.pathname ?? "/";
601
+ if (isServer) {
602
+ const ctx = _getServerContext();
603
+ if (ctx) return ctx.pathname;
604
+ return _getPagesNavigationContext()?.pathname ?? "/";
605
+ }
510
606
  const renderSnapshot = useClientNavigationRenderSnapshot();
511
- const pathname = React$1.useSyncExternalStore(subscribeToNavigation, getPathnameSnapshot, () => _getServerContext()?.pathname ?? "/");
607
+ const pathname = React$1.useSyncExternalStore(subscribeToNavigation, getPathnameSnapshot, () => _getServerContext()?.pathname ?? _getPagesNavigationContext()?.pathname ?? "/");
512
608
  if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.pathname;
513
609
  return pathname;
514
610
  }
@@ -526,7 +622,7 @@ function useSearchParams() {
526
622
  * Returns the dynamic params for the current route.
527
623
  */
528
624
  function useParams() {
529
- if (isServer) return _getServerContext()?.params ?? _EMPTY_PARAMS;
625
+ if (isServer) return getServerParamsSnapshot();
530
626
  const renderSnapshot = useClientNavigationRenderSnapshot();
531
627
  const params = React$1.useSyncExternalStore(subscribeToNavigation, getClientParamsSnapshot, getServerParamsSnapshot);
532
628
  if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.params;
@@ -536,7 +632,7 @@ function useParams() {
536
632
  * Check if a href is an external URL (any URL scheme per RFC 3986, or protocol-relative).
537
633
  */
538
634
  function isExternalUrl(href) {
539
- return /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith("//");
635
+ return isAbsoluteOrProtocolRelativeUrl(href);
540
636
  }
541
637
  /**
542
638
  * Check if a href is only a hash change relative to the current URL.
@@ -546,18 +642,6 @@ function isHashOnlyChange(href) {
546
642
  if (href.startsWith("#")) return true;
547
643
  return isHashOnlyBrowserUrlChange(href, window.location.href, __basePath);
548
644
  }
549
- /**
550
- * Scroll to a hash target element, or to the top if no hash.
551
- */
552
- function scrollToHash(hash) {
553
- if (!hash || hash === "#") {
554
- window.scrollTo(0, 0);
555
- return;
556
- }
557
- const id = hash.slice(1);
558
- const element = document.getElementById(id);
559
- if (element) element.scrollIntoView({ behavior: "auto" });
560
- }
561
645
  function withSuppressedUrlNotifications(fn) {
562
646
  const state = getClientNavigationState();
563
647
  if (!state) return fn();
@@ -594,7 +678,10 @@ function commitClientNavigationState(navId, options) {
594
678
  }
595
679
  const shouldNotify = urlChanged || state.hasPendingNavigationUpdate;
596
680
  state.hasPendingNavigationUpdate = false;
597
- if (shouldNotify) notifyNavigationListeners();
681
+ if (shouldNotify) {
682
+ notifyNavigationListeners();
683
+ window.__VINEXT_PING_VISIBLE_LINKS__?.();
684
+ }
598
685
  }
599
686
  function pushHistoryStateWithoutNotify(data, unused, url) {
600
687
  withSuppressedUrlNotifications(() => {
@@ -620,6 +707,15 @@ function saveScrollPosition() {
620
707
  __vinext_scrollY: window.scrollY
621
708
  }, "");
622
709
  }
710
+ function commitHashOnlyHistoryState(href, mode, scroll) {
711
+ const commitAppRouterHashNavigation = window.__VINEXT_RSC_COMMIT_HASH_NAVIGATION__;
712
+ if (commitAppRouterHashNavigation) {
713
+ commitAppRouterHashNavigation(href, mode, scroll);
714
+ return;
715
+ }
716
+ if (mode === "replace") replaceHistoryStateWithoutNotify(null, "", href);
717
+ else pushHistoryStateWithoutNotify(null, "", href);
718
+ }
623
719
  /**
624
720
  * Restore scroll position from a history state object (used on popstate).
625
721
  *
@@ -670,10 +766,9 @@ async function navigateClientSide(href, mode, scroll, programmaticTransition = f
670
766
  if (mode === "push") saveScrollPosition();
671
767
  if (isHashOnlyChange(fullHref)) {
672
768
  const hash = fullHref.includes("#") ? fullHref.slice(fullHref.indexOf("#")) : "";
673
- if (mode === "replace") replaceHistoryStateWithoutNotify(null, "", fullHref);
674
- else pushHistoryStateWithoutNotify(null, "", fullHref);
769
+ commitHashOnlyHistoryState(fullHref, mode, scroll);
675
770
  commitClientNavigationState();
676
- if (scroll) scrollToHash(hash);
771
+ if (scroll) scrollToHashTarget(hash);
677
772
  return;
678
773
  }
679
774
  const hashIdx = fullHref.indexOf("#");
@@ -684,19 +779,17 @@ async function navigateClientSide(href, mode, scroll, programmaticTransition = f
684
779
  else pushHistoryStateWithoutNotify(null, "", fullHref);
685
780
  commitClientNavigationState();
686
781
  }
687
- if (scroll) if (hash) scrollToHash(hash);
782
+ if (scroll) if (hash) scrollToHashTarget(hash);
688
783
  else window.scrollTo(0, 0);
689
784
  }
690
785
  /**
691
- * App Router public router instance. Mirrors Next.js's
692
- * `publicAppRouterInstance` from
693
- * `packages/next/src/client/components/app-router-instance.ts`.
786
+ * Public App Router instance, exposed for the browser entry so it can wire
787
+ * `window.next.router` to the same singleton returned from `useRouter()`.
694
788
  *
695
- * Exported so the App Router browser entry can install it on
696
- * `window.next.router` for Next.js parity (see `client/window-next.ts`).
697
- * Internal callers in this file continue to use `_appRouter` for brevity.
789
+ * Mirrors `publicAppRouterInstance` from Next.js's
790
+ * `packages/next/src/client/components/app-router-instance.ts` (line 392).
698
791
  */
699
- const _appRouter = {
792
+ const appRouterInstance = {
700
793
  bfcacheId: "0",
701
794
  push(href, options) {
702
795
  assertSafeNavigationUrl(href);
@@ -732,12 +825,12 @@ const _appRouter = {
732
825
  React$1.startTransition(navigate);
733
826
  }
734
827
  },
735
- prefetch(href) {
828
+ prefetch(href, options) {
736
829
  assertSafeNavigationUrl(href);
737
830
  if (isServer) return;
738
831
  (async () => {
739
832
  let prefetchHref = href;
740
- if (href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//")) {
833
+ if (isAbsoluteOrProtocolRelativeUrl(href)) {
741
834
  const localPath = toSameOriginAppPath(href, __basePath);
742
835
  if (localPath == null) return;
743
836
  prefetchHref = localPath;
@@ -750,27 +843,22 @@ const _appRouter = {
750
843
  const rscUrl = await createRscRequestUrl(fullHref, headers);
751
844
  const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
752
845
  const prefetched = getPrefetchedUrls();
753
- if (prefetched.has(cacheKey)) return;
846
+ if (prefetched.has(cacheKey)) {
847
+ attachPrefetchInvalidationCallback(cacheKey, options?.onInvalidate);
848
+ return;
849
+ }
754
850
  prefetched.add(cacheKey);
755
851
  prefetchRscResponse(rscUrl, fetch(rscUrl, {
756
852
  headers,
757
853
  credentials: "include",
758
854
  priority: "low"
759
- }), interceptionContext, mountedSlotsHeader);
855
+ }), interceptionContext, mountedSlotsHeader, options);
760
856
  })().catch((error) => {
761
857
  console.error("[vinext] RSC prefetch setup error:", error);
762
858
  });
763
859
  }
764
860
  };
765
861
  /**
766
- * Public App Router instance, exposed for the browser entry so it can wire
767
- * `window.next.router` to the same singleton returned from `useRouter()`.
768
- *
769
- * Mirrors `publicAppRouterInstance` from Next.js's
770
- * `packages/next/src/client/components/app-router-instance.ts` (line 392).
771
- */
772
- const appRouterInstance = _appRouter;
773
- /**
774
862
  * App Router's useRouter — returns push/replace/back/forward/refresh.
775
863
  * Different from Pages Router's useRouter (next/router).
776
864
  *
@@ -779,7 +867,10 @@ const appRouterInstance = _appRouter;
779
867
  * (e.g. useMemo / useEffect deps, React.memo) don't re-render unnecessarily.
780
868
  */
781
869
  function useRouter() {
782
- return _appRouter;
870
+ if (!AppRouterContext || typeof React$1.useContext !== "function") throw new Error("invariant expected app router to be mounted");
871
+ const router = React$1.useContext(AppRouterContext);
872
+ if (router === null) throw new Error("invariant expected app router to be mounted");
873
+ return router;
783
874
  }
784
875
  /**
785
876
  * Returns the active child segment one level below the layout where it's called.
@@ -964,6 +1055,165 @@ function forbidden() {
964
1055
  function unauthorized() {
965
1056
  throw new VinextNavigationError("NEXT_UNAUTHORIZED", `${HTTP_ERROR_FALLBACK_ERROR_CODE};401`);
966
1057
  }
1058
+ /**
1059
+ * Check whether an error was produced by `redirect()` or `permanentRedirect()`.
1060
+ *
1061
+ * **Note on vinext public surface:** Next.js does NOT expose `isRedirectError`
1062
+ * from `next/navigation` — it's an internal predicate. vinext exposes it for
1063
+ * symmetry with the already-public `isHTTPAccessFallbackError` and because
1064
+ * `unstable_rethrow` consumers benefit from being able to narrow types.
1065
+ * Treat it as a vinext-only extension.
1066
+ *
1067
+ * **Divergence from Next.js:** Next.js's internal `isRedirectError` performs
1068
+ * full 4-segment validation — it splits the digest on `;`, checks `type` ∈
1069
+ * {push, replace}, requires a non-empty destination, and validates the
1070
+ * status code (303, 307, 308). See:
1071
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/redirect-error.ts
1072
+ *
1073
+ * vinext instead uses a simple prefix check (`startsWith("NEXT_REDIRECT;")`).
1074
+ * Reasons:
1075
+ * 1. vinext emits two digest shapes — 3-part for `redirect()`
1076
+ * (`NEXT_REDIRECT;{type};{encoded-url}`) and 4-part for
1077
+ * `permanentRedirect()` (`NEXT_REDIRECT;{type};{encoded-url};308`).
1078
+ * Strict validation would have to special-case both, and Next.js's
1079
+ * validator (tuned to its 5-part canary digests) rejects them.
1080
+ * 2. The `type` field is sometimes empty in vinext's redirect digests
1081
+ * (context-dependent resolution; see `redirect()` above), which the
1082
+ * strict check disallows.
1083
+ *
1084
+ * **Consequence:** A malformed digest such as `"NEXT_REDIRECT;garbage"`
1085
+ * returns `true` here, whereas Next.js would return `false`. In practice,
1086
+ * the only callers of this predicate are vinext-internal code paths
1087
+ * (`unstable_rethrow`, `unstable_catchError`, the redirect error boundary)
1088
+ * that see digests vinext itself emits — so the divergence does not surface
1089
+ * in normal use. Maintainers extending the prefix logic should keep this
1090
+ * predicate in lockstep with the corresponding `decode*` helpers in
1091
+ * `shims/error-boundary.tsx`.
1092
+ */
1093
+ function isRedirectError(error) {
1094
+ if (!error || typeof error !== "object" || !("digest" in error) || typeof error.digest !== "string") return false;
1095
+ return error.digest.startsWith("NEXT_REDIRECT;");
1096
+ }
1097
+ /**
1098
+ * Returns true if the error is a Next.js navigation signal — either a redirect
1099
+ * or an HTTP access fallback (notFound / forbidden / unauthorized).
1100
+ *
1101
+ * **Note on vinext public surface:** Like `isRedirectError`, Next.js does NOT
1102
+ * expose this from `next/navigation`. vinext exposes it for symmetry — treat
1103
+ * it as a vinext-only extension.
1104
+ *
1105
+ * Ported from Next.js:
1106
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/is-next-router-error.ts
1107
+ */
1108
+ function isNextRouterError(error) {
1109
+ return isRedirectError(error) || isHTTPAccessFallbackError(error);
1110
+ }
1111
+ const _BAILOUT_TO_CSR_DIGEST = "BAILOUT_TO_CLIENT_SIDE_RENDERING";
1112
+ /**
1113
+ * Error thrown to bail out of server rendering and fall back to client-side
1114
+ * rendering. Used by `next/dynamic` with `ssr: false`.
1115
+ *
1116
+ * vinext does not yet emit this error itself — it's exposed so user code and
1117
+ * third-party libraries that mimic `next/dynamic`'s bailout semantics can
1118
+ * construct an error with the canonical digest that `unstable_rethrow`
1119
+ * recognises.
1120
+ *
1121
+ * Ported 1:1 from Next.js:
1122
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/lazy-dynamic/bailout-to-csr.ts
1123
+ */
1124
+ var BailoutToCSRError = class extends Error {
1125
+ digest = _BAILOUT_TO_CSR_DIGEST;
1126
+ reason;
1127
+ constructor(reason) {
1128
+ super(`Bail out to client-side rendering: ${reason}`);
1129
+ this.reason = reason;
1130
+ }
1131
+ };
1132
+ /**
1133
+ * Returns true if the error is a `BailoutToCSRError`. Matches Next.js's
1134
+ * digest-based predicate, so any error from a foreign module instance of
1135
+ * the class (or constructed manually with the canonical digest) is also
1136
+ * detected.
1137
+ *
1138
+ * **Note on vinext public surface:** Next.js does NOT expose this from
1139
+ * `next/navigation`. vinext exposes it for symmetry with `isRedirectError`
1140
+ * — treat it as a vinext-only extension. The matching producer
1141
+ * (`BailoutToCSRError`) is the public detection contract; Next.js exposes
1142
+ * neither.
1143
+ *
1144
+ * Ported from Next.js:
1145
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/lazy-dynamic/bailout-to-csr.ts
1146
+ */
1147
+ function isBailoutToCSRError(error) {
1148
+ if (!error || typeof error !== "object" || !("digest" in error)) return false;
1149
+ return error.digest === _BAILOUT_TO_CSR_DIGEST;
1150
+ }
1151
+ const _DYNAMIC_SERVER_USAGE_DIGEST = "DYNAMIC_SERVER_USAGE";
1152
+ /**
1153
+ * Error thrown when dynamic server APIs (`cookies()`, `headers()`, etc.) are
1154
+ * used inside a static/prerender context. Carries the `DYNAMIC_SERVER_USAGE`
1155
+ * digest so `unstable_rethrow` can recognise and propagate it.
1156
+ *
1157
+ * vinext does not construct this error itself — exposed for the same
1158
+ * "stable detection contract" reason as `BailoutToCSRError` above.
1159
+ *
1160
+ * Ported 1:1 from Next.js:
1161
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/hooks-server-context.ts
1162
+ */
1163
+ var DynamicServerError = class extends Error {
1164
+ digest = _DYNAMIC_SERVER_USAGE_DIGEST;
1165
+ description;
1166
+ constructor(description) {
1167
+ super(`Dynamic server usage: ${description}`);
1168
+ this.description = description;
1169
+ }
1170
+ };
1171
+ /**
1172
+ * Returns true if the error is a `DynamicServerError` (or any error with the
1173
+ * canonical `DYNAMIC_SERVER_USAGE` digest).
1174
+ *
1175
+ * **Note on vinext public surface:** Next.js does NOT expose this from
1176
+ * `next/navigation`. vinext exposes it for symmetry — treat it as a
1177
+ * vinext-only extension.
1178
+ *
1179
+ * Ported from Next.js:
1180
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/hooks-server-context.ts
1181
+ */
1182
+ function isDynamicServerError(error) {
1183
+ if (!error || typeof error !== "object" || !("digest" in error)) return false;
1184
+ return error.digest === _DYNAMIC_SERVER_USAGE_DIGEST;
1185
+ }
1186
+ /**
1187
+ * Rethrow internal Next.js errors so they're handled by the framework.
1188
+ *
1189
+ * When wrapping an API that uses errors for control flow (redirect, notFound,
1190
+ * cookies in static render, `next/dynamic` SSR bailout, etc.), call this
1191
+ * inside `catch` blocks before doing your own error handling. If the error
1192
+ * is a Next.js internal error, it's rethrown; otherwise this is a no-op
1193
+ * (apart from recursing through `error.cause`).
1194
+ *
1195
+ * Recognises (matches Next.js's browser build + the subset of the server
1196
+ * build that vinext can realistically encounter):
1197
+ * - `isNextRouterError`: redirect / notFound / forbidden / unauthorized
1198
+ * - `isBailoutToCSRError`: `next/dynamic` `ssr: false` bailout
1199
+ * - `isDynamicServerError`: dynamic API used in static render
1200
+ *
1201
+ * vinext does not yet recognise four additional server-only Next.js
1202
+ * categories — `isDynamicPostpone`, `isPostpone`,
1203
+ * `isHangingPromiseRejectionError`, `isPrerenderInterruptedError` — because
1204
+ * they signal PPR / prerender-controller events that vinext's render
1205
+ * pipeline does not generate. User code cannot construct these in normal
1206
+ * use; they will be added if/when vinext grows PPR support.
1207
+ *
1208
+ * Ported from Next.js:
1209
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/unstable-rethrow.ts
1210
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/unstable-rethrow.server.ts
1211
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/unstable-rethrow.browser.ts
1212
+ */
1213
+ function unstable_rethrow(error) {
1214
+ if (isNextRouterError(error) || isBailoutToCSRError(error) || isDynamicServerError(error)) throw error;
1215
+ if (error instanceof Error && "cause" in error) unstable_rethrow(error.cause);
1216
+ }
967
1217
  if (!isServer) {
968
1218
  const state = getClientNavigationState();
969
1219
  if (state && !state.patchInstalled) {
@@ -975,16 +1225,16 @@ if (!isServer) {
975
1225
  }
976
1226
  });
977
1227
  window.history.pushState = function patchedPushState(data, unused, url) {
978
- state.originalPushState.call(window.history, data, unused, url);
1228
+ state.originalPushState.call(window.history, createExternalHistoryStatePreservingMetadata(data, window.history.state), unused, url);
979
1229
  if (state.suppressUrlNotifyCount === 0) commitClientNavigationState();
980
1230
  };
981
1231
  window.history.replaceState = function patchedReplaceState(data, unused, url) {
982
- state.originalReplaceState.call(window.history, data, unused, url);
1232
+ state.originalReplaceState.call(window.history, createExternalHistoryStatePreservingMetadata(data, window.history.state), unused, url);
983
1233
  if (state.suppressUrlNotifyCount === 0) commitClientNavigationState();
984
1234
  };
985
1235
  }
986
1236
  }
987
1237
  //#endregion
988
- export { GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, PREFETCH_CACHE_TTL, ReadonlyURLSearchParams, RedirectType, ServerInsertedHTMLContext, __basePath, _registerStateAccessors, activateNavigationSnapshot, appRouterInstance, clearPendingPathname, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, createClientNavigationRenderSnapshot, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getClientNavigationRenderContext, getClientNavigationState, getClientParams, getCurrentInterceptionContext, getCurrentNextUrl, getLayoutSegmentContext, getMountedSlotsHeader, getNavigationContext, getPrefetchCache, getPrefetchedUrls, isHTTPAccessFallbackError, navigateClientSide, notFound, permanentRedirect, prefetchRscResponse, pushHistoryStateWithoutNotify, redirect, renderServerInsertedHTML, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, storePrefetchResponse, unauthorized, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
1238
+ export { BailoutToCSRError, DynamicServerError, GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, PREFETCH_CACHE_TTL, ReadonlyURLSearchParams, RedirectType, ServerInsertedHTMLContext, UnrecognizedActionError, __basePath, _registerStateAccessors, activateNavigationSnapshot, appRouterInstance, clearPendingPathname, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getClientNavigationRenderContext, getClientNavigationState, getClientParams, getCurrentInterceptionContext, getCurrentNextUrl, getLayoutSegmentContext, getMountedSlotsHeader, getNavigationContext, getPrefetchCache, getPrefetchedUrls, invalidatePrefetchCache, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, navigateClientSide, notFound, permanentRedirect, prefetchRscResponse, pushHistoryStateWithoutNotify, redirect, renderServerInsertedHTML, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, storePrefetchResponse, unauthorized, unstable_isUnrecognizedActionError, unstable_rethrow, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
989
1239
 
990
1240
  //# sourceMappingURL=navigation.js.map