{"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":["createHrefFromUrl","extractPathFromFlightRouterState","getFlightDataPartsFromPath","createInitialCacheNodeForHydration","convertRootFlightRouterStateToRouteTree","getStaleAt","processRuntimePrefetchStream","writeDynamicRenderResponseIntoCache","writeStaticStageResponseIntoCache","FetchStrategy","UnknownDynamicStaleTime","computeDynamicStaleAt","decodeStaticStage","discoverKnownRoute","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","tree","initialTree","seedData","initialSeedData","head","initialHead","canonicalUrl","acc","metadataVaryPath","initialRouteTree","initialTask","Date","now","pathname","undefined","then","staticStageResponse","staleAt","catch","cancel","processed","PPRRuntime","flightDatas","buildId","isResponsePartial","headVaryParams","navigationSeed","initialState","route","cache","node","pushRef","pendingPush","mpaNavigation","preserveCustomHistoryState","focusAndScrollRef","scrollRef","forceScroll","onlyHashChange","hashFragment","renderedSearch","nextUrl","previousNextUrl","debugInfo"],"mappings":"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","ignoreList":[0]}