{"version":3,"sources":["../../../../src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts"],"sourcesContent":["import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime'\nimport type {\n  FlightRouterState,\n  CacheNodeSeedData,\n} from '../../../server/app-render/types'\nimport { createRouterCacheKey } from './create-router-cache-key'\nimport {\n  PrefetchCacheEntryStatus,\n  type PrefetchCacheEntry,\n} from './router-reducer-types'\n\nexport function fillLazyItemsTillLeafWithHead(\n  navigatedAt: number,\n  newCache: CacheNode,\n  existingCache: CacheNode | undefined,\n  routerState: FlightRouterState,\n  cacheNodeSeedData: CacheNodeSeedData | null,\n  head: React.ReactNode,\n  prefetchEntry: PrefetchCacheEntry | undefined\n): void {\n  const isLastSegment = Object.keys(routerState[1]).length === 0\n  if (isLastSegment) {\n    newCache.head = head\n    return\n  }\n  // Remove segment that we got data for so that it is filled in during rendering of rsc.\n  for (const key in routerState[1]) {\n    const parallelRouteState = routerState[1][key]\n    const segmentForParallelRoute = parallelRouteState[0]\n    const cacheKey = createRouterCacheKey(segmentForParallelRoute)\n\n    // TODO: We should traverse the cacheNodeSeedData tree instead of the router\n    // state tree. Ideally, they would always be the same shape, but because of\n    // the loading.js pattern, cacheNodeSeedData sometimes only represents a\n    // partial tree. That's why this node is sometimes null. Once PPR lands,\n    // loading.js will no longer have special behavior and we can traverse the\n    // data tree instead.\n    //\n    // We should also consider merging the router state tree and the data tree\n    // in the response format, so that we don't have to send the keys twice.\n    // Then the client can convert them into separate representations.\n    const parallelSeedData =\n      cacheNodeSeedData !== null && cacheNodeSeedData[2][key] !== undefined\n        ? cacheNodeSeedData[2][key]\n        : null\n    if (existingCache) {\n      const existingParallelRoutesCacheNode =\n        existingCache.parallelRoutes.get(key)\n      if (existingParallelRoutesCacheNode) {\n        const hasReusablePrefetch =\n          prefetchEntry?.kind === 'auto' &&\n          prefetchEntry.status === PrefetchCacheEntryStatus.reusable\n\n        let parallelRouteCacheNode = new Map(existingParallelRoutesCacheNode)\n        const existingCacheNode = parallelRouteCacheNode.get(cacheKey)\n        let newCacheNode: CacheNode\n        if (parallelSeedData !== null) {\n          // New data was sent from the server.\n          const seedNode = parallelSeedData[1]\n          const loading = parallelSeedData[3]\n          newCacheNode = {\n            lazyData: null,\n            rsc: seedNode,\n            // This is a PPR-only field. When PPR is enabled, we shouldn't hit\n            // this path during a navigation, but until PPR is fully implemented\n            // yet it's possible the existing node does have a non-null\n            // `prefetchRsc`. As an incremental step, we'll just de-opt to the\n            // old behavior — no PPR value.\n            prefetchRsc: null,\n            head: null,\n            prefetchHead: null,\n            loading,\n            parallelRoutes: new Map(existingCacheNode?.parallelRoutes),\n            navigatedAt,\n          }\n        } else if (hasReusablePrefetch && existingCacheNode) {\n          // No new data was sent from the server, but the existing cache node\n          // was prefetched, so we should reuse that.\n          newCacheNode = {\n            lazyData: existingCacheNode.lazyData,\n            rsc: existingCacheNode.rsc,\n            // This is a PPR-only field. Unlike the previous branch, since we're\n            // just cloning the existing cache node, we might as well keep the\n            // PPR value, if it exists.\n            prefetchRsc: existingCacheNode.prefetchRsc,\n            head: existingCacheNode.head,\n            prefetchHead: existingCacheNode.prefetchHead,\n            parallelRoutes: new Map(existingCacheNode.parallelRoutes),\n            loading: existingCacheNode.loading,\n          } as CacheNode\n        } else {\n          // No data available for this node. This will trigger a lazy fetch\n          // during render.\n          newCacheNode = {\n            lazyData: null,\n            rsc: null,\n            prefetchRsc: null,\n            head: null,\n            prefetchHead: null,\n            parallelRoutes: new Map(existingCacheNode?.parallelRoutes),\n            loading: null,\n            navigatedAt,\n          }\n        }\n\n        // Overrides the cache key with the new cache node.\n        parallelRouteCacheNode.set(cacheKey, newCacheNode)\n        // Traverse deeper to apply the head / fill lazy items till the head.\n        fillLazyItemsTillLeafWithHead(\n          navigatedAt,\n          newCacheNode,\n          existingCacheNode,\n          parallelRouteState,\n          parallelSeedData ? parallelSeedData : null,\n          head,\n          prefetchEntry\n        )\n\n        newCache.parallelRoutes.set(key, parallelRouteCacheNode)\n        continue\n      }\n    }\n\n    let newCacheNode: CacheNode\n    if (parallelSeedData !== null) {\n      // New data was sent from the server.\n      const seedNode = parallelSeedData[1]\n      const loading = parallelSeedData[3]\n      newCacheNode = {\n        lazyData: null,\n        rsc: seedNode,\n        prefetchRsc: null,\n        head: null,\n        prefetchHead: null,\n        parallelRoutes: new Map(),\n        loading,\n        navigatedAt,\n      }\n    } else {\n      // No data available for this node. This will trigger a lazy fetch\n      // during render.\n      newCacheNode = {\n        lazyData: null,\n        rsc: null,\n        prefetchRsc: null,\n        head: null,\n        prefetchHead: null,\n        parallelRoutes: new Map(),\n        loading: null,\n        navigatedAt,\n      }\n    }\n\n    const existingParallelRoutes = newCache.parallelRoutes.get(key)\n    if (existingParallelRoutes) {\n      existingParallelRoutes.set(cacheKey, newCacheNode)\n    } else {\n      newCache.parallelRoutes.set(key, new Map([[cacheKey, newCacheNode]]))\n    }\n\n    fillLazyItemsTillLeafWithHead(\n      navigatedAt,\n      newCacheNode,\n      undefined,\n      parallelRouteState,\n      parallelSeedData,\n      head,\n      prefetchEntry\n    )\n  }\n}\n"],"names":["fillLazyItemsTillLeafWithHead","navigatedAt","newCache","existingCache","routerState","cacheNodeSeedData","head","prefetchEntry","isLastSegment","Object","keys","length","key","parallelRouteState","segmentForParallelRoute","cacheKey","createRouterCacheKey","parallelSeedData","undefined","existingParallelRoutesCacheNode","parallelRoutes","get","hasReusablePrefetch","kind","status","PrefetchCacheEntryStatus","reusable","parallelRouteCacheNode","Map","existingCacheNode","newCacheNode","seedNode","loading","lazyData","rsc","prefetchRsc","prefetchHead","set","existingParallelRoutes"],"mappings":"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","ignoreList":[0]}