Rocky_Mountain_Vending/.pnpm-store/v10/files/b7/9450b6f2fc1ae402b13b2a92075df5af4dcefb73997f10982c7a4b16d709aab7eaf56b16e0520eff83dfc038ccfad082fce8b0af9d8df8f4a8ec3bf70d11e3
DMleadgen 46d973904b
Initial commit: Rocky Mountain Vending website
Next.js website for Rocky Mountain Vending company featuring:
- Product catalog with Stripe integration
- Service areas and parts pages
- Admin dashboard with Clerk authentication
- SEO optimized pages with JSON-LD structured data

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 16:22:15 -07:00

1 line
No EOL
119 KiB
Text

{"version":3,"sources":["../../../../src/client/components/segment-cache-impl/cache.ts"],"sourcesContent":["import type {\n TreePrefetch,\n RootTreePrefetch,\n SegmentPrefetch,\n} from '../../../server/app-render/collect-segment-data'\nimport type {\n HeadData,\n LoadingModuleData,\n} from '../../../shared/lib/app-router-types'\nimport type {\n CacheNodeSeedData,\n DynamicParamTypesShort,\n Segment as FlightRouterStateSegment,\n} from '../../../shared/lib/app-router-types'\nimport { HasLoadingBoundary } from '../../../shared/lib/app-router-types'\nimport {\n NEXT_DID_POSTPONE_HEADER,\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_ROUTER_STALE_TIME_HEADER,\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_URL,\n RSC_CONTENT_TYPE_HEADER,\n RSC_HEADER,\n} from '../app-router-headers'\nimport {\n createFetch,\n createFromNextReadableStream,\n type RSCResponse,\n type RequestHeaders,\n} from '../router-reducer/fetch-server-response'\nimport {\n pingPrefetchTask,\n isPrefetchTaskDirty,\n type PrefetchTask,\n type PrefetchSubtaskResult,\n startRevalidationCooldown,\n} from './scheduler'\nimport { getAppBuildId } from '../../app-build-id'\nimport { createHrefFromUrl } from '../router-reducer/create-href-from-url'\nimport type {\n NormalizedHref,\n NormalizedNextUrl,\n NormalizedSearch,\n RouteCacheKey,\n} from './cache-key'\n// TODO: Rename this module to avoid confusion with other types of cache keys\nimport { createCacheKey as createPrefetchRequestKey } from './cache-key'\nimport {\n doesStaticSegmentAppearInURL,\n getCacheKeyForDynamicParam,\n getParamValueFromCacheKey,\n getRenderedPathname,\n getRenderedSearch,\n parseDynamicParamFromURLPart,\n type RouteParam,\n} from '../../route-params'\nimport { createTupleMap, type TupleMap, type Prefix } from './tuple-map'\nimport { createLRU } from './lru'\nimport {\n appendSegmentCacheKeyPart,\n appendSegmentRequestKeyPart,\n convertSegmentPathToStaticExportFilename,\n createSegmentCacheKeyPart,\n createSegmentRequestKeyPart,\n ROOT_SEGMENT_CACHE_KEY,\n ROOT_SEGMENT_REQUEST_KEY,\n type SegmentCacheKey,\n type SegmentRequestKey,\n} from '../../../shared/lib/segment-cache/segment-value-encoding'\nimport type {\n FlightRouterState,\n NavigationFlightResponse,\n} from '../../../shared/lib/app-router-types'\nimport {\n normalizeFlightData,\n prepareFlightRouterStateForRequest,\n} from '../../flight-data-helpers'\nimport { STATIC_STALETIME_MS } from '../router-reducer/reducers/navigate-reducer'\nimport { pingVisibleLinks } from '../links'\nimport { PAGE_SEGMENT_KEY } from '../../../shared/lib/segment'\nimport {\n DOC_PREFETCH_RANGE_HEADER_VALUE,\n doesExportedHtmlMatchBuildId,\n} from '../../../shared/lib/segment-cache/output-export-prefetch-encoding'\nimport { FetchStrategy } from '../segment-cache'\nimport { createPromiseWithResolvers } from '../../../shared/lib/promise-with-resolvers'\n\n// A note on async/await when working in the prefetch cache:\n//\n// Most async operations in the prefetch cache should *not* use async/await,\n// Instead, spawn a subtask that writes the results to a cache entry, and attach\n// a \"ping\" listener to notify the prefetch queue to try again.\n//\n// The reason is we need to be able to access the segment cache and traverse its\n// data structures synchronously. For example, if there's a synchronous update\n// we can take an immediate snapshot of the cache to produce something we can\n// render. Limiting the use of async/await also makes it easier to avoid race\n// conditions, which is especially important because is cache is mutable.\n//\n// Another reason is that while we're performing async work, it's possible for\n// existing entries to become stale, or for Link prefetches to be removed from\n// the queue. For optimal scheduling, we need to be able to \"cancel\" subtasks\n// that are no longer needed. So, when a segment is received from the server, we\n// restart from the root of the tree that's being prefetched, to confirm all the\n// parent segments are still cached. If the segment is no longer reachable from\n// the root, then it's effectively canceled. This is similar to the design of\n// Rust Futures, or React Suspense.\n\nexport type RouteTree = {\n cacheKey: SegmentCacheKey\n requestKey: SegmentRequestKey\n // TODO: Remove the `segment` field, now that it can be reconstructed\n // from `param`.\n segment: FlightRouterStateSegment\n param: RouteParam | null\n slots: null | {\n [parallelRouteKey: string]: RouteTree\n }\n isRootLayout: boolean\n\n // If this is a dynamic route, indicates whether there is a loading boundary\n // somewhere in the tree. If not, we can skip the prefetch for the data,\n // because we know it would be an empty response. (For a static/PPR route,\n // this value is disregarded, because in that model `loading.tsx` is treated\n // like any other Suspense boundary.)\n hasLoadingBoundary: HasLoadingBoundary\n\n // Indicates whether this route has a runtime prefetch that we can request.\n // This is determined by the server; it's not purely a user configuration\n // because the server may determine that a route is fully static and doesn't\n // need runtime prefetching regardless of the configuration.\n hasRuntimePrefetch: boolean\n}\n\ntype RouteCacheEntryShared = {\n staleAt: number\n // This is false only if we're certain the route cannot be intercepted. It's\n // true in all other cases, including on initialization when we haven't yet\n // received a response from the server.\n couldBeIntercepted: boolean\n\n // See comment in scheduler.ts for context\n TODO_metadataStatus: EntryStatus.Empty | EntryStatus.Fulfilled\n TODO_isHeadDynamic: boolean\n\n // LRU-related fields\n keypath: null | Prefix<RouteCacheKeypath>\n next: null | RouteCacheEntry\n prev: null | RouteCacheEntry\n size: number\n}\n\n/**\n * Tracks the status of a cache entry as it progresses from no data (Empty),\n * waiting for server data (Pending), and finished (either Fulfilled or\n * Rejected depending on the response from the server.\n */\nexport const enum EntryStatus {\n Empty = 0,\n Pending = 1,\n Fulfilled = 2,\n Rejected = 3,\n}\n\ntype PendingRouteCacheEntry = RouteCacheEntryShared & {\n status: EntryStatus.Empty | EntryStatus.Pending\n blockedTasks: Set<PrefetchTask> | null\n canonicalUrl: null\n renderedSearch: null\n tree: null\n head: HeadData | null\n isHeadPartial: true\n isPPREnabled: false\n}\n\ntype RejectedRouteCacheEntry = RouteCacheEntryShared & {\n status: EntryStatus.Rejected\n blockedTasks: Set<PrefetchTask> | null\n canonicalUrl: null\n renderedSearch: null\n tree: null\n head: null\n isHeadPartial: true\n isPPREnabled: boolean\n}\n\nexport type FulfilledRouteCacheEntry = RouteCacheEntryShared & {\n status: EntryStatus.Fulfilled\n blockedTasks: null\n canonicalUrl: string\n renderedSearch: NormalizedSearch\n tree: RouteTree\n head: HeadData\n isHeadPartial: boolean\n isPPREnabled: boolean\n}\n\nexport type RouteCacheEntry =\n | PendingRouteCacheEntry\n | FulfilledRouteCacheEntry\n | RejectedRouteCacheEntry\n\ntype SegmentCacheEntryShared = {\n staleAt: number\n fetchStrategy: FetchStrategy\n revalidating: SegmentCacheEntry | null\n\n // LRU-related fields\n keypath: null | Prefix<SegmentCacheKeypath>\n next: null | SegmentCacheEntry\n prev: null | SegmentCacheEntry\n size: number\n}\n\nexport type EmptySegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Empty\n rsc: null\n loading: null\n isPartial: true\n promise: null\n}\n\nexport type PendingSegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Pending\n rsc: null\n loading: null\n isPartial: true\n promise: null | PromiseWithResolvers<FulfilledSegmentCacheEntry | null>\n}\n\ntype RejectedSegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Rejected\n rsc: null\n loading: null\n isPartial: true\n promise: null\n}\n\nexport type FulfilledSegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Fulfilled\n rsc: React.ReactNode | null\n loading: LoadingModuleData | Promise<LoadingModuleData>\n isPartial: boolean\n promise: null\n}\n\nexport type SegmentCacheEntry =\n | EmptySegmentCacheEntry\n | PendingSegmentCacheEntry\n | RejectedSegmentCacheEntry\n | FulfilledSegmentCacheEntry\n\nexport type NonEmptySegmentCacheEntry = Exclude<\n SegmentCacheEntry,\n EmptySegmentCacheEntry\n>\n\nconst isOutputExportMode =\n process.env.NODE_ENV === 'production' &&\n process.env.__NEXT_CONFIG_OUTPUT === 'export'\n\n/**\n * Ensures a minimum stale time of 30s to avoid issues where the server sends a too\n * short-lived stale time, which would prevent anything from being prefetched.\n */\nfunction getStaleTimeMs(staleTimeSeconds: number): number {\n return Math.max(staleTimeSeconds, 30) * 1000\n}\n\n// Route cache entries vary on multiple keys: the href and the Next-Url. Each of\n// these parts needs to be included in the internal cache key. Rather than\n// concatenate the keys into a single key, we use a multi-level map, where the\n// first level is keyed by href, the second level is keyed by Next-Url, and so\n// on (if were to add more levels).\ntype RouteCacheKeypath = [NormalizedHref, NormalizedNextUrl]\nlet routeCacheMap: TupleMap<RouteCacheKeypath, RouteCacheEntry> =\n createTupleMap()\n\n// We use an LRU for memory management. We must update this whenever we add or\n// remove a new cache entry, or when an entry changes size.\n// TODO: I chose the max size somewhat arbitrarily. Consider setting this based\n// on navigator.deviceMemory, or some other heuristic. We should make this\n// customizable via the Next.js config, too.\nconst maxRouteLruSize = 10 * 1024 * 1024 // 10 MB\nlet routeCacheLru = createLRU<RouteCacheEntry>(\n maxRouteLruSize,\n onRouteLRUEviction\n)\n\ntype SegmentCacheKeypath = [string, NormalizedSearch]\nlet segmentCacheMap: TupleMap<SegmentCacheKeypath, SegmentCacheEntry> =\n createTupleMap()\n// NOTE: Segments and Route entries are managed by separate LRUs. We could\n// combine them into a single LRU, but because they are separate types, we'd\n// need to wrap each one in an extra LRU node (to maintain monomorphism, at the\n// cost of additional memory).\nconst maxSegmentLruSize = 50 * 1024 * 1024 // 50 MB\nlet segmentCacheLru = createLRU<SegmentCacheEntry>(\n maxSegmentLruSize,\n onSegmentLRUEviction\n)\n\n// All invalidation listeners for the whole cache are tracked in single set.\n// Since we don't yet support tag or path-based invalidation, there's no point\n// tracking them any more granularly than this. Once we add granular\n// invalidation, that may change, though generally the model is to just notify\n// the listeners and allow the caller to poll the prefetch cache with a new\n// prefetch task if desired.\nlet invalidationListeners: Set<PrefetchTask> | null = null\n\n// Incrementing counter used to track cache invalidations.\nlet currentCacheVersion = 0\n\nexport function getCurrentCacheVersion(): number {\n return currentCacheVersion\n}\n\n/**\n * Used to clear the client prefetch cache when a server action calls\n * revalidatePath or revalidateTag. Eventually we will support only clearing the\n * segments that were actually affected, but there's more work to be done on the\n * server before the client is able to do this correctly.\n */\nexport function revalidateEntireCache(\n nextUrl: string | null,\n tree: FlightRouterState\n) {\n currentCacheVersion++\n\n // Start a cooldown before re-prefetching to allow CDN cache propagation.\n startRevalidationCooldown()\n\n // Clearing the cache also effectively rejects any pending requests, because\n // when the response is received, it gets written into a cache entry that is\n // no longer reachable.\n // TODO: There's an exception to this case that we don't currently handle\n // correctly: background revalidations. See note in `upsertSegmentEntry`.\n routeCacheMap = createTupleMap()\n routeCacheLru = createLRU(maxRouteLruSize, onRouteLRUEviction)\n segmentCacheMap = createTupleMap()\n segmentCacheLru = createLRU(maxSegmentLruSize, onSegmentLRUEviction)\n\n // Prefetch all the currently visible links again, to re-fill the cache.\n pingVisibleLinks(nextUrl, tree)\n\n // Similarly, notify all invalidation listeners (i.e. those passed to\n // `router.prefetch(onInvalidate)`), so they can trigger a new prefetch\n // if needed.\n pingInvalidationListeners(nextUrl, tree)\n}\n\nfunction attachInvalidationListener(task: PrefetchTask): void {\n // This function is called whenever a prefetch task reads a cache entry. If\n // the task has an onInvalidate function associated with it — i.e. the one\n // optionally passed to router.prefetch(onInvalidate) — then we attach that\n // listener to the every cache entry that the task reads. Then, if an entry\n // is invalidated, we call the function.\n if (task.onInvalidate !== null) {\n if (invalidationListeners === null) {\n invalidationListeners = new Set([task])\n } else {\n invalidationListeners.add(task)\n }\n }\n}\n\nfunction notifyInvalidationListener(task: PrefetchTask): void {\n const onInvalidate = task.onInvalidate\n if (onInvalidate !== null) {\n // Clear the callback from the task object to guarantee it's not called more\n // than once.\n task.onInvalidate = null\n\n // This is a user-space function, so we must wrap in try/catch.\n try {\n onInvalidate()\n } catch (error) {\n if (typeof reportError === 'function') {\n reportError(error)\n } else {\n console.error(error)\n }\n }\n }\n}\n\nexport function pingInvalidationListeners(\n nextUrl: string | null,\n tree: FlightRouterState\n): void {\n // The rough equivalent of pingVisibleLinks, but for onInvalidate callbacks.\n // This is called when the Next-Url or the base tree changes, since those\n // may affect the result of a prefetch task. It's also called after a\n // cache invalidation.\n if (invalidationListeners !== null) {\n const tasks = invalidationListeners\n invalidationListeners = null\n for (const task of tasks) {\n if (isPrefetchTaskDirty(task, nextUrl, tree)) {\n notifyInvalidationListener(task)\n }\n }\n }\n}\n\nexport function readExactRouteCacheEntry(\n now: number,\n href: NormalizedHref,\n nextUrl: NormalizedNextUrl | null\n): RouteCacheEntry | null {\n const keypath: Prefix<RouteCacheKeypath> =\n nextUrl === null ? [href] : [href, nextUrl]\n const existingEntry = routeCacheMap.get(keypath)\n if (existingEntry !== null) {\n // Check if the entry is stale\n if (existingEntry.staleAt > now) {\n // Reuse the existing entry.\n\n // Since this is an access, move the entry to the front of the LRU.\n routeCacheLru.put(existingEntry)\n\n return existingEntry\n } else {\n // Evict the stale entry from the cache.\n deleteRouteFromCache(existingEntry, keypath)\n }\n }\n return null\n}\n\nexport function readRouteCacheEntry(\n now: number,\n key: RouteCacheKey\n): RouteCacheEntry | null {\n // First check if there's a non-intercepted entry. Most routes cannot be\n // intercepted, so this is the common case.\n const nonInterceptedEntry = readExactRouteCacheEntry(now, key.href, null)\n if (nonInterceptedEntry !== null && !nonInterceptedEntry.couldBeIntercepted) {\n // Found a match, and the route cannot be intercepted. We can reuse it.\n return nonInterceptedEntry\n }\n // There was no match. Check again but include the Next-Url this time.\n return readExactRouteCacheEntry(now, key.href, key.nextUrl)\n}\n\nexport function getSegmentKeypath(\n fetchStrategy: FetchStrategy,\n route: FulfilledRouteCacheEntry,\n cacheKey: SegmentCacheKey\n): Prefix<SegmentCacheKeypath> {\n // When a prefetch includes dynamic data, the search params are included\n // in the result, so we must include the search string in the segment\n // cache key. (Note that this is true even if the search string is empty.)\n //\n // If we're fetching using PPR, we do not need to include the search params in\n // the cache key, because the search params are treated as dynamic data. The\n // cache entry is valid for all possible search param values.\n const isDynamic =\n fetchStrategy === FetchStrategy.Full ||\n fetchStrategy === FetchStrategy.PPRRuntime ||\n !route.isPPREnabled\n return isDynamic && cacheKey.endsWith('/' + PAGE_SEGMENT_KEY)\n ? [cacheKey, route.renderedSearch]\n : [cacheKey]\n}\n\nexport function readSegmentCacheEntry(\n now: number,\n route: FulfilledRouteCacheEntry,\n cacheKey: SegmentCacheKey\n): SegmentCacheEntry | null {\n if (!cacheKey.endsWith('/' + PAGE_SEGMENT_KEY)) {\n // Fast path. Search params only exist on page segments.\n return readExactSegmentCacheEntry(now, [cacheKey])\n }\n\n const renderedSearch = route.renderedSearch\n if (renderedSearch !== null) {\n // Page segments may or may not contain search params. If they were prefetched\n // using a dynamic request, then we will have an entry with search params.\n // Check for that case first.\n const entryWithSearchParams = readExactSegmentCacheEntry(now, [\n cacheKey,\n renderedSearch,\n ])\n if (entryWithSearchParams !== null) {\n return entryWithSearchParams\n }\n }\n\n // If we did not find an entry with the given search params, check for a\n // \"fallback\" entry, where the search params are treated as dynamic data. This\n // is the common case because PPR/static prerenders always treat search params\n // as dynamic.\n //\n // See corresponding logic in `getSegmentKeypath`.\n const entryWithoutSearchParams = readExactSegmentCacheEntry(now, [cacheKey])\n return entryWithoutSearchParams\n}\n\nfunction readExactSegmentCacheEntry(\n now: number,\n keypath: Prefix<SegmentCacheKeypath>\n): SegmentCacheEntry | null {\n const existingEntry = segmentCacheMap.get(keypath)\n if (existingEntry !== null) {\n // Check if the entry is stale\n if (existingEntry.staleAt > now) {\n // Reuse the existing entry.\n\n // Since this is an access, move the entry to the front of the LRU.\n segmentCacheLru.put(existingEntry)\n\n return existingEntry\n } else {\n // This is a stale entry.\n const revalidatingEntry = existingEntry.revalidating\n if (revalidatingEntry !== null) {\n // There's a revalidation in progress. Upsert it.\n const upsertedEntry = upsertSegmentEntry(\n now,\n keypath,\n revalidatingEntry\n )\n if (upsertedEntry !== null && upsertedEntry.staleAt > now) {\n // We can use the upserted revalidation entry.\n return upsertedEntry\n }\n } else {\n // Evict the stale entry from the cache.\n deleteSegmentFromCache(existingEntry, keypath)\n }\n }\n }\n return null\n}\n\nfunction readRevalidatingSegmentCacheEntry(\n now: number,\n owner: SegmentCacheEntry\n): SegmentCacheEntry | null {\n const existingRevalidation = owner.revalidating\n if (existingRevalidation !== null) {\n if (existingRevalidation.staleAt > now) {\n // There's already a revalidation in progress. Or a previous revalidation\n // failed and it has not yet expired.\n return existingRevalidation\n } else {\n // Clear the stale revalidation from its owner.\n clearRevalidatingSegmentFromOwner(owner)\n }\n }\n return null\n}\n\nexport function waitForSegmentCacheEntry(\n pendingEntry: PendingSegmentCacheEntry\n): Promise<FulfilledSegmentCacheEntry | null> {\n // Because the entry is pending, there's already a in-progress request.\n // Attach a promise to the entry that will resolve when the server responds.\n let promiseWithResolvers = pendingEntry.promise\n if (promiseWithResolvers === null) {\n promiseWithResolvers = pendingEntry.promise =\n createPromiseWithResolvers<FulfilledSegmentCacheEntry | null>()\n } else {\n // There's already a promise we can use\n }\n return promiseWithResolvers.promise\n}\n\n/**\n * Checks if an entry for a route exists in the cache. If so, it returns the\n * entry, If not, it adds an empty entry to the cache and returns it.\n */\nexport function readOrCreateRouteCacheEntry(\n now: number,\n task: PrefetchTask,\n key: RouteCacheKey\n): RouteCacheEntry {\n attachInvalidationListener(task)\n\n const existingEntry = readRouteCacheEntry(now, key)\n if (existingEntry !== null) {\n return existingEntry\n }\n // Create a pending entry and add it to the cache.\n const pendingEntry: PendingRouteCacheEntry = {\n canonicalUrl: null,\n status: EntryStatus.Empty,\n blockedTasks: null,\n tree: null,\n head: null,\n isHeadPartial: true,\n // Since this is an empty entry, there's no reason to ever evict it. It will\n // be updated when the data is populated.\n staleAt: Infinity,\n // This is initialized to true because we don't know yet whether the route\n // could be intercepted. It's only set to false once we receive a response\n // from the server.\n couldBeIntercepted: true,\n // Similarly, we don't yet know if the route supports PPR.\n isPPREnabled: false,\n renderedSearch: null,\n\n TODO_metadataStatus: EntryStatus.Empty,\n TODO_isHeadDynamic: false,\n\n // LRU-related fields\n keypath: null,\n next: null,\n prev: null,\n size: 0,\n }\n const keypath: Prefix<RouteCacheKeypath> =\n key.nextUrl === null ? [key.href] : [key.href, key.nextUrl]\n routeCacheMap.set(keypath, pendingEntry)\n // Stash the keypath on the entry so we know how to remove it from the map\n // if it gets evicted from the LRU.\n pendingEntry.keypath = keypath\n routeCacheLru.put(pendingEntry)\n return pendingEntry\n}\n\nexport function requestOptimisticRouteCacheEntry(\n now: number,\n requestedUrl: URL,\n nextUrl: string | null\n): FulfilledRouteCacheEntry | null {\n // This function is called during a navigation when there was no matching\n // route tree in the prefetch cache. Before de-opting to a blocking,\n // unprefetched navigation, we will first attempt to construct an \"optimistic\"\n // route tree by checking the cache for similar routes.\n //\n // Check if there's a route with the same pathname, but with different\n // search params. We can then base our optimistic route tree on this entry.\n //\n // Conceptually, we are simulating what would happen if we did perform a\n // prefetch the requested URL, under the assumption that the server will\n // not redirect or rewrite the request in a different manner than the\n // base route tree. This assumption might not hold, in which case we'll have\n // to recover when we perform the dynamic navigation request. However, this\n // is what would happen if a route were dynamically rewritten/redirected\n // in between the prefetch and the navigation. So the logic needs to exist\n // to handle this case regardless.\n\n // Look for a route with the same pathname, but with an empty search string.\n // TODO: There's nothing inherently special about the empty search string;\n // it's chosen somewhat arbitrarily, with the rationale that it's the most\n // likely one to exist. But we should update this to match _any_ search\n // string. The plan is to generalize this logic alongside other improvements\n // related to \"fallback\" cache entries.\n const requestedSearch = requestedUrl.search as NormalizedSearch\n if (requestedSearch === '') {\n // The caller would have already checked if a route with an empty search\n // string is in the cache. So we can bail out here.\n return null\n }\n const urlWithoutSearchParams = new URL(requestedUrl)\n urlWithoutSearchParams.search = ''\n const routeWithNoSearchParams = readRouteCacheEntry(\n now,\n createPrefetchRequestKey(urlWithoutSearchParams.href, nextUrl)\n )\n\n if (\n routeWithNoSearchParams === null ||\n routeWithNoSearchParams.status !== EntryStatus.Fulfilled\n ) {\n // Bail out of constructing an optimistic route tree. This will result in\n // a blocking, unprefetched navigation.\n return null\n }\n\n // Now we have a base route tree we can \"patch\" with our optimistic values.\n\n const TODO_isHeadDynamic = routeWithNoSearchParams.TODO_isHeadDynamic\n let head\n let isHeadPartial\n let TODO_metadataStatus: EntryStatus.Empty | EntryStatus.Fulfilled\n if (TODO_isHeadDynamic) {\n // If the head was fetched via dynamic request, then we don't know\n // whether it accessed search params. So we must be conservative — we\n // cannot reuse it. The head will stream in during the dynamic navigation.\n // TODO: When Cache Components is enabled, we should track whether the\n // head varied on search params.\n // TODO: Because we're rendering a `null` viewport as the partial state, the\n // viewport will not block the navigation; it will stream in later,\n // alongside the metadata. Viewport is supposed to be blocking. This is\n // a subtle bug in the old implementation that we've preserved here. It's\n // rare enough that we're not going to fix it for apps that don't enable\n // Cache Components; when Cache Components is enabled, though, we should\n // use an infinite promise here to block the navigation. But only if the\n // entry actually varies on search params.\n head = [null, null]\n // Setting this to `true` ensures that on navigation, the head is requested.\n isHeadPartial = true\n TODO_metadataStatus = EntryStatus.Empty\n } else {\n // The head was fetched via a static/PPR request. So it's guaranteed to\n // not contain search params. We can reuse it.\n head = routeWithNoSearchParams.head\n isHeadPartial = routeWithNoSearchParams.isHeadPartial\n TODO_metadataStatus = EntryStatus.Empty\n }\n\n // Optimistically assume that redirects for the requested pathname do\n // not vary on the search string. Therefore, if the base route was\n // redirected to a different search string, then the optimistic route\n // should be redirected to the same search string. Otherwise, we use\n // the requested search string.\n const canonicalUrlForRouteWithNoSearchParams = new URL(\n routeWithNoSearchParams.canonicalUrl,\n requestedUrl.origin\n )\n const optimisticCanonicalSearch =\n canonicalUrlForRouteWithNoSearchParams.search !== ''\n ? // Base route was redirected. Reuse the same redirected search string.\n canonicalUrlForRouteWithNoSearchParams.search\n : requestedSearch\n\n // Similarly, optimistically assume that rewrites for the requested\n // pathname do not vary on the search string. Therefore, if the base\n // route was rewritten to a different search string, then the optimistic\n // route should be rewritten to the same search string. Otherwise, we use\n // the requested search string.\n const optimisticRenderedSearch =\n routeWithNoSearchParams.renderedSearch !== ''\n ? // Base route was rewritten. Reuse the same rewritten search string.\n routeWithNoSearchParams.renderedSearch\n : requestedSearch\n\n const optimisticUrl = new URL(\n routeWithNoSearchParams.canonicalUrl,\n location.origin\n )\n optimisticUrl.search = optimisticCanonicalSearch\n const optimisticCanonicalUrl = createHrefFromUrl(optimisticUrl)\n\n // Clone the base route tree, and override the relevant fields with our\n // optimistic values.\n const optimisticEntry: FulfilledRouteCacheEntry = {\n canonicalUrl: optimisticCanonicalUrl,\n\n status: EntryStatus.Fulfilled,\n // This isn't cloned because it's instance-specific\n blockedTasks: null,\n tree: routeWithNoSearchParams.tree,\n head,\n isHeadPartial,\n staleAt: routeWithNoSearchParams.staleAt,\n couldBeIntercepted: routeWithNoSearchParams.couldBeIntercepted,\n isPPREnabled: routeWithNoSearchParams.isPPREnabled,\n\n // Override the rendered search with the optimistic value.\n renderedSearch: optimisticRenderedSearch,\n\n TODO_metadataStatus,\n TODO_isHeadDynamic,\n\n // LRU-related fields\n keypath: null,\n next: null,\n prev: null,\n size: 0,\n }\n\n // Do not insert this entry into the cache. It only exists so we can\n // perform the current navigation. Just return it to the caller.\n return optimisticEntry\n}\n\n/**\n * Checks if an entry for a segment exists in the cache. If so, it returns the\n * entry, If not, it adds an empty entry to the cache and returns it.\n */\nexport function readOrCreateSegmentCacheEntry(\n now: number,\n fetchStrategy: FetchStrategy,\n route: FulfilledRouteCacheEntry,\n cacheKey: SegmentCacheKey\n): SegmentCacheEntry {\n const keypath = getSegmentKeypath(fetchStrategy, route, cacheKey)\n const existingEntry = readExactSegmentCacheEntry(now, keypath)\n if (existingEntry !== null) {\n return existingEntry\n }\n // Create a pending entry and add it to the cache.\n const pendingEntry = createDetachedSegmentCacheEntry(route.staleAt)\n segmentCacheMap.set(keypath, pendingEntry)\n // Stash the keypath on the entry so we know how to remove it from the map\n // if it gets evicted from the LRU.\n pendingEntry.keypath = keypath\n segmentCacheLru.put(pendingEntry)\n return pendingEntry\n}\n\nexport function readOrCreateRevalidatingSegmentEntry(\n now: number,\n prevEntry: SegmentCacheEntry\n): SegmentCacheEntry {\n const existingRevalidation = readRevalidatingSegmentCacheEntry(now, prevEntry)\n if (existingRevalidation !== null) {\n return existingRevalidation\n }\n const pendingEntry = createDetachedSegmentCacheEntry(prevEntry.staleAt)\n\n // Background revalidations are not stored directly in the cache map or LRU;\n // they're stashed on the entry that they will (potentially) replace.\n //\n // Note that we don't actually ever clear this field, except when the entry\n // expires. When the revalidation finishes, one of two things will happen:\n //\n // 1) the revalidation is successful, `prevEntry` is removed from the cache\n // and garbage collected (so there's no point clearing any of its fields)\n // 2) the revalidation fails, and we'll use the `revalidating` field to\n // prevent subsequent revalidation attempts, until it expires.\n prevEntry.revalidating = pendingEntry\n\n return pendingEntry\n}\n\nexport function upsertSegmentEntry(\n now: number,\n keypath: Prefix<SegmentCacheKeypath>,\n candidateEntry: SegmentCacheEntry\n): SegmentCacheEntry | null {\n // We have a new entry that has not yet been inserted into the cache. Before\n // we do so, we need to confirm whether it takes precedence over the existing\n // entry (if one exists).\n // TODO: We should not upsert an entry if its key was invalidated in the time\n // since the request was made. We can do that by passing the \"owner\" entry to\n // this function and confirming it's the same as `existingEntry`.\n const existingEntry = readExactSegmentCacheEntry(now, keypath)\n if (existingEntry !== null) {\n // Don't replace a more specific segment with a less-specific one. A case where this\n // might happen is if the existing segment was fetched via\n // `<Link prefetch={true}>`.\n if (\n // We fetched the new segment using a different, less specific fetch strategy\n // than the segment we already have in the cache, so it can't have more content.\n (candidateEntry.fetchStrategy !== existingEntry.fetchStrategy &&\n !canNewFetchStrategyProvideMoreContent(\n existingEntry.fetchStrategy,\n candidateEntry.fetchStrategy\n )) ||\n // The existing entry isn't partial, but the new one is.\n // (TODO: can this be true if `candidateEntry.fetchStrategy >= existingEntry.fetchStrategy`?)\n (!existingEntry.isPartial && candidateEntry.isPartial)\n ) {\n // We're going to leave the entry on the owner's `revalidating` field\n // so that it doesn't get revalidated again unnecessarily. Downgrade the\n // Fulfilled entry to Rejected and null out the data so it can be garbage\n // collected. We leave `staleAt` intact to prevent subsequent revalidation\n // attempts only until the entry expires.\n const rejectedEntry: RejectedSegmentCacheEntry = candidateEntry as any\n rejectedEntry.status = EntryStatus.Rejected\n rejectedEntry.loading = null\n rejectedEntry.rsc = null\n return null\n }\n\n // Evict the existing entry from the cache.\n deleteSegmentFromCache(existingEntry, keypath)\n }\n segmentCacheMap.set(keypath, candidateEntry)\n // Stash the keypath on the entry so we know how to remove it from the map\n // if it gets evicted from the LRU.\n candidateEntry.keypath = keypath\n segmentCacheLru.put(candidateEntry)\n return candidateEntry\n}\n\nexport function createDetachedSegmentCacheEntry(\n staleAt: number\n): EmptySegmentCacheEntry {\n const emptyEntry: EmptySegmentCacheEntry = {\n status: EntryStatus.Empty,\n // Default to assuming the fetch strategy will be PPR. This will be updated\n // when a fetch is actually initiated.\n fetchStrategy: FetchStrategy.PPR,\n revalidating: null,\n rsc: null,\n loading: null,\n staleAt,\n isPartial: true,\n promise: null,\n\n // LRU-related fields\n keypath: null,\n next: null,\n prev: null,\n size: 0,\n }\n return emptyEntry\n}\n\nexport function upgradeToPendingSegment(\n emptyEntry: EmptySegmentCacheEntry,\n fetchStrategy: FetchStrategy\n): PendingSegmentCacheEntry {\n const pendingEntry: PendingSegmentCacheEntry = emptyEntry as any\n pendingEntry.status = EntryStatus.Pending\n pendingEntry.fetchStrategy = fetchStrategy\n return pendingEntry\n}\n\nfunction deleteRouteFromCache(\n entry: RouteCacheEntry,\n keypath: Prefix<RouteCacheKeypath>\n): void {\n pingBlockedTasks(entry)\n routeCacheMap.delete(keypath)\n routeCacheLru.delete(entry)\n}\n\nfunction deleteSegmentFromCache(\n entry: SegmentCacheEntry,\n keypath: Prefix<SegmentCacheKeypath>\n): void {\n cancelEntryListeners(entry)\n segmentCacheMap.delete(keypath)\n segmentCacheLru.delete(entry)\n clearRevalidatingSegmentFromOwner(entry)\n}\n\nfunction clearRevalidatingSegmentFromOwner(owner: SegmentCacheEntry): void {\n // Revalidating segments are not stored in the cache directly; they're\n // stored as a field on the entry that they will (potentially) replace. So\n // to dispose of an existing revalidation, we just need to null out the field\n // on the owner.\n const revalidatingSegment = owner.revalidating\n if (revalidatingSegment !== null) {\n cancelEntryListeners(revalidatingSegment)\n owner.revalidating = null\n }\n}\n\nexport function resetRevalidatingSegmentEntry(\n owner: SegmentCacheEntry\n): EmptySegmentCacheEntry {\n clearRevalidatingSegmentFromOwner(owner)\n const emptyEntry = createDetachedSegmentCacheEntry(owner.staleAt)\n owner.revalidating = emptyEntry\n return emptyEntry\n}\n\nfunction onRouteLRUEviction(entry: RouteCacheEntry): void {\n // The LRU evicted this entry. Remove it from the map.\n const keypath = entry.keypath\n if (keypath !== null) {\n entry.keypath = null\n pingBlockedTasks(entry)\n routeCacheMap.delete(keypath)\n }\n}\n\nfunction onSegmentLRUEviction(entry: SegmentCacheEntry): void {\n // The LRU evicted this entry. Remove it from the map.\n const keypath = entry.keypath\n if (keypath !== null) {\n entry.keypath = null\n cancelEntryListeners(entry)\n segmentCacheMap.delete(keypath)\n }\n}\n\nfunction cancelEntryListeners(entry: SegmentCacheEntry): void {\n if (entry.status === EntryStatus.Pending && entry.promise !== null) {\n // There were listeners for this entry. Resolve them with `null` to indicate\n // that the prefetch failed. It's up to the listener to decide how to handle\n // this case.\n // NOTE: We don't currently propagate the reason the prefetch was canceled\n // but we could by accepting a `reason` argument.\n entry.promise.resolve(null)\n entry.promise = null\n }\n}\n\nfunction pingBlockedTasks(entry: {\n blockedTasks: Set<PrefetchTask> | null\n}): void {\n const blockedTasks = entry.blockedTasks\n if (blockedTasks !== null) {\n for (const task of blockedTasks) {\n pingPrefetchTask(task)\n }\n entry.blockedTasks = null\n }\n}\n\nfunction fulfillRouteCacheEntry(\n entry: RouteCacheEntry,\n tree: RouteTree,\n head: HeadData,\n isHeadPartial: boolean,\n staleAt: number,\n couldBeIntercepted: boolean,\n canonicalUrl: string,\n renderedSearch: NormalizedSearch,\n isPPREnabled: boolean,\n isHeadDynamic: boolean\n): FulfilledRouteCacheEntry {\n const fulfilledEntry: FulfilledRouteCacheEntry = entry as any\n fulfilledEntry.status = EntryStatus.Fulfilled\n fulfilledEntry.tree = tree\n fulfilledEntry.head = head\n fulfilledEntry.isHeadPartial = isHeadPartial\n fulfilledEntry.staleAt = staleAt\n fulfilledEntry.couldBeIntercepted = couldBeIntercepted\n fulfilledEntry.canonicalUrl = canonicalUrl\n fulfilledEntry.renderedSearch = renderedSearch\n fulfilledEntry.isPPREnabled = isPPREnabled\n fulfilledEntry.TODO_isHeadDynamic = isHeadDynamic\n pingBlockedTasks(entry)\n return fulfilledEntry\n}\n\nfunction fulfillSegmentCacheEntry(\n segmentCacheEntry: PendingSegmentCacheEntry,\n rsc: React.ReactNode,\n loading: LoadingModuleData | Promise<LoadingModuleData>,\n staleAt: number,\n isPartial: boolean\n): FulfilledSegmentCacheEntry {\n const fulfilledEntry: FulfilledSegmentCacheEntry = segmentCacheEntry as any\n fulfilledEntry.status = EntryStatus.Fulfilled\n fulfilledEntry.rsc = rsc\n fulfilledEntry.loading = loading\n fulfilledEntry.staleAt = staleAt\n fulfilledEntry.isPartial = isPartial\n // Resolve any listeners that were waiting for this data.\n if (segmentCacheEntry.promise !== null) {\n segmentCacheEntry.promise.resolve(fulfilledEntry)\n // Free the promise for garbage collection.\n fulfilledEntry.promise = null\n }\n return fulfilledEntry\n}\n\nfunction rejectRouteCacheEntry(\n entry: PendingRouteCacheEntry,\n staleAt: number\n): void {\n const rejectedEntry: RejectedRouteCacheEntry = entry as any\n rejectedEntry.status = EntryStatus.Rejected\n rejectedEntry.staleAt = staleAt\n pingBlockedTasks(entry)\n}\n\nfunction rejectSegmentCacheEntry(\n entry: PendingSegmentCacheEntry,\n staleAt: number\n): void {\n const rejectedEntry: RejectedSegmentCacheEntry = entry as any\n rejectedEntry.status = EntryStatus.Rejected\n rejectedEntry.staleAt = staleAt\n if (entry.promise !== null) {\n // NOTE: We don't currently propagate the reason the prefetch was canceled\n // but we could by accepting a `reason` argument.\n entry.promise.resolve(null)\n entry.promise = null\n }\n}\n\nfunction convertRootTreePrefetchToRouteTree(\n rootTree: RootTreePrefetch,\n renderedPathname: string\n) {\n // Remove trailing and leading slashes\n const pathnameParts = renderedPathname.split('/').filter((p) => p !== '')\n const index = 0\n const rootSegment = ROOT_SEGMENT_CACHE_KEY\n return convertTreePrefetchToRouteTree(\n rootTree.tree,\n rootSegment,\n null,\n ROOT_SEGMENT_REQUEST_KEY,\n ROOT_SEGMENT_CACHE_KEY,\n pathnameParts,\n index\n )\n}\n\nfunction convertTreePrefetchToRouteTree(\n prefetch: TreePrefetch,\n segment: FlightRouterStateSegment,\n param: RouteParam | null,\n requestKey: SegmentRequestKey,\n cacheKey: SegmentCacheKey,\n pathnameParts: Array<string>,\n pathnamePartsIndex: number\n): RouteTree {\n // Converts the route tree sent by the server into the format used by the\n // cache. The cached version of the tree includes additional fields, such as a\n // cache key for each segment. Since this is frequently accessed, we compute\n // it once instead of on every access. This same cache key is also used to\n // request the segment from the server.\n\n let slots: { [parallelRouteKey: string]: RouteTree } | null = null\n const prefetchSlots = prefetch.slots\n if (prefetchSlots !== null) {\n slots = {}\n for (let parallelRouteKey in prefetchSlots) {\n const childPrefetch = prefetchSlots[parallelRouteKey]\n const childParamName = childPrefetch.name\n const childParamType = childPrefetch.paramType\n const childServerSentParamKey = childPrefetch.paramKey\n\n let childDoesAppearInURL: boolean\n let childParam: RouteParam | null = null\n let childSegment: FlightRouterStateSegment\n if (childParamType !== null) {\n // This segment is parameterized. Get the param from the pathname.\n const childParamValue = parseDynamicParamFromURLPart(\n childParamType,\n pathnameParts,\n pathnamePartsIndex\n )\n\n // Assign a cache key to the segment, based on the param value. In the\n // pre-Segment Cache implementation, the server computes this and sends\n // it in the body of the response. In the Segment Cache implementation,\n // the server sends an empty string and we fill it in here.\n\n // TODO: We're intentionally not adding the search param to page\n // segments here; it's tracked separately and added back during a read.\n // This would clearer if we waited to construct the segment until it's\n // read from the cache, since that's effectively what we're\n // doing anyway.\n const renderedSearch = '' as NormalizedSearch\n const childParamKey =\n // The server omits this field from the prefetch response when\n // cacheComponents is enabled.\n childServerSentParamKey !== null\n ? childServerSentParamKey\n : // If no param key was sent, use the value parsed on the client.\n getCacheKeyForDynamicParam(childParamValue, renderedSearch)\n\n childParam = {\n name: childParamName,\n value: childParamValue,\n type: childParamType,\n }\n childSegment = [childParamName, childParamKey, childParamType]\n childDoesAppearInURL = true\n } else {\n childSegment = childParamName\n childDoesAppearInURL = doesStaticSegmentAppearInURL(childParamName)\n }\n\n // Only increment the index if the segment appears in the URL. If it's a\n // \"virtual\" segment, like a route group, it remains the same.\n const childPathnamePartsIndex = childDoesAppearInURL\n ? pathnamePartsIndex + 1\n : pathnamePartsIndex\n\n const childRequestKeyPart = createSegmentRequestKeyPart(childSegment)\n const childRequestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n childRequestKeyPart\n )\n const childCacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(childRequestKeyPart, childSegment)\n )\n slots[parallelRouteKey] = convertTreePrefetchToRouteTree(\n childPrefetch,\n childSegment,\n childParam,\n childRequestKey,\n childCacheKey,\n pathnameParts,\n childPathnamePartsIndex\n )\n }\n }\n\n return {\n cacheKey,\n requestKey,\n segment,\n param,\n slots,\n isRootLayout: prefetch.isRootLayout,\n // This field is only relevant to dynamic routes. For a PPR/static route,\n // there's always some partial loading state we can fetch.\n hasLoadingBoundary: HasLoadingBoundary.SegmentHasLoadingBoundary,\n hasRuntimePrefetch: prefetch.hasRuntimePrefetch,\n }\n}\n\nfunction convertRootFlightRouterStateToRouteTree(\n flightRouterState: FlightRouterState\n): RouteTree {\n return convertFlightRouterStateToRouteTree(\n flightRouterState,\n ROOT_SEGMENT_CACHE_KEY,\n ROOT_SEGMENT_REQUEST_KEY\n )\n}\n\nfunction convertFlightRouterStateToRouteTree(\n flightRouterState: FlightRouterState,\n cacheKey: SegmentCacheKey,\n requestKey: SegmentRequestKey\n): RouteTree {\n let slots: { [parallelRouteKey: string]: RouteTree } | null = null\n\n const parallelRoutes = flightRouterState[1]\n for (let parallelRouteKey in parallelRoutes) {\n const childRouterState = parallelRoutes[parallelRouteKey]\n const childSegment = childRouterState[0]\n // TODO: Eventually, the param values will not be included in the response\n // from the server. We'll instead fill them in on the client by parsing\n // the URL. This is where we'll do that.\n const childRequestKeyPart = createSegmentRequestKeyPart(childSegment)\n const childRequestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n childRequestKeyPart\n )\n const childCacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(childRequestKeyPart, childSegment)\n )\n const childTree = convertFlightRouterStateToRouteTree(\n childRouterState,\n childCacheKey,\n childRequestKey\n )\n if (slots === null) {\n slots = {\n [parallelRouteKey]: childTree,\n }\n } else {\n slots[parallelRouteKey] = childTree\n }\n }\n const originalSegment = flightRouterState[0]\n\n let segment: FlightRouterStateSegment\n let param: RouteParam | null = null\n if (Array.isArray(originalSegment)) {\n const paramCacheKey = originalSegment[1]\n const paramType = originalSegment[2]\n const paramValue = getParamValueFromCacheKey(paramCacheKey, paramType)\n param = {\n name: originalSegment[0],\n value: paramValue === undefined ? null : paramValue,\n type: originalSegment[2] as DynamicParamTypesShort,\n }\n segment = originalSegment\n } else {\n // The navigation implementation expects the search params to be included\n // in the segment. However, in the case of a static response, the search\n // params are omitted. So the client needs to add them back in when reading\n // from the Segment Cache.\n //\n // For consistency, we'll do this for dynamic responses, too.\n //\n // TODO: We should move search params out of FlightRouterState and handle\n // them entirely on the client, similar to our plan for dynamic params.\n segment =\n typeof originalSegment === 'string' &&\n originalSegment.startsWith(PAGE_SEGMENT_KEY)\n ? PAGE_SEGMENT_KEY\n : originalSegment\n }\n\n return {\n cacheKey,\n requestKey,\n segment,\n param,\n slots,\n isRootLayout: flightRouterState[4] === true,\n hasLoadingBoundary:\n flightRouterState[5] !== undefined\n ? flightRouterState[5]\n : HasLoadingBoundary.SubtreeHasNoLoadingBoundary,\n\n // Non-static tree responses are only used by apps that haven't adopted\n // Cache Components. So this is always false.\n hasRuntimePrefetch: false,\n }\n}\n\nexport function convertRouteTreeToFlightRouterState(\n routeTree: RouteTree\n): FlightRouterState {\n const parallelRoutes: Record<string, FlightRouterState> = {}\n if (routeTree.slots !== null) {\n for (const parallelRouteKey in routeTree.slots) {\n parallelRoutes[parallelRouteKey] = convertRouteTreeToFlightRouterState(\n routeTree.slots[parallelRouteKey]\n )\n }\n }\n const flightRouterState: FlightRouterState = [\n routeTree.segment,\n parallelRoutes,\n null,\n null,\n routeTree.isRootLayout,\n ]\n return flightRouterState\n}\n\nexport async function fetchRouteOnCacheMiss(\n entry: PendingRouteCacheEntry,\n task: PrefetchTask,\n key: RouteCacheKey\n): Promise<PrefetchSubtaskResult<null> | null> {\n // This function is allowed to use async/await because it contains the actual\n // fetch that gets issued on a cache miss. Notice it writes the result to the\n // cache entry directly, rather than return data that is then written by\n // the caller.\n const href = key.href\n const nextUrl = key.nextUrl\n const segmentPath = '/_tree' as SegmentRequestKey\n\n const headers: RequestHeaders = {\n [RSC_HEADER]: '1',\n [NEXT_ROUTER_PREFETCH_HEADER]: '1',\n [NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: segmentPath,\n }\n if (nextUrl !== null) {\n headers[NEXT_URL] = nextUrl\n }\n\n try {\n let response\n let urlAfterRedirects\n if (isOutputExportMode) {\n // In output: \"export\" mode, we can't use headers to request a particular\n // segment. Instead, we encode the extra request information into the URL.\n // This is not part of the \"public\" interface of the app; it's an internal\n // Next.js implementation detail that the app developer should not need to\n // concern themselves with.\n //\n // For example, to request a segment:\n //\n // Path passed to <Link>: /path/to/page\n // Path passed to fetch: /path/to/page/__next-segments/_tree\n //\n // (This is not the exact protocol, just an illustration.)\n //\n // Before we do that, though, we need to account for redirects. Even in\n // output: \"export\" mode, a proxy might redirect the page to a different\n // location, but we shouldn't assume or expect that they also redirect all\n // the segment files, too.\n //\n // To check whether the page is redirected, we perform a range request of\n // the first N bytes of the HTML document. The canonical URL is determined\n // from the response.\n //\n // Then we can use the canonical URL to request the route tree.\n //\n // NOTE: We could embed the route tree into the HTML document, to avoid\n // a second request. We're not doing that currently because it would make\n // the HTML document larger and affect normal page loads.\n const url = new URL(href)\n const htmlResponse = await fetch(href, {\n headers: {\n Range: DOC_PREFETCH_RANGE_HEADER_VALUE,\n },\n })\n const partialHtml = await htmlResponse.text()\n if (!doesExportedHtmlMatchBuildId(partialHtml, getAppBuildId())) {\n // The target page is not part of this app, or it belongs to a\n // different build.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n urlAfterRedirects = htmlResponse.redirected\n ? new URL(htmlResponse.url)\n : url\n response = await fetchPrefetchResponse(\n addSegmentPathToUrlInOutputExportMode(urlAfterRedirects, segmentPath),\n headers\n )\n } else {\n // \"Server\" mode. We can use request headers instead of the pathname.\n // TODO: The eventual plan is to get rid of our custom request headers and\n // encode everything into the URL, using a similar strategy to the\n // \"output: export\" block above.\n const url = new URL(href)\n response = await fetchPrefetchResponse(url, headers)\n urlAfterRedirects =\n response !== null && response.redirected ? new URL(response.url) : url\n }\n\n if (\n !response ||\n !response.ok ||\n // 204 is a Cache miss. Though theoretically this shouldn't happen when\n // PPR is enabled, because we always respond to route tree requests, even\n // if it needs to be blockingly generated on demand.\n response.status === 204 ||\n !response.body\n ) {\n // Server responded with an error, or with a miss. We should still cache\n // the response, but we can try again after 10 seconds.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n\n // TODO: The canonical URL is the href without the origin. I think\n // historically the reason for this is because the initial canonical URL\n // gets passed as a prop to the top-level React component, which means it\n // needs to be computed during SSR. If it were to include the origin, it\n // would need to always be same as location.origin on the client, to prevent\n // a hydration mismatch. To sidestep this complexity, we omit the origin.\n //\n // However, since this is neither a native URL object nor a fully qualified\n // URL string, we need to be careful about how we use it. To prevent subtle\n // mistakes, we should create a special type for it, instead of just string.\n // Or, we should just use a (readonly) URL object instead. The type of the\n // prop that we pass to seed the initial state does not need to be the same\n // type as the state itself.\n const canonicalUrl = createHrefFromUrl(urlAfterRedirects)\n\n // Check whether the response varies based on the Next-Url header.\n const varyHeader = response.headers.get('vary')\n const couldBeIntercepted =\n varyHeader !== null && varyHeader.includes(NEXT_URL)\n\n // Track when the network connection closes.\n const closed = createPromiseWithResolvers<void>()\n\n // This checks whether the response was served from the per-segment cache,\n // rather than the old prefetching flow. If it fails, it implies that PPR\n // is disabled on this route.\n const routeIsPPREnabled =\n response.headers.get(NEXT_DID_POSTPONE_HEADER) === '2' ||\n // In output: \"export\" mode, we can't rely on response headers. But if we\n // receive a well-formed response, we can assume it's a static response,\n // because all data is static in this mode.\n isOutputExportMode\n\n // Regardless of the type of response, we will never receive dynamic\n // metadata as part of this prefetch request.\n const isHeadDynamic = false\n\n if (routeIsPPREnabled) {\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(size) {\n routeCacheLru.updateSize(entry, size)\n }\n )\n const serverData = await createFromNextReadableStream<RootTreePrefetch>(\n prefetchStream,\n headers\n )\n if (serverData.buildId !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n // TODO: We should cache the fact that this is an MPA navigation.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n\n // Get the params that were used to render the target page. These may\n // be different from the params in the request URL, if the page\n // was rewritten.\n const renderedPathname = getRenderedPathname(response)\n const renderedSearch = getRenderedSearch(response)\n\n const routeTree = convertRootTreePrefetchToRouteTree(\n serverData,\n renderedPathname\n )\n\n const staleTimeMs = getStaleTimeMs(serverData.staleTime)\n fulfillRouteCacheEntry(\n entry,\n routeTree,\n serverData.head,\n serverData.isHeadPartial,\n Date.now() + staleTimeMs,\n couldBeIntercepted,\n canonicalUrl,\n renderedSearch,\n routeIsPPREnabled,\n isHeadDynamic\n )\n } else {\n // PPR is not enabled for this route. The server responds with a\n // different format (FlightRouterState) that we need to convert.\n // TODO: We will unify the responses eventually. I'm keeping the types\n // separate for now because FlightRouterState has so many\n // overloaded concerns.\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(size) {\n routeCacheLru.updateSize(entry, size)\n }\n )\n const serverData =\n await createFromNextReadableStream<NavigationFlightResponse>(\n prefetchStream,\n headers\n )\n if (serverData.b !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n // TODO: We should cache the fact that this is an MPA navigation.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n\n writeDynamicTreeResponseIntoCache(\n Date.now(),\n task,\n // The non-PPR response format is what we'd get if we prefetched these segments\n // using the LoadingBoundary fetch strategy, so mark their cache entries accordingly.\n FetchStrategy.LoadingBoundary,\n response as RSCResponse<NavigationFlightResponse>,\n serverData,\n entry,\n couldBeIntercepted,\n canonicalUrl,\n routeIsPPREnabled\n )\n }\n\n if (!couldBeIntercepted && nextUrl !== null) {\n // This route will never be intercepted. So we can use this entry for all\n // requests to this route, regardless of the Next-Url header. This works\n // because when reading the cache we always check for a valid\n // non-intercepted entry first.\n //\n // Re-key the entry. Since we're in an async task, we must first confirm\n // that the entry hasn't been concurrently modified by a different task.\n const currentKeypath: Prefix<RouteCacheKeypath> = [href, nextUrl]\n const expectedEntry = routeCacheMap.get(currentKeypath)\n if (expectedEntry === entry) {\n routeCacheMap.delete(currentKeypath)\n const newKeypath: Prefix<RouteCacheKeypath> = [href]\n routeCacheMap.set(newKeypath, entry)\n // We don't need to update the LRU because the entry is already in it.\n // But since we changed the keypath, we do need to update that, so we\n // know how to remove it from the map if it gets evicted from the LRU.\n entry.keypath = newKeypath\n } else {\n // Something else modified this entry already. Since the re-keying is\n // just a performance optimization, we can safely skip it.\n }\n }\n // Return a promise that resolves when the network connection closes, so\n // the scheduler can track the number of concurrent network connections.\n return { value: null, closed: closed.promise }\n } catch (error) {\n // Either the connection itself failed, or something bad happened while\n // decoding the response.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n}\n\nexport async function fetchSegmentOnCacheMiss(\n route: FulfilledRouteCacheEntry,\n segmentCacheEntry: PendingSegmentCacheEntry,\n routeKey: RouteCacheKey,\n tree: RouteTree\n): Promise<PrefetchSubtaskResult<FulfilledSegmentCacheEntry> | null> {\n // This function is allowed to use async/await because it contains the actual\n // fetch that gets issued on a cache miss. Notice it writes the result to the\n // cache entry directly, rather than return data that is then written by\n // the caller.\n //\n // Segment fetches are non-blocking so we don't need to ping the scheduler\n // on completion.\n\n // Use the canonical URL to request the segment, not the original URL. These\n // are usually the same, but the canonical URL will be different if the route\n // tree response was redirected. To avoid an extra waterfall on every segment\n // request, we pass the redirected URL instead of the original one.\n const url = new URL(route.canonicalUrl, routeKey.href)\n const nextUrl = routeKey.nextUrl\n\n const requestKey = tree.requestKey\n const normalizedRequestKey =\n requestKey === ROOT_SEGMENT_REQUEST_KEY\n ? // The root segment is a special case. To simplify the server-side\n // handling of these requests, we encode the root segment path as\n // `_index` instead of as an empty string. This should be treated as\n // an implementation detail and not as a stable part of the protocol.\n // It just needs to match the equivalent logic that happens when\n // prerendering the responses. It should not leak outside of Next.js.\n ('/_index' as SegmentRequestKey)\n : requestKey\n\n const headers: RequestHeaders = {\n [RSC_HEADER]: '1',\n [NEXT_ROUTER_PREFETCH_HEADER]: '1',\n [NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: normalizedRequestKey,\n }\n if (nextUrl !== null) {\n headers[NEXT_URL] = nextUrl\n }\n\n const requestUrl = isOutputExportMode\n ? // In output: \"export\" mode, we need to add the segment path to the URL.\n addSegmentPathToUrlInOutputExportMode(url, normalizedRequestKey)\n : url\n try {\n const response = await fetchPrefetchResponse(requestUrl, headers)\n if (\n !response ||\n !response.ok ||\n response.status === 204 || // Cache miss\n // This checks whether the response was served from the per-segment cache,\n // rather than the old prefetching flow. If it fails, it implies that PPR\n // is disabled on this route. Theoretically this should never happen\n // because we only issue requests for segments once we've verified that\n // the route supports PPR.\n (response.headers.get(NEXT_DID_POSTPONE_HEADER) !== '2' &&\n // In output: \"export\" mode, we can't rely on response headers. But if\n // we receive a well-formed response, we can assume it's a static\n // response, because all data is static in this mode.\n !isOutputExportMode) ||\n !response.body\n ) {\n // Server responded with an error, or with a miss. We should still cache\n // the response, but we can try again after 10 seconds.\n rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000)\n return null\n }\n\n // Track when the network connection closes.\n const closed = createPromiseWithResolvers<void>()\n\n // Wrap the original stream in a new stream that never closes. That way the\n // Flight client doesn't error if there's a hanging promise.\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(size) {\n segmentCacheLru.updateSize(segmentCacheEntry, size)\n }\n )\n const serverData = await (createFromNextReadableStream(\n prefetchStream,\n headers\n ) as Promise<SegmentPrefetch>)\n if (serverData.buildId !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000)\n return null\n }\n return {\n value: fulfillSegmentCacheEntry(\n segmentCacheEntry,\n serverData.rsc,\n serverData.loading,\n // TODO: The server does not currently provide per-segment stale time.\n // So we use the stale time of the route.\n route.staleAt,\n serverData.isPartial\n ),\n // Return a promise that resolves when the network connection closes, so\n // the scheduler can track the number of concurrent network connections.\n closed: closed.promise,\n }\n } catch (error) {\n // Either the connection itself failed, or something bad happened while\n // decoding the response.\n rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000)\n return null\n }\n}\n\nexport async function fetchSegmentPrefetchesUsingDynamicRequest(\n task: PrefetchTask,\n route: FulfilledRouteCacheEntry,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n dynamicRequestTree: FlightRouterState,\n spawnedEntries: Map<SegmentCacheKey, PendingSegmentCacheEntry>\n): Promise<PrefetchSubtaskResult<null> | null> {\n const url = new URL(route.canonicalUrl, task.key.href)\n const nextUrl = task.key.nextUrl\n const headers: RequestHeaders = {\n [RSC_HEADER]: '1',\n [NEXT_ROUTER_STATE_TREE_HEADER]:\n prepareFlightRouterStateForRequest(dynamicRequestTree),\n }\n if (nextUrl !== null) {\n headers[NEXT_URL] = nextUrl\n }\n switch (fetchStrategy) {\n case FetchStrategy.Full: {\n // We omit the prefetch header from a full prefetch because it's essentially\n // just a navigation request that happens ahead of time — it should include\n // all the same data in the response.\n break\n }\n case FetchStrategy.PPRRuntime: {\n headers[NEXT_ROUTER_PREFETCH_HEADER] = '2'\n break\n }\n case FetchStrategy.LoadingBoundary: {\n headers[NEXT_ROUTER_PREFETCH_HEADER] = '1'\n break\n }\n default: {\n fetchStrategy satisfies never\n }\n }\n\n try {\n const response = await fetchPrefetchResponse(url, headers)\n if (!response || !response.ok || !response.body) {\n // Server responded with an error, or with a miss. We should still cache\n // the response, but we can try again after 10 seconds.\n rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000)\n return null\n }\n\n const renderedSearch = getRenderedSearch(response)\n if (renderedSearch !== route.renderedSearch) {\n // The search params that were used to render the target page are\n // different from the search params in the request URL. This only happens\n // when there's a dynamic rewrite in between the tree prefetch and the\n // data prefetch.\n // TODO: For now, since this is an edge case, we reject the prefetch, but\n // the proper way to handle this is to evict the stale route tree entry\n // then fill the cache with the new response.\n rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000)\n return null\n }\n\n // Track when the network connection closes.\n const closed = createPromiseWithResolvers<void>()\n\n let fulfilledEntries: Array<FulfilledSegmentCacheEntry> | null = null\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(totalBytesReceivedSoFar) {\n // When processing a dynamic response, we don't know how large each\n // individual segment is, so approximate by assiging each segment\n // the average of the total response size.\n if (fulfilledEntries === null) {\n // Haven't received enough data yet to know which segments\n // were included.\n return\n }\n const averageSize = totalBytesReceivedSoFar / fulfilledEntries.length\n for (const entry of fulfilledEntries) {\n segmentCacheLru.updateSize(entry, averageSize)\n }\n }\n )\n const serverData = await (createFromNextReadableStream(\n prefetchStream,\n headers\n ) as Promise<NavigationFlightResponse>)\n\n const isResponsePartial =\n fetchStrategy === FetchStrategy.PPRRuntime\n ? // A runtime prefetch may have holes.\n !!response.headers.get(NEXT_DID_POSTPONE_HEADER)\n : // Full and LoadingBoundary prefetches cannot have holes.\n // (even if we did set the prefetch header, we only use this codepath for non-PPR-enabled routes)\n false\n\n // Aside from writing the data into the cache, this function also returns\n // the entries that were fulfilled, so we can streamingly update their sizes\n // in the LRU as more data comes in.\n fulfilledEntries = writeDynamicRenderResponseIntoCache(\n Date.now(),\n task,\n fetchStrategy,\n response as RSCResponse<NavigationFlightResponse>,\n serverData,\n isResponsePartial,\n route,\n spawnedEntries\n )\n\n // Return a promise that resolves when the network connection closes, so\n // the scheduler can track the number of concurrent network connections.\n return { value: null, closed: closed.promise }\n } catch (error) {\n rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000)\n return null\n }\n}\n\nfunction writeDynamicTreeResponseIntoCache(\n now: number,\n task: PrefetchTask,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n response: RSCResponse<NavigationFlightResponse>,\n serverData: NavigationFlightResponse,\n entry: PendingRouteCacheEntry,\n couldBeIntercepted: boolean,\n canonicalUrl: string,\n routeIsPPREnabled: boolean\n) {\n // Get the URL that was used to render the target page. This may be different\n // from the URL in the request URL, if the page was rewritten.\n const renderedSearch = getRenderedSearch(response)\n\n const normalizedFlightDataResult = normalizeFlightData(serverData.f)\n if (\n // A string result means navigating to this route will result in an\n // MPA navigation.\n typeof normalizedFlightDataResult === 'string' ||\n normalizedFlightDataResult.length !== 1\n ) {\n rejectRouteCacheEntry(entry, now + 10 * 1000)\n return\n }\n const flightData = normalizedFlightDataResult[0]\n if (!flightData.isRootRender) {\n // Unexpected response format.\n rejectRouteCacheEntry(entry, now + 10 * 1000)\n return\n }\n\n const flightRouterState = flightData.tree\n // TODO: Extract to function\n const staleTimeHeaderSeconds = response.headers.get(\n NEXT_ROUTER_STALE_TIME_HEADER\n )\n const staleTimeMs =\n staleTimeHeaderSeconds !== null\n ? getStaleTimeMs(parseInt(staleTimeHeaderSeconds, 10))\n : STATIC_STALETIME_MS\n\n // If the response contains dynamic holes, then we must conservatively assume\n // that any individual segment might contain dynamic holes, and also the\n // head. If it did not contain dynamic holes, then we can assume every segment\n // and the head is completely static.\n const isResponsePartial =\n response.headers.get(NEXT_DID_POSTPONE_HEADER) === '1'\n\n // Since this is a dynamic response, we must conservatively assume that the\n // head responded with dynamic data.\n const isHeadDynamic = true\n\n const fulfilledEntry = fulfillRouteCacheEntry(\n entry,\n convertRootFlightRouterStateToRouteTree(flightRouterState),\n flightData.head,\n flightData.isHeadPartial,\n now + staleTimeMs,\n couldBeIntercepted,\n canonicalUrl,\n renderedSearch,\n routeIsPPREnabled,\n isHeadDynamic\n )\n\n // If the server sent segment data as part of the response, we should write\n // it into the cache to prevent a second, redundant prefetch request.\n //\n // TODO: When `clientSegmentCache` is enabled, the server does not include\n // segment data when responding to a route tree prefetch request. However,\n // when `clientSegmentCache` is set to \"client-only\", and PPR is enabled (or\n // the page is fully static), the normal check is bypassed and the server\n // responds with the full page. This is a temporary situation until we can\n // remove the \"client-only\" option. Then, we can delete this function call.\n writeDynamicRenderResponseIntoCache(\n now,\n task,\n fetchStrategy,\n response,\n serverData,\n isResponsePartial,\n fulfilledEntry,\n null\n )\n}\n\nfunction rejectSegmentEntriesIfStillPending(\n entries: Map<SegmentCacheKey, SegmentCacheEntry>,\n staleAt: number\n): Array<FulfilledSegmentCacheEntry> {\n const fulfilledEntries = []\n for (const entry of entries.values()) {\n if (entry.status === EntryStatus.Pending) {\n rejectSegmentCacheEntry(entry, staleAt)\n } else if (entry.status === EntryStatus.Fulfilled) {\n fulfilledEntries.push(entry)\n }\n }\n return fulfilledEntries\n}\n\nfunction writeDynamicRenderResponseIntoCache(\n now: number,\n task: PrefetchTask,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n response: RSCResponse<NavigationFlightResponse>,\n serverData: NavigationFlightResponse,\n isResponsePartial: boolean,\n route: FulfilledRouteCacheEntry,\n spawnedEntries: Map<SegmentCacheKey, PendingSegmentCacheEntry> | null\n): Array<FulfilledSegmentCacheEntry> | null {\n if (serverData.b !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n if (spawnedEntries !== null) {\n rejectSegmentEntriesIfStillPending(spawnedEntries, now + 10 * 1000)\n }\n return null\n }\n\n const flightDatas = normalizeFlightData(serverData.f)\n if (typeof flightDatas === 'string') {\n // This means navigating to this route will result in an MPA navigation.\n // TODO: We should cache this, too, so that the MPA navigation is immediate.\n return null\n }\n\n const staleTimeHeaderSeconds = response.headers.get(\n NEXT_ROUTER_STALE_TIME_HEADER\n )\n const staleTimeMs =\n staleTimeHeaderSeconds !== null\n ? getStaleTimeMs(parseInt(staleTimeHeaderSeconds, 10))\n : STATIC_STALETIME_MS\n const staleAt = now + staleTimeMs\n\n for (const flightData of flightDatas) {\n const seedData = flightData.seedData\n if (seedData !== null) {\n // The data sent by the server represents only a subtree of the app. We\n // need to find the part of the task tree that matches the response.\n //\n // segmentPath represents the parent path of subtree. It's a repeating\n // pattern of parallel route key and segment:\n //\n // [string, Segment, string, Segment, string, Segment, ...]\n const segmentPath = flightData.segmentPath\n let requestKey = ROOT_SEGMENT_REQUEST_KEY\n let cacheKey = ROOT_SEGMENT_CACHE_KEY\n for (let i = 0; i < segmentPath.length; i += 2) {\n const parallelRouteKey: string = segmentPath[i]\n const segment: FlightRouterStateSegment = segmentPath[i + 1]\n const requestKeyPart = createSegmentRequestKeyPart(segment)\n requestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n requestKeyPart\n )\n cacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(requestKeyPart, segment)\n )\n }\n\n writeSeedDataIntoCache(\n now,\n task,\n fetchStrategy,\n route,\n staleAt,\n flightData.tree,\n seedData,\n isResponsePartial,\n cacheKey,\n requestKey,\n spawnedEntries\n )\n }\n\n // During a dynamic request, the server sends back new head data for the\n // page. Overwrite the existing head with the new one. Note that we're\n // intentionally not taking into account whether the existing head is\n // already complete, even though the incoming head might not have finished\n // streaming in yet. This is to prioritize consistency of the head with\n // the segment data (though it's still not a guarantee, since some of the\n // segment data may be reused from a previous request).\n route.head = flightData.head\n route.isHeadPartial = flightData.isHeadPartial\n route.TODO_isHeadDynamic = true\n\n // TODO: Currently the stale time of the route tree represents the\n // stale time of both the route tree *and* all the segment data. So we\n // can't just overwrite this field; we have to use whichever value is\n // lower. In the future, though, the plan is to track segment lifetimes\n // separately from the route tree lifetime.\n if (staleAt < route.staleAt) {\n route.staleAt = staleAt\n }\n }\n // Any entry that's still pending was intentionally not rendered by the\n // server, because it was inside the loading boundary. Mark them as rejected\n // so we know not to fetch them again.\n // TODO: If PPR is enabled on some routes but not others, then it's possible\n // that a different page is able to do a per-segment prefetch of one of the\n // segments we're marking as rejected here. We should mark on the segment\n // somehow that the reason for the rejection is because of a non-PPR prefetch.\n // That way a per-segment prefetch knows to disregard the rejection.\n if (spawnedEntries !== null) {\n const fulfilledEntries = rejectSegmentEntriesIfStillPending(\n spawnedEntries,\n now + 10 * 1000\n )\n return fulfilledEntries\n }\n return null\n}\n\nfunction writeSeedDataIntoCache(\n now: number,\n task: PrefetchTask,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n route: FulfilledRouteCacheEntry,\n staleAt: number,\n flightRouterState: FlightRouterState,\n seedData: CacheNodeSeedData,\n isResponsePartial: boolean,\n cacheKey: SegmentCacheKey,\n requestKey: SegmentRequestKey,\n entriesOwnedByCurrentTask: Map<\n SegmentCacheKey,\n PendingSegmentCacheEntry\n > | null\n) {\n // This function is used to write the result of a dynamic server request\n // (CacheNodeSeedData) into the prefetch cache. It's used in cases where we\n // want to treat a dynamic response as if it were static. The two examples\n // where this happens are <Link prefetch={true}> (which implicitly opts\n // dynamic data into being static) and when prefetching a PPR-disabled route\n const rsc = seedData[0]\n const loading = seedData[2]\n const isPartial = rsc === null || isResponsePartial\n\n // We should only write into cache entries that are owned by us. Or create\n // a new one and write into that. We must never write over an entry that was\n // created by a different task, because that causes data races.\n const ownedEntry =\n entriesOwnedByCurrentTask !== null\n ? entriesOwnedByCurrentTask.get(cacheKey)\n : undefined\n if (ownedEntry !== undefined) {\n fulfillSegmentCacheEntry(ownedEntry, rsc, loading, staleAt, isPartial)\n } else {\n // There's no matching entry. Attempt to create a new one.\n const possiblyNewEntry = readOrCreateSegmentCacheEntry(\n now,\n fetchStrategy,\n route,\n cacheKey\n )\n if (possiblyNewEntry.status === EntryStatus.Empty) {\n // Confirmed this is a new entry. We can fulfill it.\n const newEntry = possiblyNewEntry\n fulfillSegmentCacheEntry(\n upgradeToPendingSegment(newEntry, fetchStrategy),\n rsc,\n loading,\n staleAt,\n isPartial\n )\n } else {\n // There was already an entry in the cache. But we may be able to\n // replace it with the new one from the server.\n const newEntry = fulfillSegmentCacheEntry(\n upgradeToPendingSegment(\n createDetachedSegmentCacheEntry(staleAt),\n fetchStrategy\n ),\n rsc,\n loading,\n staleAt,\n isPartial\n )\n upsertSegmentEntry(\n now,\n getSegmentKeypath(fetchStrategy, route, cacheKey),\n newEntry\n )\n }\n }\n // Recursively write the child data into the cache.\n const flightRouterStateChildren = flightRouterState[1]\n const seedDataChildren = seedData[1]\n for (const parallelRouteKey in flightRouterStateChildren) {\n const childFlightRouterState = flightRouterStateChildren[parallelRouteKey]\n const childSeedData: CacheNodeSeedData | null | void =\n seedDataChildren[parallelRouteKey]\n if (childSeedData !== null && childSeedData !== undefined) {\n const childSegment = childFlightRouterState[0]\n const childRequestKeyPart = createSegmentRequestKeyPart(childSegment)\n const childRequestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n childRequestKeyPart\n )\n const childCacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(childRequestKeyPart, childSegment)\n )\n writeSeedDataIntoCache(\n now,\n task,\n fetchStrategy,\n route,\n staleAt,\n childFlightRouterState,\n childSeedData,\n isResponsePartial,\n childCacheKey,\n childRequestKey,\n entriesOwnedByCurrentTask\n )\n }\n }\n}\n\nasync function fetchPrefetchResponse<T>(\n url: URL,\n headers: RequestHeaders\n): Promise<RSCResponse<T> | null> {\n const fetchPriority = 'low'\n // When issuing a prefetch request, don't immediately decode the response; we\n // use the lower level `createFromResponse` API instead because we need to do\n // some extra processing of the response stream. See\n // `createPrefetchResponseStream` for more details.\n const shouldImmediatelyDecode = false\n const response = await createFetch<T>(\n url,\n headers,\n fetchPriority,\n shouldImmediatelyDecode\n )\n if (!response.ok) {\n return null\n }\n\n // Check the content type\n if (isOutputExportMode) {\n // In output: \"export\" mode, we relaxed about the content type, since it's\n // not Next.js that's serving the response. If the status is OK, assume the\n // response is valid. If it's not a valid response, the Flight client won't\n // be able to decode it, and we'll treat it as a miss.\n } else {\n const contentType = response.headers.get('content-type')\n const isFlightResponse =\n contentType && contentType.startsWith(RSC_CONTENT_TYPE_HEADER)\n if (!isFlightResponse) {\n return null\n }\n }\n return response\n}\n\nfunction createPrefetchResponseStream(\n originalFlightStream: ReadableStream<Uint8Array>,\n onStreamClose: () => void,\n onResponseSizeUpdate: (size: number) => void\n): ReadableStream<Uint8Array> {\n // When PPR is enabled, prefetch streams may contain references that never\n // resolve, because that's how we encode dynamic data access. In the decoded\n // object returned by the Flight client, these are reified into hanging\n // promises that suspend during render, which is effectively what we want.\n // The UI resolves when it switches to the dynamic data stream\n // (via useDeferredValue(dynamic, static)).\n //\n // However, the Flight implementation currently errors if the server closes\n // the response before all the references are resolved. As a cheat to work\n // around this, we wrap the original stream in a new stream that never closes,\n // and therefore doesn't error.\n //\n // While processing the original stream, we also incrementally update the size\n // of the cache entry in the LRU.\n let totalByteLength = 0\n const reader = originalFlightStream.getReader()\n return new ReadableStream({\n async pull(controller) {\n while (true) {\n const { done, value } = await reader.read()\n if (!done) {\n // Pass to the target stream and keep consuming the Flight response\n // from the server.\n controller.enqueue(value)\n\n // Incrementally update the size of the cache entry in the LRU.\n // NOTE: Since prefetch responses are delivered in a single chunk,\n // it's not really necessary to do this streamingly, but I'm doing it\n // anyway in case this changes in the future.\n totalByteLength += value.byteLength\n onResponseSizeUpdate(totalByteLength)\n continue\n }\n // The server stream has closed. Exit, but intentionally do not close\n // the target stream. We do notify the caller, though.\n onStreamClose()\n return\n }\n },\n })\n}\n\nfunction addSegmentPathToUrlInOutputExportMode(\n url: URL,\n segmentPath: SegmentRequestKey\n): URL {\n if (isOutputExportMode) {\n // In output: \"export\" mode, we cannot use a header to encode the segment\n // path. Instead, we append it to the end of the pathname.\n const staticUrl = new URL(url)\n const routeDir = staticUrl.pathname.endsWith('/')\n ? staticUrl.pathname.slice(0, -1)\n : staticUrl.pathname\n const staticExportFilename =\n convertSegmentPathToStaticExportFilename(segmentPath)\n staticUrl.pathname = `${routeDir}/${staticExportFilename}`\n return staticUrl\n }\n return url\n}\n\n/**\n * Checks whether the new fetch strategy is likely to provide more content than the old one.\n *\n * Generally, when an app uses dynamic data, a \"more specific\" fetch strategy is expected to provide more content:\n * - `LoadingBoundary` only provides static layouts\n * - `PPR` can provide shells for each segment (even for segments that use dynamic data)\n * - `PPRRuntime` can additionally include content that uses searchParams, params, or cookies\n * - `Full` includes all the content, even if it uses dynamic data\n *\n * However, it's possible that a more specific fetch strategy *won't* give us more content if:\n * - a segment is fully static\n * (then, `PPR`/`PPRRuntime`/`Full` will all yield equivalent results)\n * - providing searchParams/params/cookies doesn't reveal any more content, e.g. because of an `await connection()`\n * (then, `PPR` and `PPRRuntime` will yield equivalent results, only `Full` will give us more)\n * Because of this, when comparing two segments, we should also check if the existing segment is partial.\n * If it's not partial, then there's no need to prefetch it again, even using a \"more specific\" strategy.\n * There's currently no way to know if `PPRRuntime` will yield more data that `PPR`, so we have to assume it will.\n *\n * Also note that, in practice, we don't expect to be comparing `LoadingBoundary` to `PPR`/`PPRRuntime`,\n * because a non-PPR-enabled route wouldn't ever use the latter strategies. It might however use `Full`.\n */\nexport function canNewFetchStrategyProvideMoreContent(\n currentStrategy: FetchStrategy,\n newStrategy: FetchStrategy\n): boolean {\n return currentStrategy < newStrategy\n}\n"],"names":["EntryStatus","canNewFetchStrategyProvideMoreContent","convertRouteTreeToFlightRouterState","createDetachedSegmentCacheEntry","fetchRouteOnCacheMiss","fetchSegmentOnCacheMiss","fetchSegmentPrefetchesUsingDynamicRequest","getCurrentCacheVersion","getSegmentKeypath","pingInvalidationListeners","readExactRouteCacheEntry","readOrCreateRevalidatingSegmentEntry","readOrCreateRouteCacheEntry","readOrCreateSegmentCacheEntry","readRouteCacheEntry","readSegmentCacheEntry","requestOptimisticRouteCacheEntry","resetRevalidatingSegmentEntry","revalidateEntireCache","upgradeToPendingSegment","upsertSegmentEntry","waitForSegmentCacheEntry","isOutputExportMode","process","env","NODE_ENV","__NEXT_CONFIG_OUTPUT","getStaleTimeMs","staleTimeSeconds","Math","max","routeCacheMap","createTupleMap","maxRouteLruSize","routeCacheLru","createLRU","onRouteLRUEviction","segmentCacheMap","maxSegmentLruSize","segmentCacheLru","onSegmentLRUEviction","invalidationListeners","currentCacheVersion","nextUrl","tree","startRevalidationCooldown","pingVisibleLinks","attachInvalidationListener","task","onInvalidate","Set","add","notifyInvalidationListener","error","reportError","console","tasks","isPrefetchTaskDirty","now","href","keypath","existingEntry","get","staleAt","put","deleteRouteFromCache","key","nonInterceptedEntry","couldBeIntercepted","fetchStrategy","route","cacheKey","isDynamic","FetchStrategy","Full","PPRRuntime","isPPREnabled","endsWith","PAGE_SEGMENT_KEY","renderedSearch","readExactSegmentCacheEntry","entryWithSearchParams","entryWithoutSearchParams","revalidatingEntry","revalidating","upsertedEntry","deleteSegmentFromCache","readRevalidatingSegmentCacheEntry","owner","existingRevalidation","clearRevalidatingSegmentFromOwner","pendingEntry","promiseWithResolvers","promise","createPromiseWithResolvers","canonicalUrl","status","blockedTasks","head","isHeadPartial","Infinity","TODO_metadataStatus","TODO_isHeadDynamic","next","prev","size","set","requestedUrl","requestedSearch","search","urlWithoutSearchParams","URL","routeWithNoSearchParams","createPrefetchRequestKey","canonicalUrlForRouteWithNoSearchParams","origin","optimisticCanonicalSearch","optimisticRenderedSearch","optimisticUrl","location","optimisticCanonicalUrl","createHrefFromUrl","optimisticEntry","prevEntry","candidateEntry","isPartial","rejectedEntry","loading","rsc","emptyEntry","PPR","entry","pingBlockedTasks","delete","cancelEntryListeners","revalidatingSegment","resolve","pingPrefetchTask","fulfillRouteCacheEntry","isHeadDynamic","fulfilledEntry","fulfillSegmentCacheEntry","segmentCacheEntry","rejectRouteCacheEntry","rejectSegmentCacheEntry","convertRootTreePrefetchToRouteTree","rootTree","renderedPathname","pathnameParts","split","filter","p","index","rootSegment","ROOT_SEGMENT_CACHE_KEY","convertTreePrefetchToRouteTree","ROOT_SEGMENT_REQUEST_KEY","prefetch","segment","param","requestKey","pathnamePartsIndex","slots","prefetchSlots","parallelRouteKey","childPrefetch","childParamName","name","childParamType","paramType","childServerSentParamKey","paramKey","childDoesAppearInURL","childParam","childSegment","childParamValue","parseDynamicParamFromURLPart","childParamKey","getCacheKeyForDynamicParam","value","type","doesStaticSegmentAppearInURL","childPathnamePartsIndex","childRequestKeyPart","createSegmentRequestKeyPart","childRequestKey","appendSegmentRequestKeyPart","childCacheKey","appendSegmentCacheKeyPart","createSegmentCacheKeyPart","isRootLayout","hasLoadingBoundary","HasLoadingBoundary","SegmentHasLoadingBoundary","hasRuntimePrefetch","convertRootFlightRouterStateToRouteTree","flightRouterState","convertFlightRouterStateToRouteTree","parallelRoutes","childRouterState","childTree","originalSegment","Array","isArray","paramCacheKey","paramValue","getParamValueFromCacheKey","undefined","startsWith","SubtreeHasNoLoadingBoundary","routeTree","segmentPath","headers","RSC_HEADER","NEXT_ROUTER_PREFETCH_HEADER","NEXT_ROUTER_SEGMENT_PREFETCH_HEADER","NEXT_URL","response","urlAfterRedirects","url","htmlResponse","fetch","Range","DOC_PREFETCH_RANGE_HEADER_VALUE","partialHtml","text","doesExportedHtmlMatchBuildId","getAppBuildId","Date","redirected","fetchPrefetchResponse","addSegmentPathToUrlInOutputExportMode","ok","body","varyHeader","includes","closed","routeIsPPREnabled","NEXT_DID_POSTPONE_HEADER","prefetchStream","createPrefetchResponseStream","onResponseSizeUpdate","updateSize","serverData","createFromNextReadableStream","buildId","getRenderedPathname","getRenderedSearch","staleTimeMs","staleTime","b","writeDynamicTreeResponseIntoCache","LoadingBoundary","currentKeypath","expectedEntry","newKeypath","routeKey","normalizedRequestKey","requestUrl","dynamicRequestTree","spawnedEntries","NEXT_ROUTER_STATE_TREE_HEADER","prepareFlightRouterStateForRequest","rejectSegmentEntriesIfStillPending","fulfilledEntries","totalBytesReceivedSoFar","averageSize","length","isResponsePartial","writeDynamicRenderResponseIntoCache","normalizedFlightDataResult","normalizeFlightData","f","flightData","isRootRender","staleTimeHeaderSeconds","NEXT_ROUTER_STALE_TIME_HEADER","parseInt","STATIC_STALETIME_MS","entries","values","push","flightDatas","seedData","i","requestKeyPart","writeSeedDataIntoCache","entriesOwnedByCurrentTask","ownedEntry","possiblyNewEntry","newEntry","flightRouterStateChildren","seedDataChildren","childFlightRouterState","childSeedData","fetchPriority","shouldImmediatelyDecode","createFetch","contentType","isFlightResponse","RSC_CONTENT_TYPE_HEADER","originalFlightStream","onStreamClose","totalByteLength","reader","getReader","ReadableStream","pull","controller","done","read","enqueue","byteLength","staticUrl","routeDir","pathname","slice","staticExportFilename","convertSegmentPathToStaticExportFilename","currentStrategy","newStrategy"],"mappings":"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","ignoreList":[0]}