{"version":3,"sources":["../../../../src/client/dev/debug-channel.ts"],"sourcesContent":["import { NEXT_REQUEST_ID_HEADER } from '../components/app-router-headers'\nimport { InvariantError } from '../../shared/lib/invariant-error'\n\nexport interface DebugChannelReadableWriterPair {\n  /**\n   * The remaining, not-yet-handed-out copy of the request's debug stream. A\n   * request can be decoded more than once (the primary decode plus any stage\n   * extractions that re-parse a slice of the same response, see\n   * `decodeStageUntilBoundary`), and each decode needs its own reader. Every\n   * time a consumer asks for the readable we tee it and reassign this field to\n   * the remainder, so each consumer gets an independent branch. The remainder\n   * is only ever tee'd again, never read directly, so it retains every chunk\n   * from the start and replays the full stream into each new branch.\n   */\n  readable: ReadableStream<Uint8Array>\n  readonly writer: WritableStreamDefaultWriter<Uint8Array>\n}\n\nconst pairs = new Map<string, DebugChannelReadableWriterPair>()\n\n/**\n * Upper bound on the number of in-memory debug-channel pairs we retain, evicted\n * least-recently-used, bounding the live per-request map.\n *\n * A pair must outlive its stream's close so a late decode of the same response\n * (the primary decode plus stage extractions via `decodeStageUntilBoundary`,\n * which can run after the channel closed over the WebSocket) still finds the\n * buffered data. The cap only needs to exceed the pairs live or recently closed\n * at once (bounded by how many prefetch/navigation requests are in flight\n * together), so a few dozen leaves ample headroom even for the segment-heavy\n * bursts the Instant Navs DevTools capture can produce.\n */\nconst MAX_DEBUG_CHANNEL_PAIRS = 64\n\nconst DB_NAME = '__next_debug_channel'\nconst STORE_NAME = 'channels'\nconst CREATED_AT_INDEX = 'createdAt'\n/**\n * Upper bound on persisted document debug channels in IndexedDB (one per\n * document, kept for HTTP-cache restore), evicted oldest-first.\n */\nconst MAX_PERSISTED_DOCUMENT_CHANNELS = 10\n\ninterface DebugChannelEntry {\n  readonly requestId: string\n  readonly createdAt: number\n  readonly chunks: Uint8Array[]\n}\n\nfunction openDebugChannelDB(): Promise<IDBDatabase> {\n  return new Promise((resolve, reject) => {\n    const openRequest = indexedDB.open(DB_NAME, 1)\n    openRequest.onupgradeneeded = () => {\n      const store = openRequest.result.createObjectStore(STORE_NAME, {\n        keyPath: 'requestId',\n      })\n      store.createIndex(CREATED_AT_INDEX, 'createdAt')\n    }\n    openRequest.onsuccess = () => resolve(openRequest.result)\n    openRequest.onerror = () => reject(openRequest.error)\n    openRequest.onblocked = () => reject(openRequest.error)\n  })\n}\n\n/**\n * Resolves on the next idle period via `requestIdleCallback`, falling back to a\n * `setTimeout` where `requestIdleCallback` is unavailable.\n */\nfunction whenIdle(): Promise<void> {\n  return new Promise((resolve) => {\n    if (typeof requestIdleCallback === 'function') {\n      requestIdleCallback(() => resolve())\n    } else {\n      setTimeout(resolve, 0)\n    }\n  })\n}\n\nasync function persistDebugChannelToIndexedDB(\n  requestId: string,\n  chunks: Uint8Array[]\n): Promise<void> {\n  let db: IDBDatabase\n  try {\n    db = await openDebugChannelDB()\n  } catch (error) {\n    console.debug('Failed to open debug channel IndexedDB for write', error)\n    return\n  }\n\n  try {\n    await new Promise<void>((resolve, reject) => {\n      const transaction = db.transaction(STORE_NAME, 'readwrite')\n      const store = transaction.objectStore(STORE_NAME)\n\n      store.put({\n        requestId,\n        createdAt: Date.now(),\n        chunks,\n      } satisfies DebugChannelEntry)\n\n      // Prune oldest entries beyond the cap to bound storage growth across tabs\n      // and/or page loads. The createdAt index gives ordered traversal without\n      // scanning, and the cursor deletes commit atomically with the put above.\n      const countReq = store.count()\n      countReq.onsuccess = () => {\n        let entriesToDelete = countReq.result - MAX_PERSISTED_DOCUMENT_CHANNELS\n        if (entriesToDelete <= 0) {\n          return\n        }\n        const cursorReq = store.index(CREATED_AT_INDEX).openCursor()\n        cursorReq.onsuccess = () => {\n          const cursor = cursorReq.result\n          if (!cursor || entriesToDelete === 0) {\n            return\n          }\n          cursor.delete()\n          entriesToDelete--\n          cursor.continue()\n        }\n      }\n\n      transaction.oncomplete = () => {\n        if (process.env.__NEXT_TEST_MODE) {\n          // Test-only flag, set once this document's debug channel entry is\n          // durably committed. Persistence is deferred to an idle callback and\n          // the IndexedDB write is async, so this flag lets e2e tests await\n          // persistence deterministically — coupling only to \"an entry was\n          // persisted\" and not to how or where it is stored. It resets\n          // naturally on each navigation since every document gets a fresh\n          // window. The local cast keeps the augmentation out of the shipped\n          // declaration files.\n          ;(\n            self as { __NEXT_DEBUG_CHANNEL_PERSISTED?: boolean }\n          ).__NEXT_DEBUG_CHANNEL_PERSISTED = true\n        }\n        resolve()\n      }\n      transaction.onerror = () => reject(transaction.error)\n      transaction.onabort = () => reject(transaction.error)\n    })\n  } catch (error) {\n    // Best-effort: if persistence fails (quota, transaction abort, etc.), an\n    // HTTP cache restore will fall back to location.reload() since no entry\n    // will be found.\n    console.debug('Failed to write debug channel entry to IndexedDB', error)\n  } finally {\n    db.close()\n  }\n}\nfunction restoreDebugChannelFromIndexedDB(\n  requestId: string\n): ReadableStream<Uint8Array> {\n  return new ReadableStream<Uint8Array>({\n    async start(controller) {\n      let entry: DebugChannelEntry | undefined\n\n      try {\n        const db = await openDebugChannelDB()\n        try {\n          entry = await new Promise((resolve, reject) => {\n            const tx = db.transaction(STORE_NAME, 'readonly')\n            const store = tx.objectStore(STORE_NAME)\n            const getReq: IDBRequest<DebugChannelEntry | undefined> =\n              store.get(requestId)\n            getReq.onsuccess = () => resolve(getReq.result)\n            getReq.onerror = () => reject(getReq.error)\n          })\n        } finally {\n          db.close()\n        }\n      } catch (error) {\n        // Treat any IDB failure as \"no entry\" and fall through to reload.\n        console.debug(\n          'Failed to read debug channel entry from IndexedDB',\n          error\n        )\n      }\n\n      if (!entry) {\n        // Debug channel can't be restored — missing debug chunks would block\n        // hydration. Force a fresh page load from the server. Leave the stream\n        // parked (no enqueue, no close) so the Flight client stays put until\n        // the reload tears the document down, instead of synchronously erroring\n        // with \"Connection closed.\".\n        location.reload()\n        return\n      }\n\n      for (const chunk of entry.chunks) {\n        controller.enqueue(chunk)\n      }\n      controller.close()\n    },\n  })\n}\n\nconst enum ExecTimeCacheDecision {\n  /**\n   * The HTML document was served from the browser's cache; replay the\n   * previously persisted chunks instead of waiting for the WebSocket-backed\n   * channel.\n   */\n  CacheRestore,\n\n  /**\n   * The HTML document came fresh from the server. The live WebSocket-backed\n   * channel will deliver the debug chunks.\n   */\n  FreshResponse,\n\n  /**\n   * Can't tell from the navigation entry as it stands now. Caller should defer\n   * to `pageshow` and re-check there with `wasServedFromCacheAtPageshow`.\n   */\n  Undecided,\n}\n\n/**\n * Decide at script-execution time whether the document was served from the\n * browser's cache or freshly fetched from the server. `type === 'back_forward'`\n * alone isn't enough: a back/forward navigation can also be a fresh server\n * re-fetch when the HTTP cache entry was evicted (long-lived tab, storage\n * pressure, manual cache clear), and treating that as a cache restore would\n * trigger an unnecessary `location.reload()` when no persisted chunks are\n * found.\n */\nfunction wasServedFromCacheKnownAtExec(\n  entry: NavigationEntry | undefined\n): ExecTimeCacheDecision {\n  if (!entry) {\n    return ExecTimeCacheDecision.FreshResponse\n  }\n\n  // Safari tab-duplication cache restore: type='navigate' paired with\n  // responseStart=0 (no first-body-byte over the network) and a non-zero\n  // responseEnd. Fresh navigations always have responseStart > 0.\n  if (\n    entry.type === 'navigate' &&\n    entry.responseStart === 0 &&\n    entry.responseEnd > 0\n  ) {\n    return ExecTimeCacheDecision.CacheRestore\n  }\n\n  // Every remaining cache-restore signal requires a back/forward navigation.\n  // (bfcache restores don't re-execute scripts and never reach this code.)\n  if (entry.type !== 'back_forward') {\n    return ExecTimeCacheDecision.FreshResponse\n  }\n\n  // Chrome ≥109 and Safari ≥17 populate `deliveryType` at exec time even when\n  // the size fields aren't filled in yet. This is the only exec-time fast path\n  // for real Safari ≥17 cache restores (Safari leaves encodedBodySize at 0 at\n  // exec).\n  if (entry.deliveryType === 'cache') {\n    return ExecTimeCacheDecision.CacheRestore\n  }\n\n  // Chrome and Firefox publish an HTTP cache restore as transferSize=0 (no\n  // bytes over the wire) plus a non-zero cached body size at exec time.\n  if (entry.transferSize === 0 && entry.encodedBodySize > 0) {\n    return ExecTimeCacheDecision.CacheRestore\n  }\n\n  // No body bytes measured yet. Either the response is still streaming, or\n  // WebKit is reporting transferSize=0 and encodedBodySize=0 at exec time\n  // regardless of whether the document was cached or re-fetched. Defer to\n  // `pageshow` where the two cases become distinguishable.\n  if (entry.encodedBodySize === 0) {\n    return ExecTimeCacheDecision.Undecided\n  }\n\n  // Body bytes already measured at exec time with no other cache signal: a\n  // re-fetched back-nav whose response happened to complete before our script\n  // ran. The deferred branch above would have caught the same case if the\n  // response had still been streaming.\n  return ExecTimeCacheDecision.FreshResponse\n}\n\n/**\n * Re-check the cache-restore decision at `pageshow`, when every browser has\n * populated the navigation-entry size fields. Only called when\n * `wasServedFromCacheKnownAtExec` returned `ExecTimeCacheDecision.Undecided`.\n */\nfunction wasServedFromCacheAtPageshow(\n  entry: NavigationEntry | undefined\n): boolean {\n  if (!entry) {\n    return false\n  }\n\n  // Safari tab-duplication signature; see the matching branch in\n  // `wasServedFromCacheKnownAtExec`.\n  if (\n    entry.type === 'navigate' &&\n    entry.responseStart === 0 &&\n    entry.responseEnd > 0\n  ) {\n    return true\n  }\n\n  // A back/forward navigation where at least one of the size fields is zero\n  // means the body didn't come over the wire. Browsers signal a cache restore\n  // differently — Chrome/Firefox zero `transferSize` and keep a non-zero cached\n  // `encodedBodySize`; Safari does the inverse with a small `transferSize`\n  // (header overhead) and `encodedBodySize=0`; WebKit under Playwright zeros\n  // both. A fresh re-fetch populates both with the response size.\n  return (\n    entry.type === 'back_forward' &&\n    (entry.transferSize === 0 || entry.encodedBodySize === 0)\n  )\n}\n\n/**\n * The DOM lib's `PerformanceNavigationTiming` doesn't include the\n * `deliveryType` property yet, even though it's shipped in Chrome ≥109,\n * Firefox ≥115, and Safari ≥17. See\n * https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-deliverytype.\n */\ntype NavigationEntry = PerformanceNavigationTiming & {\n  readonly deliveryType?: string\n}\n\nfunction getNavigationEntry(): NavigationEntry | undefined {\n  try {\n    return performance.getEntriesByType('navigation')[0] as\n      | NavigationEntry\n      | undefined\n  } catch {\n    return undefined\n  }\n}\n\n/**\n * Reclaim the least-recently-used debug-channel pairs once the map exceeds\n * `MAX_DEBUG_CHANNEL_PAIRS`. The map is iterated in insertion order and we\n * re-insert entries on access (see\n * `getOrCreateDebugChannelReadableWriterPair`), so the least-recently-used\n * pairs sit at the front. Evicting only ever affects future lookups for that\n * request id; consumers that already hold a tee branch keep reading\n * independently of the map.\n */\nfunction evictExcessDebugChannelPairs(): void {\n  while (pairs.size > MAX_DEBUG_CHANNEL_PAIRS) {\n    const oldestRequestId = pairs.keys().next().value\n    if (oldestRequestId === undefined) {\n      break\n    }\n    pairs.delete(oldestRequestId)\n  }\n}\n\nexport function getOrCreateDebugChannelReadableWriterPair(\n  requestId: string\n): DebugChannelReadableWriterPair {\n  const existingPair = pairs.get(requestId)\n  if (existingPair) {\n    // Refresh the LRU recency of an already-known channel by re-inserting it at\n    // the most-recent position, so a channel that's still being written to or\n    // read from isn't evicted while a late consumer (e.g. a stage re-decode of\n    // the same response) still needs it.\n    pairs.delete(requestId)\n    pairs.set(requestId, existingPair)\n    return existingPair\n  }\n\n  // Buffer chunks only for the initial document's debug channel, not for\n  // client-side navigation requests. Persisted to IndexedDB once complete so it\n  // can be restored when the browser serves the page from HTTP cache\n  // (back-forward navigation, tab duplication, etc.).\n  const chunks: Uint8Array[] | null = requestId === self.__next_r ? [] : null\n\n  const { readable, writable } = new TransformStream<Uint8Array, Uint8Array>({\n    transform(chunk, controller) {\n      if (chunks) {\n        chunks.push(chunk.slice())\n      }\n      controller.enqueue(chunk)\n    },\n  })\n\n  const pair: DebugChannelReadableWriterPair = {\n    readable,\n    writer: writable.getWriter(),\n  }\n  pairs.set(requestId, pair)\n  // Retain the pair past its stream's close (see MAX_DEBUG_CHANNEL_PAIRS) and\n  // bound the map by reclaiming the least-recently-used.\n  evictExcessDebugChannelPairs()\n\n  pair.writer.closed\n    .then(async () => {\n      if (!chunks) {\n        return\n      }\n      // The initial document's debug stream closes while hydration is still\n      // running, so persisting here would steal main-thread time from it. Wait\n      // for genuine idle (no timeout): persistence is best-effort, so if the\n      // page never idles before navigation we skip it and a later restore falls\n      // back to a reload, rather than forcing a blocking write.\n      await whenIdle()\n      await persistDebugChannelToIndexedDB(requestId, chunks)\n    })\n    .catch((error) => {\n      // writer.closed rejected (e.g., stream aborted), nothing to persist.\n      console.debug('Debug channel writer closed with error', error)\n    })\n    .finally(() => {\n      // Keep the now-closed pair in the map so late decodes of this request\n      // still resolve against its buffered stream; it's reclaimed later by LRU\n      // eviction. Release the IndexedDB staging buffer now that it's persisted.\n      if (chunks) {\n        chunks.length = 0\n      }\n    })\n\n  return pair\n}\n\nexport function createDebugChannel(\n  requestHeaders: Record<string, string> | undefined\n): {\n  writable?: WritableStream\n  readable?: ReadableStream\n} {\n  let requestId: string | undefined\n\n  if (requestHeaders) {\n    requestId = requestHeaders[NEXT_REQUEST_ID_HEADER] ?? undefined\n\n    if (!requestId) {\n      throw new InvariantError(\n        `Expected a ${JSON.stringify(NEXT_REQUEST_ID_HEADER)} request header.`\n      )\n    }\n  } else {\n    requestId = self.__next_r\n\n    if (!requestId) {\n      throw new InvariantError(\n        `Expected a request ID to be defined for the document via self.__next_r.`\n      )\n    }\n  }\n\n  // Only attempt to restore the IndexedDB debug channel entry for the\n  // initial document load (no request headers). Client-side navigations pass\n  // request headers and should always use the WebSocket-backed debug channel.\n  if (!requestHeaders) {\n    switch (wasServedFromCacheKnownAtExec(getNavigationEntry())) {\n      case ExecTimeCacheDecision.CacheRestore:\n        return { readable: restoreDebugChannelOrReload(requestId) }\n      case ExecTimeCacheDecision.Undecided:\n        // Body bytes haven't been measured on the navigation entry yet. Suspend\n        // the stream until pageshow, re-check there, then source from the\n        // persisted chunks or the WebSocket-backed pair accordingly.\n        return { readable: createDeferredDebugChannelReadable(requestId) }\n      case ExecTimeCacheDecision.FreshResponse:\n        // Fall through to the shared WebSocket-backed channel below.\n        break\n    }\n  }\n\n  const pair = getOrCreateDebugChannelReadableWriterPair(requestId)\n  // Hand out a fresh tee branch per consumer and keep the remainder for the\n  // next one (see the `readable` field doc above).\n  const [branch, rest] = pair.readable.tee()\n  pair.readable = rest\n\n  return { readable: branch }\n}\n\n/**\n * Try to restore the debug channel from the persisted chunks. If none are\n * found, force a fresh page load.\n */\nfunction restoreDebugChannelOrReload(\n  requestId: string\n): ReadableStream<Uint8Array> {\n  const readable = restoreDebugChannelFromIndexedDB(requestId)\n\n  if (readable) {\n    return readable\n  }\n\n  // No persisted entry. Typically this happens when the HTTP cache held the\n  // HTML but the persisted entry was never written, or was overwritten by a\n  // newer document in this tab.\n  location.reload()\n\n  // Never-closing stream. Keeps the Flight client suspended until the reload\n  // tears the document down, instead of letting it synchronously error with\n  // \"Connection closed.\".\n  return new ReadableStream<Uint8Array>()\n}\n\n/**\n * Used when `wasServedFromCacheKnownAtExec` returns\n * `ExecTimeCacheDecision.Undecided`. Waits for `pageshow`, re-runs the check,\n * and forwards data from either the persisted chunks or the WebSocket.\n */\nfunction createDeferredDebugChannelReadable(\n  requestId: string\n): ReadableStream<Uint8Array> {\n  return new ReadableStream<Uint8Array>({\n    async start(controller) {\n      // By `pageshow` every browser has populated the navigation-entry size\n      // fields, so the re-check below is unambiguous.\n      await new Promise<void>((resolve) => {\n        window.addEventListener('pageshow', () => resolve(), { once: true })\n      })\n\n      const source = wasServedFromCacheAtPageshow(getNavigationEntry())\n        ? restoreDebugChannelOrReload(requestId)\n        : getOrCreateDebugChannelReadableWriterPair(requestId).readable\n\n      const reader = source.getReader()\n      try {\n        while (true) {\n          const { done, value } = await reader.read()\n          if (done) {\n            controller.close()\n            return\n          }\n          controller.enqueue(value)\n        }\n      } catch (error) {\n        controller.error(error)\n      } finally {\n        reader.releaseLock()\n      }\n    },\n  })\n}\n"],"names":["NEXT_REQUEST_ID_HEADER","InvariantError","pairs","Map","MAX_DEBUG_CHANNEL_PAIRS","DB_NAME","STORE_NAME","CREATED_AT_INDEX","MAX_PERSISTED_DOCUMENT_CHANNELS","openDebugChannelDB","Promise","resolve","reject","openRequest","indexedDB","open","onupgradeneeded","store","result","createObjectStore","keyPath","createIndex","onsuccess","onerror","error","onblocked","whenIdle","requestIdleCallback","setTimeout","persistDebugChannelToIndexedDB","requestId","chunks","db","console","debug","transaction","objectStore","put","createdAt","Date","now","countReq","count","entriesToDelete","cursorReq","index","openCursor","cursor","delete","continue","oncomplete","process","env","__NEXT_TEST_MODE","self","__NEXT_DEBUG_CHANNEL_PERSISTED","onabort","close","restoreDebugChannelFromIndexedDB","ReadableStream","start","controller","entry","tx","getReq","get","location","reload","chunk","enqueue","wasServedFromCacheKnownAtExec","type","responseStart","responseEnd","deliveryType","transferSize","encodedBodySize","wasServedFromCacheAtPageshow","getNavigationEntry","performance","getEntriesByType","undefined","evictExcessDebugChannelPairs","size","oldestRequestId","keys","next","value","getOrCreateDebugChannelReadableWriterPair","existingPair","set","__next_r","readable","writable","TransformStream","transform","push","slice","pair","writer","getWriter","closed","then","catch","finally","length","createDebugChannel","requestHeaders","JSON","stringify","restoreDebugChannelOrReload","createDeferredDebugChannelReadable","branch","rest","tee","window","addEventListener","once","source","reader","getReader","done","read","releaseLock"],"mappings":"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","ignoreList":[0]}