BLUE
PHP 7.4.33
Path:
/var/www/uibuilder.cmshelp.dk/httpdocs/node_modules/next/dist/client/components/segment-cache-impl
Run
Logout
Edit File
Size: 83.03 KB
Close
/var/www/uibuilder.cmshelp.dk/httpdocs/node_modules/next/dist/client/components/segment-cache-impl/cache.js.map
Text
Base64
{"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-context.shared-runtime'\nimport type {\n CacheNodeSeedData,\n Segment as FlightRouterStateSegment,\n} from '../../../server/app-render/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 RequestHeaders,\n} from '../router-reducer/fetch-server-response'\nimport {\n pingPrefetchTask,\n type PrefetchTask,\n type PrefetchSubtaskResult,\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'\nimport { createTupleMap, type TupleMap, type Prefix } from './tuple-map'\nimport { createLRU } from './lru'\nimport {\n convertSegmentPathToStaticExportFilename,\n encodeChildSegmentKey,\n encodeSegment,\n ROOT_SEGMENT_KEY,\n} from '../../../shared/lib/segment-cache/segment-value-encoding'\nimport type {\n FlightRouterState,\n NavigationFlightResponse,\n} from '../../../server/app-render/types'\nimport { normalizeFlightData } from '../../flight-data-helpers'\nimport { STATIC_STALETIME_MS } from '../router-reducer/prefetch-cache-utils'\nimport { pingVisibleLinks } from '../links'\nimport { PAGE_SEGMENT_KEY } from '../../../shared/lib/segment'\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 key: string\n segment: FlightRouterStateSegment\n slots: null | {\n [parallelRouteKey: string]: RouteTree\n }\n isRootLayout: 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 // 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,\n Pending,\n Fulfilled,\n Rejected,\n}\n\ntype PendingRouteCacheEntry = RouteCacheEntryShared & {\n status: EntryStatus.Empty | EntryStatus.Pending\n blockedTasks: Set<PrefetchTask> | null\n canonicalUrl: 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 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 tree: RouteTree\n head: HeadData\n isHeadPartial: boolean\n isPPREnabled: boolean\n}\n\nexport type RouteCacheEntry =\n | PendingRouteCacheEntry\n | FulfilledRouteCacheEntry\n | RejectedRouteCacheEntry\n\nexport const enum FetchStrategy {\n PPR,\n Full,\n LoadingBoundary,\n}\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// 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// 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 // 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\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 getSegmentKeypathForTask(\n task: PrefetchTask,\n route: FulfilledRouteCacheEntry,\n path: string\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 isDynamicTask = task.includeDynamicData || !route.isPPREnabled\n return isDynamicTask && path.endsWith('/' + PAGE_SEGMENT_KEY)\n ? [path, task.key.search]\n : [path]\n}\n\nexport function readSegmentCacheEntry(\n now: number,\n routeCacheKey: RouteCacheKey,\n path: string\n): SegmentCacheEntry | null {\n if (!path.endsWith('/' + PAGE_SEGMENT_KEY)) {\n // Fast path. Search params only exist on page segments.\n return readExactSegmentCacheEntry(now, [path])\n }\n\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 path,\n routeCacheKey.search,\n ])\n if (entryWithSearchParams !== null) {\n return entryWithSearchParams\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 `getSegmentKeypathForTask`.\n const entryWithoutSearchParams = readExactSegmentCacheEntry(now, [path])\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): RouteCacheEntry {\n const key = task.key\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\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\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 task: PrefetchTask,\n route: FulfilledRouteCacheEntry,\n path: string\n): SegmentCacheEntry {\n const keypath = getSegmentKeypathForTask(task, route, path)\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 if (candidateEntry.isPartial && !existingEntry.isPartial) {\n // Don't replace a full segment with a partial one. A case where this\n // might happen is if the existing segment was fetched via\n // <Link prefetch={true}>.\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 // 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 isPPREnabled: 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.isPPREnabled = isPPREnabled\n pingBlockedTasks(entry)\n return fulfilledEntry\n}\n\nfunction fulfillSegmentCacheEntry(\n segmentCacheEntry: EmptySegmentCacheEntry | 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(rootTree: RootTreePrefetch) {\n return convertTreePrefetchToRouteTree(rootTree.tree, ROOT_SEGMENT_KEY)\n}\n\nfunction convertTreePrefetchToRouteTree(\n prefetch: TreePrefetch,\n key: string\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 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 childSegment = childPrefetch.segment\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 childKey = encodeChildSegmentKey(\n key,\n parallelRouteKey,\n encodeSegment(childSegment)\n )\n slots[parallelRouteKey] = convertTreePrefetchToRouteTree(\n childPrefetch,\n childKey\n )\n }\n }\n return {\n key,\n segment: prefetch.segment,\n slots,\n isRootLayout: prefetch.isRootLayout,\n }\n}\n\nfunction convertRootFlightRouterStateToRouteTree(\n flightRouterState: FlightRouterState\n): RouteTree {\n return convertFlightRouterStateToRouteTree(\n flightRouterState,\n ROOT_SEGMENT_KEY\n )\n}\n\nfunction convertFlightRouterStateToRouteTree(\n flightRouterState: FlightRouterState,\n key: string\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 childKey = encodeChildSegmentKey(\n key,\n parallelRouteKey,\n encodeSegment(childSegment)\n )\n const childTree = convertFlightRouterStateToRouteTree(\n childRouterState,\n childKey\n )\n if (slots === null) {\n slots = {\n [parallelRouteKey]: childTree,\n }\n } else {\n slots[parallelRouteKey] = childTree\n }\n }\n\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 them\n // entirely on the client, similar to our plan for dynamic params.\n const originalSegment = flightRouterState[0]\n const segmentWithoutSearchParams =\n typeof originalSegment === 'string' &&\n originalSegment.startsWith(PAGE_SEGMENT_KEY)\n ? PAGE_SEGMENT_KEY\n : originalSegment\n\n return {\n key,\n segment: segmentWithoutSearchParams,\n slots,\n isRootLayout: flightRouterState[4] === true,\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): 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 key = task.key\n const href = key.href\n const nextUrl = key.nextUrl\n const segmentPath = '/_tree'\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 // In output: \"export\" mode, we need to add the segment path to the URL.\n const url = new URL(href)\n const requestUrl = isOutputExportMode\n ? addSegmentPathToUrlInOutputExportMode(url, segmentPath)\n : url\n\n try {\n const response = await fetchPrefetchResponse(requestUrl, headers)\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(\n new URL(\n response.redirected\n ? removeSegmentPathFromURLInOutputExportMode(\n href,\n requestUrl.href,\n response.url\n )\n : href\n )\n )\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 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(\n prefetchStream\n ) as Promise<RootTreePrefetch>)\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 rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n\n const staleTimeMs = serverData.staleTime * 1000\n fulfillRouteCacheEntry(\n entry,\n convertRootTreePrefetchToRouteTree(serverData),\n serverData.head,\n serverData.isHeadPartial,\n Date.now() + staleTimeMs,\n couldBeIntercepted,\n canonicalUrl,\n routeIsPPREnabled\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 = await (createFromNextReadableStream(\n prefetchStream\n ) as Promise<NavigationFlightResponse>)\n\n writeDynamicTreeResponseIntoCache(\n Date.now(),\n response,\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 segmentPath: string\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 normalizedSegmentPath =\n segmentPath === ROOT_SEGMENT_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'\n : segmentPath\n\n const headers: RequestHeaders = {\n [RSC_HEADER]: '1',\n [NEXT_ROUTER_PREFETCH_HEADER]: '1',\n [NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: normalizedSegmentPath,\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, normalizedSegmentPath)\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 ) 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: FetchStrategy,\n dynamicRequestTree: FlightRouterState,\n spawnedEntries: Map<string, 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]: encodeURIComponent(\n JSON.stringify(dynamicRequestTree)\n ),\n }\n if (nextUrl !== null) {\n headers[NEXT_URL] = nextUrl\n }\n // Only set the prefetch header if we're not doing a \"full\" prefetch. We\n // 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 if (fetchStrategy !== FetchStrategy.Full) {\n headers[NEXT_ROUTER_PREFETCH_HEADER] = '1'\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 // 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 ) as Promise<NavigationFlightResponse>)\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 response,\n serverData,\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 response: Response,\n serverData: NavigationFlightResponse,\n entry: PendingRouteCacheEntry,\n couldBeIntercepted: boolean,\n canonicalUrl: string,\n routeIsPPREnabled: boolean\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 rejectRouteCacheEntry(entry, now + 10 * 1000)\n return\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 ? parseInt(staleTimeHeaderSeconds, 10) * 1000\n : STATIC_STALETIME_MS\n fulfillRouteCacheEntry(\n entry,\n convertRootFlightRouterStateToRouteTree(flightRouterState),\n flightData.head,\n flightData.isHeadPartial,\n now + staleTimeMs,\n couldBeIntercepted,\n canonicalUrl,\n routeIsPPREnabled\n )\n}\n\nfunction rejectSegmentEntriesIfStillPending(\n entries: Map<string, 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 response: Response,\n serverData: NavigationFlightResponse,\n route: FulfilledRouteCacheEntry,\n spawnedEntries: Map<string, PendingSegmentCacheEntry>\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 rejectSegmentEntriesIfStillPending(spawnedEntries, now + 10 * 1000)\n return null\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 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 segmentKey = ROOT_SEGMENT_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 segmentKey = encodeChildSegmentKey(\n segmentKey,\n parallelRouteKey,\n encodeSegment(segment)\n )\n }\n const staleTimeHeaderSeconds = response.headers.get(\n NEXT_ROUTER_STALE_TIME_HEADER\n )\n const staleTimeMs =\n staleTimeHeaderSeconds !== null\n ? parseInt(staleTimeHeaderSeconds, 10) * 1000\n : STATIC_STALETIME_MS\n writeSeedDataIntoCache(\n now,\n task,\n route,\n now + staleTimeMs,\n seedData,\n segmentKey,\n spawnedEntries\n )\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 const fulfilledEntries = rejectSegmentEntriesIfStillPending(\n spawnedEntries,\n now + 10 * 1000\n )\n return fulfilledEntries\n}\n\nfunction writeSeedDataIntoCache(\n now: number,\n task: PrefetchTask,\n route: FulfilledRouteCacheEntry,\n staleAt: number,\n seedData: CacheNodeSeedData,\n key: string,\n entriesOwnedByCurrentTask: Map<string, PendingSegmentCacheEntry>\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[1]\n const loading = seedData[3]\n const isPartial = rsc === null\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 = entriesOwnedByCurrentTask.get(key)\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 task,\n route,\n key\n )\n if (possiblyNewEntry.status === EntryStatus.Empty) {\n // Confirmed this is a new entry. We can fulfill it.\n const newEntry = possiblyNewEntry\n fulfillSegmentCacheEntry(newEntry, rsc, loading, staleAt, isPartial)\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 createDetachedSegmentCacheEntry(staleAt),\n rsc,\n loading,\n staleAt,\n isPartial\n )\n upsertSegmentEntry(\n now,\n getSegmentKeypathForTask(task, route, key),\n newEntry\n )\n }\n }\n // Recursively write the child data into the cache.\n const seedDataChildren = seedData[2]\n if (seedDataChildren !== null) {\n for (const parallelRouteKey in seedDataChildren) {\n const childSeedData = seedDataChildren[parallelRouteKey]\n if (childSeedData !== null) {\n const childSegment = childSeedData[0]\n writeSeedDataIntoCache(\n now,\n task,\n route,\n staleAt,\n childSeedData,\n encodeChildSegmentKey(\n key,\n parallelRouteKey,\n encodeSegment(childSegment)\n ),\n entriesOwnedByCurrentTask\n )\n }\n }\n }\n}\n\nasync function fetchPrefetchResponse(\n url: URL,\n headers: RequestHeaders\n): Promise<Response | null> {\n const fetchPriority = 'low'\n const response = await createFetch(url, headers, fetchPriority)\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: string\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.substring(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\nfunction removeSegmentPathFromURLInOutputExportMode(\n href: string,\n requestUrl: string,\n redirectUrl: string\n) {\n if (isOutputExportMode) {\n // Reverse of addSegmentPathToUrlInOutputExportMode.\n //\n // In output: \"export\" mode, we append an extra string to the URL that\n // represents the segment path. If the server performs a redirect, it must\n // include the segment path in new URL.\n //\n // This removes the segment path from the redirected URL to obtain the\n // URL of the page.\n const segmentPath = requestUrl.substring(href.length)\n if (redirectUrl.endsWith(segmentPath)) {\n // Remove the segment path from the redirect URL to get the page URL.\n return redirectUrl.substring(0, redirectUrl.length - segmentPath.length)\n } else {\n // The server redirected to a URL that doesn't include the segment path.\n // This suggests the server may not have been configured correctly, but\n // we'll assume the redirected URL represents the page URL and continue.\n // TODO: Consider printing a warning with a link to a page that explains\n // how to configure redirects and rewrites correctly.\n }\n }\n return redirectUrl\n}\n\nfunction createPromiseWithResolvers<T>(): PromiseWithResolvers<T> {\n // Shim of Stage 4 Promise.withResolvers proposal\n let resolve: (value: T | PromiseLike<T>) => void\n let reject: (reason: any) => void\n const promise = new Promise<T>((res, rej) => {\n resolve = res\n reject = rej\n })\n return { resolve: resolve!, reject: reject!, promise }\n}\n"],"names":["EntryStatus","FetchStrategy","convertRouteTreeToFlightRouterState","createDetachedSegmentCacheEntry","fetchRouteOnCacheMiss","fetchSegmentOnCacheMiss","fetchSegmentPrefetchesUsingDynamicRequest","getCurrentCacheVersion","getSegmentKeypathForTask","readExactRouteCacheEntry","readOrCreateRevalidatingSegmentEntry","readOrCreateRouteCacheEntry","readOrCreateSegmentCacheEntry","readRouteCacheEntry","readSegmentCacheEntry","resetRevalidatingSegmentEntry","revalidateEntireCache","upgradeToPendingSegment","upsertSegmentEntry","waitForSegmentCacheEntry","isOutputExportMode","process","env","NODE_ENV","__NEXT_CONFIG_OUTPUT","routeCacheMap","createTupleMap","maxRouteLruSize","routeCacheLru","createLRU","onRouteLRUEviction","segmentCacheMap","maxSegmentLruSize","segmentCacheLru","onSegmentLRUEviction","currentCacheVersion","nextUrl","tree","pingVisibleLinks","now","href","keypath","existingEntry","get","staleAt","put","deleteRouteFromCache","key","nonInterceptedEntry","couldBeIntercepted","task","route","path","isDynamicTask","includeDynamicData","isPPREnabled","endsWith","PAGE_SEGMENT_KEY","search","routeCacheKey","readExactSegmentCacheEntry","entryWithSearchParams","entryWithoutSearchParams","revalidatingEntry","revalidating","upsertedEntry","deleteSegmentFromCache","readRevalidatingSegmentCacheEntry","owner","existingRevalidation","clearRevalidatingSegmentFromOwner","pendingEntry","promiseWithResolvers","promise","createPromiseWithResolvers","canonicalUrl","status","blockedTasks","head","isHeadPartial","Infinity","next","prev","size","set","prevEntry","candidateEntry","isPartial","rejectedEntry","loading","rsc","emptyEntry","fetchStrategy","entry","pingBlockedTasks","delete","cancelEntryListeners","revalidatingSegment","resolve","pingPrefetchTask","fulfillRouteCacheEntry","fulfilledEntry","fulfillSegmentCacheEntry","segmentCacheEntry","rejectRouteCacheEntry","rejectSegmentCacheEntry","convertRootTreePrefetchToRouteTree","rootTree","convertTreePrefetchToRouteTree","ROOT_SEGMENT_KEY","prefetch","slots","prefetchSlots","parallelRouteKey","childPrefetch","childSegment","segment","childKey","encodeChildSegmentKey","encodeSegment","isRootLayout","convertRootFlightRouterStateToRouteTree","flightRouterState","convertFlightRouterStateToRouteTree","parallelRoutes","childRouterState","childTree","originalSegment","segmentWithoutSearchParams","startsWith","routeTree","segmentPath","headers","RSC_HEADER","NEXT_ROUTER_PREFETCH_HEADER","NEXT_ROUTER_SEGMENT_PREFETCH_HEADER","NEXT_URL","url","URL","requestUrl","addSegmentPathToUrlInOutputExportMode","response","fetchPrefetchResponse","ok","body","Date","createHrefFromUrl","redirected","removeSegmentPathFromURLInOutputExportMode","varyHeader","includes","closed","routeIsPPREnabled","NEXT_DID_POSTPONE_HEADER","prefetchStream","createPrefetchResponseStream","onResponseSizeUpdate","updateSize","serverData","createFromNextReadableStream","buildId","getAppBuildId","staleTimeMs","staleTime","writeDynamicTreeResponseIntoCache","currentKeypath","expectedEntry","newKeypath","value","error","routeKey","normalizedSegmentPath","dynamicRequestTree","spawnedEntries","NEXT_ROUTER_STATE_TREE_HEADER","encodeURIComponent","JSON","stringify","rejectSegmentEntriesIfStillPending","fulfilledEntries","totalBytesReceivedSoFar","averageSize","length","writeDynamicRenderResponseIntoCache","b","normalizedFlightDataResult","normalizeFlightData","f","flightData","isRootRender","staleTimeHeaderSeconds","NEXT_ROUTER_STALE_TIME_HEADER","parseInt","STATIC_STALETIME_MS","entries","values","push","flightDatas","seedData","segmentKey","i","writeSeedDataIntoCache","entriesOwnedByCurrentTask","ownedEntry","undefined","possiblyNewEntry","newEntry","seedDataChildren","childSeedData","fetchPriority","createFetch","contentType","isFlightResponse","RSC_CONTENT_TYPE_HEADER","originalFlightStream","onStreamClose","totalByteLength","reader","getReader","ReadableStream","pull","controller","done","read","enqueue","byteLength","staticUrl","routeDir","pathname","substring","staticExportFilename","convertSegmentPathToStaticExportFilename","redirectUrl","reject","Promise","res","rej"],"mappings":"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"}
Save
Close
Exit & Reset
Text mode: syntax highlighting auto-detects file type.
Directory Contents
Dirs: 0 × Files: 21
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
cache-key.d.ts
509 B
lrw-r--r--
2025-03-28 11:04:44
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
cache-key.js
877 B
lrw-r--r--
2025-03-28 11:04:39
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
cache-key.js.map
1.36 KB
lrw-r--r--
2025-03-28 11:04:43
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
cache.d.ts
6.58 KB
lrw-r--r--
2025-03-28 11:04:44
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
cache.js
52.66 KB
lrw-r--r--
2025-03-28 11:04:39
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
cache.js.map
83.03 KB
lrw-r--r--
2025-03-28 11:04:43
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
lru.d.ts
349 B
lrw-r--r--
2025-03-28 11:04:45
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
lru.js
4.00 KB
lrw-r--r--
2025-03-28 11:04:41
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
lru.js.map
5.96 KB
lrw-r--r--
2025-03-28 11:04:44
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
navigation.d.ts
1.58 KB
lrw-r--r--
2025-03-28 11:04:45
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
navigation.js
16.45 KB
lrw-r--r--
2025-03-28 11:04:41
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
navigation.js.map
26.50 KB
lrw-r--r--
2025-03-28 11:04:44
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
prefetch.d.ts
846 B
lrw-r--r--
2025-03-28 11:04:45
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
prefetch.js
1.15 KB
lrw-r--r--
2025-03-28 11:04:41
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
prefetch.js.map
1.96 KB
lrw-r--r--
2025-03-28 11:04:44
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
scheduler.d.ts
4.56 KB
lrw-r--r--
2025-03-28 11:04:45
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
scheduler.js
38.00 KB
lrw-r--r--
2025-03-28 11:04:42
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
scheduler.js.map
60.44 KB
lrw-r--r--
2025-03-28 11:04:44
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
tuple-map.d.ts
858 B
lrw-r--r--
2025-03-28 11:04:45
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
tuple-map.js
5.39 KB
lrw-r--r--
2025-03-28 11:04:42
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
tuple-map.js.map
8.29 KB
lrw-r--r--
2025-03-28 11:04:44
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).