vinext 0.0.41 → 0.0.42

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 (162) hide show
  1. package/README.md +0 -1
  2. package/dist/build/client-build-config.d.ts +119 -0
  3. package/dist/build/client-build-config.js +149 -0
  4. package/dist/build/client-build-config.js.map +1 -0
  5. package/dist/build/layout-classification-types.d.ts +62 -0
  6. package/dist/build/layout-classification-types.js +1 -0
  7. package/dist/build/layout-classification.d.ts +60 -0
  8. package/dist/build/layout-classification.js +98 -0
  9. package/dist/build/layout-classification.js.map +1 -0
  10. package/dist/build/report.d.ts +15 -1
  11. package/dist/build/report.js +50 -1
  12. package/dist/build/report.js.map +1 -1
  13. package/dist/build/route-classification-manifest.d.ts +53 -0
  14. package/dist/build/route-classification-manifest.js +145 -0
  15. package/dist/build/route-classification-manifest.js.map +1 -0
  16. package/dist/build/run-prerender.js +1 -1
  17. package/dist/build/ssr-manifest.d.ts +19 -0
  18. package/dist/build/ssr-manifest.js +71 -0
  19. package/dist/build/ssr-manifest.js.map +1 -0
  20. package/dist/check.js +2 -2
  21. package/dist/check.js.map +1 -1
  22. package/dist/cli.js +1 -1
  23. package/dist/client/entry.js +1 -1
  24. package/dist/config/config-matchers.js +1 -0
  25. package/dist/config/config-matchers.js.map +1 -1
  26. package/dist/entries/app-rsc-entry.js +287 -95
  27. package/dist/entries/app-rsc-entry.js.map +1 -1
  28. package/dist/index.d.ts +1 -169
  29. package/dist/index.js +112 -432
  30. package/dist/index.js.map +1 -1
  31. package/dist/plugins/fonts.d.ts +49 -1
  32. package/dist/plugins/fonts.js +96 -3
  33. package/dist/plugins/fonts.js.map +1 -1
  34. package/dist/plugins/postcss.d.ts +27 -0
  35. package/dist/plugins/postcss.js +94 -0
  36. package/dist/plugins/postcss.js.map +1 -0
  37. package/dist/plugins/strip-server-exports.d.ts +14 -0
  38. package/dist/plugins/strip-server-exports.js +73 -0
  39. package/dist/plugins/strip-server-exports.js.map +1 -0
  40. package/dist/routing/app-router.d.ts +6 -4
  41. package/dist/routing/app-router.js +21 -22
  42. package/dist/routing/app-router.js.map +1 -1
  43. package/dist/server/app-browser-entry.js +235 -97
  44. package/dist/server/app-browser-entry.js.map +1 -1
  45. package/dist/server/app-browser-error.d.ts +8 -0
  46. package/dist/server/app-browser-error.js +9 -0
  47. package/dist/server/app-browser-error.js.map +1 -0
  48. package/dist/server/app-browser-state.d.ts +93 -0
  49. package/dist/server/app-browser-state.js +132 -0
  50. package/dist/server/app-browser-state.js.map +1 -0
  51. package/dist/server/app-elements.d.ts +92 -0
  52. package/dist/server/app-elements.js +122 -0
  53. package/dist/server/app-elements.js.map +1 -0
  54. package/dist/server/app-page-boundary-render.d.ts +2 -1
  55. package/dist/server/app-page-boundary-render.js +40 -1
  56. package/dist/server/app-page-boundary-render.js.map +1 -1
  57. package/dist/server/app-page-cache.d.ts +6 -3
  58. package/dist/server/app-page-cache.js +14 -8
  59. package/dist/server/app-page-cache.js.map +1 -1
  60. package/dist/server/app-page-execution.d.ts +36 -3
  61. package/dist/server/app-page-execution.js +50 -10
  62. package/dist/server/app-page-execution.js.map +1 -1
  63. package/dist/server/app-page-probe.d.ts +10 -4
  64. package/dist/server/app-page-probe.js +24 -15
  65. package/dist/server/app-page-probe.js.map +1 -1
  66. package/dist/server/app-page-render.d.ts +7 -4
  67. package/dist/server/app-page-render.js +13 -4
  68. package/dist/server/app-page-render.js.map +1 -1
  69. package/dist/server/app-page-request.d.ts +52 -4
  70. package/dist/server/app-page-request.js +86 -16
  71. package/dist/server/app-page-request.js.map +1 -1
  72. package/dist/server/app-page-response.d.ts +1 -0
  73. package/dist/server/app-page-response.js +1 -0
  74. package/dist/server/app-page-response.js.map +1 -1
  75. package/dist/server/app-page-route-wiring.d.ts +22 -8
  76. package/dist/server/app-page-route-wiring.js +219 -83
  77. package/dist/server/app-page-route-wiring.js.map +1 -1
  78. package/dist/server/app-render-dependency.d.ts +13 -0
  79. package/dist/server/app-render-dependency.js +35 -0
  80. package/dist/server/app-render-dependency.js.map +1 -0
  81. package/dist/server/app-route-handler-execution.d.ts +1 -0
  82. package/dist/server/app-route-handler-execution.js +1 -0
  83. package/dist/server/app-route-handler-execution.js.map +1 -1
  84. package/dist/server/app-route-handler-runtime.d.ts +1 -0
  85. package/dist/server/app-route-handler-runtime.js +26 -1
  86. package/dist/server/app-route-handler-runtime.js.map +1 -1
  87. package/dist/server/app-ssr-entry.js +6 -2
  88. package/dist/server/app-ssr-entry.js.map +1 -1
  89. package/dist/server/dev-server.js +2 -4
  90. package/dist/server/dev-server.js.map +1 -1
  91. package/dist/server/middleware.js +1 -5
  92. package/dist/server/middleware.js.map +1 -1
  93. package/dist/server/prod-server.d.ts +3 -3
  94. package/dist/server/prod-server.js +1 -1
  95. package/dist/server/prod-server.js.map +1 -1
  96. package/dist/server/request-pipeline.d.ts +2 -1
  97. package/dist/server/request-pipeline.js +34 -5
  98. package/dist/server/request-pipeline.js.map +1 -1
  99. package/dist/shims/cache-runtime.d.ts +1 -0
  100. package/dist/shims/cache-runtime.js +0 -5
  101. package/dist/shims/cache-runtime.js.map +1 -1
  102. package/dist/shims/cache.d.ts +1 -0
  103. package/dist/shims/cache.js +1 -8
  104. package/dist/shims/cache.js.map +1 -1
  105. package/dist/shims/client-hook-error.d.ts +14 -0
  106. package/dist/shims/client-hook-error.js +19 -0
  107. package/dist/shims/client-hook-error.js.map +1 -0
  108. package/dist/shims/constants.d.ts +3 -3
  109. package/dist/shims/constants.js +3 -3
  110. package/dist/shims/constants.js.map +1 -1
  111. package/dist/shims/document.d.ts +6 -6
  112. package/dist/shims/error-boundary.d.ts +4 -4
  113. package/dist/shims/error-boundary.js +1 -1
  114. package/dist/shims/error-boundary.js.map +1 -1
  115. package/dist/shims/form.d.ts +3 -3
  116. package/dist/shims/head-state.d.ts +1 -0
  117. package/dist/shims/head-state.js +0 -5
  118. package/dist/shims/head-state.js.map +1 -1
  119. package/dist/shims/headers.d.ts +11 -0
  120. package/dist/shims/headers.js +13 -10
  121. package/dist/shims/headers.js.map +1 -1
  122. package/dist/shims/i18n-state.d.ts +1 -0
  123. package/dist/shims/i18n-state.js +0 -4
  124. package/dist/shims/i18n-state.js.map +1 -1
  125. package/dist/shims/internal/app-router-context.d.ts +6 -6
  126. package/dist/shims/internal/router-context.d.ts +2 -2
  127. package/dist/shims/layout-segment-context.d.ts +2 -2
  128. package/dist/shims/link.js +19 -11
  129. package/dist/shims/link.js.map +1 -1
  130. package/dist/shims/metadata.d.ts +3 -3
  131. package/dist/shims/navigation-state.d.ts +2 -0
  132. package/dist/shims/navigation-state.js +0 -13
  133. package/dist/shims/navigation-state.js.map +1 -1
  134. package/dist/shims/navigation.d.ts +55 -8
  135. package/dist/shims/navigation.js +97 -23
  136. package/dist/shims/navigation.js.map +1 -1
  137. package/dist/shims/navigation.react-server.d.ts +14 -0
  138. package/dist/shims/navigation.react-server.js +29 -0
  139. package/dist/shims/navigation.react-server.js.map +1 -0
  140. package/dist/shims/request-context.d.ts +1 -0
  141. package/dist/shims/request-context.js +0 -9
  142. package/dist/shims/request-context.js.map +1 -1
  143. package/dist/shims/request-state-types.d.ts +1 -1
  144. package/dist/shims/router-state.d.ts +1 -0
  145. package/dist/shims/router-state.js +0 -5
  146. package/dist/shims/router-state.js.map +1 -1
  147. package/dist/shims/slot.d.ts +11 -7
  148. package/dist/shims/slot.js +28 -19
  149. package/dist/shims/slot.js.map +1 -1
  150. package/dist/shims/unified-request-context.d.ts +2 -0
  151. package/dist/shims/unified-request-context.js +0 -14
  152. package/dist/shims/unified-request-context.js.map +1 -1
  153. package/dist/utils/mdx-scan.d.ts +10 -0
  154. package/dist/utils/mdx-scan.js +36 -0
  155. package/dist/utils/mdx-scan.js.map +1 -0
  156. package/dist/utils/public-routes.d.ts +5 -0
  157. package/dist/utils/public-routes.js +50 -0
  158. package/dist/utils/public-routes.js.map +1 -0
  159. package/package.json +3 -3
  160. package/dist/plugins/fix-use-server-closure-collision.d.ts +0 -29
  161. package/dist/plugins/fix-use-server-closure-collision.js +0 -204
  162. package/dist/plugins/fix-use-server-closure-collision.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"app-browser-entry.js","names":[],"sources":["../../src/server/app-browser-entry.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport {\n createElement,\n startTransition,\n use,\n useLayoutEffect,\n useState,\n type Dispatch,\n type ReactNode,\n type SetStateAction,\n} from \"react\";\nimport {\n createFromFetch,\n createFromReadableStream,\n createTemporaryReferenceSet,\n encodeReply,\n setServerCallback,\n} from \"@vitejs/plugin-rsc/browser\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport \"../client/instrumentation-client.js\";\nimport { notifyAppRouterTransitionStart } from \"../client/instrumentation-client-state.js\";\nimport {\n __basePath,\n activateNavigationSnapshot,\n commitClientNavigationState,\n consumePrefetchResponse,\n createClientNavigationRenderSnapshot,\n getClientNavigationRenderContext,\n getPrefetchCache,\n getPrefetchedUrls,\n pushHistoryStateWithoutNotify,\n replaceClientParamsWithoutNotify,\n replaceHistoryStateWithoutNotify,\n restoreRscResponse,\n setClientParams,\n snapshotRscResponse,\n setNavigationContext,\n toRscUrl,\n type CachedRscResponse,\n type ClientNavigationRenderSnapshot,\n} from \"../shims/navigation.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport {\n chunksToReadableStream,\n createProgressiveRscStream,\n getVinextBrowserGlobal,\n} from \"./app-browser-stream.js\";\n\ntype SearchParamInput = ConstructorParameters<typeof URLSearchParams>[0];\n\ntype ServerActionResult = {\n root: ReactNode;\n returnValue?: {\n ok: boolean;\n data: unknown;\n };\n};\n\ntype BrowserTreeState = {\n renderId: number;\n node: ReactNode;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n};\ntype NavigationKind = \"navigate\" | \"traverse\" | \"refresh\";\ntype HistoryUpdateMode = \"push\" | \"replace\";\ntype VisitedResponseCacheEntry = {\n params: Record<string, string | string[]>;\n expiresAt: number;\n response: CachedRscResponse;\n};\n\nconst MAX_VISITED_RESPONSE_CACHE_SIZE = 50;\nconst VISITED_RESPONSE_CACHE_TTL = 5 * 60_000;\nconst MAX_TRAVERSAL_CACHE_TTL = 30 * 60_000;\n\n// These are plain module-level variables, unlike ClientNavigationState in\n// navigation.ts which uses Symbol.for to survive multiple Vite module instances.\n// The browser entry is loaded exactly once (via the RSC plugin's generated\n// bootstrap), so module-level state is safe here. If that assumption ever\n// changes, these should be migrated to a Symbol.for-backed global.\n//\n// The most severe consequence of multiple instances would be Map fragmentation:\n// pendingNavigationCommits and pendingNavigationPrePaintEffects would split\n// across instances, so drainPrePaintEffects in one instance could never drain\n// effects queued by the other, permanently leaking navigationSnapshotActiveCount\n// and causing hooks to prefer stale snapshot values indefinitely.\nlet nextNavigationRenderId = 0;\nlet activeNavigationId = 0;\nconst pendingNavigationCommits = new Map<number, () => void>();\nconst pendingNavigationPrePaintEffects = new Map<number, () => void>();\nlet setBrowserTreeState: Dispatch<SetStateAction<BrowserTreeState>> | null = null;\nlet latestClientParams: Record<string, string | string[]> = {};\nconst visitedResponseCache = new Map<string, VisitedResponseCacheEntry>();\n\nfunction isServerActionResult(value: unknown): value is ServerActionResult {\n return !!value && typeof value === \"object\" && \"root\" in value;\n}\n\nfunction getBrowserTreeStateSetter(): Dispatch<SetStateAction<BrowserTreeState>> {\n if (!setBrowserTreeState) {\n throw new Error(\"[vinext] Browser tree state is not initialized\");\n }\n return setBrowserTreeState;\n}\n\nfunction applyClientParams(params: Record<string, string | string[]>): void {\n latestClientParams = params;\n setClientParams(params);\n}\n\nfunction stageClientParams(params: Record<string, string | string[]>): void {\n // NB: latestClientParams diverges from ClientNavigationState.clientParams\n // between staging and commit. Server action snapshots (updateBrowserTree\n // calls inside registerServerActionCallback) read latestClientParams, so a\n // server action fired during this window would get the pending (not yet\n // committed) params. This is acceptable because the commit effect fires\n // synchronously in the same React commit phase, keeping the window\n // vanishingly small.\n latestClientParams = params;\n replaceClientParamsWithoutNotify(params);\n}\n\nfunction clearVisitedResponseCache(): void {\n visitedResponseCache.clear();\n}\n\nfunction clearPrefetchState(): void {\n getPrefetchCache().clear();\n getPrefetchedUrls().clear();\n}\n\nfunction clearClientNavigationCaches(): void {\n clearVisitedResponseCache();\n clearPrefetchState();\n}\n\nfunction queuePrePaintNavigationEffect(renderId: number, effect: (() => void) | null): void {\n if (!effect) {\n return;\n }\n pendingNavigationPrePaintEffects.set(renderId, effect);\n}\n\n/**\n * Run all queued pre-paint effects for renderIds up to and including the\n * given renderId. When React supersedes a startTransition update (rapid\n * clicks on same-route links), the superseded NavigationCommitSignal never\n * mounts, so its pre-paint effect never fires. By draining all effects\n * <= the committed renderId here, the winning transition cleans up after\n * any superseded ones, keeping the counter balanced.\n *\n * Invariant: each superseded navigation gets a commitClientNavigationState()\n * to balance the activateNavigationSnapshot() from its renderNavigationPayload call.\n */\nfunction drainPrePaintEffects(upToRenderId: number): void {\n for (const [id, effect] of pendingNavigationPrePaintEffects) {\n if (id <= upToRenderId) {\n pendingNavigationPrePaintEffects.delete(id);\n if (id === upToRenderId) {\n // Winning navigation: run its actual pre-paint effect\n effect();\n } else {\n // Superseded navigation: balance its activateNavigationSnapshot()\n commitClientNavigationState();\n }\n }\n }\n}\n\nfunction createNavigationCommitEffect(\n href: string,\n historyUpdateMode: HistoryUpdateMode | undefined,\n): () => void {\n return () => {\n const targetHref = new URL(href, window.location.origin).href;\n\n if (historyUpdateMode === \"replace\" && window.location.href !== targetHref) {\n replaceHistoryStateWithoutNotify(null, \"\", href);\n } else if (historyUpdateMode === \"push\" && window.location.href !== targetHref) {\n pushHistoryStateWithoutNotify(null, \"\", href);\n }\n\n commitClientNavigationState();\n };\n}\n\nfunction evictVisitedResponseCacheIfNeeded(): void {\n while (visitedResponseCache.size >= MAX_VISITED_RESPONSE_CACHE_SIZE) {\n const oldest = visitedResponseCache.keys().next().value;\n if (oldest === undefined) {\n return;\n }\n visitedResponseCache.delete(oldest);\n }\n}\n\nfunction getVisitedResponse(\n rscUrl: string,\n navigationKind: NavigationKind,\n): VisitedResponseCacheEntry | null {\n const cached = visitedResponseCache.get(rscUrl);\n if (!cached) {\n return null;\n }\n\n if (navigationKind === \"refresh\") {\n return null;\n }\n\n if (navigationKind === \"traverse\") {\n const createdAt = cached.expiresAt - VISITED_RESPONSE_CACHE_TTL;\n if (Date.now() - createdAt >= MAX_TRAVERSAL_CACHE_TTL) {\n visitedResponseCache.delete(rscUrl);\n return null;\n }\n // LRU: promote to most-recently-used (delete + re-insert moves to end of Map)\n visitedResponseCache.delete(rscUrl);\n visitedResponseCache.set(rscUrl, cached);\n return cached;\n }\n\n if (cached.expiresAt > Date.now()) {\n // LRU: promote to most-recently-used\n visitedResponseCache.delete(rscUrl);\n visitedResponseCache.set(rscUrl, cached);\n return cached;\n }\n\n visitedResponseCache.delete(rscUrl);\n return null;\n}\n\nfunction storeVisitedResponseSnapshot(\n rscUrl: string,\n snapshot: CachedRscResponse,\n params: Record<string, string | string[]>,\n): void {\n visitedResponseCache.delete(rscUrl);\n evictVisitedResponseCacheIfNeeded();\n const now = Date.now();\n visitedResponseCache.set(rscUrl, {\n params,\n expiresAt: now + VISITED_RESPONSE_CACHE_TTL,\n response: snapshot,\n });\n}\n\n/**\n * Resolve all pending navigation commits with renderId <= the committed renderId.\n * Note: Map iteration handles concurrent deletion safely — entries are visited in\n * insertion order and deletion doesn't affect the iterator's view of remaining entries.\n * This pattern is also used in drainPrePaintEffects with the same semantics.\n */\nfunction resolveCommittedNavigations(renderId: number): void {\n for (const [pendingId, resolve] of pendingNavigationCommits) {\n if (pendingId <= renderId) {\n pendingNavigationCommits.delete(pendingId);\n resolve();\n }\n }\n}\n\nfunction NavigationCommitSignal({\n renderId,\n children,\n}: {\n renderId: number;\n children?: ReactNode;\n}) {\n useLayoutEffect(() => {\n drainPrePaintEffects(renderId);\n\n const frame = requestAnimationFrame(() => {\n resolveCommittedNavigations(renderId);\n });\n\n return () => {\n cancelAnimationFrame(frame);\n // Resolve pending commits to prevent callers from hanging if React\n // unmounts this component without committing (e.g., error boundary).\n resolveCommittedNavigations(renderId);\n };\n }, [renderId]);\n\n return children;\n}\n\nfunction BrowserRoot({\n initialNode,\n initialNavigationSnapshot,\n}: {\n initialNode: ReactNode | Promise<ReactNode>;\n initialNavigationSnapshot: ClientNavigationRenderSnapshot;\n}) {\n const resolvedNode = use(initialNode as Promise<ReactNode>);\n const [treeState, setTreeState] = useState<BrowserTreeState>({\n renderId: 0,\n node: resolvedNode,\n navigationSnapshot: initialNavigationSnapshot,\n });\n\n // Assign the module-level setter via useLayoutEffect instead of during render\n // to avoid side effects that React Strict Mode / concurrent features may\n // call multiple times. useLayoutEffect fires synchronously during commit,\n // before hydrateRoot returns to main(), so setBrowserTreeState is available\n // before __VINEXT_RSC_NAVIGATE__ is assigned. setTreeState is referentially\n // stable so the effect only runs on mount.\n useLayoutEffect(() => {\n setBrowserTreeState = setTreeState;\n }, []); // eslint-disable-line react-hooks/exhaustive-deps -- setTreeState is referentially stable\n\n const committedTree = createElement(\n NavigationCommitSignal,\n { renderId: treeState.renderId },\n treeState.node,\n );\n\n const ClientNavigationRenderContext = getClientNavigationRenderContext();\n if (!ClientNavigationRenderContext) {\n return committedTree;\n }\n\n return createElement(\n ClientNavigationRenderContext.Provider,\n { value: treeState.navigationSnapshot },\n committedTree,\n );\n}\n\nfunction updateBrowserTree(\n node: ReactNode | Promise<ReactNode>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n renderId: number,\n useTransitionMode: boolean,\n snapshotActivated = false,\n): void {\n const setter = getBrowserTreeStateSetter();\n\n const resolvedThenSet = (resolvedNode: ReactNode) => {\n setter({ renderId, node: resolvedNode, navigationSnapshot });\n };\n\n // Balance the activate/commit pairing if the async payload rejects after\n // activateNavigationSnapshot() was called. Only decrement when snapshotActivated\n // is true — server action callers skip renderNavigationPayload entirely and\n // never call activateNavigationSnapshot(), so decrementing there would corrupt\n // the counter for any concurrent RSC navigation.\n const handleAsyncError = () => {\n pendingNavigationPrePaintEffects.delete(renderId);\n const resolve = pendingNavigationCommits.get(renderId);\n pendingNavigationCommits.delete(renderId);\n if (snapshotActivated) {\n commitClientNavigationState();\n }\n resolve?.();\n };\n\n if (node != null && typeof (node as PromiseLike<ReactNode>).then === \"function\") {\n const thenable = node as PromiseLike<ReactNode>;\n if (useTransitionMode) {\n void thenable.then(\n (resolved) => startTransition(() => resolvedThenSet(resolved)),\n handleAsyncError,\n );\n } else {\n void thenable.then(resolvedThenSet, handleAsyncError);\n }\n return;\n }\n\n const syncNode = node as ReactNode;\n if (useTransitionMode) {\n startTransition(() => resolvedThenSet(syncNode));\n return;\n }\n\n resolvedThenSet(syncNode);\n}\n\nfunction renderNavigationPayload(\n payload: Promise<ReactNode> | ReactNode,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n prePaintEffect: (() => void) | null = null,\n useTransition = true,\n): Promise<void> {\n const renderId = ++nextNavigationRenderId;\n queuePrePaintNavigationEffect(renderId, prePaintEffect);\n\n const committed = new Promise<void>((resolve) => {\n pendingNavigationCommits.set(renderId, resolve);\n });\n\n activateNavigationSnapshot();\n\n // Wrap updateBrowserTree in try-catch to ensure counter is decremented\n // if a synchronous error occurs before the async promise chain is established.\n try {\n updateBrowserTree(payload, navigationSnapshot, renderId, useTransition, true);\n } catch (error) {\n // Clean up pending state and decrement counter on synchronous error.\n pendingNavigationPrePaintEffects.delete(renderId);\n const resolve = pendingNavigationCommits.get(renderId);\n pendingNavigationCommits.delete(renderId);\n commitClientNavigationState();\n resolve?.();\n throw error; // Re-throw to maintain error propagation\n }\n\n return committed;\n}\n\nfunction restoreHydrationNavigationContext(\n pathname: string,\n searchParams: SearchParamInput,\n params: Record<string, string | string[]>,\n): void {\n setNavigationContext({\n pathname,\n searchParams: new URLSearchParams(searchParams),\n params,\n });\n}\n\nfunction restorePopstateScrollPosition(state: unknown): void {\n if (!(state && typeof state === \"object\" && \"__vinext_scrollY\" in state)) {\n return;\n }\n\n const y = Number(state.__vinext_scrollY);\n const x = \"__vinext_scrollX\" in state ? Number(state.__vinext_scrollX) : 0;\n\n requestAnimationFrame(() => {\n window.scrollTo(x, y);\n });\n}\n\nasync function readInitialRscStream(): Promise<ReadableStream<Uint8Array>> {\n const vinext = getVinextBrowserGlobal();\n\n if (vinext.__VINEXT_RSC__ || vinext.__VINEXT_RSC_CHUNKS__ || vinext.__VINEXT_RSC_DONE__) {\n if (vinext.__VINEXT_RSC__) {\n const embedData = vinext.__VINEXT_RSC__;\n delete vinext.__VINEXT_RSC__;\n\n const params = embedData.params ?? {};\n if (embedData.params) {\n applyClientParams(embedData.params);\n }\n if (embedData.nav) {\n restoreHydrationNavigationContext(\n embedData.nav.pathname,\n embedData.nav.searchParams,\n params,\n );\n }\n\n return chunksToReadableStream(embedData.rsc);\n }\n\n const params = vinext.__VINEXT_RSC_PARAMS__ ?? {};\n if (vinext.__VINEXT_RSC_PARAMS__) {\n applyClientParams(vinext.__VINEXT_RSC_PARAMS__);\n }\n if (vinext.__VINEXT_RSC_NAV__) {\n restoreHydrationNavigationContext(\n vinext.__VINEXT_RSC_NAV__.pathname,\n vinext.__VINEXT_RSC_NAV__.searchParams,\n params,\n );\n }\n\n return createProgressiveRscStream();\n }\n\n const rscResponse = await fetch(toRscUrl(window.location.pathname + window.location.search));\n\n let params: Record<string, string | string[]> = {};\n const paramsHeader = rscResponse.headers.get(\"X-Vinext-Params\");\n if (paramsHeader) {\n try {\n params = JSON.parse(decodeURIComponent(paramsHeader)) as Record<string, string | string[]>;\n applyClientParams(params);\n } catch {\n // Ignore malformed param headers and continue with hydration.\n }\n }\n\n restoreHydrationNavigationContext(window.location.pathname, window.location.search, params);\n\n if (!rscResponse.body) {\n throw new Error(\"[vinext] Initial RSC response had no body\");\n }\n\n return rscResponse.body;\n}\n\nfunction registerServerActionCallback(): void {\n setServerCallback(async (id, args) => {\n const temporaryReferences = createTemporaryReferenceSet();\n const body = await encodeReply(args, { temporaryReferences });\n\n const fetchResponse = await fetch(toRscUrl(window.location.pathname + window.location.search), {\n method: \"POST\",\n headers: { \"x-rsc-action\": id },\n body,\n });\n\n const actionRedirect = fetchResponse.headers.get(\"x-action-redirect\");\n if (actionRedirect) {\n // Check for external URLs that need a hard redirect.\n try {\n const redirectUrl = new URL(actionRedirect, window.location.origin);\n if (redirectUrl.origin !== window.location.origin) {\n window.location.href = actionRedirect;\n return undefined;\n }\n } catch {\n // Fall through to hard redirect below if URL parsing fails.\n }\n\n // Use hard redirect for all action redirects because vinext's server\n // currently returns an empty body for redirect responses. RSC navigation\n // requires a valid RSC payload. This is a known parity gap with Next.js,\n // which pre-renders the redirect target's RSC payload.\n const redirectType = fetchResponse.headers.get(\"x-action-redirect-type\") ?? \"replace\";\n if (redirectType === \"push\") {\n window.location.assign(actionRedirect);\n } else {\n window.location.replace(actionRedirect);\n }\n return undefined;\n }\n\n clearClientNavigationCaches();\n\n const result = await createFromFetch<ServerActionResult | ReactNode>(\n Promise.resolve(fetchResponse),\n { temporaryReferences },\n );\n\n // Note: Server actions update the tree via updateBrowserTree directly (not\n // renderNavigationPayload) because they stay on the same URL. This means\n // activateNavigationSnapshot is not called, so hooks use useSyncExternalStore\n // values directly. snapshotActivated is intentionally omitted (defaults false)\n // so handleAsyncError skips commitClientNavigationState() — decrementing an\n // unincremented counter would corrupt it for concurrent RSC navigations.\n // If server actions ever trigger URL changes via RSC payload (instead of hard\n // redirects), this would need renderNavigationPayload() + snapshotActivated=true.\n if (isServerActionResult(result)) {\n updateBrowserTree(\n result.root,\n createClientNavigationRenderSnapshot(window.location.href, latestClientParams),\n ++nextNavigationRenderId,\n false,\n );\n if (result.returnValue) {\n if (!result.returnValue.ok) throw result.returnValue.data;\n return result.returnValue.data;\n }\n return undefined;\n }\n\n // Same reasoning as above: snapshotActivated omitted intentionally.\n updateBrowserTree(\n result,\n createClientNavigationRenderSnapshot(window.location.href, latestClientParams),\n ++nextNavigationRenderId,\n false,\n );\n return result;\n });\n}\n\nasync function main(): Promise<void> {\n registerServerActionCallback();\n\n const rscStream = await readInitialRscStream();\n const root = createFromReadableStream<ReactNode>(rscStream);\n const initialNavigationSnapshot = createClientNavigationRenderSnapshot(\n window.location.href,\n latestClientParams,\n );\n\n window.__VINEXT_RSC_ROOT__ = hydrateRoot(\n document,\n createElement(BrowserRoot, {\n initialNode: root,\n initialNavigationSnapshot,\n }),\n import.meta.env.DEV ? { onCaughtError() {} } : undefined,\n );\n window.__VINEXT_HYDRATED_AT = performance.now();\n\n window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(\n href: string,\n redirectDepth = 0,\n navigationKind: NavigationKind = \"navigate\",\n historyUpdateMode?: HistoryUpdateMode,\n ): Promise<void> {\n if (redirectDepth > 10) {\n console.error(\n \"[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.\",\n );\n window.location.href = href;\n return;\n }\n\n let _snapshotPending = false;\n // Hoist navId above try so the catch block can guard against hard-navigating\n // to a stale URL when this navigation has already been superseded.\n const navId = ++activeNavigationId;\n try {\n const url = new URL(href, window.location.origin);\n const rscUrl = toRscUrl(url.pathname + url.search);\n // Use startTransition for same-route navigations (searchParam changes)\n // so React keeps the old UI visible during the transition. For cross-route\n // navigations (different pathname), use synchronous updates — React's\n // startTransition hangs in Firefox when replacing the entire tree.\n // NB: During rapid navigations, window.location.pathname may not reflect\n // the previous navigation's URL yet (URL commit is deferred). This could\n // cause misclassification (synchronous instead of startTransition or vice\n // versa), resulting in slightly less smooth transitions but correct behavior.\n const isSameRoute =\n stripBasePath(url.pathname, __basePath) ===\n stripBasePath(window.location.pathname, __basePath);\n const cachedRoute = getVisitedResponse(rscUrl, navigationKind);\n const navigationCommitEffect = createNavigationCommitEffect(href, historyUpdateMode);\n\n if (cachedRoute) {\n // Check stale-navigation before and after createFromFetch. The pre-check\n // avoids wasted parse work; the post-check catches supersessions that\n // occur during the await. createFromFetch on a buffered response is fast\n // but still async, so the window exists. The non-cached path (below) places\n // its heavyweight async steps (fetch, snapshotRscResponse, createFromFetch)\n // between navId checks consistently; the cached path omits the check between\n // createClientNavigationRenderSnapshot (synchronous) and createFromFetch\n // because there is no await in that gap.\n if (navId !== activeNavigationId) return;\n const cachedParams = cachedRoute.params;\n // createClientNavigationRenderSnapshot is synchronous (URL parsing + param\n // wrapping only) — no stale-navigation recheck needed between here and the\n // next await.\n const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(href, cachedParams);\n const cachedPayload = await createFromFetch<ReactNode>(\n Promise.resolve(restoreRscResponse(cachedRoute.response)),\n );\n if (navId !== activeNavigationId) return;\n // Stage params only after confirming this navigation hasn't been superseded.\n // Set _snapshotPending before stageClientParams: if renderNavigationPayload\n // throws synchronously, its inner catch calls commitClientNavigationState()\n // which would flush pendingClientParams for a route that never rendered.\n // Ordering _snapshotPending first makes the intent explicit — params are\n // staged as part of an in-flight snapshot, not as a standalone side-effect.\n _snapshotPending = true; // Set before renderNavigationPayload\n stageClientParams(cachedParams); // NB: if this throws, outer catch hard-navigates, resetting all JS state\n try {\n await renderNavigationPayload(\n cachedPayload,\n cachedNavigationSnapshot,\n navigationCommitEffect,\n isSameRoute,\n );\n } finally {\n // Always clear _snapshotPending so the outer catch does not\n // double-decrement if renderNavigationPayload throws.\n _snapshotPending = false;\n }\n return;\n }\n\n let navResponse: Response | undefined;\n let navResponseUrl: string | null = null;\n if (navigationKind !== \"refresh\") {\n const prefetchedResponse = consumePrefetchResponse(rscUrl);\n if (prefetchedResponse) {\n navResponse = restoreRscResponse(prefetchedResponse, false);\n navResponseUrl = prefetchedResponse.url;\n }\n }\n\n if (!navResponse) {\n navResponse = await fetch(rscUrl, {\n headers: { Accept: \"text/x-component\" },\n credentials: \"include\",\n });\n }\n\n if (navId !== activeNavigationId) return;\n\n const finalUrl = new URL(navResponseUrl ?? navResponse.url, window.location.origin);\n const requestedUrl = new URL(rscUrl, window.location.origin);\n\n if (finalUrl.pathname !== requestedUrl.pathname) {\n const destinationPath = finalUrl.pathname.replace(/\\.rsc$/, \"\") + finalUrl.search;\n replaceHistoryStateWithoutNotify(null, \"\", destinationPath);\n\n const navigate = window.__VINEXT_RSC_NAVIGATE__;\n if (!navigate) {\n window.location.href = destinationPath;\n return;\n }\n\n // The URL has already been updated via replaceHistoryStateWithoutNotify above,\n // so the recursive navigation should NOT push/replace again. Pass undefined\n // for historyUpdateMode to make the commit effect a no-op for history updates.\n return navigate(destinationPath, redirectDepth + 1, navigationKind, undefined);\n }\n\n let navParams: Record<string, string | string[]> = {};\n const paramsHeader = navResponse.headers.get(\"X-Vinext-Params\");\n if (paramsHeader) {\n try {\n navParams = JSON.parse(decodeURIComponent(paramsHeader)) as Record<\n string,\n string | string[]\n >;\n } catch {\n // navParams stays as {}\n }\n }\n // Build snapshot from local params, not latestClientParams\n const navigationSnapshot = createClientNavigationRenderSnapshot(href, navParams);\n\n const responseSnapshot = await snapshotRscResponse(navResponse);\n\n if (navId !== activeNavigationId) return;\n\n const rscPayload = await createFromFetch<ReactNode>(\n Promise.resolve(restoreRscResponse(responseSnapshot)),\n );\n\n if (navId !== activeNavigationId) return;\n\n // Stage params only after confirming this navigation hasn't been superseded\n // (avoids stale cache entries). Set _snapshotPending before stageClientParams\n // for the same reason as the cached path above: ensures params are only staged\n // as part of an in-flight snapshot.\n _snapshotPending = true; // Set before renderNavigationPayload\n stageClientParams(navParams); // NB: if this throws, outer catch hard-navigates, resetting all JS state\n try {\n await renderNavigationPayload(\n rscPayload,\n navigationSnapshot,\n navigationCommitEffect,\n isSameRoute,\n );\n } finally {\n // Always clear _snapshotPending after renderNavigationPayload returns or\n // throws. renderNavigationPayload's inner catch already calls\n // commitClientNavigationState() on synchronous errors and re-throws, so\n // the outer catch must not call it again. Clearing here prevents the outer\n // catch from double-decrementing navigationSnapshotActiveCount.\n _snapshotPending = false;\n }\n // Store the visited response only after renderNavigationPayload succeeds.\n // If we stored it before and renderNavigationPayload threw, a future\n // back/forward navigation could replay a snapshot from a navigation that\n // never actually rendered successfully.\n storeVisitedResponseSnapshot(rscUrl, responseSnapshot, navParams);\n return;\n } catch (error) {\n // Only decrement counter if snapshot was activated but not yet committed.\n // renderNavigationPayload clears _snapshotPending (via its inner try-finally)\n // before re-throwing, so this guard correctly skips the double-decrement case.\n if (_snapshotPending) {\n _snapshotPending = false;\n commitClientNavigationState();\n }\n // Don't hard-navigate to a stale URL if this navigation was superseded by\n // a newer one — the newer navigation is already in flight and would be clobbered.\n if (navId !== activeNavigationId) return;\n console.error(\"[vinext] RSC navigation error:\", error);\n window.location.href = href;\n }\n };\n\n if (\"scrollRestoration\" in history) {\n history.scrollRestoration = \"manual\";\n }\n\n // Note: This popstate handler runs for App Router (RSC navigation available).\n // It coordinates scroll restoration with the pending RSC navigation.\n // Pages Router scroll restoration is handled in shims/navigation.ts:1289 with\n // microtask-based deferral for compatibility with non-RSC navigation.\n // See: https://github.com/vercel/next.js/discussions/41934#discussioncomment-4602607\n window.addEventListener(\"popstate\", (event) => {\n notifyAppRouterTransitionStart(window.location.href, \"traverse\");\n const pendingNavigation =\n window.__VINEXT_RSC_NAVIGATE__?.(window.location.href, 0, \"traverse\") ?? Promise.resolve();\n window.__VINEXT_RSC_PENDING__ = pendingNavigation;\n void pendingNavigation.finally(() => {\n restorePopstateScrollPosition(event.state);\n if (window.__VINEXT_RSC_PENDING__ === pendingNavigation) {\n window.__VINEXT_RSC_PENDING__ = null;\n }\n });\n });\n\n if (import.meta.hot) {\n import.meta.hot.on(\"rsc:update\", async () => {\n try {\n clearClientNavigationCaches();\n const rscPayload = await createFromFetch<ReactNode>(\n fetch(toRscUrl(window.location.pathname + window.location.search)),\n );\n // HMR updates skip renderNavigationPayload — no snapshot activated.\n updateBrowserTree(\n rscPayload,\n createClientNavigationRenderSnapshot(window.location.href, latestClientParams),\n ++nextNavigationRenderId,\n false,\n );\n } catch (error) {\n console.error(\"[vinext] RSC HMR error:\", error);\n }\n });\n }\n}\n\nvoid main();\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-browser-entry.js","names":[],"sources":["../../src/server/app-browser-entry.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport {\n createElement,\n startTransition,\n use,\n useLayoutEffect,\n useReducer,\n useRef,\n type Dispatch,\n type ReactNode,\n} from \"react\";\nimport {\n createFromFetch,\n createFromReadableStream,\n createTemporaryReferenceSet,\n encodeReply,\n setServerCallback,\n} from \"@vitejs/plugin-rsc/browser\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport \"../client/instrumentation-client.js\";\nimport { notifyAppRouterTransitionStart } from \"../client/instrumentation-client-state.js\";\nimport {\n __basePath,\n activateNavigationSnapshot,\n clearPendingPathname,\n commitClientNavigationState,\n consumePrefetchResponse,\n createClientNavigationRenderSnapshot,\n getCurrentNextUrl,\n getCurrentInterceptionContext,\n getClientNavigationRenderContext,\n getClientNavigationState,\n getPrefetchCache,\n getPrefetchedUrls,\n pushHistoryStateWithoutNotify,\n replaceClientParamsWithoutNotify,\n replaceHistoryStateWithoutNotify,\n restoreRscResponse,\n setClientParams,\n setPendingPathname,\n snapshotRscResponse,\n setMountedSlotsHeader,\n setNavigationContext,\n toRscUrl,\n type CachedRscResponse,\n type ClientNavigationRenderSnapshot,\n} from \"../shims/navigation.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport {\n chunksToReadableStream,\n createProgressiveRscStream,\n getVinextBrowserGlobal,\n} from \"./app-browser-stream.js\";\nimport {\n createAppPayloadCacheKey,\n getMountedSlotIdsHeader,\n normalizeAppElements,\n readAppElementsMetadata,\n resolveVisitedResponseInterceptionContext,\n type AppElements,\n type AppWireElements,\n type LayoutFlags,\n} from \"./app-elements.js\";\nimport {\n createHistoryStateWithPreviousNextUrl,\n createPendingNavigationCommit,\n readHistoryStatePreviousNextUrl,\n resolveAndClassifyNavigationCommit,\n resolveInterceptionContextFromPreviousNextUrl,\n resolvePendingNavigationCommitDisposition,\n resolveServerActionRequestState,\n routerReducer,\n type AppRouterAction,\n type AppRouterState,\n} from \"./app-browser-state.js\";\nimport { ElementsContext, Slot } from \"../shims/slot.js\";\nimport { devOnCaughtError } from \"./app-browser-error.js\";\n\ntype SearchParamInput = ConstructorParameters<typeof URLSearchParams>[0];\n\ntype ServerActionResult = {\n root: AppWireElements;\n returnValue?: {\n ok: boolean;\n data: unknown;\n };\n};\n\ntype NavigationKind = \"navigate\" | \"traverse\" | \"refresh\";\n\n// Maps NavigationKind to the AppRouterAction type used by the reducer.\n// \"refresh\" is intentionally treated as \"navigate\" (merge, preserve absent slots).\n// Both call sites must stay in sync — update here if NavigationKind gains new values.\nfunction toActionType(kind: NavigationKind): \"navigate\" | \"traverse\" {\n return kind === \"traverse\" ? \"traverse\" : \"navigate\";\n}\n\ntype HistoryUpdateMode = \"push\" | \"replace\";\ntype VisitedResponseCacheEntry = {\n params: Record<string, string | string[]>;\n expiresAt: number;\n response: CachedRscResponse;\n};\n\nconst MAX_VISITED_RESPONSE_CACHE_SIZE = 50;\nconst VISITED_RESPONSE_CACHE_TTL = 5 * 60_000;\nconst MAX_TRAVERSAL_CACHE_TTL = 30 * 60_000;\n\n// These are plain module-level variables, unlike ClientNavigationState in\n// navigation.ts which uses Symbol.for to survive multiple Vite module instances.\n// The browser entry is loaded exactly once (via the RSC plugin's generated\n// bootstrap), so module-level state is safe here. If that assumption ever\n// changes, these should be migrated to a Symbol.for-backed global.\n//\n// The most severe consequence of multiple instances would be Map fragmentation:\n// pendingNavigationCommits and pendingNavigationPrePaintEffects would split\n// across instances, so drainPrePaintEffects in one instance could never drain\n// effects queued by the other, permanently leaking navigationSnapshotActiveCount\n// and causing hooks to prefer stale snapshot values indefinitely.\nlet nextNavigationRenderId = 0;\nlet activeNavigationId = 0;\nconst pendingNavigationCommits = new Map<number, () => void>();\nconst pendingNavigationPrePaintEffects = new Map<number, () => void>();\nlet dispatchBrowserRouterAction: Dispatch<AppRouterAction> | null = null;\nlet browserRouterStateRef: { current: AppRouterState } | null = null;\nlet latestClientParams: Record<string, string | string[]> = {};\nconst visitedResponseCache = new Map<string, VisitedResponseCacheEntry>();\n\nfunction isServerActionResult(value: unknown): value is ServerActionResult {\n return !!value && typeof value === \"object\" && \"root\" in value;\n}\n\nfunction getBrowserRouterDispatch(): Dispatch<AppRouterAction> {\n if (!dispatchBrowserRouterAction) {\n throw new Error(\"[vinext] Browser router dispatch is not initialized\");\n }\n return dispatchBrowserRouterAction;\n}\n\nfunction getBrowserRouterState(): AppRouterState {\n if (!browserRouterStateRef) {\n throw new Error(\"[vinext] Browser router state is not initialized\");\n }\n return browserRouterStateRef.current;\n}\n\nfunction applyClientParams(params: Record<string, string | string[]>): void {\n latestClientParams = params;\n setClientParams(params);\n}\n\nfunction stageClientParams(params: Record<string, string | string[]>): void {\n // NB: latestClientParams diverges from ClientNavigationState.clientParams\n // between staging and commit. Server action snapshots (same-URL\n // commitSameUrlNavigatePayload() calls inside registerServerActionCallback)\n // read latestClientParams, so a\n // server action fired during this window would get the pending (not yet\n // committed) params. This is acceptable because the commit effect fires\n // before hooks observe the new URL state, keeping the window vanishingly small.\n latestClientParams = params;\n replaceClientParamsWithoutNotify(params);\n}\n\nfunction clearVisitedResponseCache(): void {\n visitedResponseCache.clear();\n}\n\nfunction clearPrefetchState(): void {\n getPrefetchCache().clear();\n getPrefetchedUrls().clear();\n}\n\nfunction clearClientNavigationCaches(): void {\n clearVisitedResponseCache();\n clearPrefetchState();\n}\n\nfunction queuePrePaintNavigationEffect(renderId: number, effect: (() => void) | null): void {\n if (!effect) {\n return;\n }\n pendingNavigationPrePaintEffects.set(renderId, effect);\n}\n\n/**\n * Run all queued pre-paint effects for renderIds up to and including the\n * given renderId. When React supersedes a startTransition update (rapid\n * clicks on same-route links), the superseded NavigationCommitSignal never\n * mounts, so its pre-paint effect never fires. By draining all effects\n * <= the committed renderId here, the winning transition cleans up after\n * any superseded ones, keeping the counter balanced.\n *\n * Invariant: each superseded navigation gets a commitClientNavigationState()\n * to balance the activateNavigationSnapshot() from its renderNavigationPayload call.\n */\nfunction drainPrePaintEffects(upToRenderId: number): void {\n for (const [id, effect] of pendingNavigationPrePaintEffects) {\n if (id <= upToRenderId) {\n pendingNavigationPrePaintEffects.delete(id);\n if (id === upToRenderId) {\n // Winning navigation: run its actual pre-paint effect\n effect();\n } else {\n // Superseded navigation: balance its activateNavigationSnapshot().\n // Pass undefined navId intentionally so this cleanup cannot clear\n // pendingPathname owned by the current active navigation.\n commitClientNavigationState(undefined);\n }\n }\n }\n}\n\nfunction createNavigationCommitEffect(\n href: string,\n historyUpdateMode: HistoryUpdateMode | undefined,\n navId: number,\n params: Record<string, string | string[]>,\n previousNextUrl: string | null,\n): () => void {\n return () => {\n // Only update URL if this is still the active navigation.\n // A newer navigation would have incremented activeNavigationId.\n if (navId !== activeNavigationId) {\n // This transition was superseded before commit; balance the active\n // snapshot counter without clearing pendingPathname ownership.\n commitClientNavigationState(undefined);\n return;\n }\n\n const targetHref = new URL(href, window.location.origin).href;\n stageClientParams(params);\n const preserveExistingState = historyUpdateMode === \"replace\";\n const historyState = createHistoryStateWithPreviousNextUrl(\n preserveExistingState ? window.history.state : null,\n previousNextUrl,\n );\n\n if (historyUpdateMode === \"replace\" && window.location.href !== targetHref) {\n replaceHistoryStateWithoutNotify(historyState, \"\", href);\n } else if (historyUpdateMode === \"push\" && window.location.href !== targetHref) {\n pushHistoryStateWithoutNotify(historyState, \"\", href);\n }\n\n commitClientNavigationState(navId);\n };\n}\n\nfunction evictVisitedResponseCacheIfNeeded(): void {\n while (visitedResponseCache.size >= MAX_VISITED_RESPONSE_CACHE_SIZE) {\n const oldest = visitedResponseCache.keys().next().value;\n if (oldest === undefined) {\n return;\n }\n visitedResponseCache.delete(oldest);\n }\n}\n\nfunction getVisitedResponse(\n rscUrl: string,\n interceptionContext: string | null,\n mountedSlotsHeader: string | null,\n navigationKind: NavigationKind,\n): VisitedResponseCacheEntry | null {\n const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);\n const cached = visitedResponseCache.get(cacheKey);\n if (!cached) {\n return null;\n }\n\n if ((cached.response.mountedSlotsHeader ?? null) !== mountedSlotsHeader) {\n visitedResponseCache.delete(cacheKey);\n return null;\n }\n\n if (navigationKind === \"refresh\") {\n return null;\n }\n\n if (navigationKind === \"traverse\") {\n const createdAt = cached.expiresAt - VISITED_RESPONSE_CACHE_TTL;\n if (Date.now() - createdAt >= MAX_TRAVERSAL_CACHE_TTL) {\n visitedResponseCache.delete(cacheKey);\n return null;\n }\n // LRU: promote to most-recently-used (delete + re-insert moves to end of Map)\n visitedResponseCache.delete(cacheKey);\n visitedResponseCache.set(cacheKey, cached);\n return cached;\n }\n\n if (cached.expiresAt > Date.now()) {\n // LRU: promote to most-recently-used\n visitedResponseCache.delete(cacheKey);\n visitedResponseCache.set(cacheKey, cached);\n return cached;\n }\n\n visitedResponseCache.delete(cacheKey);\n return null;\n}\n\nfunction storeVisitedResponseSnapshot(\n rscUrl: string,\n interceptionContext: string | null,\n snapshot: CachedRscResponse,\n params: Record<string, string | string[]>,\n): void {\n const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);\n visitedResponseCache.delete(cacheKey);\n evictVisitedResponseCacheIfNeeded();\n const now = Date.now();\n visitedResponseCache.set(cacheKey, {\n params,\n expiresAt: now + VISITED_RESPONSE_CACHE_TTL,\n response: snapshot,\n });\n}\n\ntype NavigationRequestState = {\n interceptionContext: string | null;\n previousNextUrl: string | null;\n};\n\nfunction getRequestState(\n navigationKind: NavigationKind,\n previousNextUrlOverride?: string | null,\n): NavigationRequestState {\n if (previousNextUrlOverride !== undefined) {\n return {\n interceptionContext: resolveInterceptionContextFromPreviousNextUrl(\n previousNextUrlOverride,\n __basePath,\n ),\n previousNextUrl: previousNextUrlOverride,\n };\n }\n\n switch (navigationKind) {\n case \"navigate\":\n return {\n interceptionContext: getCurrentInterceptionContext(),\n previousNextUrl: getCurrentNextUrl(),\n };\n case \"traverse\": {\n const previousNextUrl = readHistoryStatePreviousNextUrl(window.history.state);\n return {\n interceptionContext: resolveInterceptionContextFromPreviousNextUrl(\n previousNextUrl,\n __basePath,\n ),\n previousNextUrl,\n };\n }\n case \"refresh\": {\n const currentPreviousNextUrl = getBrowserRouterState().previousNextUrl;\n return {\n interceptionContext: resolveInterceptionContextFromPreviousNextUrl(\n currentPreviousNextUrl,\n __basePath,\n ),\n previousNextUrl: currentPreviousNextUrl,\n };\n }\n default: {\n const _exhaustive: never = navigationKind;\n throw new Error(\"[vinext] Unknown navigation kind: \" + String(_exhaustive));\n }\n }\n}\n\nfunction createRscRequestHeaders(interceptionContext: string | null): Headers {\n const headers = new Headers({ Accept: \"text/x-component\" });\n if (interceptionContext !== null) {\n headers.set(\"X-Vinext-Interception-Context\", interceptionContext);\n }\n return headers;\n}\n\n/**\n * Resolve all pending navigation commits with renderId <= the committed renderId.\n * Note: Map iteration handles concurrent deletion safely — entries are visited in\n * insertion order and deletion doesn't affect the iterator's view of remaining entries.\n * This pattern is also used in drainPrePaintEffects with the same semantics.\n */\nfunction resolveCommittedNavigations(renderId: number): void {\n for (const [pendingId, resolve] of pendingNavigationCommits) {\n if (pendingId <= renderId) {\n pendingNavigationCommits.delete(pendingId);\n resolve();\n }\n }\n}\n\nfunction NavigationCommitSignal({\n renderId,\n children,\n}: {\n renderId: number;\n children?: ReactNode;\n}) {\n useLayoutEffect(() => {\n drainPrePaintEffects(renderId);\n\n const frame = requestAnimationFrame(() => {\n resolveCommittedNavigations(renderId);\n });\n\n return () => {\n cancelAnimationFrame(frame);\n // Resolve pending commits to prevent callers from hanging if React\n // unmounts this component without committing (e.g., error boundary).\n resolveCommittedNavigations(renderId);\n };\n }, [renderId]);\n\n return children;\n}\n\nfunction normalizeAppElementsPromise(payload: Promise<AppWireElements>): Promise<AppElements> {\n // Wrap in Promise.resolve() because createFromReadableStream() returns a\n // React Flight thenable whose .then() returns undefined (not a new Promise).\n // Without the wrap, chaining .then() produces undefined → use() crashes.\n return Promise.resolve(payload).then((elements) => normalizeAppElements(elements));\n}\n\nasync function commitSameUrlNavigatePayload(\n nextElements: Promise<AppElements>,\n returnValue?: ServerActionResult[\"returnValue\"],\n): Promise<unknown> {\n const navigationSnapshot = createClientNavigationRenderSnapshot(\n window.location.href,\n latestClientParams,\n );\n const currentState = getBrowserRouterState();\n const startedNavigationId = activeNavigationId;\n const { disposition, pending } = await resolveAndClassifyNavigationCommit({\n activeNavigationId,\n currentState,\n navigationSnapshot,\n nextElements,\n renderId: ++nextNavigationRenderId,\n startedNavigationId,\n type: \"navigate\",\n });\n\n // Known limitation: if a same-URL navigation fully commits while this\n // server action is awaiting createPendingNavigationCommit(), the action\n // can still dispatch its older payload afterward. The old pre-2c code had\n // the same race, and Next.js has similar behavior. Tightening this would\n // need a stronger commit-version gate than activeNavigationId alone.\n if (disposition === \"hard-navigate\") {\n window.location.assign(window.location.href);\n return undefined;\n }\n\n if (disposition === \"dispatch\") {\n dispatchBrowserTree(\n pending.action.elements,\n navigationSnapshot,\n pending.action.renderId,\n \"navigate\",\n pending.interceptionContext,\n pending.action.layoutFlags,\n pending.previousNextUrl,\n pending.routeId,\n pending.rootLayoutTreePath,\n false,\n );\n }\n\n // Same-URL server actions still return their action value even if the UI\n // update was skipped due to a superseding navigation. That preserves the\n // existing caller contract; a future Phase 2 router state model could make\n // skipped UI updates observable to the caller without conflating them here.\n if (returnValue) {\n if (!returnValue.ok) {\n throw returnValue.data;\n }\n return returnValue.data;\n }\n\n return undefined;\n}\n\nfunction BrowserRoot({\n initialElements,\n initialNavigationSnapshot,\n}: {\n initialElements: Promise<AppElements>;\n initialNavigationSnapshot: ClientNavigationRenderSnapshot;\n}) {\n const resolvedElements = use(initialElements);\n const initialMetadata = readAppElementsMetadata(resolvedElements);\n const [treeState, dispatchTreeState] = useReducer(routerReducer, {\n elements: resolvedElements,\n interceptionContext: initialMetadata.interceptionContext,\n layoutFlags: initialMetadata.layoutFlags,\n navigationSnapshot: initialNavigationSnapshot,\n previousNextUrl: null,\n renderId: 0,\n rootLayoutTreePath: initialMetadata.rootLayoutTreePath,\n routeId: initialMetadata.routeId,\n });\n\n // Keep the latest router state in a ref so external callers (navigate(),\n // server actions, HMR) always read the current state. Safe: those readers\n // run from events/effects, never from React render itself.\n // Note: stateRef.current is written during render, not in an effect, to\n // avoid a stale-read window between commit and layout effects. This mirrors\n // the same render-phase ref update pattern used by Next.js's own router.\n const stateRef = useRef(treeState);\n stateRef.current = treeState;\n\n // Publish the stable ref object and dispatch during layout commit. This keeps\n // the module-level escape hatches aligned with React's committed tree without\n // performing module writes during render. __VINEXT_RSC_NAVIGATE__ is assigned\n // after hydrateRoot() returns; by then this layout effect has already run for\n // the hydration commit, so getBrowserRouterState() never observes a null ref.\n useLayoutEffect(() => {\n dispatchBrowserRouterAction = dispatchTreeState;\n browserRouterStateRef = stateRef;\n return () => {\n if (dispatchBrowserRouterAction === dispatchTreeState) {\n dispatchBrowserRouterAction = null;\n }\n if (browserRouterStateRef === stateRef) {\n browserRouterStateRef = null;\n }\n setMountedSlotsHeader(null);\n };\n }, [dispatchTreeState]);\n\n useLayoutEffect(() => {\n setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));\n }, [treeState.elements]);\n\n useLayoutEffect(() => {\n if (treeState.renderId !== 0) {\n return;\n }\n\n replaceHistoryStateWithoutNotify(\n createHistoryStateWithPreviousNextUrl(window.history.state, treeState.previousNextUrl),\n \"\",\n window.location.href,\n );\n }, [treeState.previousNextUrl, treeState.renderId]);\n\n const committedTree = createElement(\n NavigationCommitSignal,\n { renderId: treeState.renderId },\n createElement(\n ElementsContext.Provider,\n { value: treeState.elements },\n createElement(Slot, { id: treeState.routeId }),\n ),\n );\n\n const ClientNavigationRenderContext = getClientNavigationRenderContext();\n if (!ClientNavigationRenderContext) {\n return committedTree;\n }\n\n return createElement(\n ClientNavigationRenderContext.Provider,\n { value: treeState.navigationSnapshot },\n committedTree,\n );\n}\n\nfunction dispatchBrowserTree(\n elements: AppElements,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n renderId: number,\n actionType: \"navigate\" | \"replace\" | \"traverse\",\n interceptionContext: string | null,\n layoutFlags: LayoutFlags,\n previousNextUrl: string | null,\n routeId: string,\n rootLayoutTreePath: string | null,\n useTransitionMode: boolean,\n): void {\n const dispatch = getBrowserRouterDispatch();\n\n const applyAction = () =>\n dispatch({\n elements,\n interceptionContext,\n layoutFlags,\n navigationSnapshot,\n previousNextUrl,\n renderId,\n rootLayoutTreePath,\n routeId,\n type: actionType,\n });\n\n if (useTransitionMode) {\n startTransition(applyAction);\n } else {\n applyAction();\n }\n}\n\nasync function renderNavigationPayload(\n payload: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n targetHref: string,\n navId: number,\n historyUpdateMode: HistoryUpdateMode | undefined,\n params: Record<string, string | string[]>,\n previousNextUrl: string | null,\n useTransition = true,\n actionType: \"navigate\" | \"replace\" | \"traverse\" = \"navigate\",\n): Promise<void> {\n const renderId = ++nextNavigationRenderId;\n const committed = new Promise<void>((resolve) => {\n pendingNavigationCommits.set(renderId, resolve);\n });\n\n let snapshotActivated = false;\n try {\n const currentState = getBrowserRouterState();\n const pending = await createPendingNavigationCommit({\n currentState,\n nextElements: payload,\n navigationSnapshot,\n previousNextUrl,\n renderId,\n type: actionType,\n });\n\n const disposition = resolvePendingNavigationCommitDisposition({\n activeNavigationId,\n currentRootLayoutTreePath: currentState.rootLayoutTreePath,\n nextRootLayoutTreePath: pending.rootLayoutTreePath,\n startedNavigationId: navId,\n });\n\n if (disposition === \"skip\") {\n const resolve = pendingNavigationCommits.get(renderId);\n pendingNavigationCommits.delete(renderId);\n resolve?.();\n return;\n }\n\n if (disposition === \"hard-navigate\") {\n pendingNavigationCommits.delete(renderId);\n window.location.assign(targetHref);\n return;\n }\n\n queuePrePaintNavigationEffect(\n renderId,\n createNavigationCommitEffect(\n targetHref,\n historyUpdateMode,\n navId,\n params,\n pending.previousNextUrl,\n ),\n );\n activateNavigationSnapshot();\n snapshotActivated = true;\n dispatchBrowserTree(\n pending.action.elements,\n navigationSnapshot,\n renderId,\n actionType,\n pending.interceptionContext,\n pending.action.layoutFlags,\n pending.previousNextUrl,\n pending.routeId,\n pending.rootLayoutTreePath,\n useTransition,\n );\n } catch (error) {\n // Clean up pending state on error. Only decrement the snapshot counter\n // if activateNavigationSnapshot() was actually called — if\n // createPendingNavigationCommit() threw, the counter was never\n // incremented so decrementing would underflow it.\n pendingNavigationPrePaintEffects.delete(renderId);\n const resolve = pendingNavigationCommits.get(renderId);\n pendingNavigationCommits.delete(renderId);\n if (snapshotActivated) {\n commitClientNavigationState(navId);\n }\n resolve?.();\n throw error;\n }\n\n return committed;\n}\n\nfunction restoreHydrationNavigationContext(\n pathname: string,\n searchParams: SearchParamInput,\n params: Record<string, string | string[]>,\n): void {\n setNavigationContext({\n pathname,\n searchParams: new URLSearchParams(searchParams),\n params,\n });\n}\n\nfunction restorePopstateScrollPosition(state: unknown): void {\n if (!(state && typeof state === \"object\" && \"__vinext_scrollY\" in state)) {\n return;\n }\n\n const y = Number(state.__vinext_scrollY);\n const x = \"__vinext_scrollX\" in state ? Number(state.__vinext_scrollX) : 0;\n\n requestAnimationFrame(() => {\n window.scrollTo(x, y);\n });\n}\n\nasync function readInitialRscStream(): Promise<ReadableStream<Uint8Array>> {\n const vinext = getVinextBrowserGlobal();\n\n if (vinext.__VINEXT_RSC__ || vinext.__VINEXT_RSC_CHUNKS__ || vinext.__VINEXT_RSC_DONE__) {\n if (vinext.__VINEXT_RSC__) {\n const embedData = vinext.__VINEXT_RSC__;\n delete vinext.__VINEXT_RSC__;\n\n const params = embedData.params ?? {};\n if (embedData.params) {\n applyClientParams(embedData.params);\n }\n if (embedData.nav) {\n restoreHydrationNavigationContext(\n embedData.nav.pathname,\n embedData.nav.searchParams,\n params,\n );\n }\n\n return chunksToReadableStream(embedData.rsc);\n }\n\n const params = vinext.__VINEXT_RSC_PARAMS__ ?? {};\n if (vinext.__VINEXT_RSC_PARAMS__) {\n applyClientParams(vinext.__VINEXT_RSC_PARAMS__);\n }\n if (vinext.__VINEXT_RSC_NAV__) {\n restoreHydrationNavigationContext(\n vinext.__VINEXT_RSC_NAV__.pathname,\n vinext.__VINEXT_RSC_NAV__.searchParams,\n params,\n );\n }\n\n return createProgressiveRscStream();\n }\n\n const rscResponse = await fetch(toRscUrl(window.location.pathname + window.location.search));\n\n let params: Record<string, string | string[]> = {};\n const paramsHeader = rscResponse.headers.get(\"X-Vinext-Params\");\n if (paramsHeader) {\n try {\n params = JSON.parse(decodeURIComponent(paramsHeader)) as Record<string, string | string[]>;\n applyClientParams(params);\n } catch {\n // Ignore malformed param headers and continue with hydration.\n }\n }\n\n restoreHydrationNavigationContext(window.location.pathname, window.location.search, params);\n\n if (!rscResponse.body) {\n throw new Error(\"[vinext] Initial RSC response had no body\");\n }\n\n return rscResponse.body;\n}\n\nfunction registerServerActionCallback(): void {\n setServerCallback(async (id, args) => {\n const temporaryReferences = createTemporaryReferenceSet();\n const body = await encodeReply(args, { temporaryReferences });\n\n // Carry the interception context + mounted slots from the current router\n // state so the server-action re-render rebuilds the intercepted tree\n // instead of replacing it with the direct page. Parity with Next.js,\n // which sends `Next-URL` on action POSTs when the current tree contains\n // an interception route.\n const currentState = getBrowserRouterState();\n const { headers } = resolveServerActionRequestState({\n actionId: id,\n basePath: __basePath,\n elements: currentState.elements,\n previousNextUrl: currentState.previousNextUrl,\n });\n\n const fetchResponse = await fetch(toRscUrl(window.location.pathname + window.location.search), {\n method: \"POST\",\n headers,\n body,\n });\n\n const actionRedirect = fetchResponse.headers.get(\"x-action-redirect\");\n if (actionRedirect) {\n // Check for external URLs that need a hard redirect.\n try {\n const redirectUrl = new URL(actionRedirect, window.location.origin);\n if (redirectUrl.origin !== window.location.origin) {\n window.location.href = actionRedirect;\n return undefined;\n }\n } catch {\n // Fall through to hard redirect below if URL parsing fails.\n }\n\n // Use hard redirect for all action redirects because vinext's server\n // currently returns an empty body for redirect responses. RSC navigation\n // requires a valid RSC payload. This is a known parity gap with Next.js,\n // which pre-renders the redirect target's RSC payload.\n const redirectType = fetchResponse.headers.get(\"x-action-redirect-type\") ?? \"replace\";\n if (redirectType === \"push\") {\n window.location.assign(actionRedirect);\n } else {\n window.location.replace(actionRedirect);\n }\n return undefined;\n }\n\n clearClientNavigationCaches();\n\n const result = await createFromFetch<ServerActionResult | AppWireElements>(\n Promise.resolve(fetchResponse),\n { temporaryReferences },\n );\n\n // Server actions stay on the same URL and use commitSameUrlNavigatePayload()\n // for merge-based dispatch. This path does not call\n // activateNavigationSnapshot() because there is no URL change to commit, so\n // hooks continue reading the live external-store values directly. If server\n // actions ever trigger URL changes via RSC payload (instead of hard\n // redirects), this would need renderNavigationPayload().\n if (isServerActionResult(result)) {\n return commitSameUrlNavigatePayload(\n Promise.resolve(normalizeAppElements(result.root)),\n result.returnValue,\n );\n }\n\n return commitSameUrlNavigatePayload(Promise.resolve(normalizeAppElements(result)));\n });\n}\n\nasync function main(): Promise<void> {\n registerServerActionCallback();\n\n const rscStream = await readInitialRscStream();\n const root = normalizeAppElementsPromise(createFromReadableStream<AppWireElements>(rscStream));\n const initialNavigationSnapshot = createClientNavigationRenderSnapshot(\n window.location.href,\n latestClientParams,\n );\n replaceHistoryStateWithoutNotify(\n createHistoryStateWithPreviousNextUrl(window.history.state, null),\n \"\",\n window.location.href,\n );\n\n window.__VINEXT_RSC_ROOT__ = hydrateRoot(\n document,\n createElement(BrowserRoot, {\n initialElements: root,\n initialNavigationSnapshot,\n }),\n import.meta.env.DEV ? { onCaughtError: devOnCaughtError } : undefined,\n );\n window.__VINEXT_HYDRATED_AT = performance.now();\n\n window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(\n href: string,\n redirectDepth = 0,\n navigationKind: NavigationKind = \"navigate\",\n historyUpdateMode?: HistoryUpdateMode,\n previousNextUrlOverride?: string | null,\n ): Promise<void> {\n if (redirectDepth > 10) {\n console.error(\n \"[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.\",\n );\n window.location.href = href;\n return;\n }\n\n let _snapshotPending = false;\n // Hoist navId above try so the catch block can guard against hard-navigating\n // to a stale URL when this navigation has already been superseded.\n const navId = ++activeNavigationId;\n try {\n const url = new URL(href, window.location.origin);\n const rscUrl = toRscUrl(url.pathname + url.search);\n const requestState = getRequestState(navigationKind, previousNextUrlOverride);\n const requestInterceptionContext = requestState.interceptionContext;\n const requestPreviousNextUrl = requestState.previousNextUrl;\n\n // Compare against previous pending navigation first, then committed state.\n // This avoids isSameRoute misclassification during rapid back-to-back clicks.\n const navState = getClientNavigationState();\n const currentPath =\n navState?.pendingPathname ??\n navState?.cachedPathname ??\n stripBasePath(window.location.pathname, __basePath);\n\n const targetPath = stripBasePath(url.pathname, __basePath);\n const isSameRoute = targetPath === currentPath;\n\n // Set this navigation as the pending pathname, overwriting any previous.\n // Pass navId so only this navigation (or a newer one) can clear it later.\n setPendingPathname(url.pathname, navId);\n\n const elementsAtNavStart = getBrowserRouterState().elements;\n const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);\n const cachedRoute = getVisitedResponse(\n rscUrl,\n requestInterceptionContext,\n mountedSlotsHeader,\n navigationKind,\n );\n if (cachedRoute) {\n // Check stale-navigation before and after createFromFetch. The pre-check\n // avoids wasted parse work; the post-check catches supersessions that\n // occur during the await. createFromFetch on a buffered response is fast\n // but still async, so the window exists. The non-cached path (below) places\n // its heavyweight async steps (fetch, snapshotRscResponse, createFromFetch)\n // between navId checks consistently; the cached path omits the check between\n // createClientNavigationRenderSnapshot (synchronous) and createFromFetch\n // because there is no await in that gap.\n if (navId !== activeNavigationId) return;\n const cachedParams = cachedRoute.params;\n // createClientNavigationRenderSnapshot is synchronous (URL parsing + param\n // wrapping only) — no stale-navigation recheck needed between here and the\n // next await.\n const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(href, cachedParams);\n const cachedPayload = normalizeAppElementsPromise(\n createFromFetch<AppWireElements>(\n Promise.resolve(restoreRscResponse(cachedRoute.response)),\n ),\n );\n if (navId !== activeNavigationId) return;\n _snapshotPending = true; // Set before renderNavigationPayload\n try {\n await renderNavigationPayload(\n cachedPayload,\n cachedNavigationSnapshot,\n href,\n navId,\n historyUpdateMode,\n cachedParams,\n requestPreviousNextUrl,\n isSameRoute,\n toActionType(navigationKind),\n );\n } finally {\n // Always clear _snapshotPending so the outer catch does not\n // double-decrement if renderNavigationPayload throws.\n _snapshotPending = false;\n }\n return;\n }\n\n // Continue using the slot state captured at navigation start for fetches\n // and prefetch compatibility decisions.\n\n let navResponse: Response | undefined;\n let navResponseUrl: string | null = null;\n if (navigationKind !== \"refresh\") {\n const prefetchedResponse = consumePrefetchResponse(\n rscUrl,\n requestInterceptionContext,\n mountedSlotsHeader,\n );\n if (prefetchedResponse) {\n navResponse = restoreRscResponse(prefetchedResponse, false);\n navResponseUrl = prefetchedResponse.url;\n }\n }\n\n if (!navResponse) {\n const requestHeaders = createRscRequestHeaders(requestInterceptionContext);\n if (mountedSlotsHeader) {\n requestHeaders.set(\"X-Vinext-Mounted-Slots\", mountedSlotsHeader);\n }\n navResponse = await fetch(rscUrl, {\n headers: requestHeaders,\n credentials: \"include\",\n });\n }\n\n if (navId !== activeNavigationId) return;\n\n const finalUrl = new URL(navResponseUrl ?? navResponse.url, window.location.origin);\n const requestedUrl = new URL(rscUrl, window.location.origin);\n\n if (finalUrl.pathname !== requestedUrl.pathname) {\n const destinationPath = finalUrl.pathname.replace(/\\.rsc$/, \"\") + finalUrl.search;\n replaceHistoryStateWithoutNotify(\n createHistoryStateWithPreviousNextUrl(null, requestPreviousNextUrl),\n \"\",\n destinationPath,\n );\n\n const navigate = window.__VINEXT_RSC_NAVIGATE__;\n if (!navigate) {\n window.location.href = destinationPath;\n return;\n }\n\n // The URL has already been updated via replaceHistoryStateWithoutNotify above,\n // so the recursive navigation should NOT push/replace again. Pass undefined\n // for historyUpdateMode to make the commit effect a no-op for history updates.\n return navigate(\n destinationPath,\n redirectDepth + 1,\n navigationKind,\n undefined,\n requestPreviousNextUrl,\n );\n }\n\n let navParams: Record<string, string | string[]> = {};\n const paramsHeader = navResponse.headers.get(\"X-Vinext-Params\");\n if (paramsHeader) {\n try {\n navParams = JSON.parse(decodeURIComponent(paramsHeader)) as Record<\n string,\n string | string[]\n >;\n } catch {\n // navParams stays as {}\n }\n }\n // Build snapshot from local params, not latestClientParams\n const navigationSnapshot = createClientNavigationRenderSnapshot(href, navParams);\n\n const responseSnapshot = await snapshotRscResponse(navResponse);\n\n if (navId !== activeNavigationId) return;\n\n const rscPayload = normalizeAppElementsPromise(\n createFromFetch<AppWireElements>(Promise.resolve(restoreRscResponse(responseSnapshot))),\n );\n\n if (navId !== activeNavigationId) return;\n\n _snapshotPending = true; // Set before renderNavigationPayload\n try {\n await renderNavigationPayload(\n rscPayload,\n navigationSnapshot,\n href,\n navId,\n historyUpdateMode,\n navParams,\n requestPreviousNextUrl,\n isSameRoute,\n toActionType(navigationKind),\n );\n } finally {\n // Always clear _snapshotPending after renderNavigationPayload returns or\n // throws. renderNavigationPayload's inner catch already calls\n // commitClientNavigationState() on synchronous errors and re-throws, so\n // the outer catch must not call it again. Clearing here prevents the outer\n // catch from double-decrementing navigationSnapshotActiveCount.\n _snapshotPending = false;\n }\n // Don't cache the response if this navigation was superseded during\n // renderNavigationPayload's await — the elements were never dispatched.\n if (navId !== activeNavigationId) return;\n // Store the visited response only after renderNavigationPayload succeeds.\n // If we stored it before and renderNavigationPayload threw, a future\n // back/forward navigation could replay a snapshot from a navigation that\n // never actually rendered successfully.\n const resolvedElements = await rscPayload;\n const metadata = readAppElementsMetadata(resolvedElements);\n storeVisitedResponseSnapshot(\n rscUrl,\n resolveVisitedResponseInterceptionContext(\n requestInterceptionContext,\n metadata.interceptionContext,\n ),\n responseSnapshot,\n navParams,\n );\n return;\n } catch (error) {\n // Only decrement counter if snapshot was activated but not yet committed.\n // renderNavigationPayload clears _snapshotPending (via its inner try-finally)\n // before re-throwing, so this guard correctly skips the double-decrement case.\n if (_snapshotPending) {\n _snapshotPending = false;\n commitClientNavigationState(navId);\n }\n // Clear pending pathname on error so subsequent navigations compare correctly.\n // Only clear if this is still the active navigation — a newer navigation\n // has already overwritten pendingPathname with its own target.\n if (navId === activeNavigationId) {\n clearPendingPathname(navId);\n }\n // Don't hard-navigate to a stale URL if this navigation was superseded by\n // a newer one — the newer navigation is already in flight and would be clobbered.\n if (navId !== activeNavigationId) return;\n console.error(\"[vinext] RSC navigation error:\", error);\n window.location.href = href;\n }\n };\n\n if (\"scrollRestoration\" in history) {\n history.scrollRestoration = \"manual\";\n }\n\n // Note: This popstate handler runs for App Router (RSC navigation available).\n // It coordinates scroll restoration with the pending RSC navigation.\n // Pages Router scroll restoration is handled in shims/navigation.ts:1289 with\n // microtask-based deferral for compatibility with non-RSC navigation.\n // See: https://github.com/vercel/next.js/discussions/41934#discussioncomment-4602607\n window.addEventListener(\"popstate\", (event) => {\n notifyAppRouterTransitionStart(window.location.href, \"traverse\");\n const pendingNavigation =\n window.__VINEXT_RSC_NAVIGATE__?.(window.location.href, 0, \"traverse\") ?? Promise.resolve();\n window.__VINEXT_RSC_PENDING__ = pendingNavigation;\n void pendingNavigation.finally(() => {\n restorePopstateScrollPosition(event.state);\n if (window.__VINEXT_RSC_PENDING__ === pendingNavigation) {\n window.__VINEXT_RSC_PENDING__ = null;\n }\n });\n });\n\n if (import.meta.hot) {\n import.meta.hot.on(\"rsc:update\", async () => {\n try {\n clearClientNavigationCaches();\n const navigationSnapshot = createClientNavigationRenderSnapshot(\n window.location.href,\n latestClientParams,\n );\n // Interception context on HMR re-renders is intentionally deferred:\n // preserving intercepted modal state across HMR reloads is out of scope\n // for the previousNextUrl mechanism.\n const pending = await createPendingNavigationCommit({\n currentState: getBrowserRouterState(),\n nextElements: normalizeAppElementsPromise(\n createFromFetch<AppWireElements>(\n fetch(toRscUrl(window.location.pathname + window.location.search)),\n ),\n ),\n navigationSnapshot,\n renderId: ++nextNavigationRenderId,\n type: \"replace\",\n });\n dispatchBrowserTree(\n pending.action.elements,\n navigationSnapshot,\n pending.action.renderId,\n \"replace\",\n pending.interceptionContext,\n pending.action.layoutFlags,\n pending.previousNextUrl,\n pending.routeId,\n pending.rootLayoutTreePath,\n false,\n );\n } catch (error) {\n console.error(\"[vinext] RSC HMR error:\", error);\n }\n });\n }\n}\n\nif (typeof document !== \"undefined\") {\n void main();\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ //#region src/server/app-browser-error.d.ts
2
+ declare function devOnCaughtError(error: unknown, errorInfo: {
3
+ componentStack?: string;
4
+ errorBoundary?: unknown;
5
+ }): void;
6
+ //#endregion
7
+ export { devOnCaughtError };
8
+ //# sourceMappingURL=app-browser-error.d.ts.map
@@ -0,0 +1,9 @@
1
+ //#region src/server/app-browser-error.ts
2
+ function devOnCaughtError(error, errorInfo) {
3
+ console.error(error);
4
+ if (errorInfo?.componentStack) console.error("The above error occurred in a React component:\n" + errorInfo.componentStack);
5
+ }
6
+ //#endregion
7
+ export { devOnCaughtError };
8
+
9
+ //# sourceMappingURL=app-browser-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-browser-error.js","names":[],"sources":["../../src/server/app-browser-error.ts"],"sourcesContent":["// Preserve console visibility for errors caught during hydration in dev\n// without re-dispatching them through Vite's overlay path.\n//\n// Note: sentinel errors (NEXT_NOT_FOUND, NEXT_REDIRECT, etc.) are re-thrown\n// in getDerivedStateFromError before they reach onCaughtError, so they will\n// not appear here in practice.\nexport function devOnCaughtError(\n error: unknown,\n errorInfo: { componentStack?: string; errorBoundary?: unknown },\n): void {\n console.error(error);\n if (errorInfo?.componentStack) {\n console.error(\"The above error occurred in a React component:\\n\" + errorInfo.componentStack);\n }\n}\n"],"mappings":";AAMA,SAAgB,iBACd,OACA,WACM;AACN,SAAQ,MAAM,MAAM;AACpB,KAAI,WAAW,eACb,SAAQ,MAAM,qDAAqD,UAAU,eAAe"}
@@ -0,0 +1,93 @@
1
+ import { AppElements, LayoutFlags } from "./app-elements.js";
2
+ import { ClientNavigationRenderSnapshot } from "../shims/navigation.js";
3
+
4
+ //#region src/server/app-browser-state.d.ts
5
+ type HistoryStateRecord = {
6
+ [key: string]: unknown;
7
+ };
8
+ type AppRouterState = {
9
+ elements: AppElements;
10
+ interceptionContext: string | null;
11
+ layoutFlags: LayoutFlags;
12
+ previousNextUrl: string | null;
13
+ renderId: number;
14
+ navigationSnapshot: ClientNavigationRenderSnapshot;
15
+ rootLayoutTreePath: string | null;
16
+ routeId: string;
17
+ };
18
+ type AppRouterAction = {
19
+ elements: AppElements;
20
+ interceptionContext: string | null;
21
+ layoutFlags: LayoutFlags;
22
+ navigationSnapshot: ClientNavigationRenderSnapshot;
23
+ previousNextUrl: string | null;
24
+ renderId: number;
25
+ rootLayoutTreePath: string | null;
26
+ routeId: string;
27
+ type: "navigate" | "replace" | "traverse";
28
+ };
29
+ type PendingNavigationCommit = {
30
+ action: AppRouterAction;
31
+ interceptionContext: string | null;
32
+ previousNextUrl: string | null;
33
+ rootLayoutTreePath: string | null;
34
+ routeId: string;
35
+ };
36
+ type PendingNavigationCommitDisposition = "dispatch" | "hard-navigate" | "skip";
37
+ type ClassifiedPendingNavigationCommit = {
38
+ disposition: PendingNavigationCommitDisposition;
39
+ pending: PendingNavigationCommit;
40
+ };
41
+ declare function createHistoryStateWithPreviousNextUrl(state: unknown, previousNextUrl: string | null): HistoryStateRecord | null;
42
+ declare function readHistoryStatePreviousNextUrl(state: unknown): string | null;
43
+ declare function resolveInterceptionContextFromPreviousNextUrl(previousNextUrl: string | null, basePath?: string): string | null;
44
+ type ResolveServerActionRequestStateOptions = {
45
+ actionId: string;
46
+ basePath: string;
47
+ elements: AppElements;
48
+ previousNextUrl: string | null;
49
+ };
50
+ type ResolveServerActionRequestStateResult = {
51
+ headers: Headers;
52
+ };
53
+ /**
54
+ * Pure: builds the fetch Headers for a server-action POST. Carries the same
55
+ * interception-context and mounted-slots headers the refresh path already
56
+ * sends, so the server-action re-render can rebuild the intercepted tree
57
+ * instead of replacing it with the direct route.
58
+ *
59
+ * Next.js sends `Next-URL: state.previousNextUrl || state.nextUrl` on action
60
+ * POSTs when `hasInterceptionRouteInCurrentTree(state.tree)`. Vinext's
61
+ * X-Vinext-Interception-Context is the equivalent signal for the server-side
62
+ * `findIntercept` lookup.
63
+ */
64
+ declare function resolveServerActionRequestState(options: ResolveServerActionRequestStateOptions): ResolveServerActionRequestStateResult;
65
+ declare function routerReducer(state: AppRouterState, action: AppRouterAction): AppRouterState;
66
+ declare function shouldHardNavigate(currentRootLayoutTreePath: string | null, nextRootLayoutTreePath: string | null): boolean;
67
+ declare function resolvePendingNavigationCommitDisposition(options: {
68
+ activeNavigationId: number;
69
+ currentRootLayoutTreePath: string | null;
70
+ nextRootLayoutTreePath: string | null;
71
+ startedNavigationId: number;
72
+ }): PendingNavigationCommitDisposition;
73
+ declare function createPendingNavigationCommit(options: {
74
+ currentState: AppRouterState;
75
+ nextElements: Promise<AppElements>;
76
+ navigationSnapshot: ClientNavigationRenderSnapshot;
77
+ previousNextUrl?: string | null;
78
+ renderId: number;
79
+ type: "navigate" | "replace" | "traverse";
80
+ }): Promise<PendingNavigationCommit>;
81
+ declare function resolveAndClassifyNavigationCommit(options: {
82
+ activeNavigationId: number;
83
+ currentState: AppRouterState;
84
+ navigationSnapshot: ClientNavigationRenderSnapshot;
85
+ nextElements: Promise<AppElements>;
86
+ previousNextUrl?: string | null;
87
+ renderId: number;
88
+ startedNavigationId: number;
89
+ type: "navigate" | "replace" | "traverse";
90
+ }): Promise<ClassifiedPendingNavigationCommit>;
91
+ //#endregion
92
+ export { AppRouterAction, AppRouterState, ClassifiedPendingNavigationCommit, PendingNavigationCommit, PendingNavigationCommitDisposition, ResolveServerActionRequestStateOptions, ResolveServerActionRequestStateResult, createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, readHistoryStatePreviousNextUrl, resolveAndClassifyNavigationCommit, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDisposition, resolveServerActionRequestState, routerReducer, shouldHardNavigate };
93
+ //# sourceMappingURL=app-browser-state.d.ts.map
@@ -0,0 +1,132 @@
1
+ import { stripBasePath } from "../utils/base-path.js";
2
+ import { getMountedSlotIdsHeader, readAppElementsMetadata } from "./app-elements.js";
3
+ import { mergeElements } from "../shims/slot.js";
4
+ //#region src/server/app-browser-state.ts
5
+ const VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY = "__vinext_previousNextUrl";
6
+ function cloneHistoryState(state) {
7
+ if (!state || typeof state !== "object") return {};
8
+ const nextState = {};
9
+ for (const [key, value] of Object.entries(state)) nextState[key] = value;
10
+ return nextState;
11
+ }
12
+ function createHistoryStateWithPreviousNextUrl(state, previousNextUrl) {
13
+ const nextState = cloneHistoryState(state);
14
+ if (previousNextUrl === null) delete nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];
15
+ else nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY] = previousNextUrl;
16
+ return Object.keys(nextState).length > 0 ? nextState : null;
17
+ }
18
+ function readHistoryStatePreviousNextUrl(state) {
19
+ const value = cloneHistoryState(state)[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];
20
+ return typeof value === "string" ? value : null;
21
+ }
22
+ function resolveInterceptionContextFromPreviousNextUrl(previousNextUrl, basePath = "") {
23
+ if (previousNextUrl === null) return null;
24
+ return stripBasePath(new URL(previousNextUrl, "http://localhost").pathname, basePath);
25
+ }
26
+ /**
27
+ * Pure: builds the fetch Headers for a server-action POST. Carries the same
28
+ * interception-context and mounted-slots headers the refresh path already
29
+ * sends, so the server-action re-render can rebuild the intercepted tree
30
+ * instead of replacing it with the direct route.
31
+ *
32
+ * Next.js sends `Next-URL: state.previousNextUrl || state.nextUrl` on action
33
+ * POSTs when `hasInterceptionRouteInCurrentTree(state.tree)`. Vinext's
34
+ * X-Vinext-Interception-Context is the equivalent signal for the server-side
35
+ * `findIntercept` lookup.
36
+ */
37
+ function resolveServerActionRequestState(options) {
38
+ const headers = new Headers({
39
+ Accept: "text/x-component",
40
+ "x-rsc-action": options.actionId
41
+ });
42
+ const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(options.previousNextUrl, options.basePath);
43
+ if (interceptionContext !== null) headers.set("X-Vinext-Interception-Context", interceptionContext);
44
+ const mountedSlotsHeader = getMountedSlotIdsHeader(options.elements);
45
+ if (mountedSlotsHeader !== null) headers.set("X-Vinext-Mounted-Slots", mountedSlotsHeader);
46
+ return { headers };
47
+ }
48
+ function routerReducer(state, action) {
49
+ switch (action.type) {
50
+ case "traverse":
51
+ case "navigate": return {
52
+ elements: mergeElements(state.elements, action.elements, action.type === "traverse"),
53
+ interceptionContext: action.interceptionContext,
54
+ layoutFlags: {
55
+ ...state.layoutFlags,
56
+ ...action.layoutFlags
57
+ },
58
+ navigationSnapshot: action.navigationSnapshot,
59
+ previousNextUrl: action.previousNextUrl,
60
+ renderId: action.renderId,
61
+ rootLayoutTreePath: action.rootLayoutTreePath,
62
+ routeId: action.routeId
63
+ };
64
+ case "replace": return {
65
+ elements: action.elements,
66
+ interceptionContext: action.interceptionContext,
67
+ layoutFlags: action.layoutFlags,
68
+ navigationSnapshot: action.navigationSnapshot,
69
+ previousNextUrl: action.previousNextUrl,
70
+ renderId: action.renderId,
71
+ rootLayoutTreePath: action.rootLayoutTreePath,
72
+ routeId: action.routeId
73
+ };
74
+ default: {
75
+ const _exhaustive = action.type;
76
+ throw new Error("[vinext] Unknown router action: " + String(_exhaustive));
77
+ }
78
+ }
79
+ }
80
+ function shouldHardNavigate(currentRootLayoutTreePath, nextRootLayoutTreePath) {
81
+ return currentRootLayoutTreePath !== null && nextRootLayoutTreePath !== null && currentRootLayoutTreePath !== nextRootLayoutTreePath;
82
+ }
83
+ function resolvePendingNavigationCommitDisposition(options) {
84
+ if (options.startedNavigationId !== options.activeNavigationId) return "skip";
85
+ if (shouldHardNavigate(options.currentRootLayoutTreePath, options.nextRootLayoutTreePath)) return "hard-navigate";
86
+ return "dispatch";
87
+ }
88
+ async function createPendingNavigationCommit(options) {
89
+ const elements = await options.nextElements;
90
+ const metadata = readAppElementsMetadata(elements);
91
+ const previousNextUrl = options.previousNextUrl !== void 0 ? options.previousNextUrl : options.currentState.previousNextUrl;
92
+ return {
93
+ action: {
94
+ elements,
95
+ interceptionContext: metadata.interceptionContext,
96
+ layoutFlags: metadata.layoutFlags,
97
+ navigationSnapshot: options.navigationSnapshot,
98
+ previousNextUrl,
99
+ renderId: options.renderId,
100
+ rootLayoutTreePath: metadata.rootLayoutTreePath,
101
+ routeId: metadata.routeId,
102
+ type: options.type
103
+ },
104
+ interceptionContext: metadata.interceptionContext,
105
+ previousNextUrl,
106
+ rootLayoutTreePath: metadata.rootLayoutTreePath,
107
+ routeId: metadata.routeId
108
+ };
109
+ }
110
+ async function resolveAndClassifyNavigationCommit(options) {
111
+ const pending = await createPendingNavigationCommit({
112
+ currentState: options.currentState,
113
+ nextElements: options.nextElements,
114
+ navigationSnapshot: options.navigationSnapshot,
115
+ previousNextUrl: options.previousNextUrl,
116
+ renderId: options.renderId,
117
+ type: options.type
118
+ });
119
+ return {
120
+ disposition: resolvePendingNavigationCommitDisposition({
121
+ activeNavigationId: options.activeNavigationId,
122
+ currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,
123
+ nextRootLayoutTreePath: pending.rootLayoutTreePath,
124
+ startedNavigationId: options.startedNavigationId
125
+ }),
126
+ pending
127
+ };
128
+ }
129
+ //#endregion
130
+ export { createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, readHistoryStatePreviousNextUrl, resolveAndClassifyNavigationCommit, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDisposition, resolveServerActionRequestState, routerReducer, shouldHardNavigate };
131
+
132
+ //# sourceMappingURL=app-browser-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-browser-state.js","names":[],"sources":["../../src/server/app-browser-state.ts"],"sourcesContent":["import { mergeElements } from \"../shims/slot.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport {\n getMountedSlotIdsHeader,\n readAppElementsMetadata,\n type AppElements,\n type LayoutFlags,\n} from \"./app-elements.js\";\nimport type { ClientNavigationRenderSnapshot } from \"../shims/navigation.js\";\n\nconst VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY = \"__vinext_previousNextUrl\";\n\ntype HistoryStateRecord = {\n [key: string]: unknown;\n};\n\nexport type AppRouterState = {\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n previousNextUrl: string | null;\n renderId: number;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n rootLayoutTreePath: string | null;\n routeId: string;\n};\n\nexport type AppRouterAction = {\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n previousNextUrl: string | null;\n renderId: number;\n rootLayoutTreePath: string | null;\n routeId: string;\n type: \"navigate\" | \"replace\" | \"traverse\";\n};\n\nexport type PendingNavigationCommit = {\n action: AppRouterAction;\n interceptionContext: string | null;\n previousNextUrl: string | null;\n rootLayoutTreePath: string | null;\n routeId: string;\n};\n\nexport type PendingNavigationCommitDisposition = \"dispatch\" | \"hard-navigate\" | \"skip\";\nexport type ClassifiedPendingNavigationCommit = {\n disposition: PendingNavigationCommitDisposition;\n pending: PendingNavigationCommit;\n};\n\nfunction cloneHistoryState(state: unknown): HistoryStateRecord {\n if (!state || typeof state !== \"object\") {\n return {};\n }\n\n const nextState: HistoryStateRecord = {};\n for (const [key, value] of Object.entries(state)) {\n nextState[key] = value;\n }\n return nextState;\n}\n\nexport function createHistoryStateWithPreviousNextUrl(\n state: unknown,\n previousNextUrl: string | null,\n): HistoryStateRecord | null {\n const nextState = cloneHistoryState(state);\n\n if (previousNextUrl === null) {\n delete nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n } else {\n nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY] = previousNextUrl;\n }\n\n return Object.keys(nextState).length > 0 ? nextState : null;\n}\n\nexport function readHistoryStatePreviousNextUrl(state: unknown): string | null {\n const value = cloneHistoryState(state)[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n return typeof value === \"string\" ? value : null;\n}\n\nexport function resolveInterceptionContextFromPreviousNextUrl(\n previousNextUrl: string | null,\n basePath: string = \"\",\n): string | null {\n if (previousNextUrl === null) {\n return null;\n }\n\n const parsedUrl = new URL(previousNextUrl, \"http://localhost\");\n return stripBasePath(parsedUrl.pathname, basePath);\n}\n\nexport type ResolveServerActionRequestStateOptions = {\n actionId: string;\n basePath: string;\n elements: AppElements;\n previousNextUrl: string | null;\n};\n\nexport type ResolveServerActionRequestStateResult = {\n headers: Headers;\n};\n\n/**\n * Pure: builds the fetch Headers for a server-action POST. Carries the same\n * interception-context and mounted-slots headers the refresh path already\n * sends, so the server-action re-render can rebuild the intercepted tree\n * instead of replacing it with the direct route.\n *\n * Next.js sends `Next-URL: state.previousNextUrl || state.nextUrl` on action\n * POSTs when `hasInterceptionRouteInCurrentTree(state.tree)`. Vinext's\n * X-Vinext-Interception-Context is the equivalent signal for the server-side\n * `findIntercept` lookup.\n */\nexport function resolveServerActionRequestState(\n options: ResolveServerActionRequestStateOptions,\n): ResolveServerActionRequestStateResult {\n const headers = new Headers({\n Accept: \"text/x-component\",\n \"x-rsc-action\": options.actionId,\n });\n\n const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(\n options.previousNextUrl,\n options.basePath,\n );\n if (interceptionContext !== null) {\n headers.set(\"X-Vinext-Interception-Context\", interceptionContext);\n }\n\n const mountedSlotsHeader = getMountedSlotIdsHeader(options.elements);\n if (mountedSlotsHeader !== null) {\n headers.set(\"X-Vinext-Mounted-Slots\", mountedSlotsHeader);\n }\n\n return { headers };\n}\n\nexport function routerReducer(state: AppRouterState, action: AppRouterAction): AppRouterState {\n switch (action.type) {\n case \"traverse\":\n case \"navigate\":\n return {\n elements: mergeElements(state.elements, action.elements, action.type === \"traverse\"),\n interceptionContext: action.interceptionContext,\n layoutFlags: { ...state.layoutFlags, ...action.layoutFlags },\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n };\n case \"replace\":\n return {\n elements: action.elements,\n interceptionContext: action.interceptionContext,\n layoutFlags: action.layoutFlags,\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n };\n default: {\n const _exhaustive: never = action.type;\n throw new Error(\"[vinext] Unknown router action: \" + String(_exhaustive));\n }\n }\n}\n\nexport function shouldHardNavigate(\n currentRootLayoutTreePath: string | null,\n nextRootLayoutTreePath: string | null,\n): boolean {\n // `null` means the payload could not identify an enclosing root layout\n // boundary. Treat that as soft-navigation compatible so fallback payloads\n // do not force a hard reload purely because metadata is absent.\n return (\n currentRootLayoutTreePath !== null &&\n nextRootLayoutTreePath !== null &&\n currentRootLayoutTreePath !== nextRootLayoutTreePath\n );\n}\n\nexport function resolvePendingNavigationCommitDisposition(options: {\n activeNavigationId: number;\n currentRootLayoutTreePath: string | null;\n nextRootLayoutTreePath: string | null;\n startedNavigationId: number;\n}): PendingNavigationCommitDisposition {\n if (options.startedNavigationId !== options.activeNavigationId) {\n return \"skip\";\n }\n\n if (shouldHardNavigate(options.currentRootLayoutTreePath, options.nextRootLayoutTreePath)) {\n return \"hard-navigate\";\n }\n\n return \"dispatch\";\n}\n\nexport async function createPendingNavigationCommit(options: {\n currentState: AppRouterState;\n nextElements: Promise<AppElements>;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n previousNextUrl?: string | null;\n renderId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<PendingNavigationCommit> {\n const elements = await options.nextElements;\n const metadata = readAppElementsMetadata(elements);\n const previousNextUrl =\n options.previousNextUrl !== undefined\n ? options.previousNextUrl\n : options.currentState.previousNextUrl;\n\n return {\n action: {\n elements,\n interceptionContext: metadata.interceptionContext,\n layoutFlags: metadata.layoutFlags,\n navigationSnapshot: options.navigationSnapshot,\n previousNextUrl,\n renderId: options.renderId,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n type: options.type,\n },\n // Convenience aliases — always equal action.interceptionContext / action.rootLayoutTreePath / action.routeId.\n interceptionContext: metadata.interceptionContext,\n previousNextUrl,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n };\n}\n\nexport async function resolveAndClassifyNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n previousNextUrl?: string | null;\n renderId: number;\n startedNavigationId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<ClassifiedPendingNavigationCommit> {\n const pending = await createPendingNavigationCommit({\n currentState: options.currentState,\n nextElements: options.nextElements,\n navigationSnapshot: options.navigationSnapshot,\n previousNextUrl: options.previousNextUrl,\n renderId: options.renderId,\n type: options.type,\n });\n\n return {\n disposition: resolvePendingNavigationCommitDisposition({\n activeNavigationId: options.activeNavigationId,\n currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,\n nextRootLayoutTreePath: pending.rootLayoutTreePath,\n startedNavigationId: options.startedNavigationId,\n }),\n pending,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { ReactNode } from "react";
2
+
3
+ //#region src/server/app-elements.d.ts
4
+ declare const APP_INTERCEPTION_CONTEXT_KEY = "__interceptionContext";
5
+ declare const APP_LAYOUT_FLAGS_KEY = "__layoutFlags";
6
+ declare const APP_ROUTE_KEY = "__route";
7
+ declare const APP_ROOT_LAYOUT_KEY = "__rootLayout";
8
+ declare const APP_UNMATCHED_SLOT_WIRE_VALUE = "__VINEXT_UNMATCHED_SLOT__";
9
+ declare const UNMATCHED_SLOT: unique symbol;
10
+ type AppElementValue = ReactNode | typeof UNMATCHED_SLOT | string | null;
11
+ type AppWireElementValue = ReactNode | string | null;
12
+ type AppElements = Readonly<Record<string, AppElementValue>>;
13
+ type AppWireElements = Readonly<Record<string, AppWireElementValue>>;
14
+ /**
15
+ * Per-layout static/dynamic flags. `"s"` = static (skippable on next nav);
16
+ * `"d"` = dynamic (must always render).
17
+ *
18
+ * Lifecycle (partial — later PRs extend this):
19
+ *
20
+ * 1. PROBE — probeAppPageLayouts (server/app-page-execution.ts) returns
21
+ * LayoutFlags for every layout in the route at render time.
22
+ *
23
+ * 2. ATTACH — withLayoutFlags (this file) writes `__layoutFlags` into the
24
+ * outgoing App Router payload record.
25
+ *
26
+ * 3. WIRE — renderToReadableStream serializes the record as RSC row 0.
27
+ *
28
+ * 4. PARSE — readAppElementsMetadata (this file) extracts layoutFlags from
29
+ * the wire payload on the client side.
30
+ */
31
+ type LayoutFlags = Readonly<Record<string, "s" | "d">>;
32
+ type AppElementsMetadata = {
33
+ interceptionContext: string | null;
34
+ layoutFlags: LayoutFlags;
35
+ routeId: string;
36
+ rootLayoutTreePath: string | null;
37
+ };
38
+ declare function normalizeMountedSlotsHeader(header: string | null | undefined): string | null;
39
+ declare function getMountedSlotIds(elements: AppElements): string[];
40
+ declare function getMountedSlotIdsHeader(elements: AppElements): string | null;
41
+ declare function createAppPayloadRouteId(routePath: string, interceptionContext: string | null): string;
42
+ declare function createAppPayloadPageId(routePath: string, interceptionContext: string | null): string;
43
+ declare function createAppPayloadCacheKey(rscUrl: string, interceptionContext: string | null): string;
44
+ declare function resolveVisitedResponseInterceptionContext(requestInterceptionContext: string | null, payloadInterceptionContext: string | null): string | null;
45
+ declare function normalizeAppElements(elements: AppWireElements): AppElements;
46
+ /**
47
+ * Type predicate for a plain (non-null, non-array) record of app payload values.
48
+ * Used to distinguish the App Router payload object from bare React elements at
49
+ * the render boundary. Narrows to `Readonly<Record<string, unknown>>` because
50
+ * the outgoing payload carries heterogeneous values (ReactNodes for the rendered
51
+ * tree, plus metadata like `__layoutFlags` which is a plain object). Delegates
52
+ * to React's canonical `isValidElement` so we don't depend on React's internal
53
+ * `$$typeof` marker scheme.
54
+ */
55
+ declare function isAppElementsRecord(value: unknown): value is Readonly<Record<string, unknown>>;
56
+ /**
57
+ * Pure: returns a new record with `__layoutFlags` attached. Owns the write
58
+ * boundary for the layout flags key so the write side sits next to
59
+ * `readAppElementsMetadata`.
60
+ *
61
+ * See `LayoutFlags` type docblock in this file for lifecycle.
62
+ */
63
+ declare function withLayoutFlags<T extends Record<string, unknown>>(elements: T, layoutFlags: LayoutFlags): T & {
64
+ [APP_LAYOUT_FLAGS_KEY]: LayoutFlags;
65
+ };
66
+ /**
67
+ * The outgoing wire payload shape. Includes ReactNode values for the
68
+ * rendered tree plus metadata values like LayoutFlags attached under
69
+ * known keys (e.g. __layoutFlags). Distinct from AppElements / AppWireElements
70
+ * which only carry render-time values.
71
+ */
72
+ type AppOutgoingElements = Readonly<Record<string, ReactNode | LayoutFlags>>;
73
+ /**
74
+ * Pure: builds the outgoing payload for the wire. Non-record inputs (e.g. a
75
+ * bare React element) are returned unchanged. Record inputs get a fresh copy
76
+ * with `__layoutFlags` attached. Never mutates `input.element`.
77
+ */
78
+ declare function buildOutgoingAppPayload(input: {
79
+ element: ReactNode | Readonly<Record<string, ReactNode>>;
80
+ layoutFlags: LayoutFlags;
81
+ }): ReactNode | AppOutgoingElements;
82
+ /**
83
+ * Parses metadata from the wire payload. Accepts `Record<string, unknown>`
84
+ * because the RSC payload carries heterogeneous values (React elements,
85
+ * strings, and plain objects like layout flags) under the same record type.
86
+ *
87
+ * See `LayoutFlags` type docblock in this file for lifecycle.
88
+ */
89
+ declare function readAppElementsMetadata(elements: Readonly<Record<string, unknown>>): AppElementsMetadata;
90
+ //#endregion
91
+ export { APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsMetadata, AppOutgoingElements, AppWireElementValue, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, createAppPayloadCacheKey, createAppPayloadPageId, createAppPayloadRouteId, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, normalizeMountedSlotsHeader, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
92
+ //# sourceMappingURL=app-elements.d.ts.map