{"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":["createRouterCacheKey","PrefetchCacheEntryStatus","fillLazyItemsTillLeafWithHead","navigatedAt","newCache","existingCache","routerState","cacheNodeSeedData","head","prefetchEntry","isLastSegment","Object","keys","length","key","parallelRouteState","segmentForParallelRoute","cacheKey","parallelSeedData","undefined","existingParallelRoutesCacheNode","parallelRoutes","get","hasReusablePrefetch","kind","status","reusable","parallelRouteCacheNode","Map","existingCacheNode","newCacheNode","seedNode","loading","lazyData","rsc","prefetchRsc","prefetchHead","set","existingParallelRoutes"],"mappings":"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","ignoreList":[0]}