{"version":3,"sources":["../../../../../src/client/dev/hot-reloader/turbopack-hot-reloader-common.ts"],"sourcesContent":["import type { TurbopackMessage } from '../../../server/dev/hot-reloader-types'\nimport type { Update as TurbopackUpdate } from '../../../build/swc/types'\n\ndeclare global {\n  interface Window {\n    __NEXT_HMR_TURBOPACK_REPORT_NOISY_NOOP_EVENTS: boolean | undefined\n  }\n}\n\n// How long to wait before reporting the HMR start, used to suppress irrelevant\n// `BUILDING` events. Does not impact reported latency.\nconst TURBOPACK_HMR_START_DELAY_MS = 100\n\ninterface HmrUpdate {\n  hasUpdates: boolean\n  updatedModules: Set<string>\n  startMsSinceEpoch: number\n  endMsSinceEpoch: number\n}\n\nexport class TurbopackHmr {\n  #updatedModules: Set<string>\n  #startMsSinceEpoch: number | undefined\n  #lastUpdateMsSinceEpoch: number | undefined\n  #deferredReportHmrStartId: ReturnType<typeof setTimeout> | undefined\n  #reportedHmrStart: boolean\n\n  constructor() {\n    this.#updatedModules = new Set()\n    this.#reportedHmrStart = false\n  }\n\n  // HACK: Turbopack tends to generate a lot of irrelevant \"BUILDING\" actions,\n  // as it reports *any* compilation, including fully no-op/cached compilations\n  // and those unrelated to HMR. Fixing this would require significant\n  // architectural changes.\n  //\n  // Work around this by deferring any \"rebuilding\" message by 100ms. If we get\n  // a BUILT event within that threshold and nothing has changed, just suppress\n  // the message entirely.\n  #runDeferredReportHmrStart() {\n    if (this.#deferredReportHmrStartId != null) {\n      console.log('[Fast Refresh] rebuilding')\n      this.#reportedHmrStart = true\n      this.#cancelDeferredReportHmrStart()\n    }\n  }\n\n  #cancelDeferredReportHmrStart() {\n    clearTimeout(this.#deferredReportHmrStartId)\n    this.#deferredReportHmrStartId = undefined\n  }\n\n  onBuilding() {\n    this.#lastUpdateMsSinceEpoch = undefined\n    this.#cancelDeferredReportHmrStart()\n    this.#startMsSinceEpoch = Date.now()\n\n    // report the HMR start after a short delay\n    this.#deferredReportHmrStartId = setTimeout(\n      () => this.#runDeferredReportHmrStart(),\n      // debugging feature: don't defer/suppress noisy no-op HMR update messages\n      self.__NEXT_HMR_TURBOPACK_REPORT_NOISY_NOOP_EVENTS\n        ? 0\n        : TURBOPACK_HMR_START_DELAY_MS\n    )\n  }\n\n  /** Helper for other `onEvent` methods. */\n  #onUpdate() {\n    this.#runDeferredReportHmrStart()\n    this.#lastUpdateMsSinceEpoch = Date.now()\n  }\n\n  onTurbopackMessage(msg: TurbopackMessage) {\n    this.#onUpdate()\n    const updatedModules = extractModulesFromTurbopackMessage(msg.data)\n    for (const module of updatedModules) {\n      this.#updatedModules.add(module)\n    }\n  }\n\n  onServerComponentChanges() {\n    this.#onUpdate()\n  }\n\n  onReloadPage() {\n    this.#onUpdate()\n  }\n\n  onPageAddRemove() {\n    this.#onUpdate()\n  }\n\n  /**\n   * @returns `null` if the caller should ignore the update entirely. Returns an\n   *   object with `hasUpdates: false` if the caller should report the end of\n   *   the HMR in the browser console, but the HMR was a no-op.\n   */\n  onBuilt(): HmrUpdate | null {\n    // Check that we got *any* `TurbopackMessage`, even if\n    // `updatedModules` is empty (not everything gets recorded there).\n    //\n    // There's also a case where `onBuilt` gets called before `onBuilding`,\n    // which can happen during initial page load. Ignore that too!\n    const hasUpdates =\n      this.#lastUpdateMsSinceEpoch != null && this.#startMsSinceEpoch != null\n    if (!hasUpdates && !this.#reportedHmrStart) {\n      // suppress the update entirely\n      this.#cancelDeferredReportHmrStart()\n      return null\n    }\n    this.#runDeferredReportHmrStart()\n\n    const result = {\n      hasUpdates,\n      updatedModules: this.#updatedModules,\n      startMsSinceEpoch: this.#startMsSinceEpoch!,\n      endMsSinceEpoch: this.#lastUpdateMsSinceEpoch ?? Date.now(),\n    }\n    this.#updatedModules = new Set()\n    this.#reportedHmrStart = false\n    return result\n  }\n}\n\nfunction extractModulesFromTurbopackMessage(\n  data: TurbopackUpdate | TurbopackUpdate[]\n): Set<string> {\n  const updatedModules: Set<string> = new Set()\n\n  const updates = Array.isArray(data) ? data : [data]\n  for (const update of updates) {\n    // TODO this won't capture changes to CSS since they don't result in a \"merged\" update\n    if (\n      update.type !== 'partial' ||\n      update.instruction.type !== 'ChunkListUpdate' ||\n      update.instruction.merged === undefined\n    ) {\n      continue\n    }\n\n    for (const mergedUpdate of update.instruction.merged) {\n      for (const name of Object.keys(mergedUpdate.entries)) {\n        const res = /(.*)\\s+[([].*/.exec(name)\n        if (res === null) {\n          continue\n        }\n\n        updatedModules.add(res[1])\n      }\n    }\n  }\n\n  return updatedModules\n}\n"],"names":["TURBOPACK_HMR_START_DELAY_MS","TurbopackHmr","constructor","Set","console","log","clearTimeout","undefined","onBuilding","Date","now","setTimeout","self","__NEXT_HMR_TURBOPACK_REPORT_NOISY_NOOP_EVENTS","onTurbopackMessage","msg","updatedModules","extractModulesFromTurbopackMessage","data","module","add","onServerComponentChanges","onReloadPage","onPageAddRemove","onBuilt","hasUpdates","result","startMsSinceEpoch","endMsSinceEpoch","updates","Array","isArray","update","type","instruction","merged","mergedUpdate","name","Object","keys","entries","res","exec"],"mappings":"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","ignoreList":[0]}