@rsc-kit/core 0.21.3 → 0.21.4
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.
- package/dist/js/navigate.js +16 -3
- package/dist/js/navigate.js.map +1 -1
- package/dist/vite.js +8 -56
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
package/dist/js/navigate.js
CHANGED
|
@@ -1125,16 +1125,29 @@ export function prefetch(url, cacheForMs, intent = false) {
|
|
|
1125
1125
|
* the tap on Sign in decoded the login page and loaded its chunks after the
|
|
1126
1126
|
* click, 154 ms of a 225 ms tap.
|
|
1127
1127
|
*/
|
|
1128
|
-
function warm(entry, cacheKey) {
|
|
1128
|
+
function warm(entry, cacheKey, followed = new Set()) {
|
|
1129
|
+
// A redirect this touch has already followed. Two guards can point at each
|
|
1130
|
+
// other - a guard's answer kept from before a sign-in beside the live one
|
|
1131
|
+
// after it - and a destination can normalise to the key of the entry that
|
|
1132
|
+
// named it (/agent/ to /agent). Every entry in such a chain is settled, so
|
|
1133
|
+
// following it is a chain of resolved promises: no request, no yield, the
|
|
1134
|
+
// tab pegged at 100% until it is killed. A port found its landing page
|
|
1135
|
+
// freezing on the first tap after a hard reload, with nothing in the
|
|
1136
|
+
// console and the network idle. Navigation caps the same walk at
|
|
1137
|
+
// MAX_REDIRECTS; this is the warm's own cap.
|
|
1138
|
+
if (followed.has(cacheKey) || followed.size > MAX_REDIRECTS)
|
|
1139
|
+
return;
|
|
1140
|
+
followed.add(cacheKey);
|
|
1129
1141
|
// The tree is read by the navigation that takes the entry, and a decode
|
|
1130
1142
|
// that fails - a chunk the deploy no longer serves - fails there, where it
|
|
1131
1143
|
// is handled. Here the rejection has nobody to reach.
|
|
1132
1144
|
entry.body
|
|
1133
1145
|
.then((text) => {
|
|
1134
1146
|
if (entry.redirectTo) {
|
|
1135
|
-
const
|
|
1147
|
+
const destinationKey = retentionKeyFor(entry.redirectTo, matchIntercept(entry.redirectTo));
|
|
1148
|
+
const destination = cache.get(destinationKey);
|
|
1136
1149
|
if (destination)
|
|
1137
|
-
warm(destination,
|
|
1150
|
+
warm(destination, destinationKey, followed);
|
|
1138
1151
|
return;
|
|
1139
1152
|
}
|
|
1140
1153
|
if (text === null)
|
package/dist/js/navigate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../src/js/navigate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core SPA navigation engine for RSC.\n *\n * Uses module-level state (singleton in the browser bundle).\n * The Flight deserializer is injected by createViteRscApp to avoid\n * duplicate bundling of react-server-dom-webpack.\n */\n\nimport {\n announceDocumentLoad,\n isStaleAssetError,\n loadDocumentOnce,\n} from \"./staleAssets\";\nimport { isUpdated, markStale } from \"./updateStore\";\nimport { navigationAbandoned, navigationCommitted, navigationReached, navigationStarted } from \"./perf\";\nimport { preloadImages } from \"./imagePreload\";\nimport { preloadChunks } from \"./chunkPreload\";\nimport { isSafeRedirect } from \"../safeUrl.js\";\nimport type { Route } from \"../routes.js\";\nimport { reportReachable } from \"./onlineStore\";\nimport { clearSlots, setSlot } from \"./slotStore\";\n// Shared with the host: it stores a page under this key and the client looks\n// under it, so the format cannot live in two places.\nimport {\n matchRoute,\n retentionKey as retentionKeyFor,\n sharedDepth,\n} from \"../routing\";\nimport type { ManifestRoute } from \"../manifest\";\n\ntype ReactNode = unknown;\ntype Deserializer = (\n stream: ReadableStream,\n options: Record<string, unknown>,\n) => Promise<ReactNode>;\ntype CallServerFn = (id: string, args: unknown[]) => Promise<unknown>;\n\ninterface CacheEntry {\n /**\n * The payload as it arrived, undecoded. Decoding a payload is what loads\n * the client chunks it names, and a prefetch decoded on arrival loaded\n * the sign-in page's thirty chunks onto a landing page for every phone\n * visitor, whether they tapped or not. The text is kept; \\`tree\\` decodes\n * it the first time a navigation asks, which is the moment those chunks\n * are wanted.\n */\n body: Promise<string | null>;\n /** The decoded page, on first read. */\n readonly tree: Promise<ReactNode>;\n expiresAt: number;\n /**\n * What the server said about the payload. A prefetch is a real request, so\n * it comes back partial like any other — losing that and treating it as a\n * whole document replaces the root with a page that has no layouts.\n */\n segmentDepth: number;\n layouts: string[] | null;\n /**\n * The slot this payload fills, when it is one region rather than a segment.\n *\n * A prefetch is a real request and comes back as whatever the host answers.\n * An interception answers with the interceptor alone, and an entry that\n * forgets that is applied as a whole document — so a hovered modal link\n * renders the modal *as* the page, with nothing around it. Only after a\n * hover, which is why a scripted click never finds it.\n */\n slot: string | null;\n /**\n * The chain held when this was prefetched. A partial payload is only valid\n * against the chain it was rendered for; navigate somewhere else first and\n * it no longer composes.\n */\n heldWhenFetched: string;\n /**\n * Where the prefetch was sent instead, when the host answered a redirect.\n * The entry leaves the cache - a hover must not navigate - but a click\n * that took the entry while the request was in flight awaits its tree, and\n * a tree of null committed as the page was the whole document gone: url\n * changed, root unmounted, nothing in the console. On a phone the tap's\n * touchstart prefetches with no delay and the click lands 100-300 ms\n * later, the length of a round trip, so a tapped link to a guarded page\n * blanked the page about half the time. The navigation reads this and\n * follows it, the way it follows a redirect on its own request.\n */\n redirectTo: string | null;\n /** The request failed or was aborted; a navigation that took the entry asks again. */\n failed: boolean;\n}\n\ninterface InterceptEntry {\n urlPattern: string;\n slot: string;\n}\n\nlet version = \"\";\n/** Pages a navigation is fetching right now, so a prefetch does not ask again. */\nconst navigating = new Set<string>();\nlet onNavigate:\n ((tree: ReactNode, key: string, segmentDepth: number) => void) | null = null;\nlet onRestore: ((key: string, maxAge?: number) => boolean) | null = null;\n/**\n * Re-render the whole document in place, for revalidate(\"all\"): the page the\n * visitor is on, not a page they went to. Without one registered, the\n * navigation handler at depth 0 is used, which shows the tree as a page.\n */\nlet onReplaceRoot: ((tree: ReactNode) => void) | null = null;\n\n/** Whether a navigation to the key would reveal a held page, asked without revealing it. */\nlet isHeldPage: ((key: string, maxAge?: number) => boolean) | null = null;\n/** Drop the pages held behind the one on screen - after a mutation. */\nlet dropHeld: (() => void) | null = null;\n/**\n * Render a decoded page in the background, hidden, before the click - see\n * warm(). Given the same tree the navigation will hand to onNavigate, so\n * that the navigation is a reveal of work already done rather than a render.\n */\nlet onPrerender: ((tree: ReactNode, key: string, segmentDepth: number) => void) | null = null;\n\n/**\n * How stale a held page may be and still be revealed by a link.\n *\n * The back button ignores this: it names a moment, and the page from that\n * moment is the right answer however old. A link says \"go here\", so there is a\n * point past which answering with what you saw before is stale data presented\n * as fresh. Thirty seconds covers leaving a form to check something and coming\n * straight back, which is the case this exists for.\n */\nlet revealWithin = 30_000;\n\nexport function setRevealWindow(ms: number): void {\n revealWithin = ms;\n}\nlet flightDeserializer: Deserializer | null = null;\nlet callServerFn: CallServerFn | null = null;\nlet activeController: AbortController | null = null;\nconst cache = new Map<string, CacheEntry>();\n/** In-flight prefetches, so one the pointer moved away from can be dropped. */\nconst prefetchControllers = new Map<string, AbortController>();\nlet interceptManifest: InterceptEntry[] = [];\n\n// The layout chain currently mounted, outermost first. Sent so the server can\n// skip re-rendering the layouts still on screen.\nlet heldLayouts: string[] = [];\n\n/**\n * The chain each page was shown under, by retention key.\n *\n * A held page revealed - the back button, or a link to the page just left -\n * puts its layouts back on screen, and the chain has to say so. It used to\n * keep the chain of the page being left: home, a category, back to home,\n * then another category claimed the first category's layout as mounted. The\n * server sent the page alone, and the client put it in the boundary that\n * layout owns - inside the hidden category. The url changed and the page did\n * not, and every tap after it did the same, until a reload. The demo froze\n * on a phone within a dozen taps.\n *\n * Bounded like the payload cache: a key that is no longer held is never\n * asked for, so the oldest can go.\n */\nconst chainOf = new Map<string, string[]>();\nconst MAX_CHAINS = 64;\n\nfunction rememberChain(key: string): void {\n chainOf.delete(key);\n chainOf.set(key, heldLayouts);\n\n while (chainOf.size > MAX_CHAINS) {\n const oldest = chainOf.keys().next().value as string | undefined;\n\n if (oldest === undefined) break;\n\n chainOf.delete(oldest);\n }\n}\n\n/**\n * The boundary depth an interception was rendered at, while one is showing.\n *\n * An interceptor replaces a slot on the layout that declares it, so leaving the\n * intercepted view has to re-render that layout for the slot to go back to its\n * default. Left to itself the next navigation shares the whole chain, replaces\n * only the page below it, and the modal stays open over the new one.\n */\nlet interceptedAtDepth: number | null = null;\n\n/**\n * The url showing underneath an open interception.\n *\n * An interception puts something in a slot on a page that stays where it is,\n * so closing it is not a navigation at all — the page beneath was never\n * replaced. Remembering which url that is means going back to it costs\n * nothing, rather than fetching and rebuilding a page that is already on\n * screen with everything the user typed into it.\n */\nlet interceptedOver: string | null = null;\n\n/**\n * The url an interception was opened from, whichever way it was rendered -\n * the page still on screen under the modal. Only stillShowing asks.\n */\nlet interceptedFrom: string | null = null;\n\nconst DEFAULT_PREFETCH_TTL = 30_000;\n/**\n * How long a payload the host marked `public` is kept.\n *\n * The same build-time bytes for everyone, so the only way it changes is a\n * deploy, and the version handshake catches that on the tap. Thirty seconds\n * was Next's figure for a dynamic page; its static pages are held five\n * minutes, and a landing page read for a minute before the tap on Sign in\n * was, at thirty, an expired entry and a round trip on a phone.\n */\nconst STATIC_PREFETCH_TTL = 300_000;\n\n/**\n * How many prefetched payloads are kept. Entries carry a TTL but were only\n * dropped when read again, so a long session hovering its way through a big\n * nav held every payload it had ever fetched. On insert, anything expired\n * goes, and past the cap the oldest goes - insertion order is age.\n */\nconst MAX_CACHED = 50;\n\nfunction makeRoom(): void {\n const now = Date.now();\n\n for (const [key, entry] of cache) {\n if (entry.expiresAt <= now && !prefetchControllers.has(key))\n cache.delete(key);\n }\n\n while (cache.size >= MAX_CACHED) {\n const oldest = cache.keys().next().value as string | undefined;\n\n if (oldest === undefined) break;\n\n prefetchControllers.get(oldest)?.abort();\n prefetchControllers.delete(oldest);\n cache.delete(oldest);\n }\n}\n\n/**\n * Where a payload lives when there is no server to negotiate with.\n *\n * Normally the payload and the page share a url and are told apart by the\n * X-RSC header. A static host cannot vary by header — it serves one file per\n * url — so an exported build gives payloads their own addresses and the client\n * asks for those instead.\n */\nlet staticPayloadSuffix: string | null = null;\n\n/**\n * The route table, on a static host only.\n *\n * A server works out how much of the page to send by comparing the chain the\n * client sent with the route's own, and says so in a header. A file server\n * does neither — so on an exported site the client has to know the target's\n * layout chain before it asks, or every navigation takes the whole document\n * and replaces the root, which unmounts everything retained behind it.\n *\n * Inlined into the browser entry by the build, so it costs no request.\n */\nlet staticRoutes: ManifestRoute[] | null = null;\n\nexport function setStaticRoutes(routes: ManifestRoute[]): void {\n staticRoutes = routes;\n}\n\n/**\n * The layout chain of the page loaded from a file, since no header said.\n *\n * Without this the client believes it holds nothing, every navigation asks\n * for a whole document, and the depth variants sitting beside it are never\n * requested — the export looks correct and retention silently never happens.\n */\nexport function seedStaticChain(url: string): boolean {\n const segments = staticSegments(url);\n\n if (!segments) return false;\n\n heldLayouts = segments.chain;\n rememberChain(retentionKey(url, null));\n\n return true;\n}\n\n/**\n * The depth an exported payload should be asked for, and the chain it leaves\n * mounted — the two things a header would otherwise have carried.\n */\nfunction staticSegments(\n url: string,\n held: string[] = heldLayouts,\n): { depth: number; chain: string[] } | null {\n if (staticRoutes === null) return null;\n\n const path = new URL(url, window.location.origin).pathname;\n const match = matchRoute({ routes: staticRoutes } as never, path);\n\n if (!match) return null;\n\n return {\n // Against the chain the request is made with, never against whatever is\n // mounted by the time the answer arrives. A prefetch is fetched against\n // one chain and applied later, and reading live state here labels its\n // payload with a depth it was not rendered for.\n depth: sharedDepth(held.join(\",\"), match.route.layouts),\n // Copied: this is the build's table, and the caller assigns it to the\n // chain it holds — handing out the array itself makes the two the same\n // object.\n chain: [...match.route.layouts],\n };\n}\n\nexport function setStaticPayloads(suffix: string | null): void {\n staticPayloadSuffix = suffix;\n}\n\n/** The url to request a payload from, which is the page's own unless exported. */\nexport function payloadUrl(url: string, held: string[] = heldLayouts): string {\n if (staticPayloadSuffix === null) return url;\n\n const parsed = new URL(url, window.location.origin);\n const path = parsed.pathname.replace(/\\/+$/, \"\");\n const segments = staticSegments(url, held);\n\n // The variant for exactly the depth this client shares. Asking for the whole\n // document when a segment would do is not merely wasteful: it replaces the\n // root, and replacing the root throws away every page retained behind it.\n const name =\n segments && segments.depth > 0\n ? staticPayloadSuffix.replace(/^index\\./, `index.seg${segments.depth}.`)\n : staticPayloadSuffix;\n\n return `${path}/${name}${parsed.search}`;\n}\n\n/**\n * What a static payload was fetched as, recorded against its own response.\n *\n * The depth asked for and the depth applied have to be the same number. Worked\n * out separately at the two call sites they can disagree — and a payload\n * rendered whole but applied as a segment nests a boundary inside itself,\n * which does not error, it recurses until the renderer stops responding.\n */\nconst staticFetches = new WeakMap<\n Response,\n { depth: number; chain: string[] }\n>();\n\nexport function setVersion(v: string): void {\n version = v;\n}\n\n/**\n * Tell the worker which build the server is on, and wait to be heard - a\n * document load follows, and the message has to land before the request\n * the load makes. Bounded: a worker that does not answer is not worth a\n * visitor's wait, and a page with no worker has nothing to tell.\n */\nasync function tellWorkerServerBuild(build: string | null): Promise<void> {\n if (!build || typeof navigator === \"undefined\" || !(\"serviceWorker\" in navigator)) return;\n\n const worker = navigator.serviceWorker.controller;\n\n if (!worker) return;\n\n await new Promise<void>((resolve) => {\n const channel = new MessageChannel();\n const done = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(done, 300);\n\n channel.port1.onmessage = done;\n worker.postMessage({ type: \"rsc-kit:server-build\", version: build }, [channel.port2]);\n });\n\n // And look for the successor now rather than on the next navigation.\n void navigator.serviceWorker.getRegistration().then((registration) => registration?.update()).catch(() => {});\n}\n\n/**\n * The layout chain the client is holding.\n *\n * Seeded from the initial page's response and updated on every navigation, so\n * the next request can say what is already mounted.\n */\nexport function setHeldLayouts(chain: string[]): void {\n heldLayouts = chain;\n rememberChain(retentionKey(window.location.href, null));\n}\n\nexport function getHeldLayouts(): string[] {\n return heldLayouts;\n}\n\nexport function setNavigateHandler(\n fn: (tree: ReactNode, key: string, segmentDepth: number) => void,\n): void {\n onNavigate = fn;\n}\n\nexport function setReplaceRootHandler(fn: ((tree: ReactNode) => void) | null): void {\n onReplaceRoot = fn;\n}\n\nexport function setHeldHandlers(\n held: ((key: string, maxAge?: number) => boolean) | null,\n drop: (() => void) | null,\n): void {\n isHeldPage = held;\n dropHeld = drop;\n}\n\n/**\n * Everything the router holds about pages other than the one on screen,\n * dropped: prefetched payloads, and pages kept behind this one.\n *\n * After an action that revalidated. The list a link prefetched before the\n * mutation still shows the table without the new row - visit() landed on\n * it with no request made, and a reload showed the row. What was fetched\n * before a write is not a cache of what is true after it; the pages held\n * for the back button are from before it too.\n */\nexport function forgetOtherPages(): void {\n for (const [key, controller] of prefetchControllers) {\n controller.abort();\n prefetchControllers.delete(key);\n }\n\n cache.clear();\n dropHeld?.();\n}\n\nexport function setPrerenderHandler(\n fn: ((tree: ReactNode, key: string, segmentDepth: number) => void) | null,\n): void {\n onPrerender = fn;\n}\n\n/**\n * How the router reveals a page that is still mounted behind the current one.\n *\n * Returning true means the page was restored with its client state intact and\n * no request was made.\n */\nexport function setRestoreHandler(\n fn: (key: string, maxAge?: number) => boolean,\n): void {\n onRestore = fn;\n}\n\nexport function setDeserializer(fn: Deserializer): void {\n flightDeserializer = fn;\n}\n\nexport function setCallServer(fn: CallServerFn): void {\n callServerFn = fn;\n}\n\n/**\n * The urls a route.ts answers, so a link to one is treated as the anchor it\n * is: no prefetch - a hover must not run a route - and a full navigation\n * rather than a payload fetch, since the answer is a Response, not a page.\n * Baked into the generated browser entry from the route tree.\n */\nlet apiRoutePatterns: RegExp[] = [];\n\nexport function setApiRoutes(patterns: string[]): void {\n apiRoutePatterns = patterns.map(\n (pattern) =>\n new RegExp(\n \"^\" +\n pattern\n .split(\"/\")\n .map((part) =>\n part.startsWith(\"[...\") ? \".+\" : part.startsWith(\"[\") ? \"[^/]+\" : part.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"),\n )\n .join(\"/\") +\n \"/?$\",\n ),\n );\n}\n\n/** Whether a url is one a route.ts answers. */\nexport function isApiRoute(url: string): boolean {\n if (apiRoutePatterns.length === 0) return false;\n\n try {\n const { pathname } = new URL(url, window.location.origin);\n\n return apiRoutePatterns.some((pattern) => pattern.test(pathname));\n } catch {\n return false;\n }\n}\n\nexport function setInterceptManifest(entries: InterceptEntry[]): void {\n interceptManifest = entries;\n}\n\n/**\n * Check if a URL matches any intercept pattern.\n * Returns the matching slot name, or null if no match.\n */\nfunction matchIntercept(url: string): string | null {\n if (interceptManifest.length === 0) return null;\n\n let pathname: string;\n try {\n pathname = new URL(url, window.location.origin).pathname;\n } catch {\n pathname = url.split(\"?\")[0];\n }\n\n for (const entry of interceptManifest) {\n // urlPattern already has a leading slash (e.g. \"/docs/item/[id]\")\n const regex = new RegExp(\n \"^\" +\n entry.urlPattern\n .replace(/\\[\\.\\.\\.(\\w+)\\]/g, \"(.+)\")\n .replace(/\\[(\\w+)\\]/g, \"([^/]+)\") +\n \"$\",\n );\n\n if (regex.test(pathname)) {\n return entry.slot;\n }\n }\n\n return null;\n}\n\nexport function renderTree(tree: ReactNode): void {\n onNavigate?.(tree, retentionKey(window.location.href, null), 0);\n}\n\n/**\n * Identity of a page for retention purposes.\n *\n * Path and query only: a hash is a position within the same page, and an\n * intercepted route is a different rendering of the same URL, so it retains\n * separately from the full page.\n */\nexport function retentionKey(\n url: string,\n interceptSlot: string | null,\n): string {\n let path: string;\n\n try {\n const parsed = new URL(url, window.location.origin);\n path = parsed.pathname + parsed.search;\n } catch {\n path = url.split(\"#\")[0];\n }\n\n return retentionKeyFor(path, interceptSlot);\n}\n\nexport function getCallServer(): CallServerFn {\n if (!callServerFn) {\n throw new Error(\n \"callServer not initialized. Ensure createViteRscApp() has been called.\",\n );\n }\n return callServerFn;\n}\n\nfunction fetchRscPayload(\n url: string,\n signal?: AbortSignal,\n interceptSlot?: string,\n refererUrl?: string,\n chain: string[] = heldLayouts,\n // A prefetch is speculative and a navigation is not, but on the wire they\n // were identical — so a click could queue behind several prefetches the user\n // had already moved past. Over HTTP/1.1 a browser opens ~6 connections per\n // origin, which a sweep across a nav bar fills on its own.\n priority: \"high\" | \"low\" = \"high\",\n /**\n * A prefetch is speculative: a 409 on one must not load a document the\n * visitor never asked for. A viewport prefetch of the sign-in link, sent\n * from an old page after a deploy, took the visitor reading the home page\n * to /login half a second after it appeared - and a hover over a sidebar\n * link did the same to a half-filled form. The session is marked stale\n * instead, so the next navigation the visitor makes is a document load.\n */\n speculative = false,\n): Promise<Response> {\n const headers: Record<string, string> = {\n \"X-RSC\": \"true\",\n \"X-RSC-Version\": version,\n };\n\n if (chain.length) {\n headers[\"X-RSC-Segments\"] = chain.join(\",\");\n }\n\n if (interceptSlot) {\n headers[\"X-RSC-Intercept\"] = interceptSlot;\n }\n\n if (refererUrl) {\n headers[\"X-RSC-Referer\"] = refererUrl;\n }\n\n // `priority` is not in every lib.dom yet; browsers without it ignore it.\n const asked = staticSegments(url, chain);\n const request = fetch(payloadUrl(url, chain), {\n headers,\n signal,\n priority,\n } as RequestInit).catch((err: unknown) => {\n // Nothing answered at all. An abort is our own doing, not the network's —\n // leaving a link cancels its prefetch, and that must not read as offline.\n if (!(err instanceof DOMException && err.name === \"AbortError\")) {\n reportReachable(false);\n }\n\n throw err;\n });\n\n return request.then(async (response) => {\n // What this payload was asked for, so the apply side cannot work out a\n // different answer from state that has moved on since.\n if (asked) staticFetches.set(response, asked);\n\n // Something answered, whatever it said. A 500 is a reachable server.\n reportReachable(true);\n // Adopt the server's build version from the first response that carries\n // one. Until we know it we send an empty version, which the middleware\n // treats as \"no opinion\"; afterwards a redeploy mid-session answers 409.\n const served = response.headers.get(\"X-RSC-Version\");\n\n if (served && version === \"\") {\n version = served;\n }\n\n if (response.status === 409) {\n const location = response.headers.get(\"X-RSC-Location\");\n // Server-chosen, so checked again here: the engine refuses these at the\n // source, but a host in front of it can put anything on the header.\n // Once per url: a worker still serving the last build's document would\n // answer the load with it, and the next click would be here again.\n const to = isSafeRedirect(location ?? url) ? (location ?? url) : url;\n\n // The worker first. It serves a stored document from its cache, and\n // its cache is the build this page came from - the document it would\n // answer the load with is the one being left. Told which build the\n // server is on, it serves the network for a copy from any other, and\n // is asked to look for its successor. Then the load.\n await tellWorkerServerBuild(served);\n\n if (speculative) {\n markStale();\n\n throw new Error(\"This page is from an earlier build; the next navigation loads the document\");\n }\n\n throw new Error(\n loadDocumentOnce(to)\n ? \"This page is from an earlier build; loading the document from the current one\"\n : \"This page is from an earlier build, and loading the document did not bring the current one\",\n );\n }\n\n return response;\n });\n}\n\n/**\n * Deserialize a Flight response into a React tree.\n *\n * Client modules, CSS <link>s and <title>/<meta> all travel inside the Flight\n * payload — @vitejs/plugin-rsc emits stylesheet links as tree elements and\n * resolves client references through its own browser runtime, and React 19\n * hoists document metadata into <head>. Nothing needs injecting from headers.\n */\nfunction deserializeResponse(response: Response): Promise<ReactNode> {\n return flightDeserializer!(response.body!, {\n callServer:\n callServerFn ??\n (async () => {\n throw new Error(\"Server actions not initialized\");\n }),\n });\n}\n\nfunction isExternalUrl(url: string): boolean {\n try {\n return (\n new URL(url, window.location.origin).origin !== window.location.origin\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Whether a cached payload can be used for a navigation claiming this chain.\n *\n * A partial payload only composes against the chain it was rendered for, so\n * the chain it was fetched against has to be the one the navigation is about\n * to claim — not whatever happens to be mounted.\n */\nfunction isUsable(cached: CacheEntry | undefined, chain: string[]): boolean {\n return (\n cached !== undefined &&\n cached.expiresAt > Date.now() &&\n cached.heldWhenFetched === chain.join(\",\")\n );\n}\n\n/**\n * Whether a navigation to this url would be served from the prefetch cache.\n *\n * Lets a caller decide whether showing an already-fetched page is free. A form\n * uses it to put its target route's shell on screen while the real query runs:\n * worth doing when the shell is in hand, never worth an extra request.\n */\nexport function isPrefetched(url: string): boolean {\n if (isExternalUrl(url)) return false;\n\n const interceptSlot = matchIntercept(url);\n const cacheKey = retentionKeyFor(url, interceptSlot);\n\n return isUsable(cache.get(cacheKey), claimedChain(interceptSlot));\n}\n\n/**\n * The layout chain a navigation to a url will claim.\n *\n * Leaving an interception claims fewer layouts than are held, which is what\n * forces the layout owning the slot to render again so the slot can empty.\n * Both sides have to agree on it: a prefetch recorded against a different\n * chain can never be used, so the close of every modal refetched a payload it\n * had already fetched.\n */\nfunction claimedChain(interceptSlot: string | null): string[] {\n return !interceptSlot && interceptedAtDepth !== null\n ? heldLayouts.slice(0, interceptedAtDepth)\n : heldLayouts;\n}\n\n/**\n * How many redirects a single navigation will follow before giving up.\n *\n * A page that redirects to itself is a mistake someone will make, and without\n * a ceiling it is an unbounded loop of requests rather than an error. The\n * browser's own limit for HTTP redirects is 20; this is smaller because these\n * are full renders, not header exchanges.\n */\nconst MAX_REDIRECTS = 8;\n\n/**\n * Go to a url, the way a Link does.\n *\n * `url` is typed to the routes the build found; cast with `as Route` when the\n * destination is computed rather than written.\n */\nexport async function navigate(\n url: Route,\n opts?: {\n replace?: boolean;\n preserveScroll?: boolean;\n restore?: boolean;\n /** Internal: how many redirects led here. */\n redirectsFollowed?: number;\n },\n): Promise<void> {\n const redirectsFollowed = opts?.redirectsFollowed ?? 0;\n\n // The worker has said a newer build is live. This page's client cannot\n // load what that build's payloads name, so the next navigation is the\n // document, from the new build - the router knows; the banner was only\n // advice. Not for a restore: going back to a page still held asks the\n // server for nothing.\n if (!opts?.restore && isUpdated()) {\n announceDocumentLoad(url, \"newer-build\");\n window.location.href = url;\n\n return;\n }\n\n if (redirectsFollowed > MAX_REDIRECTS) {\n throw new Error(\n `Too many redirects following a navigation (${MAX_REDIRECTS}); last was ${url}`,\n );\n }\n\n // External URLs can't be fetched (CORS) — go directly to full page navigation\n if (isExternalUrl(url)) {\n announceDocumentLoad(url, \"external\");\n window.location.href = url;\n return;\n }\n\n // A route.ts answers with a Response, not a page: a download, a redirect\n // that decides where someone belongs, a sign-out. The browser goes there.\n if (isApiRoute(url)) {\n announceDocumentLoad(url, \"api-route\");\n window.location.href = url;\n return;\n }\n\n // Hash-only URLs — let the browser handle scrolling natively\n if (url.startsWith(\"#\")) {\n window.location.hash = url;\n return;\n }\n\n // Abort any in-flight navigation\n activeController?.abort();\n\n navigationStarted(url);\n\n // Not window.stop(). It used to be called here while the document was\n // still loading, to free a single-threaded server for the new request -\n // and it cancels every load the page has in flight: the client chunks a\n // just-decoded tree still needs, the stylesheet, the boundaries still\n // streaming. A navigation that left the page before the runtime had\n // finished arriving rendered a document with nothing in it. The server\n // has workers; the page keeps loading.\n\n const controller = new AbortController();\n activeController = controller;\n\n // Check if this URL matches an intercept pattern.\n // If so, send the intercept slot + current URL as referer so the server\n // renders the full tree with the interceptor in the right slot.\n const interceptSlot = matchIntercept(url);\n const currentUrl = interceptSlot\n ? window.location.pathname + window.location.search\n : undefined;\n\n const activityKey = retentionKey(url, interceptSlot);\n\n // A page still being held is revealed rather than refetched, whichever\n // gesture asked for it — the back button or a link. Both mean \"the page I\n // was just on\", and having the form you were filling in survive one and not\n // the other is a distinction nobody makes while using the app.\n //\n // The cost is honest: what comes back is the tree from when you left, so its\n // data is from then. Retention is four pages deep, so this reaches only\n // somewhere you were moments ago, and `revalidate()` is how a page says its\n // data has moved on.\n // Closing an interception. The page underneath was never replaced, so this\n // is a matter of emptying the slot — no request, and nothing rebuilt. The\n // form behind the modal is still the one the user was filling in.\n if (\n !interceptSlot &&\n interceptedOver !== null &&\n retentionKey(url, null) === retentionKey(interceptedOver, null)\n ) {\n clearSlots();\n interceptedOver = null;\n interceptedFrom = null;\n interceptedAtDepth = null;\n\n if (opts?.replace) {\n history.replaceState({ rscUrl: url }, \"\", url);\n } else {\n history.pushState({ rscUrl: url }, \"\", url);\n }\n\n window.dispatchEvent(new CustomEvent(\"rsc-navigate\", { detail: url }));\n navigationCommitted();\n\n return;\n }\n\n // Not when the target is the page already showing: asking for this page\n // again means asking the server again, and revealing what is already there\n // would make refresh a no-op. Not while an interception is opening or\n // closing either — those rebuild the chain deliberately.\n const askingForThisPage =\n retentionKey(window.location.href, null) === retentionKey(url, null);\n //\n // And not while an interception is on screen. Leaving a modal has to\n // re-render the layout that owns the slot, because that is what empties it;\n // revealing the page underneath instead leaves the modal sitting over a page\n // whose url has already changed.\n const mayReveal =\n opts?.restore === true ||\n (!askingForThisPage &&\n !interceptSlot &&\n interceptedOver === null &&\n interceptedAtDepth === null);\n\n // Unbounded for the back button, bounded for a link.\n if (\n mayReveal &&\n onRestore?.(activityKey, opts?.restore ? undefined : revealWithin)\n ) {\n // A restored tree carries its own slot contents, so the flag only has to\n // reflect whether what is now showing is an intercepted view.\n if (!interceptSlot) {\n interceptedAtDepth = null;\n interceptedFrom = null;\n }\n\n // Its layouts are the ones on screen now - see chainOf.\n const chain = chainOf.get(activityKey);\n\n if (chain) heldLayouts = chain;\n\n // opts?.replace, not opts.replace: this branch used to be reachable only\n // with opts.restore set, so opts was always there. A link reaches it now\n // with nothing passed at all.\n if (opts?.replace) {\n history.replaceState({ rscUrl: url }, \"\", url);\n } else {\n history.pushState({ rscUrl: url }, \"\", url);\n }\n\n window.dispatchEvent(new CustomEvent(\"rsc-navigate\", { detail: url }));\n navigationCommitted();\n\n return;\n }\n\n // A prefetched payload was rendered against the chain held at prefetch time.\n let segmentDepth = 0;\n let nextLayouts: string[] | null = null;\n /** The slot this answer fills, when it is one region rather than a segment. */\n let slotPayload: string | null = null;\n /** The cache entry this navigation is using, whose metadata settles with it. */\n let reused: CacheEntry | null = null;\n const previousUrl = window.location.pathname + window.location.search;\n\n try {\n const cacheKey = retentionKeyFor(url, interceptSlot);\n const cached = cache.get(cacheKey);\n let treePromise: Promise<ReactNode>;\n\n const chain = claimedChain(interceptSlot);\n\n // A partial payload only composes against the chain it was rendered for —\n // the one this navigation is about to claim, not whatever is mounted.\n // Hovering a link inside a modal prefetches it against the full chain, so\n // reusing that here would skip the layout holding the modal and leave it\n // open over the page behind it.\n const usable = isUsable(cached, chain);\n\n if (usable) {\n treePromise = cached!.tree;\n // Read after the tree resolves, not now. A prefetch fills these in when\n // its response lands, and a click can land first — hover a modal link\n // and click it quickly and the entry still says depth 0, so the\n // interceptor is applied as a whole document and the modal renders *as*\n // the page. The fields are set before the tree promise resolves, so\n // waiting for it is what makes them true.\n reused = cached!;\n cache.delete(cacheKey);\n } else {\n cache.delete(cacheKey);\n\n // Marked while in flight, so a prefetch of the same page - a held\n // tap's replay landing beside the idle viewport prefetch of the link\n // it came from - does not ask for it a second time.\n navigating.add(cacheKey);\n\n let response: Response;\n\n try {\n response = await fetchRscPayload(\n url,\n controller.signal,\n interceptSlot ?? undefined,\n currentUrl,\n chain,\n );\n } finally {\n navigating.delete(cacheKey);\n }\n\n // The check is for a host that answered the page instead of the\n // payload, which is what a server does when it does not recognise the\n // header. An exported build asks a url that only ever holds a payload,\n // and a file server labels it by extension — commonly\n // application/octet-stream — so the check would reject every navigation\n // and send the browser on a full page load instead.\n // The render asked to go somewhere else, and said so before writing\n // anything — so this is still a navigation, not a page load. A redirect\n // decided later than that cannot travel here; it arrives in the payload\n // as an error digest and RedirectBoundary performs it.\n const redirectTo = response.headers.get(\"X-RSC-Redirect\");\n\n if (redirectTo) {\n // The url that redirected was never pushed - the history entry is\n // written after the tree arrives, below - so the destination takes\n // this navigation's own mode. `replace: true` here replaced the page\n // the visitor was ON, and Back from the login page skipped home.\n // Chosen by the server, not written here.\n await navigate(redirectTo as Route, {\n replace: opts?.replace,\n redirectsFollowed: redirectsFollowed + 1,\n });\n\n return;\n }\n\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n\n if (\n staticPayloadSuffix === null &&\n !contentType.includes(\"text/x-component\")\n ) {\n announceDocumentLoad(url, `not-a-payload:${response.status}:${contentType.split(\";\")[0]}`);\n window.location.href = url;\n return;\n }\n\n // Headers on a server; worked out locally on a static host, where there\n // is nothing to send them.\n const served = staticFetches.get(response) ?? null;\n\n segmentDepth =\n Number(\n response.headers.get(\"X-RSC-Segment-Depth\") ?? served?.depth ?? 0,\n ) || 0;\n\n // Named region rather than a segment — see the apply below.\n slotPayload = response.headers.get(\"X-RSC-Revalidate\");\n\n const servedLayouts = response.headers.get(\"X-RSC-Layouts\");\n\n if (servedLayouts !== null) {\n nextLayouts = servedLayouts === \"\" ? [] : servedLayouts.split(\",\");\n } else if (served) {\n nextLayouts = served.chain;\n }\n\n treePromise = deserializeResponse(response);\n }\n\n let tree: ReactNode;\n\n try {\n tree = await treePromise;\n navigationReached(\"decoded\");\n } catch (error) {\n // A navigation another one overtook: its request was aborted, and\n // the decoder reports that as a failure of the payload. It is not one\n // - nothing of it was going to be shown - so it ends here, quietly,\n // rather than as a rejection nobody is waiting on.\n if (controller.signal.aborted) return;\n\n throw error;\n }\n\n if (reused) {\n if (controller.signal.aborted) return;\n\n // The prefetch this navigation took did not come back as a page. A\n // redirect is followed as one on this request would be; a failure is\n // asked again, from a cache that no longer holds the entry.\n if (reused.redirectTo) {\n await navigate(reused.redirectTo as Route, {\n replace: opts?.replace,\n redirectsFollowed: redirectsFollowed + 1,\n });\n\n return;\n }\n\n if (reused.failed) {\n await navigate(url, opts);\n\n return;\n }\n\n segmentDepth = reused.segmentDepth;\n nextLayouts = reused.layouts;\n slotPayload = reused.slot;\n }\n\n if (controller.signal.aborted) return;\n\n if (opts?.replace) {\n history.replaceState({ rscUrl: url }, \"\", url);\n } else {\n history.pushState({ rscUrl: url }, \"\", url);\n }\n\n if (nextLayouts !== null) heldLayouts = nextLayouts;\n rememberChain(activityKey);\n\n // The answer is one region, not a piece of the page: the host rendered\n // only the interceptor because the page underneath is already mounted and\n // still correct. Putting it in the slot leaves that page — and everything\n // typed into it — exactly as it was.\n if (slotPayload !== null) {\n setSlot(slotPayload, tree as ReactNode);\n interceptedOver = interceptedOver ?? previousUrl;\n interceptedFrom = interceptedFrom ?? previousUrl;\n interceptedAtDepth = null;\n\n return;\n }\n\n // A slot rendered for the page being left has no claim on the one being\n // arrived at.\n clearSlots();\n\n interceptedOver = null;\n interceptedAtDepth = interceptSlot ? segmentDepth : null;\n interceptedFrom = interceptSlot ? (interceptedFrom ?? previousUrl) : null;\n\n navigationReached(\"applied\");\n onNavigate?.(tree, activityKey, segmentDepth);\n\n if (!opts?.preserveScroll && !interceptSlot) {\n // Wait for React to commit the DOM update before scrolling.\n // Intercepted navigations preserve scroll (e.g. modal over current page).\n requestAnimationFrame(() => {\n window.scrollTo(0, 0);\n });\n }\n\n window.dispatchEvent(new CustomEvent(\"rsc-navigate\", { detail: url }));\n } catch (err) {\n navigationAbandoned();\n\n if (err instanceof DOMException && err.name === \"AbortError\") return;\n\n // A chunk the deploy no longer serves: the browser would have loaded the\n // document, and the new names with it. Do what it would have done.\n if (isStaleAssetError(err)) {\n announceDocumentLoad(url, `stale-asset:${String((err as Error)?.message ?? err).slice(0, 120)}`);\n window.location.href = url;\n\n return;\n }\n\n // Without this a navigation that fails does nothing observable: the click\n // clears its own pending state and the page stays as it was, with no\n // error, no fallback and nothing for an app to react to. Dispatched before\n // rethrowing, so a programmatic caller still sees the failure.\n window.dispatchEvent(\n new CustomEvent(\"rsc-navigate-error\", { detail: { url, error: err } }),\n );\n\n throw err;\n } finally {\n if (activeController === controller) {\n activeController = null;\n }\n }\n}\n\n/**\n * Put something the server re-rendered on screen.\n *\n * The trees arrive with an action's answer rather than being fetched, so this\n * is the same apply path a navigation uses — without a request, a url change\n * or a history entry.\n */\n/**\n * Whether the page an action was invoked from is the one on screen.\n *\n * The one underneath, when an interception is showing: a modal opened after\n * the submit sits over the same page.\n */\nexport function stillShowing(url: string): boolean {\n const key = retentionKey(url, null);\n const now = retentionKey(window.location.pathname + window.location.search, null);\n\n return key === now || (interceptedFrom !== null && key === retentionKey(interceptedFrom, null));\n}\n\n/**\n * Put what an action re-rendered on screen.\n *\n * `from` is the url the action was invoked on - what the host rendered the\n * trees for. A tap that left the page while the action was in flight has\n * changed what is showing, and a document rendered for the page before\n * cannot go under the url after: \"Add to cart\", then the brand link at\n * once, showed the home page and then, when the answer landed, the product\n * again under `/`. The write still happened, and the page on screen was\n * fetched before it - so that page is asked for again, whole, instead.\n */\nexport function applyRevalidations(from: string, revalidated: Record<string, ReactNode>): void {\n // What was fetched or held before the write is from before it.\n forgetOtherPages();\n\n if (!stillShowing(from)) {\n void refresh(\"all\");\n\n return;\n }\n\n for (const [target, tree] of Object.entries(revalidated)) {\n applyRevalidated(target, tree);\n }\n}\n\nexport function applyRevalidated(target: string, tree: ReactNode): void {\n const url = window.location.pathname + window.location.search;\n const key = retentionKey(url, null);\n\n if (target === \"all\") {\n // The whole document again, in place. Not a navigation to this url:\n // the visible entry may be keyed by the url the document loaded with,\n // and showing the tree under the current one made a second entry and\n // remounted the app under it.\n if (onReplaceRoot) onReplaceRoot(tree);\n else onNavigate?.(tree, key, 0);\n\n return;\n }\n\n if (target === \"page\") {\n onNavigate?.(tree, key, heldLayouts.length);\n\n return;\n }\n\n setSlot(target, tree);\n}\n\n/**\n * Ask the server for part of this page again.\n *\n * refresh() the page, leaving the layouts mounted\n * refresh('all') the whole document, layouts included\n * refresh('orders') one parallel slot, by the name its directory gave it\n *\n * The same words an action uses, so a thing can be invalidated from either\n * side. This is the path for a refresh nobody mutated anything to earn — a\n * button, a poll, a message saying that table has moved; what an action\n * invalidated travels back inside the action's own answer instead.\n *\n * A slot is the only region smaller than a page the server can name, so two\n * tables refresh apart from each other only if they are two slots. The page\n * form leaves the layouts alone, which is what makes it cheap and also why a\n * count living in a layout will not move until you ask for 'all'.\n */\nexport async function refresh(target = \"page\"): Promise<void> {\n const url = window.location.pathname + window.location.search;\n\n // Asked because the data moved on; what was fetched or held before is\n // from before.\n forgetOtherPages();\n\n if (target !== \"page\" && target !== \"all\") {\n const response = await fetch(payloadUrl(url), {\n headers: {\n \"X-RSC\": \"true\",\n \"X-RSC-Version\": version,\n \"X-RSC-Revalidate\": target,\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `Could not revalidate ${target}: the server answered ${response.status}`,\n );\n }\n\n setSlot(target, await deserializeResponse(response));\n\n return;\n }\n\n const interceptSlot = matchIntercept(url);\n const cacheKey = retentionKeyFor(url, interceptSlot);\n\n // Never from the cache: refreshing asks what the server says now, not what\n // it said a moment ago.\n cache.delete(cacheKey);\n\n if (target === \"all\") {\n heldLayouts = [];\n }\n\n // A refresh is not a navigation: the same page stays under the reader, so\n // where they were reading has to survive the tree being replaced.\n //\n // `preserveScroll` is not enough on its own. It stops navigate() scrolling\n // to the top deliberately, and says nothing about the scroll positions\n // *inside* the page. Refreshing everything replaces the root, so every\n // element that scrolls is a new node and starts at zero — a sidebar,\n // a code block, any pane with its own overflow. The window survives because\n // the document element is not the thing being replaced, which is why this\n // looks fine until a page has a second scroller in it.\n const positions = scrollPositions();\n\n await navigate(url as Route, { replace: true, preserveScroll: true });\n\n restoreScroll(positions);\n}\n\ninterface ScrollPosition {\n tag: string;\n top: number;\n left: number;\n}\n\n/** Every element that can scroll, whether or not it currently is. */\nfunction scrollables(): HTMLElement[] {\n return [...document.querySelectorAll<HTMLElement>(\"*\")].filter(\n (el) =>\n el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth,\n );\n}\n\n/**\n * Where everything on the page is scrolled to, in document order.\n *\n * Identified by position in the list rather than by a selector: a refresh\n * re-renders the same page, so the nth scrollable element is the same one, and\n * a selector would have to survive whatever classes the markup happens to use.\n * The tag is carried only to notice when that assumption has broken.\n *\n * Everything that *can* scroll, not everything that *is* scrolled — the two\n * lists have to be built the same way or they do not line up. Recording only\n * the scrolled ones and restoring over the scrollable ones puts a sidebar's\n * position onto whatever element happens to come first, which on any page long\n * enough to scroll is <html>.\n */\nfunction scrollPositions(): ScrollPosition[] {\n return [\n { tag: \"window\", top: window.scrollY, left: window.scrollX },\n ...scrollables().map((el) => ({\n tag: el.tagName,\n top: el.scrollTop,\n left: el.scrollLeft,\n })),\n ];\n}\n\n/**\n * Put the page back where it was, once React has finished replacing it.\n *\n * Applied over several ticks rather than once, because `root.render()`\n * schedules the update instead of performing it: a single pass writes the\n * position onto the nodes that are about to be thrown away, and the ones that\n * replace them start at zero. There is nothing to await — the navigation\n * resolves when the tree is handed to React, not when React has committed it.\n *\n * `setTimeout`, not `requestAnimationFrame`. A hidden tab never runs an\n * animation frame, so a refresh in a background tab — an HMR update, a poll —\n * would leave the scroll state wrong the moment it came back into view. It\n * also makes this untestable in an automated browser, where the tab under test\n * is usually not the visible one.\n */\nconst RESTORE_ATTEMPTS = 5;\n\nfunction restoreScroll(positions: ScrollPosition[]): void {\n const [win, ...inner] = positions;\n\n const apply = (attempt: number) => {\n if (window.scrollY !== win.top || window.scrollX !== win.left) {\n window.scrollTo(win.left, win.top);\n }\n\n const now = scrollables();\n\n for (let i = 0; i < inner.length && i < now.length; i++) {\n // A different element here means the page came back a different shape,\n // and guessing further would scroll something nobody touched.\n if (now[i].tagName !== inner[i].tag) break;\n\n if (inner[i].top !== 0 && now[i].scrollTop !== inner[i].top)\n now[i].scrollTop = inner[i].top;\n if (inner[i].left !== 0 && now[i].scrollLeft !== inner[i].left)\n now[i].scrollLeft = inner[i].left;\n }\n\n if (attempt < RESTORE_ATTEMPTS) setTimeout(() => apply(attempt + 1), 16);\n };\n\n apply(1);\n}\n\n/**\n * Fetch a page's payload ahead of the navigation that may ask for it.\n *\n * `intent` is the difference between a link that came into view and one the\n * visitor is about to follow: a hover that settled, a touch. Only then is the\n * payload decoded on arrival - decoding is what loads the client chunks the\n * page names, and a viewport prefetch that decoded put the sign-in page's\n * thirty chunks onto a landing page for every phone visitor. A touch leads\n * its click by 100-300 ms, about a round trip, and a tap that found the\n * bytes here but not the chunks spent that round trip after the click\n * instead of before it: the tap-to-paint that was \"not zero\" beside Next,\n * whose prefetch decodes as it lands.\n */\nexport function prefetch(url: string, cacheForMs?: number, intent = false): void {\n // Never a route.ts: fetching one runs it, and a hover is not a click.\n if (isApiRoute(url)) return;\n\n // Never the page the visitor is on. A logo link to / on the home page,\n // in view, was a 14 KB payload for the page already on screen.\n if (retentionKey(url, null) === retentionKey(window.location.href, null)) return;\n\n // Nor a page still held behind this one, which a navigation would reveal\n // rather than fetch: the page just left, whose link is on every page,\n // was one wasted payload per navigation.\n if (!matchIntercept(url) && isHeldPage?.(retentionKey(url, null), revealWithin)) return;\n\n // Nor anything, once this page is known to be the previous build: the\n // next navigation is a document load, and a payload it would not use is\n // a 409 for nothing - one per tap, measured.\n if (isUpdated()) return;\n\n if (isExternalUrl(url)) return;\n\n const ttl = cacheForMs ?? DEFAULT_PREFETCH_TTL;\n const interceptSlot = matchIntercept(url);\n\n const held = { intent, explicitTtl: cacheForMs !== undefined };\n\n if (interceptSlot) {\n // Intercepted route — only prefetch the intercepted variant\n const currentUrl = window.location.pathname + window.location.search;\n const cacheKey = retentionKeyFor(url, interceptSlot);\n prefetchUrl(cacheKey, url, ttl, interceptSlot, currentUrl, held);\n } else {\n prefetchUrl(retentionKeyFor(url, null), url, ttl, undefined, undefined, held);\n }\n}\n\n/**\n * Do the click's work now: decode the held payload, which loads the chunks\n * it names, and render the page hidden so the click is a reveal.\n *\n * The numbers this came from, on an iPhone with everything prefetched: a\n * first visit to the landing page was 107 ms from tap to paint, 4 of them\n * decoding and 87 rendering; a page still held from a visit before was\n * 15 ms, a reveal. The render is the page's size on the phone's CPU, and\n * nothing in the payload's path shrinks it - but it can be paid before the\n * finger lifts. A touch leads its click by 100-300 ms; a settled hover, by\n * 200 or more. React renders a hidden Activity at idle priority, so the\n * work yields to scrolling, and the navigation then hands the boundary the\n * same tree it prerendered: React bails out of the whole subtree and flips\n * it visible.\n *\n * Only a segment at depth 1 or more, rendered against the chain held now: a\n * whole document replaces the root, and a slot is a region of a page not on\n * screen yet. A prefetch that landed on a redirect - a guarded link, on a\n * landing page all of them - warms the destination it prefetched instead:\n * the tap on Sign in decoded the login page and loaded its chunks after the\n * click, 154 ms of a 225 ms tap.\n */\nfunction warm(entry: CacheEntry, cacheKey: string): void {\n // The tree is read by the navigation that takes the entry, and a decode\n // that fails - a chunk the deploy no longer serves - fails there, where it\n // is handled. Here the rejection has nobody to reach.\n entry.body\n .then((text) => {\n if (entry.redirectTo) {\n const destination = cache.get(\n retentionKeyFor(entry.redirectTo, matchIntercept(entry.redirectTo)),\n );\n\n if (destination) warm(destination, retentionKeyFor(entry.redirectTo, matchIntercept(entry.redirectTo)));\n\n return;\n }\n\n if (text === null) return;\n\n // The page about to show: its pictures ahead of every other page's.\n preloadImages(text, \"high\");\n\n return entry.tree.then((tree) => {\n if (\n entry.slot !== null ||\n entry.segmentDepth === 0 ||\n !isUsable(entry, claimedChain(null)) ||\n cache.get(cacheKey) !== entry\n )\n return;\n\n onPrerender?.(tree, cacheKey, entry.segmentDepth);\n });\n })\n .catch(() => {});\n}\n\nfunction prefetchUrl(\n cacheKey: string,\n url: string,\n ttl: number,\n interceptSlot?: string,\n refererUrl?: string,\n held: { intent: boolean; explicitTtl: boolean } = { intent: false, explicitTtl: false },\n): void {\n const chain = claimedChain(interceptSlot ?? null);\n const existing = cache.get(cacheKey);\n\n if (existing && existing.expiresAt > Date.now()) {\n // Fetched as it came into view, undecoded; the touch says decode it.\n if (held.intent) warm(existing, cacheKey);\n\n return;\n }\n\n // A navigation is already fetching it; the answer is on its way.\n if (navigating.has(cacheKey)) return;\n\n cache.delete(cacheKey);\n makeRoom();\n\n const controller = new AbortController();\n prefetchControllers.set(cacheKey, controller);\n\n let decoded: Promise<ReactNode> | null = null;\n const entry: CacheEntry = {\n body: Promise.resolve(null),\n get tree() {\n return (decoded ??= this.body.then((text) => (text === null ? null : deserializeResponse(new Response(text)))));\n },\n expiresAt: Date.now() + ttl,\n segmentDepth: 0,\n layouts: null,\n slot: null,\n heldWhenFetched: chain.join(\",\"),\n redirectTo: null,\n failed: false,\n };\n\n // Low priority: the browser then lets a real navigation overtake a queue of\n // speculative requests instead of serving them in the order they were made.\n entry.body = fetchRscPayload(\n url,\n controller.signal,\n interceptSlot,\n refererUrl,\n chain,\n \"low\",\n true,\n )\n .then((response) => {\n // On a static host there are no headers to read, and dropping the depth\n // is not a small loss: the entry then claims a segment is a whole\n // document, and rendering a layout-less page as the document root does\n // not warn — it hangs the renderer.\n // A prefetch that lands on a redirect is not cached. Following it would\n // navigate on hover, and storing it would hand the click a 204 with no\n // body to deserialize. The click re-requests and redirects properly.\n const redirectTo = response.headers.get(\"X-RSC-Redirect\");\n\n if (redirectTo) {\n // The guard's answer is kept, for the entry's TTL, and the\n // destination is prefetched now. A tap on the link then goes\n // straight to a payload already here: no request for the page the\n // visitor may not see, none for the one they will. Before this,\n // every tap on a guarded link paid the guard's round trip and the\n // destination's, in sequence - on a phone, the two slowest things a\n // navigation can do, and the port's \"Sign in is slow from home\".\n // Next's prefetch follows the redirect the same way.\n entry.redirectTo = redirectTo;\n\n if (!isExternalUrl(redirectTo) && isSafeRedirect(redirectTo)) prefetch(redirectTo, ttl);\n\n return null;\n }\n\n entry.slot = response.headers.get(\"X-RSC-Revalidate\");\n\n const local = staticFetches.get(response) ?? null;\n\n entry.segmentDepth =\n Number(\n response.headers.get(\"X-RSC-Segment-Depth\") ?? local?.depth ?? 0,\n ) || 0;\n\n const served = response.headers.get(\"X-RSC-Layouts\");\n\n if (served !== null) {\n entry.layouts = served === \"\" ? [] : served.split(\",\");\n } else if (local) {\n entry.layouts = local.chain;\n }\n\n // Marked public: the build's bytes, the same for everyone, and held\n // for as long as Next holds a static page - unless the link said how\n // long. A deploy is caught by the version handshake, not by the clock.\n if (\n !held.explicitTtl &&\n /\\bpublic\\b/.test(response.headers.get(\"Cache-Control\") ?? \"\")\n ) {\n entry.expiresAt = Math.max(entry.expiresAt, Date.now() + STATIC_PREFETCH_TTL);\n }\n\n // The bytes, not the page: decoding is the navigation's, see CacheEntry\n // - unless the visitor is already on the way, see prefetch(). The\n // pictures the page shows are asked for now, though: on a phone they\n // take longer than the touch-to-click a hidden render has.\n return response.text().then((text) => {\n preloadImages(text);\n // And the code for its client components, so the first visit to a\n // page does not wait on a chunk after it has arrived.\n preloadChunks(text);\n\n return text;\n });\n })\n .catch(() => {\n entry.failed = true;\n cache.delete(cacheKey);\n return null;\n })\n .finally(() => {\n // Settled, so there is nothing left to abort. A completed prefetch stays\n // in the cache — only an in-flight one is ever dropped.\n if (prefetchControllers.get(cacheKey) === controller) {\n prefetchControllers.delete(cacheKey);\n }\n });\n\n cache.set(cacheKey, entry);\n\n if (held.intent) warm(entry, cacheKey);\n}\n\n/**\n * Drop a prefetch that is still in flight — the pointer left the link.\n *\n * The cache entry goes synchronously rather than in the abort's catch: the\n * rejection lands a tick later, and a click in between would find an entry\n * whose tree resolves to null and navigate to a blank page. A prefetch that\n * has already completed is kept; there is no request left to cancel and the\n * payload is still good.\n */\nexport function cancelPrefetch(url: string): void {\n if (isExternalUrl(url)) return;\n\n const interceptSlot = matchIntercept(url);\n const cacheKey = retentionKeyFor(url, interceptSlot);\n const controller = prefetchControllers.get(cacheKey);\n\n if (!controller) return;\n\n prefetchControllers.delete(cacheKey);\n cache.delete(cacheKey);\n controller.abort();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../src/js/navigate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core SPA navigation engine for RSC.\n *\n * Uses module-level state (singleton in the browser bundle).\n * The Flight deserializer is injected by createViteRscApp to avoid\n * duplicate bundling of react-server-dom-webpack.\n */\n\nimport {\n announceDocumentLoad,\n isStaleAssetError,\n loadDocumentOnce,\n} from \"./staleAssets\";\nimport { isUpdated, markStale } from \"./updateStore\";\nimport { navigationAbandoned, navigationCommitted, navigationReached, navigationStarted } from \"./perf\";\nimport { preloadImages } from \"./imagePreload\";\nimport { preloadChunks } from \"./chunkPreload\";\nimport { isSafeRedirect } from \"../safeUrl.js\";\nimport type { Route } from \"../routes.js\";\nimport { reportReachable } from \"./onlineStore\";\nimport { clearSlots, setSlot } from \"./slotStore\";\n// Shared with the host: it stores a page under this key and the client looks\n// under it, so the format cannot live in two places.\nimport {\n matchRoute,\n retentionKey as retentionKeyFor,\n sharedDepth,\n} from \"../routing\";\nimport type { ManifestRoute } from \"../manifest\";\n\ntype ReactNode = unknown;\ntype Deserializer = (\n stream: ReadableStream,\n options: Record<string, unknown>,\n) => Promise<ReactNode>;\ntype CallServerFn = (id: string, args: unknown[]) => Promise<unknown>;\n\ninterface CacheEntry {\n /**\n * The payload as it arrived, undecoded. Decoding a payload is what loads\n * the client chunks it names, and a prefetch decoded on arrival loaded\n * the sign-in page's thirty chunks onto a landing page for every phone\n * visitor, whether they tapped or not. The text is kept; \\`tree\\` decodes\n * it the first time a navigation asks, which is the moment those chunks\n * are wanted.\n */\n body: Promise<string | null>;\n /** The decoded page, on first read. */\n readonly tree: Promise<ReactNode>;\n expiresAt: number;\n /**\n * What the server said about the payload. A prefetch is a real request, so\n * it comes back partial like any other — losing that and treating it as a\n * whole document replaces the root with a page that has no layouts.\n */\n segmentDepth: number;\n layouts: string[] | null;\n /**\n * The slot this payload fills, when it is one region rather than a segment.\n *\n * A prefetch is a real request and comes back as whatever the host answers.\n * An interception answers with the interceptor alone, and an entry that\n * forgets that is applied as a whole document — so a hovered modal link\n * renders the modal *as* the page, with nothing around it. Only after a\n * hover, which is why a scripted click never finds it.\n */\n slot: string | null;\n /**\n * The chain held when this was prefetched. A partial payload is only valid\n * against the chain it was rendered for; navigate somewhere else first and\n * it no longer composes.\n */\n heldWhenFetched: string;\n /**\n * Where the prefetch was sent instead, when the host answered a redirect.\n * The entry leaves the cache - a hover must not navigate - but a click\n * that took the entry while the request was in flight awaits its tree, and\n * a tree of null committed as the page was the whole document gone: url\n * changed, root unmounted, nothing in the console. On a phone the tap's\n * touchstart prefetches with no delay and the click lands 100-300 ms\n * later, the length of a round trip, so a tapped link to a guarded page\n * blanked the page about half the time. The navigation reads this and\n * follows it, the way it follows a redirect on its own request.\n */\n redirectTo: string | null;\n /** The request failed or was aborted; a navigation that took the entry asks again. */\n failed: boolean;\n}\n\ninterface InterceptEntry {\n urlPattern: string;\n slot: string;\n}\n\nlet version = \"\";\n/** Pages a navigation is fetching right now, so a prefetch does not ask again. */\nconst navigating = new Set<string>();\nlet onNavigate:\n ((tree: ReactNode, key: string, segmentDepth: number) => void) | null = null;\nlet onRestore: ((key: string, maxAge?: number) => boolean) | null = null;\n/**\n * Re-render the whole document in place, for revalidate(\"all\"): the page the\n * visitor is on, not a page they went to. Without one registered, the\n * navigation handler at depth 0 is used, which shows the tree as a page.\n */\nlet onReplaceRoot: ((tree: ReactNode) => void) | null = null;\n\n/** Whether a navigation to the key would reveal a held page, asked without revealing it. */\nlet isHeldPage: ((key: string, maxAge?: number) => boolean) | null = null;\n/** Drop the pages held behind the one on screen - after a mutation. */\nlet dropHeld: (() => void) | null = null;\n/**\n * Render a decoded page in the background, hidden, before the click - see\n * warm(). Given the same tree the navigation will hand to onNavigate, so\n * that the navigation is a reveal of work already done rather than a render.\n */\nlet onPrerender: ((tree: ReactNode, key: string, segmentDepth: number) => void) | null = null;\n\n/**\n * How stale a held page may be and still be revealed by a link.\n *\n * The back button ignores this: it names a moment, and the page from that\n * moment is the right answer however old. A link says \"go here\", so there is a\n * point past which answering with what you saw before is stale data presented\n * as fresh. Thirty seconds covers leaving a form to check something and coming\n * straight back, which is the case this exists for.\n */\nlet revealWithin = 30_000;\n\nexport function setRevealWindow(ms: number): void {\n revealWithin = ms;\n}\nlet flightDeserializer: Deserializer | null = null;\nlet callServerFn: CallServerFn | null = null;\nlet activeController: AbortController | null = null;\nconst cache = new Map<string, CacheEntry>();\n/** In-flight prefetches, so one the pointer moved away from can be dropped. */\nconst prefetchControllers = new Map<string, AbortController>();\nlet interceptManifest: InterceptEntry[] = [];\n\n// The layout chain currently mounted, outermost first. Sent so the server can\n// skip re-rendering the layouts still on screen.\nlet heldLayouts: string[] = [];\n\n/**\n * The chain each page was shown under, by retention key.\n *\n * A held page revealed - the back button, or a link to the page just left -\n * puts its layouts back on screen, and the chain has to say so. It used to\n * keep the chain of the page being left: home, a category, back to home,\n * then another category claimed the first category's layout as mounted. The\n * server sent the page alone, and the client put it in the boundary that\n * layout owns - inside the hidden category. The url changed and the page did\n * not, and every tap after it did the same, until a reload. The demo froze\n * on a phone within a dozen taps.\n *\n * Bounded like the payload cache: a key that is no longer held is never\n * asked for, so the oldest can go.\n */\nconst chainOf = new Map<string, string[]>();\nconst MAX_CHAINS = 64;\n\nfunction rememberChain(key: string): void {\n chainOf.delete(key);\n chainOf.set(key, heldLayouts);\n\n while (chainOf.size > MAX_CHAINS) {\n const oldest = chainOf.keys().next().value as string | undefined;\n\n if (oldest === undefined) break;\n\n chainOf.delete(oldest);\n }\n}\n\n/**\n * The boundary depth an interception was rendered at, while one is showing.\n *\n * An interceptor replaces a slot on the layout that declares it, so leaving the\n * intercepted view has to re-render that layout for the slot to go back to its\n * default. Left to itself the next navigation shares the whole chain, replaces\n * only the page below it, and the modal stays open over the new one.\n */\nlet interceptedAtDepth: number | null = null;\n\n/**\n * The url showing underneath an open interception.\n *\n * An interception puts something in a slot on a page that stays where it is,\n * so closing it is not a navigation at all — the page beneath was never\n * replaced. Remembering which url that is means going back to it costs\n * nothing, rather than fetching and rebuilding a page that is already on\n * screen with everything the user typed into it.\n */\nlet interceptedOver: string | null = null;\n\n/**\n * The url an interception was opened from, whichever way it was rendered -\n * the page still on screen under the modal. Only stillShowing asks.\n */\nlet interceptedFrom: string | null = null;\n\nconst DEFAULT_PREFETCH_TTL = 30_000;\n/**\n * How long a payload the host marked `public` is kept.\n *\n * The same build-time bytes for everyone, so the only way it changes is a\n * deploy, and the version handshake catches that on the tap. Thirty seconds\n * was Next's figure for a dynamic page; its static pages are held five\n * minutes, and a landing page read for a minute before the tap on Sign in\n * was, at thirty, an expired entry and a round trip on a phone.\n */\nconst STATIC_PREFETCH_TTL = 300_000;\n\n/**\n * How many prefetched payloads are kept. Entries carry a TTL but were only\n * dropped when read again, so a long session hovering its way through a big\n * nav held every payload it had ever fetched. On insert, anything expired\n * goes, and past the cap the oldest goes - insertion order is age.\n */\nconst MAX_CACHED = 50;\n\nfunction makeRoom(): void {\n const now = Date.now();\n\n for (const [key, entry] of cache) {\n if (entry.expiresAt <= now && !prefetchControllers.has(key))\n cache.delete(key);\n }\n\n while (cache.size >= MAX_CACHED) {\n const oldest = cache.keys().next().value as string | undefined;\n\n if (oldest === undefined) break;\n\n prefetchControllers.get(oldest)?.abort();\n prefetchControllers.delete(oldest);\n cache.delete(oldest);\n }\n}\n\n/**\n * Where a payload lives when there is no server to negotiate with.\n *\n * Normally the payload and the page share a url and are told apart by the\n * X-RSC header. A static host cannot vary by header — it serves one file per\n * url — so an exported build gives payloads their own addresses and the client\n * asks for those instead.\n */\nlet staticPayloadSuffix: string | null = null;\n\n/**\n * The route table, on a static host only.\n *\n * A server works out how much of the page to send by comparing the chain the\n * client sent with the route's own, and says so in a header. A file server\n * does neither — so on an exported site the client has to know the target's\n * layout chain before it asks, or every navigation takes the whole document\n * and replaces the root, which unmounts everything retained behind it.\n *\n * Inlined into the browser entry by the build, so it costs no request.\n */\nlet staticRoutes: ManifestRoute[] | null = null;\n\nexport function setStaticRoutes(routes: ManifestRoute[]): void {\n staticRoutes = routes;\n}\n\n/**\n * The layout chain of the page loaded from a file, since no header said.\n *\n * Without this the client believes it holds nothing, every navigation asks\n * for a whole document, and the depth variants sitting beside it are never\n * requested — the export looks correct and retention silently never happens.\n */\nexport function seedStaticChain(url: string): boolean {\n const segments = staticSegments(url);\n\n if (!segments) return false;\n\n heldLayouts = segments.chain;\n rememberChain(retentionKey(url, null));\n\n return true;\n}\n\n/**\n * The depth an exported payload should be asked for, and the chain it leaves\n * mounted — the two things a header would otherwise have carried.\n */\nfunction staticSegments(\n url: string,\n held: string[] = heldLayouts,\n): { depth: number; chain: string[] } | null {\n if (staticRoutes === null) return null;\n\n const path = new URL(url, window.location.origin).pathname;\n const match = matchRoute({ routes: staticRoutes } as never, path);\n\n if (!match) return null;\n\n return {\n // Against the chain the request is made with, never against whatever is\n // mounted by the time the answer arrives. A prefetch is fetched against\n // one chain and applied later, and reading live state here labels its\n // payload with a depth it was not rendered for.\n depth: sharedDepth(held.join(\",\"), match.route.layouts),\n // Copied: this is the build's table, and the caller assigns it to the\n // chain it holds — handing out the array itself makes the two the same\n // object.\n chain: [...match.route.layouts],\n };\n}\n\nexport function setStaticPayloads(suffix: string | null): void {\n staticPayloadSuffix = suffix;\n}\n\n/** The url to request a payload from, which is the page's own unless exported. */\nexport function payloadUrl(url: string, held: string[] = heldLayouts): string {\n if (staticPayloadSuffix === null) return url;\n\n const parsed = new URL(url, window.location.origin);\n const path = parsed.pathname.replace(/\\/+$/, \"\");\n const segments = staticSegments(url, held);\n\n // The variant for exactly the depth this client shares. Asking for the whole\n // document when a segment would do is not merely wasteful: it replaces the\n // root, and replacing the root throws away every page retained behind it.\n const name =\n segments && segments.depth > 0\n ? staticPayloadSuffix.replace(/^index\\./, `index.seg${segments.depth}.`)\n : staticPayloadSuffix;\n\n return `${path}/${name}${parsed.search}`;\n}\n\n/**\n * What a static payload was fetched as, recorded against its own response.\n *\n * The depth asked for and the depth applied have to be the same number. Worked\n * out separately at the two call sites they can disagree — and a payload\n * rendered whole but applied as a segment nests a boundary inside itself,\n * which does not error, it recurses until the renderer stops responding.\n */\nconst staticFetches = new WeakMap<\n Response,\n { depth: number; chain: string[] }\n>();\n\nexport function setVersion(v: string): void {\n version = v;\n}\n\n/**\n * Tell the worker which build the server is on, and wait to be heard - a\n * document load follows, and the message has to land before the request\n * the load makes. Bounded: a worker that does not answer is not worth a\n * visitor's wait, and a page with no worker has nothing to tell.\n */\nasync function tellWorkerServerBuild(build: string | null): Promise<void> {\n if (!build || typeof navigator === \"undefined\" || !(\"serviceWorker\" in navigator)) return;\n\n const worker = navigator.serviceWorker.controller;\n\n if (!worker) return;\n\n await new Promise<void>((resolve) => {\n const channel = new MessageChannel();\n const done = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(done, 300);\n\n channel.port1.onmessage = done;\n worker.postMessage({ type: \"rsc-kit:server-build\", version: build }, [channel.port2]);\n });\n\n // And look for the successor now rather than on the next navigation.\n void navigator.serviceWorker.getRegistration().then((registration) => registration?.update()).catch(() => {});\n}\n\n/**\n * The layout chain the client is holding.\n *\n * Seeded from the initial page's response and updated on every navigation, so\n * the next request can say what is already mounted.\n */\nexport function setHeldLayouts(chain: string[]): void {\n heldLayouts = chain;\n rememberChain(retentionKey(window.location.href, null));\n}\n\nexport function getHeldLayouts(): string[] {\n return heldLayouts;\n}\n\nexport function setNavigateHandler(\n fn: (tree: ReactNode, key: string, segmentDepth: number) => void,\n): void {\n onNavigate = fn;\n}\n\nexport function setReplaceRootHandler(fn: ((tree: ReactNode) => void) | null): void {\n onReplaceRoot = fn;\n}\n\nexport function setHeldHandlers(\n held: ((key: string, maxAge?: number) => boolean) | null,\n drop: (() => void) | null,\n): void {\n isHeldPage = held;\n dropHeld = drop;\n}\n\n/**\n * Everything the router holds about pages other than the one on screen,\n * dropped: prefetched payloads, and pages kept behind this one.\n *\n * After an action that revalidated. The list a link prefetched before the\n * mutation still shows the table without the new row - visit() landed on\n * it with no request made, and a reload showed the row. What was fetched\n * before a write is not a cache of what is true after it; the pages held\n * for the back button are from before it too.\n */\nexport function forgetOtherPages(): void {\n for (const [key, controller] of prefetchControllers) {\n controller.abort();\n prefetchControllers.delete(key);\n }\n\n cache.clear();\n dropHeld?.();\n}\n\nexport function setPrerenderHandler(\n fn: ((tree: ReactNode, key: string, segmentDepth: number) => void) | null,\n): void {\n onPrerender = fn;\n}\n\n/**\n * How the router reveals a page that is still mounted behind the current one.\n *\n * Returning true means the page was restored with its client state intact and\n * no request was made.\n */\nexport function setRestoreHandler(\n fn: (key: string, maxAge?: number) => boolean,\n): void {\n onRestore = fn;\n}\n\nexport function setDeserializer(fn: Deserializer): void {\n flightDeserializer = fn;\n}\n\nexport function setCallServer(fn: CallServerFn): void {\n callServerFn = fn;\n}\n\n/**\n * The urls a route.ts answers, so a link to one is treated as the anchor it\n * is: no prefetch - a hover must not run a route - and a full navigation\n * rather than a payload fetch, since the answer is a Response, not a page.\n * Baked into the generated browser entry from the route tree.\n */\nlet apiRoutePatterns: RegExp[] = [];\n\nexport function setApiRoutes(patterns: string[]): void {\n apiRoutePatterns = patterns.map(\n (pattern) =>\n new RegExp(\n \"^\" +\n pattern\n .split(\"/\")\n .map((part) =>\n part.startsWith(\"[...\") ? \".+\" : part.startsWith(\"[\") ? \"[^/]+\" : part.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"),\n )\n .join(\"/\") +\n \"/?$\",\n ),\n );\n}\n\n/** Whether a url is one a route.ts answers. */\nexport function isApiRoute(url: string): boolean {\n if (apiRoutePatterns.length === 0) return false;\n\n try {\n const { pathname } = new URL(url, window.location.origin);\n\n return apiRoutePatterns.some((pattern) => pattern.test(pathname));\n } catch {\n return false;\n }\n}\n\nexport function setInterceptManifest(entries: InterceptEntry[]): void {\n interceptManifest = entries;\n}\n\n/**\n * Check if a URL matches any intercept pattern.\n * Returns the matching slot name, or null if no match.\n */\nfunction matchIntercept(url: string): string | null {\n if (interceptManifest.length === 0) return null;\n\n let pathname: string;\n try {\n pathname = new URL(url, window.location.origin).pathname;\n } catch {\n pathname = url.split(\"?\")[0];\n }\n\n for (const entry of interceptManifest) {\n // urlPattern already has a leading slash (e.g. \"/docs/item/[id]\")\n const regex = new RegExp(\n \"^\" +\n entry.urlPattern\n .replace(/\\[\\.\\.\\.(\\w+)\\]/g, \"(.+)\")\n .replace(/\\[(\\w+)\\]/g, \"([^/]+)\") +\n \"$\",\n );\n\n if (regex.test(pathname)) {\n return entry.slot;\n }\n }\n\n return null;\n}\n\nexport function renderTree(tree: ReactNode): void {\n onNavigate?.(tree, retentionKey(window.location.href, null), 0);\n}\n\n/**\n * Identity of a page for retention purposes.\n *\n * Path and query only: a hash is a position within the same page, and an\n * intercepted route is a different rendering of the same URL, so it retains\n * separately from the full page.\n */\nexport function retentionKey(\n url: string,\n interceptSlot: string | null,\n): string {\n let path: string;\n\n try {\n const parsed = new URL(url, window.location.origin);\n path = parsed.pathname + parsed.search;\n } catch {\n path = url.split(\"#\")[0];\n }\n\n return retentionKeyFor(path, interceptSlot);\n}\n\nexport function getCallServer(): CallServerFn {\n if (!callServerFn) {\n throw new Error(\n \"callServer not initialized. Ensure createViteRscApp() has been called.\",\n );\n }\n return callServerFn;\n}\n\nfunction fetchRscPayload(\n url: string,\n signal?: AbortSignal,\n interceptSlot?: string,\n refererUrl?: string,\n chain: string[] = heldLayouts,\n // A prefetch is speculative and a navigation is not, but on the wire they\n // were identical — so a click could queue behind several prefetches the user\n // had already moved past. Over HTTP/1.1 a browser opens ~6 connections per\n // origin, which a sweep across a nav bar fills on its own.\n priority: \"high\" | \"low\" = \"high\",\n /**\n * A prefetch is speculative: a 409 on one must not load a document the\n * visitor never asked for. A viewport prefetch of the sign-in link, sent\n * from an old page after a deploy, took the visitor reading the home page\n * to /login half a second after it appeared - and a hover over a sidebar\n * link did the same to a half-filled form. The session is marked stale\n * instead, so the next navigation the visitor makes is a document load.\n */\n speculative = false,\n): Promise<Response> {\n const headers: Record<string, string> = {\n \"X-RSC\": \"true\",\n \"X-RSC-Version\": version,\n };\n\n if (chain.length) {\n headers[\"X-RSC-Segments\"] = chain.join(\",\");\n }\n\n if (interceptSlot) {\n headers[\"X-RSC-Intercept\"] = interceptSlot;\n }\n\n if (refererUrl) {\n headers[\"X-RSC-Referer\"] = refererUrl;\n }\n\n // `priority` is not in every lib.dom yet; browsers without it ignore it.\n const asked = staticSegments(url, chain);\n const request = fetch(payloadUrl(url, chain), {\n headers,\n signal,\n priority,\n } as RequestInit).catch((err: unknown) => {\n // Nothing answered at all. An abort is our own doing, not the network's —\n // leaving a link cancels its prefetch, and that must not read as offline.\n if (!(err instanceof DOMException && err.name === \"AbortError\")) {\n reportReachable(false);\n }\n\n throw err;\n });\n\n return request.then(async (response) => {\n // What this payload was asked for, so the apply side cannot work out a\n // different answer from state that has moved on since.\n if (asked) staticFetches.set(response, asked);\n\n // Something answered, whatever it said. A 500 is a reachable server.\n reportReachable(true);\n // Adopt the server's build version from the first response that carries\n // one. Until we know it we send an empty version, which the middleware\n // treats as \"no opinion\"; afterwards a redeploy mid-session answers 409.\n const served = response.headers.get(\"X-RSC-Version\");\n\n if (served && version === \"\") {\n version = served;\n }\n\n if (response.status === 409) {\n const location = response.headers.get(\"X-RSC-Location\");\n // Server-chosen, so checked again here: the engine refuses these at the\n // source, but a host in front of it can put anything on the header.\n // Once per url: a worker still serving the last build's document would\n // answer the load with it, and the next click would be here again.\n const to = isSafeRedirect(location ?? url) ? (location ?? url) : url;\n\n // The worker first. It serves a stored document from its cache, and\n // its cache is the build this page came from - the document it would\n // answer the load with is the one being left. Told which build the\n // server is on, it serves the network for a copy from any other, and\n // is asked to look for its successor. Then the load.\n await tellWorkerServerBuild(served);\n\n if (speculative) {\n markStale();\n\n throw new Error(\"This page is from an earlier build; the next navigation loads the document\");\n }\n\n throw new Error(\n loadDocumentOnce(to)\n ? \"This page is from an earlier build; loading the document from the current one\"\n : \"This page is from an earlier build, and loading the document did not bring the current one\",\n );\n }\n\n return response;\n });\n}\n\n/**\n * Deserialize a Flight response into a React tree.\n *\n * Client modules, CSS <link>s and <title>/<meta> all travel inside the Flight\n * payload — @vitejs/plugin-rsc emits stylesheet links as tree elements and\n * resolves client references through its own browser runtime, and React 19\n * hoists document metadata into <head>. Nothing needs injecting from headers.\n */\nfunction deserializeResponse(response: Response): Promise<ReactNode> {\n return flightDeserializer!(response.body!, {\n callServer:\n callServerFn ??\n (async () => {\n throw new Error(\"Server actions not initialized\");\n }),\n });\n}\n\nfunction isExternalUrl(url: string): boolean {\n try {\n return (\n new URL(url, window.location.origin).origin !== window.location.origin\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Whether a cached payload can be used for a navigation claiming this chain.\n *\n * A partial payload only composes against the chain it was rendered for, so\n * the chain it was fetched against has to be the one the navigation is about\n * to claim — not whatever happens to be mounted.\n */\nfunction isUsable(cached: CacheEntry | undefined, chain: string[]): boolean {\n return (\n cached !== undefined &&\n cached.expiresAt > Date.now() &&\n cached.heldWhenFetched === chain.join(\",\")\n );\n}\n\n/**\n * Whether a navigation to this url would be served from the prefetch cache.\n *\n * Lets a caller decide whether showing an already-fetched page is free. A form\n * uses it to put its target route's shell on screen while the real query runs:\n * worth doing when the shell is in hand, never worth an extra request.\n */\nexport function isPrefetched(url: string): boolean {\n if (isExternalUrl(url)) return false;\n\n const interceptSlot = matchIntercept(url);\n const cacheKey = retentionKeyFor(url, interceptSlot);\n\n return isUsable(cache.get(cacheKey), claimedChain(interceptSlot));\n}\n\n/**\n * The layout chain a navigation to a url will claim.\n *\n * Leaving an interception claims fewer layouts than are held, which is what\n * forces the layout owning the slot to render again so the slot can empty.\n * Both sides have to agree on it: a prefetch recorded against a different\n * chain can never be used, so the close of every modal refetched a payload it\n * had already fetched.\n */\nfunction claimedChain(interceptSlot: string | null): string[] {\n return !interceptSlot && interceptedAtDepth !== null\n ? heldLayouts.slice(0, interceptedAtDepth)\n : heldLayouts;\n}\n\n/**\n * How many redirects a single navigation will follow before giving up.\n *\n * A page that redirects to itself is a mistake someone will make, and without\n * a ceiling it is an unbounded loop of requests rather than an error. The\n * browser's own limit for HTTP redirects is 20; this is smaller because these\n * are full renders, not header exchanges.\n */\nconst MAX_REDIRECTS = 8;\n\n/**\n * Go to a url, the way a Link does.\n *\n * `url` is typed to the routes the build found; cast with `as Route` when the\n * destination is computed rather than written.\n */\nexport async function navigate(\n url: Route,\n opts?: {\n replace?: boolean;\n preserveScroll?: boolean;\n restore?: boolean;\n /** Internal: how many redirects led here. */\n redirectsFollowed?: number;\n },\n): Promise<void> {\n const redirectsFollowed = opts?.redirectsFollowed ?? 0;\n\n // The worker has said a newer build is live. This page's client cannot\n // load what that build's payloads name, so the next navigation is the\n // document, from the new build - the router knows; the banner was only\n // advice. Not for a restore: going back to a page still held asks the\n // server for nothing.\n if (!opts?.restore && isUpdated()) {\n announceDocumentLoad(url, \"newer-build\");\n window.location.href = url;\n\n return;\n }\n\n if (redirectsFollowed > MAX_REDIRECTS) {\n throw new Error(\n `Too many redirects following a navigation (${MAX_REDIRECTS}); last was ${url}`,\n );\n }\n\n // External URLs can't be fetched (CORS) — go directly to full page navigation\n if (isExternalUrl(url)) {\n announceDocumentLoad(url, \"external\");\n window.location.href = url;\n return;\n }\n\n // A route.ts answers with a Response, not a page: a download, a redirect\n // that decides where someone belongs, a sign-out. The browser goes there.\n if (isApiRoute(url)) {\n announceDocumentLoad(url, \"api-route\");\n window.location.href = url;\n return;\n }\n\n // Hash-only URLs — let the browser handle scrolling natively\n if (url.startsWith(\"#\")) {\n window.location.hash = url;\n return;\n }\n\n // Abort any in-flight navigation\n activeController?.abort();\n\n navigationStarted(url);\n\n // Not window.stop(). It used to be called here while the document was\n // still loading, to free a single-threaded server for the new request -\n // and it cancels every load the page has in flight: the client chunks a\n // just-decoded tree still needs, the stylesheet, the boundaries still\n // streaming. A navigation that left the page before the runtime had\n // finished arriving rendered a document with nothing in it. The server\n // has workers; the page keeps loading.\n\n const controller = new AbortController();\n activeController = controller;\n\n // Check if this URL matches an intercept pattern.\n // If so, send the intercept slot + current URL as referer so the server\n // renders the full tree with the interceptor in the right slot.\n const interceptSlot = matchIntercept(url);\n const currentUrl = interceptSlot\n ? window.location.pathname + window.location.search\n : undefined;\n\n const activityKey = retentionKey(url, interceptSlot);\n\n // A page still being held is revealed rather than refetched, whichever\n // gesture asked for it — the back button or a link. Both mean \"the page I\n // was just on\", and having the form you were filling in survive one and not\n // the other is a distinction nobody makes while using the app.\n //\n // The cost is honest: what comes back is the tree from when you left, so its\n // data is from then. Retention is four pages deep, so this reaches only\n // somewhere you were moments ago, and `revalidate()` is how a page says its\n // data has moved on.\n // Closing an interception. The page underneath was never replaced, so this\n // is a matter of emptying the slot — no request, and nothing rebuilt. The\n // form behind the modal is still the one the user was filling in.\n if (\n !interceptSlot &&\n interceptedOver !== null &&\n retentionKey(url, null) === retentionKey(interceptedOver, null)\n ) {\n clearSlots();\n interceptedOver = null;\n interceptedFrom = null;\n interceptedAtDepth = null;\n\n if (opts?.replace) {\n history.replaceState({ rscUrl: url }, \"\", url);\n } else {\n history.pushState({ rscUrl: url }, \"\", url);\n }\n\n window.dispatchEvent(new CustomEvent(\"rsc-navigate\", { detail: url }));\n navigationCommitted();\n\n return;\n }\n\n // Not when the target is the page already showing: asking for this page\n // again means asking the server again, and revealing what is already there\n // would make refresh a no-op. Not while an interception is opening or\n // closing either — those rebuild the chain deliberately.\n const askingForThisPage =\n retentionKey(window.location.href, null) === retentionKey(url, null);\n //\n // And not while an interception is on screen. Leaving a modal has to\n // re-render the layout that owns the slot, because that is what empties it;\n // revealing the page underneath instead leaves the modal sitting over a page\n // whose url has already changed.\n const mayReveal =\n opts?.restore === true ||\n (!askingForThisPage &&\n !interceptSlot &&\n interceptedOver === null &&\n interceptedAtDepth === null);\n\n // Unbounded for the back button, bounded for a link.\n if (\n mayReveal &&\n onRestore?.(activityKey, opts?.restore ? undefined : revealWithin)\n ) {\n // A restored tree carries its own slot contents, so the flag only has to\n // reflect whether what is now showing is an intercepted view.\n if (!interceptSlot) {\n interceptedAtDepth = null;\n interceptedFrom = null;\n }\n\n // Its layouts are the ones on screen now - see chainOf.\n const chain = chainOf.get(activityKey);\n\n if (chain) heldLayouts = chain;\n\n // opts?.replace, not opts.replace: this branch used to be reachable only\n // with opts.restore set, so opts was always there. A link reaches it now\n // with nothing passed at all.\n if (opts?.replace) {\n history.replaceState({ rscUrl: url }, \"\", url);\n } else {\n history.pushState({ rscUrl: url }, \"\", url);\n }\n\n window.dispatchEvent(new CustomEvent(\"rsc-navigate\", { detail: url }));\n navigationCommitted();\n\n return;\n }\n\n // A prefetched payload was rendered against the chain held at prefetch time.\n let segmentDepth = 0;\n let nextLayouts: string[] | null = null;\n /** The slot this answer fills, when it is one region rather than a segment. */\n let slotPayload: string | null = null;\n /** The cache entry this navigation is using, whose metadata settles with it. */\n let reused: CacheEntry | null = null;\n const previousUrl = window.location.pathname + window.location.search;\n\n try {\n const cacheKey = retentionKeyFor(url, interceptSlot);\n const cached = cache.get(cacheKey);\n let treePromise: Promise<ReactNode>;\n\n const chain = claimedChain(interceptSlot);\n\n // A partial payload only composes against the chain it was rendered for —\n // the one this navigation is about to claim, not whatever is mounted.\n // Hovering a link inside a modal prefetches it against the full chain, so\n // reusing that here would skip the layout holding the modal and leave it\n // open over the page behind it.\n const usable = isUsable(cached, chain);\n\n if (usable) {\n treePromise = cached!.tree;\n // Read after the tree resolves, not now. A prefetch fills these in when\n // its response lands, and a click can land first — hover a modal link\n // and click it quickly and the entry still says depth 0, so the\n // interceptor is applied as a whole document and the modal renders *as*\n // the page. The fields are set before the tree promise resolves, so\n // waiting for it is what makes them true.\n reused = cached!;\n cache.delete(cacheKey);\n } else {\n cache.delete(cacheKey);\n\n // Marked while in flight, so a prefetch of the same page - a held\n // tap's replay landing beside the idle viewport prefetch of the link\n // it came from - does not ask for it a second time.\n navigating.add(cacheKey);\n\n let response: Response;\n\n try {\n response = await fetchRscPayload(\n url,\n controller.signal,\n interceptSlot ?? undefined,\n currentUrl,\n chain,\n );\n } finally {\n navigating.delete(cacheKey);\n }\n\n // The check is for a host that answered the page instead of the\n // payload, which is what a server does when it does not recognise the\n // header. An exported build asks a url that only ever holds a payload,\n // and a file server labels it by extension — commonly\n // application/octet-stream — so the check would reject every navigation\n // and send the browser on a full page load instead.\n // The render asked to go somewhere else, and said so before writing\n // anything — so this is still a navigation, not a page load. A redirect\n // decided later than that cannot travel here; it arrives in the payload\n // as an error digest and RedirectBoundary performs it.\n const redirectTo = response.headers.get(\"X-RSC-Redirect\");\n\n if (redirectTo) {\n // The url that redirected was never pushed - the history entry is\n // written after the tree arrives, below - so the destination takes\n // this navigation's own mode. `replace: true` here replaced the page\n // the visitor was ON, and Back from the login page skipped home.\n // Chosen by the server, not written here.\n await navigate(redirectTo as Route, {\n replace: opts?.replace,\n redirectsFollowed: redirectsFollowed + 1,\n });\n\n return;\n }\n\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n\n if (\n staticPayloadSuffix === null &&\n !contentType.includes(\"text/x-component\")\n ) {\n announceDocumentLoad(url, `not-a-payload:${response.status}:${contentType.split(\";\")[0]}`);\n window.location.href = url;\n return;\n }\n\n // Headers on a server; worked out locally on a static host, where there\n // is nothing to send them.\n const served = staticFetches.get(response) ?? null;\n\n segmentDepth =\n Number(\n response.headers.get(\"X-RSC-Segment-Depth\") ?? served?.depth ?? 0,\n ) || 0;\n\n // Named region rather than a segment — see the apply below.\n slotPayload = response.headers.get(\"X-RSC-Revalidate\");\n\n const servedLayouts = response.headers.get(\"X-RSC-Layouts\");\n\n if (servedLayouts !== null) {\n nextLayouts = servedLayouts === \"\" ? [] : servedLayouts.split(\",\");\n } else if (served) {\n nextLayouts = served.chain;\n }\n\n treePromise = deserializeResponse(response);\n }\n\n let tree: ReactNode;\n\n try {\n tree = await treePromise;\n navigationReached(\"decoded\");\n } catch (error) {\n // A navigation another one overtook: its request was aborted, and\n // the decoder reports that as a failure of the payload. It is not one\n // - nothing of it was going to be shown - so it ends here, quietly,\n // rather than as a rejection nobody is waiting on.\n if (controller.signal.aborted) return;\n\n throw error;\n }\n\n if (reused) {\n if (controller.signal.aborted) return;\n\n // The prefetch this navigation took did not come back as a page. A\n // redirect is followed as one on this request would be; a failure is\n // asked again, from a cache that no longer holds the entry.\n if (reused.redirectTo) {\n await navigate(reused.redirectTo as Route, {\n replace: opts?.replace,\n redirectsFollowed: redirectsFollowed + 1,\n });\n\n return;\n }\n\n if (reused.failed) {\n await navigate(url, opts);\n\n return;\n }\n\n segmentDepth = reused.segmentDepth;\n nextLayouts = reused.layouts;\n slotPayload = reused.slot;\n }\n\n if (controller.signal.aborted) return;\n\n if (opts?.replace) {\n history.replaceState({ rscUrl: url }, \"\", url);\n } else {\n history.pushState({ rscUrl: url }, \"\", url);\n }\n\n if (nextLayouts !== null) heldLayouts = nextLayouts;\n rememberChain(activityKey);\n\n // The answer is one region, not a piece of the page: the host rendered\n // only the interceptor because the page underneath is already mounted and\n // still correct. Putting it in the slot leaves that page — and everything\n // typed into it — exactly as it was.\n if (slotPayload !== null) {\n setSlot(slotPayload, tree as ReactNode);\n interceptedOver = interceptedOver ?? previousUrl;\n interceptedFrom = interceptedFrom ?? previousUrl;\n interceptedAtDepth = null;\n\n return;\n }\n\n // A slot rendered for the page being left has no claim on the one being\n // arrived at.\n clearSlots();\n\n interceptedOver = null;\n interceptedAtDepth = interceptSlot ? segmentDepth : null;\n interceptedFrom = interceptSlot ? (interceptedFrom ?? previousUrl) : null;\n\n navigationReached(\"applied\");\n onNavigate?.(tree, activityKey, segmentDepth);\n\n if (!opts?.preserveScroll && !interceptSlot) {\n // Wait for React to commit the DOM update before scrolling.\n // Intercepted navigations preserve scroll (e.g. modal over current page).\n requestAnimationFrame(() => {\n window.scrollTo(0, 0);\n });\n }\n\n window.dispatchEvent(new CustomEvent(\"rsc-navigate\", { detail: url }));\n } catch (err) {\n navigationAbandoned();\n\n if (err instanceof DOMException && err.name === \"AbortError\") return;\n\n // A chunk the deploy no longer serves: the browser would have loaded the\n // document, and the new names with it. Do what it would have done.\n if (isStaleAssetError(err)) {\n announceDocumentLoad(url, `stale-asset:${String((err as Error)?.message ?? err).slice(0, 120)}`);\n window.location.href = url;\n\n return;\n }\n\n // Without this a navigation that fails does nothing observable: the click\n // clears its own pending state and the page stays as it was, with no\n // error, no fallback and nothing for an app to react to. Dispatched before\n // rethrowing, so a programmatic caller still sees the failure.\n window.dispatchEvent(\n new CustomEvent(\"rsc-navigate-error\", { detail: { url, error: err } }),\n );\n\n throw err;\n } finally {\n if (activeController === controller) {\n activeController = null;\n }\n }\n}\n\n/**\n * Put something the server re-rendered on screen.\n *\n * The trees arrive with an action's answer rather than being fetched, so this\n * is the same apply path a navigation uses — without a request, a url change\n * or a history entry.\n */\n/**\n * Whether the page an action was invoked from is the one on screen.\n *\n * The one underneath, when an interception is showing: a modal opened after\n * the submit sits over the same page.\n */\nexport function stillShowing(url: string): boolean {\n const key = retentionKey(url, null);\n const now = retentionKey(window.location.pathname + window.location.search, null);\n\n return key === now || (interceptedFrom !== null && key === retentionKey(interceptedFrom, null));\n}\n\n/**\n * Put what an action re-rendered on screen.\n *\n * `from` is the url the action was invoked on - what the host rendered the\n * trees for. A tap that left the page while the action was in flight has\n * changed what is showing, and a document rendered for the page before\n * cannot go under the url after: \"Add to cart\", then the brand link at\n * once, showed the home page and then, when the answer landed, the product\n * again under `/`. The write still happened, and the page on screen was\n * fetched before it - so that page is asked for again, whole, instead.\n */\nexport function applyRevalidations(from: string, revalidated: Record<string, ReactNode>): void {\n // What was fetched or held before the write is from before it.\n forgetOtherPages();\n\n if (!stillShowing(from)) {\n void refresh(\"all\");\n\n return;\n }\n\n for (const [target, tree] of Object.entries(revalidated)) {\n applyRevalidated(target, tree);\n }\n}\n\nexport function applyRevalidated(target: string, tree: ReactNode): void {\n const url = window.location.pathname + window.location.search;\n const key = retentionKey(url, null);\n\n if (target === \"all\") {\n // The whole document again, in place. Not a navigation to this url:\n // the visible entry may be keyed by the url the document loaded with,\n // and showing the tree under the current one made a second entry and\n // remounted the app under it.\n if (onReplaceRoot) onReplaceRoot(tree);\n else onNavigate?.(tree, key, 0);\n\n return;\n }\n\n if (target === \"page\") {\n onNavigate?.(tree, key, heldLayouts.length);\n\n return;\n }\n\n setSlot(target, tree);\n}\n\n/**\n * Ask the server for part of this page again.\n *\n * refresh() the page, leaving the layouts mounted\n * refresh('all') the whole document, layouts included\n * refresh('orders') one parallel slot, by the name its directory gave it\n *\n * The same words an action uses, so a thing can be invalidated from either\n * side. This is the path for a refresh nobody mutated anything to earn — a\n * button, a poll, a message saying that table has moved; what an action\n * invalidated travels back inside the action's own answer instead.\n *\n * A slot is the only region smaller than a page the server can name, so two\n * tables refresh apart from each other only if they are two slots. The page\n * form leaves the layouts alone, which is what makes it cheap and also why a\n * count living in a layout will not move until you ask for 'all'.\n */\nexport async function refresh(target = \"page\"): Promise<void> {\n const url = window.location.pathname + window.location.search;\n\n // Asked because the data moved on; what was fetched or held before is\n // from before.\n forgetOtherPages();\n\n if (target !== \"page\" && target !== \"all\") {\n const response = await fetch(payloadUrl(url), {\n headers: {\n \"X-RSC\": \"true\",\n \"X-RSC-Version\": version,\n \"X-RSC-Revalidate\": target,\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `Could not revalidate ${target}: the server answered ${response.status}`,\n );\n }\n\n setSlot(target, await deserializeResponse(response));\n\n return;\n }\n\n const interceptSlot = matchIntercept(url);\n const cacheKey = retentionKeyFor(url, interceptSlot);\n\n // Never from the cache: refreshing asks what the server says now, not what\n // it said a moment ago.\n cache.delete(cacheKey);\n\n if (target === \"all\") {\n heldLayouts = [];\n }\n\n // A refresh is not a navigation: the same page stays under the reader, so\n // where they were reading has to survive the tree being replaced.\n //\n // `preserveScroll` is not enough on its own. It stops navigate() scrolling\n // to the top deliberately, and says nothing about the scroll positions\n // *inside* the page. Refreshing everything replaces the root, so every\n // element that scrolls is a new node and starts at zero — a sidebar,\n // a code block, any pane with its own overflow. The window survives because\n // the document element is not the thing being replaced, which is why this\n // looks fine until a page has a second scroller in it.\n const positions = scrollPositions();\n\n await navigate(url as Route, { replace: true, preserveScroll: true });\n\n restoreScroll(positions);\n}\n\ninterface ScrollPosition {\n tag: string;\n top: number;\n left: number;\n}\n\n/** Every element that can scroll, whether or not it currently is. */\nfunction scrollables(): HTMLElement[] {\n return [...document.querySelectorAll<HTMLElement>(\"*\")].filter(\n (el) =>\n el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth,\n );\n}\n\n/**\n * Where everything on the page is scrolled to, in document order.\n *\n * Identified by position in the list rather than by a selector: a refresh\n * re-renders the same page, so the nth scrollable element is the same one, and\n * a selector would have to survive whatever classes the markup happens to use.\n * The tag is carried only to notice when that assumption has broken.\n *\n * Everything that *can* scroll, not everything that *is* scrolled — the two\n * lists have to be built the same way or they do not line up. Recording only\n * the scrolled ones and restoring over the scrollable ones puts a sidebar's\n * position onto whatever element happens to come first, which on any page long\n * enough to scroll is <html>.\n */\nfunction scrollPositions(): ScrollPosition[] {\n return [\n { tag: \"window\", top: window.scrollY, left: window.scrollX },\n ...scrollables().map((el) => ({\n tag: el.tagName,\n top: el.scrollTop,\n left: el.scrollLeft,\n })),\n ];\n}\n\n/**\n * Put the page back where it was, once React has finished replacing it.\n *\n * Applied over several ticks rather than once, because `root.render()`\n * schedules the update instead of performing it: a single pass writes the\n * position onto the nodes that are about to be thrown away, and the ones that\n * replace them start at zero. There is nothing to await — the navigation\n * resolves when the tree is handed to React, not when React has committed it.\n *\n * `setTimeout`, not `requestAnimationFrame`. A hidden tab never runs an\n * animation frame, so a refresh in a background tab — an HMR update, a poll —\n * would leave the scroll state wrong the moment it came back into view. It\n * also makes this untestable in an automated browser, where the tab under test\n * is usually not the visible one.\n */\nconst RESTORE_ATTEMPTS = 5;\n\nfunction restoreScroll(positions: ScrollPosition[]): void {\n const [win, ...inner] = positions;\n\n const apply = (attempt: number) => {\n if (window.scrollY !== win.top || window.scrollX !== win.left) {\n window.scrollTo(win.left, win.top);\n }\n\n const now = scrollables();\n\n for (let i = 0; i < inner.length && i < now.length; i++) {\n // A different element here means the page came back a different shape,\n // and guessing further would scroll something nobody touched.\n if (now[i].tagName !== inner[i].tag) break;\n\n if (inner[i].top !== 0 && now[i].scrollTop !== inner[i].top)\n now[i].scrollTop = inner[i].top;\n if (inner[i].left !== 0 && now[i].scrollLeft !== inner[i].left)\n now[i].scrollLeft = inner[i].left;\n }\n\n if (attempt < RESTORE_ATTEMPTS) setTimeout(() => apply(attempt + 1), 16);\n };\n\n apply(1);\n}\n\n/**\n * Fetch a page's payload ahead of the navigation that may ask for it.\n *\n * `intent` is the difference between a link that came into view and one the\n * visitor is about to follow: a hover that settled, a touch. Only then is the\n * payload decoded on arrival - decoding is what loads the client chunks the\n * page names, and a viewport prefetch that decoded put the sign-in page's\n * thirty chunks onto a landing page for every phone visitor. A touch leads\n * its click by 100-300 ms, about a round trip, and a tap that found the\n * bytes here but not the chunks spent that round trip after the click\n * instead of before it: the tap-to-paint that was \"not zero\" beside Next,\n * whose prefetch decodes as it lands.\n */\nexport function prefetch(url: string, cacheForMs?: number, intent = false): void {\n // Never a route.ts: fetching one runs it, and a hover is not a click.\n if (isApiRoute(url)) return;\n\n // Never the page the visitor is on. A logo link to / on the home page,\n // in view, was a 14 KB payload for the page already on screen.\n if (retentionKey(url, null) === retentionKey(window.location.href, null)) return;\n\n // Nor a page still held behind this one, which a navigation would reveal\n // rather than fetch: the page just left, whose link is on every page,\n // was one wasted payload per navigation.\n if (!matchIntercept(url) && isHeldPage?.(retentionKey(url, null), revealWithin)) return;\n\n // Nor anything, once this page is known to be the previous build: the\n // next navigation is a document load, and a payload it would not use is\n // a 409 for nothing - one per tap, measured.\n if (isUpdated()) return;\n\n if (isExternalUrl(url)) return;\n\n const ttl = cacheForMs ?? DEFAULT_PREFETCH_TTL;\n const interceptSlot = matchIntercept(url);\n\n const held = { intent, explicitTtl: cacheForMs !== undefined };\n\n if (interceptSlot) {\n // Intercepted route — only prefetch the intercepted variant\n const currentUrl = window.location.pathname + window.location.search;\n const cacheKey = retentionKeyFor(url, interceptSlot);\n prefetchUrl(cacheKey, url, ttl, interceptSlot, currentUrl, held);\n } else {\n prefetchUrl(retentionKeyFor(url, null), url, ttl, undefined, undefined, held);\n }\n}\n\n/**\n * Do the click's work now: decode the held payload, which loads the chunks\n * it names, and render the page hidden so the click is a reveal.\n *\n * The numbers this came from, on an iPhone with everything prefetched: a\n * first visit to the landing page was 107 ms from tap to paint, 4 of them\n * decoding and 87 rendering; a page still held from a visit before was\n * 15 ms, a reveal. The render is the page's size on the phone's CPU, and\n * nothing in the payload's path shrinks it - but it can be paid before the\n * finger lifts. A touch leads its click by 100-300 ms; a settled hover, by\n * 200 or more. React renders a hidden Activity at idle priority, so the\n * work yields to scrolling, and the navigation then hands the boundary the\n * same tree it prerendered: React bails out of the whole subtree and flips\n * it visible.\n *\n * Only a segment at depth 1 or more, rendered against the chain held now: a\n * whole document replaces the root, and a slot is a region of a page not on\n * screen yet. A prefetch that landed on a redirect - a guarded link, on a\n * landing page all of them - warms the destination it prefetched instead:\n * the tap on Sign in decoded the login page and loaded its chunks after the\n * click, 154 ms of a 225 ms tap.\n */\nfunction warm(entry: CacheEntry, cacheKey: string, followed: Set<string> = new Set()): void {\n // A redirect this touch has already followed. Two guards can point at each\n // other - a guard's answer kept from before a sign-in beside the live one\n // after it - and a destination can normalise to the key of the entry that\n // named it (/agent/ to /agent). Every entry in such a chain is settled, so\n // following it is a chain of resolved promises: no request, no yield, the\n // tab pegged at 100% until it is killed. A port found its landing page\n // freezing on the first tap after a hard reload, with nothing in the\n // console and the network idle. Navigation caps the same walk at\n // MAX_REDIRECTS; this is the warm's own cap.\n if (followed.has(cacheKey) || followed.size > MAX_REDIRECTS) return;\n\n followed.add(cacheKey);\n\n // The tree is read by the navigation that takes the entry, and a decode\n // that fails - a chunk the deploy no longer serves - fails there, where it\n // is handled. Here the rejection has nobody to reach.\n entry.body\n .then((text) => {\n if (entry.redirectTo) {\n const destinationKey = retentionKeyFor(entry.redirectTo, matchIntercept(entry.redirectTo));\n const destination = cache.get(destinationKey);\n\n if (destination) warm(destination, destinationKey, followed);\n\n return;\n }\n\n if (text === null) return;\n\n // The page about to show: its pictures ahead of every other page's.\n preloadImages(text, \"high\");\n\n return entry.tree.then((tree) => {\n if (\n entry.slot !== null ||\n entry.segmentDepth === 0 ||\n !isUsable(entry, claimedChain(null)) ||\n cache.get(cacheKey) !== entry\n )\n return;\n\n onPrerender?.(tree, cacheKey, entry.segmentDepth);\n });\n })\n .catch(() => {});\n}\n\nfunction prefetchUrl(\n cacheKey: string,\n url: string,\n ttl: number,\n interceptSlot?: string,\n refererUrl?: string,\n held: { intent: boolean; explicitTtl: boolean } = { intent: false, explicitTtl: false },\n): void {\n const chain = claimedChain(interceptSlot ?? null);\n const existing = cache.get(cacheKey);\n\n if (existing && existing.expiresAt > Date.now()) {\n // Fetched as it came into view, undecoded; the touch says decode it.\n if (held.intent) warm(existing, cacheKey);\n\n return;\n }\n\n // A navigation is already fetching it; the answer is on its way.\n if (navigating.has(cacheKey)) return;\n\n cache.delete(cacheKey);\n makeRoom();\n\n const controller = new AbortController();\n prefetchControllers.set(cacheKey, controller);\n\n let decoded: Promise<ReactNode> | null = null;\n const entry: CacheEntry = {\n body: Promise.resolve(null),\n get tree() {\n return (decoded ??= this.body.then((text) => (text === null ? null : deserializeResponse(new Response(text)))));\n },\n expiresAt: Date.now() + ttl,\n segmentDepth: 0,\n layouts: null,\n slot: null,\n heldWhenFetched: chain.join(\",\"),\n redirectTo: null,\n failed: false,\n };\n\n // Low priority: the browser then lets a real navigation overtake a queue of\n // speculative requests instead of serving them in the order they were made.\n entry.body = fetchRscPayload(\n url,\n controller.signal,\n interceptSlot,\n refererUrl,\n chain,\n \"low\",\n true,\n )\n .then((response) => {\n // On a static host there are no headers to read, and dropping the depth\n // is not a small loss: the entry then claims a segment is a whole\n // document, and rendering a layout-less page as the document root does\n // not warn — it hangs the renderer.\n // A prefetch that lands on a redirect is not cached. Following it would\n // navigate on hover, and storing it would hand the click a 204 with no\n // body to deserialize. The click re-requests and redirects properly.\n const redirectTo = response.headers.get(\"X-RSC-Redirect\");\n\n if (redirectTo) {\n // The guard's answer is kept, for the entry's TTL, and the\n // destination is prefetched now. A tap on the link then goes\n // straight to a payload already here: no request for the page the\n // visitor may not see, none for the one they will. Before this,\n // every tap on a guarded link paid the guard's round trip and the\n // destination's, in sequence - on a phone, the two slowest things a\n // navigation can do, and the port's \"Sign in is slow from home\".\n // Next's prefetch follows the redirect the same way.\n entry.redirectTo = redirectTo;\n\n if (!isExternalUrl(redirectTo) && isSafeRedirect(redirectTo)) prefetch(redirectTo, ttl);\n\n return null;\n }\n\n entry.slot = response.headers.get(\"X-RSC-Revalidate\");\n\n const local = staticFetches.get(response) ?? null;\n\n entry.segmentDepth =\n Number(\n response.headers.get(\"X-RSC-Segment-Depth\") ?? local?.depth ?? 0,\n ) || 0;\n\n const served = response.headers.get(\"X-RSC-Layouts\");\n\n if (served !== null) {\n entry.layouts = served === \"\" ? [] : served.split(\",\");\n } else if (local) {\n entry.layouts = local.chain;\n }\n\n // Marked public: the build's bytes, the same for everyone, and held\n // for as long as Next holds a static page - unless the link said how\n // long. A deploy is caught by the version handshake, not by the clock.\n if (\n !held.explicitTtl &&\n /\\bpublic\\b/.test(response.headers.get(\"Cache-Control\") ?? \"\")\n ) {\n entry.expiresAt = Math.max(entry.expiresAt, Date.now() + STATIC_PREFETCH_TTL);\n }\n\n // The bytes, not the page: decoding is the navigation's, see CacheEntry\n // - unless the visitor is already on the way, see prefetch(). The\n // pictures the page shows are asked for now, though: on a phone they\n // take longer than the touch-to-click a hidden render has.\n return response.text().then((text) => {\n preloadImages(text);\n // And the code for its client components, so the first visit to a\n // page does not wait on a chunk after it has arrived.\n preloadChunks(text);\n\n return text;\n });\n })\n .catch(() => {\n entry.failed = true;\n cache.delete(cacheKey);\n return null;\n })\n .finally(() => {\n // Settled, so there is nothing left to abort. A completed prefetch stays\n // in the cache — only an in-flight one is ever dropped.\n if (prefetchControllers.get(cacheKey) === controller) {\n prefetchControllers.delete(cacheKey);\n }\n });\n\n cache.set(cacheKey, entry);\n\n if (held.intent) warm(entry, cacheKey);\n}\n\n/**\n * Drop a prefetch that is still in flight — the pointer left the link.\n *\n * The cache entry goes synchronously rather than in the abort's catch: the\n * rejection lands a tick later, and a click in between would find an entry\n * whose tree resolves to null and navigate to a blank page. A prefetch that\n * has already completed is kept; there is no request left to cancel and the\n * payload is still good.\n */\nexport function cancelPrefetch(url: string): void {\n if (isExternalUrl(url)) return;\n\n const interceptSlot = matchIntercept(url);\n const cacheKey = retentionKeyFor(url, interceptSlot);\n const controller = prefetchControllers.get(cacheKey);\n\n if (!controller) return;\n\n prefetchControllers.delete(cacheKey);\n cache.delete(cacheKey);\n controller.abort();\n}\n"]}
|
package/dist/vite.js
CHANGED
|
@@ -849,43 +849,6 @@ const INSTALL_FETCH_MS = 30000
|
|
|
849
849
|
const within = (ms, promise) =>
|
|
850
850
|
Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject(new Error('no answer in ' + ms + ' ms')), ms))])
|
|
851
851
|
|
|
852
|
-
// The same limit, and the download stopped when it is reached. A race only
|
|
853
|
-
// stops the waiting: the fetch it gave up on went on downloading beside
|
|
854
|
-
// everything after it.
|
|
855
|
-
const abortable = (ms, start) => {
|
|
856
|
-
const controller = new AbortController()
|
|
857
|
-
const timer = setTimeout(() => controller.abort(), ms)
|
|
858
|
-
|
|
859
|
-
return within(ms, start(controller.signal)).finally(() => clearTimeout(timer))
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
// How many precache downloads run together. The page a visitor is looking at
|
|
863
|
-
// comes first; the precache is for the next visit.
|
|
864
|
-
const PRECACHE_AT_ONCE = 4
|
|
865
|
-
|
|
866
|
-
// Run a task over every item, at most limit of them at a time. Resolves once
|
|
867
|
-
// all have settled; a task that fails is its own business.
|
|
868
|
-
const pool = (items, limit, task) =>
|
|
869
|
-
new Promise((resolve) => {
|
|
870
|
-
let next = 0
|
|
871
|
-
let running = 0
|
|
872
|
-
const launch = () => {
|
|
873
|
-
if (next >= items.length && running === 0) return resolve()
|
|
874
|
-
|
|
875
|
-
while (running < limit && next < items.length) {
|
|
876
|
-
running++
|
|
877
|
-
Promise.resolve(task(items[next++]))
|
|
878
|
-
.catch(() => {})
|
|
879
|
-
.finally(() => {
|
|
880
|
-
running--
|
|
881
|
-
launch()
|
|
882
|
-
})
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
launch()
|
|
887
|
-
})
|
|
888
|
-
|
|
889
852
|
self.addEventListener('install', (event) => {
|
|
890
853
|
// The new worker takes over rather than waiting for every tab to close.
|
|
891
854
|
// Safe here because assets are content-hashed: a page already open keeps
|
|
@@ -899,33 +862,22 @@ self.addEventListener('install', (event) => {
|
|
|
899
862
|
// worker cannot see. Added here so it is in the cache before it is
|
|
900
863
|
// needed, which is the only moment it cannot be fetched.
|
|
901
864
|
//
|
|
902
|
-
//
|
|
903
|
-
// for one failure - and a worker whose install rejects is never
|
|
865
|
+
// Each file on its own rather than cache.addAll, which rejects the whole
|
|
866
|
+
// list for one failure - and a worker whose install rejects is never
|
|
904
867
|
// installed. The worker before it then stays in charge, serving its own
|
|
905
868
|
// build's pages, for every visit until one install happens to succeed:
|
|
906
|
-
// a network blip, a quota, a file a deploy replaced mid-install
|
|
907
|
-
// phone kept a worker from builds ago whose bugs had long been fixed.
|
|
869
|
+
// a network blip, a quota, a file a deploy replaced mid-install.
|
|
908
870
|
// A file that did not arrive costs a cache entry; the update still
|
|
909
871
|
// lands. The browser checks /sw.js for itself, without the page's
|
|
910
872
|
// javascript, so an install that cannot fail is also what rescues a
|
|
911
873
|
// visitor stuck on a worker far older than this one.
|
|
912
|
-
//
|
|
913
|
-
// A few at a time and at low priority, never all at once. An install
|
|
914
|
-
// runs beside the page that triggered it - the first visit after a
|
|
915
|
-
// deploy - and a hundred and seventy files requested together queued
|
|
916
|
-
// that page's own requests behind them: on a phone, the page sat
|
|
917
|
-
// unhydrated for about forty seconds, until the precache had finished.
|
|
918
874
|
.then((cache) =>
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
return cache.put(url, response)
|
|
875
|
+
Promise.all(
|
|
876
|
+
(OFFLINE_URL ? [...PRECACHE, OFFLINE_URL] : PRECACHE).map((url) =>
|
|
877
|
+
within(INSTALL_FETCH_MS, cache.add(url)).catch((error) => {
|
|
878
|
+
console.warn('[rsc-kit] offline: ' + url + ' was not precached (' + (error && error.message || error) + '); it will be cached the first time it is fetched')
|
|
925
879
|
}),
|
|
926
|
-
)
|
|
927
|
-
console.warn('[rsc-kit] offline: ' + url + ' was not precached (' + (error && error.message || error) + '); it will be cached the first time it is fetched')
|
|
928
|
-
}),
|
|
880
|
+
),
|
|
929
881
|
).then(() => cache),
|
|
930
882
|
)
|
|
931
883
|
// And the payload each precached page boots from. A document alone is
|