{"version":3,"sources":["../../../../src/client/components/router-reducer/create-initial-router-state.ts"],"sourcesContent":["import type { InitialRSCPayload } from '../../../shared/lib/app-router-types'\n\nimport { createHrefFromUrl } from './create-href-from-url'\nimport { extractPathFromFlightRouterState } from './compute-changed-path'\n\nimport type { AppRouterState } from './router-reducer-types'\nimport { getFlightDataPartsFromPath } from '../../flight-data-helpers'\nimport { createInitialCacheNodeForHydration } from './ppr-navigations'\nimport {\n  convertRootFlightRouterStateToRouteTree,\n  getStaleAt,\n  processRuntimePrefetchStream,\n  writeDynamicRenderResponseIntoCache,\n  writeStaticStageResponseIntoCache,\n} from '../segment-cache/cache'\nimport { FetchStrategy } from '../segment-cache/types'\nimport {\n  UnknownDynamicStaleTime,\n  computeDynamicStaleAt,\n} from '../segment-cache/bfcache'\nimport { decodeStaticStage } from './fetch-server-response'\nimport { discoverKnownRoute } from '../segment-cache/optimistic-routes'\nimport type { NormalizedSearch } from '../segment-cache/cache-key'\n\nexport interface InitialRouterStateParameters {\n  navigatedAt: number\n  initialRSCPayload: InitialRSCPayload\n  initialFlightStreamForCache?: ReadableStream<Uint8Array> | null\n  location: Location | null\n}\n\nexport function createInitialRouterState({\n  navigatedAt,\n  initialRSCPayload,\n  initialFlightStreamForCache,\n  location,\n}: InitialRouterStateParameters): AppRouterState {\n  const {\n    c: initialCanonicalUrlParts,\n    f: initialFlightData,\n    q: initialRenderedSearch,\n    i: initialCouldBeIntercepted,\n    S: initialSupportsPerSegmentPrefetching,\n    s: initialStaleTime,\n    l: initialStaticStageByteLength,\n    h: initialHeadVaryParams,\n    p: initialRuntimePrefetchStream,\n    d: initialDynamicStaleTimeSeconds,\n  } = initialRSCPayload\n\n  // When initialized on the server, the canonical URL is provided as an array of parts.\n  // This is to ensure that when the RSC payload streamed to the client, crawlers don't interpret it\n  // as a URL that should be crawled.\n  const initialCanonicalUrl = initialCanonicalUrlParts.join('/')\n\n  const normalizedFlightData = getFlightDataPartsFromPath(initialFlightData[0])\n  const {\n    tree: initialTree,\n    seedData: initialSeedData,\n    head: initialHead,\n  } = normalizedFlightData\n  // For the SSR render, seed data should always be available (we only send back a `null` response\n  // in the case of a `loading` segment, pre-PPR.)\n\n  const canonicalUrl =\n    // location.href is read as the initial value for canonicalUrl in the browser\n    // This is safe to do as canonicalUrl can't be rendered, it's only used to control the history updates in the useEffect further down in this file.\n    location\n      ? // window.location does not have the same type as URL but has all the fields createHrefFromUrl needs.\n        createHrefFromUrl(location)\n      : initialCanonicalUrl\n\n  // Convert the initial FlightRouterState into the RouteTree type.\n  // NOTE: The metadataVaryPath isn't used for anything currently because the\n  // head is embedded into the CacheNode tree, but eventually we'll lift it out\n  // and store it on the top-level state object.\n  //\n  // TODO: For statically-generated-at-build-time HTML pages, the\n  // FlightRouterState baked into the initial RSC payload won't have the\n  // correct segment inlining hints (ParentInlinedIntoSelf, InlinedIntoChild)\n  // because those are computed after the pre-render. The client will need to\n  // fetch the correct hints from the route tree prefetch (/_tree) response\n  // before acting on inlining decisions.\n  const acc = { metadataVaryPath: null }\n  const initialRouteTree = convertRootFlightRouterStateToRouteTree(\n    initialTree,\n    initialRenderedSearch as NormalizedSearch,\n    acc\n  )\n  const metadataVaryPath = acc.metadataVaryPath\n  const initialTask = createInitialCacheNodeForHydration(\n    navigatedAt,\n    initialRouteTree,\n    initialSeedData,\n    initialHead,\n    computeDynamicStaleAt(\n      navigatedAt,\n      initialDynamicStaleTimeSeconds ?? UnknownDynamicStaleTime\n    )\n  )\n\n  // The following only applies in the browser (location !== null) since neither\n  // route learning nor segment cache state persists from SSR to client.\n  if (location !== null && metadataVaryPath !== null) {\n    // Learn the route pattern so we can predict it for future navigations.\n    discoverKnownRoute(\n      Date.now(),\n      location.pathname,\n      null, // nextUrl — initial render is never an interception\n      null, // No pending entry\n      initialRouteTree,\n      metadataVaryPath,\n      initialCouldBeIntercepted,\n      canonicalUrl,\n      initialSupportsPerSegmentPrefetching,\n      false // hasDynamicRewrite\n    )\n\n    // Write the initial seed data into the segment cache so subsequent\n    // navigations to the initial page can serve cached segments instantly.\n    if (initialSeedData !== null && initialStaleTime !== undefined) {\n      if (\n        initialStaticStageByteLength !== undefined &&\n        initialFlightStreamForCache != null\n      ) {\n        // Partially static page — truncate the cloned Flight stream at the\n        // static stage byte boundary, decode, and cache the static subset.\n        decodeStaticStage<InitialRSCPayload>(\n          initialFlightStreamForCache,\n          initialStaticStageByteLength,\n          undefined\n        )\n          .then(async (staticStageResponse) => {\n            const now = Date.now()\n            const staleAt = await getStaleAt(now, staticStageResponse.s)\n\n            writeStaticStageResponseIntoCache(\n              now,\n              staticStageResponse.f,\n              undefined, // no build ID mismatch check for initial HTML\n              staticStageResponse.h,\n              staleAt,\n              initialTree,\n              initialRenderedSearch,\n              true // isResponsePartial\n            )\n          })\n          .catch(() => {\n            // The static stage processing failed. Not fatal — the page\n            // rendered normally, we just won't write into the cache.\n          })\n      } else {\n        // Fully static page — cache the entire decoded seed data as-is. We're\n        // not using the initial response here (which would allow us to combine\n        // the two branches) to avoid unnecessary decoding of the Flight data,\n        // since we can just take the seed data that we already decoded during\n        // hydration and write it into the cache directly.\n        const now = Date.now()\n\n        getStaleAt(now, initialStaleTime)\n          .then((staleAt) => {\n            writeStaticStageResponseIntoCache(\n              now,\n              initialFlightData,\n              undefined, // buildId — not applicable for initial HTML\n              initialHeadVaryParams,\n              staleAt,\n              initialTree,\n              initialRenderedSearch,\n              false // isResponsePartial\n            )\n          })\n          .catch(() => {\n            // The static stage processing failed. Not fatal — the page\n            // rendered normally, we just won't write into the cache.\n          })\n\n        // Cancel the stream clone — fully static path doesn't need it.\n        initialFlightStreamForCache?.cancel()\n      }\n    } else {\n      // No caching — cancel the unused stream clone.\n      initialFlightStreamForCache?.cancel()\n    }\n\n    // If the initial RSC payload includes an embedded runtime prefetch stream,\n    // decode it and write the runtime data into the segment cache. This allows\n    // subsequent navigations to serve runtime-prefetchable content from cache\n    // without a separate prefetch request.\n    if (initialRuntimePrefetchStream != null) {\n      processRuntimePrefetchStream(\n        Date.now(),\n        initialRuntimePrefetchStream,\n        initialTree,\n        initialRenderedSearch\n      )\n        .then((processed) => {\n          if (processed !== null) {\n            writeDynamicRenderResponseIntoCache(\n              Date.now(),\n              FetchStrategy.PPRRuntime,\n              processed.flightDatas,\n              processed.buildId,\n              processed.isResponsePartial,\n              processed.headVaryParams,\n              processed.staleAt,\n              processed.navigationSeed,\n              null\n            )\n          }\n        })\n        .catch(() => {\n          // Runtime prefetch cache write failed. Not fatal — the page rendered\n          // normally, we just won't cache runtime data.\n        })\n    }\n  }\n\n  // NOTE: We intentionally don't check if any data needs to be fetched from the\n  // server. We assume the initial hydration payload is sufficient to render\n  // the page.\n  //\n  // The completeness of the initial data is an important property that we rely\n  // on as a last-ditch mechanism for recovering the app; we must always be able\n  // to reload a fresh HTML document to get to a consistent state.\n  //\n  // In the future, there may be cases where the server intentionally sends\n  // partial data and expects the client to fill in the rest, in which case this\n  // logic may change. (There already is a similar case where the server sends\n  // _no_ hydration data in the HTML document at all, and the client fetches it\n  // separately, but that's different because we still end up hydrating with a\n  // complete tree.)\n\n  const initialState = {\n    tree: initialTask.route,\n    cache: initialTask.node,\n    pushRef: {\n      pendingPush: false,\n      mpaNavigation: false,\n      // First render needs to preserve the previous window.history.state\n      // to avoid it being overwritten on navigation back/forward with MPA Navigation.\n      preserveCustomHistoryState: true,\n    },\n    focusAndScrollRef: {\n      scrollRef: null,\n      forceScroll: false,\n      onlyHashChange: false,\n      hashFragment: null,\n    },\n    canonicalUrl,\n    renderedSearch: initialRenderedSearch,\n    // the || operator is intentional, the pathname can be an empty string\n    nextUrl:\n      (extractPathFromFlightRouterState(initialTree) || location?.pathname) ??\n      null,\n    previousNextUrl: null,\n    debugInfo: null,\n  }\n\n  return initialState\n}\n"],"names":["createInitialRouterState","navigatedAt","initialRSCPayload","initialFlightStreamForCache","location","c","initialCanonicalUrlParts","f","initialFlightData","q","initialRenderedSearch","i","initialCouldBeIntercepted","S","initialSupportsPerSegmentPrefetching","s","initialStaleTime","l","initialStaticStageByteLength","h","initialHeadVaryParams","p","initialRuntimePrefetchStream","d","initialDynamicStaleTimeSeconds","initialCanonicalUrl","join","normalizedFlightData","getFlightDataPartsFromPath","tree","initialTree","seedData","initialSeedData","head","initialHead","canonicalUrl","createHrefFromUrl","acc","metadataVaryPath","initialRouteTree","convertRootFlightRouterStateToRouteTree","initialTask","createInitialCacheNodeForHydration","computeDynamicStaleAt","UnknownDynamicStaleTime","discoverKnownRoute","Date","now","pathname","undefined","decodeStaticStage","then","staticStageResponse","staleAt","getStaleAt","writeStaticStageResponseIntoCache","catch","cancel","processRuntimePrefetchStream","processed","writeDynamicRenderResponseIntoCache","FetchStrategy","PPRRuntime","flightDatas","buildId","isResponsePartial","headVaryParams","navigationSeed","initialState","route","cache","node","pushRef","pendingPush","mpaNavigation","preserveCustomHistoryState","focusAndScrollRef","scrollRef","forceScroll","onlyHashChange","hashFragment","renderedSearch","nextUrl","extractPathFromFlightRouterState","previousNextUrl","debugInfo"],"mappings":"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","ignoreList":[0]}