{"version":3,"file":"log.mjs","names":[],"sources":["../../../src/loadDictionaries/log.ts"],"sourcesContent":["import { default as defaultConfiguration } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n  colorize,\n  getPrefix,\n  spinnerFrames,\n  v,\n  x,\n} from '@intlayer/config/logger';\nimport { extractErrorMessage } from '@intlayer/config/utils';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport class DictionariesLogger {\n  private statuses: DictionariesStatus[] = [];\n  private spinnerTimer: NodeJS.Timeout | null = null;\n  private spinnerIndex = 0;\n  private renderedLines = 0;\n  private readonly spinnerFrames = spinnerFrames;\n  private isFinished = false;\n  private readonly prefix: string;\n  private lastRenderedState: string = '';\n  private remoteCheckInProgress = false;\n  private expectRemote = false;\n  private remoteError: string | undefined;\n  private pluginTotal = 0;\n  private pluginDone = 0;\n  private pluginError: string | undefined;\n\n  constructor() {\n    this.prefix = getPrefix(defaultConfiguration.log?.prefix) ?? '';\n  }\n\n  setExpectRemote(expect: boolean) {\n    this.expectRemote = expect;\n  }\n\n  startRemoteCheck() {\n    if (this.isFinished) return;\n    this.remoteCheckInProgress = true;\n    this.startSpinner();\n    this.render();\n  }\n\n  stopRemoteCheck() {\n    this.remoteCheckInProgress = false;\n  }\n\n  update(newStatuses: DictionariesStatus[]) {\n    if (this.isFinished) return;\n    for (const status of newStatuses) {\n      const index = this.statuses.findIndex(\n        (s) =>\n          s.dictionaryKey === status.dictionaryKey && s.type === status.type\n      );\n      if (index >= 0) {\n        this.statuses[index] = status;\n      } else {\n        this.statuses.push(status);\n      }\n    }\n\n    // If we expect remote fetch later, avoid rendering a local-only line first\n    const { remoteTotal } = this.computeProgress();\n    if (this.expectRemote && !this.remoteCheckInProgress && remoteTotal === 0) {\n      // Do not start spinner or render yet; wait until remote check starts\n      return;\n    }\n\n    this.startSpinner();\n    this.render();\n  }\n\n  finish() {\n    this.isFinished = true;\n    this.stopSpinner();\n    // Render final state and keep it visible\n    this.render();\n  }\n\n  private startSpinner() {\n    if (this.spinnerTimer || this.isFinished) return;\n    this.spinnerTimer = setInterval(() => {\n      this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;\n      this.render();\n    }, 100);\n  }\n\n  private stopSpinner() {\n    if (!this.spinnerTimer) return;\n    clearInterval(this.spinnerTimer);\n    this.spinnerTimer = null;\n  }\n\n  public setRemoteError = (error?: Error) => {\n    this.remoteError = extractErrorMessage(error);\n    // Avoid rendering a transient remote-only line while the remote check flag is still true\n    // Ensure local + remote are rendered together after a failure\n    this.stopRemoteCheck();\n    this.render();\n  };\n\n  setPluginTotal(total: number) {\n    if (this.isFinished) return;\n    this.pluginTotal = total;\n    if (total > 0) {\n      this.startSpinner();\n    }\n    this.render();\n  }\n\n  setPluginDone(done: number) {\n    if (this.isFinished) return;\n    this.pluginDone = done;\n    this.render();\n  }\n\n  setPluginError(error?: Error) {\n    if (this.isFinished) return;\n    this.pluginError = extractErrorMessage(error);\n    this.render();\n  }\n\n  private render() {\n    const {\n      localTotal,\n      localDone,\n      remoteTotal,\n      remoteDone,\n      pluginTotal,\n      pluginDone,\n    } = this.computeProgress();\n\n    const frame = this.spinnerFrames[this.spinnerIndex];\n    const clock = colorize(frame, ANSIColors.BLUE);\n    const lines: string[] = [];\n\n    const isLocalDone = localDone === localTotal;\n    const isRemoteDone = remoteDone === remoteTotal;\n    const isPluginDone = pluginDone === pluginTotal;\n\n    const suppressLocalWhileCheckingRemote =\n      this.expectRemote && this.remoteCheckInProgress && remoteTotal === 0;\n\n    if (!suppressLocalWhileCheckingRemote) {\n      if (isLocalDone) {\n        lines.push(\n          `${this.prefix} ${v} Local content: ${colorize(`${localDone}`, ANSIColors.GREEN)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n        );\n      } else {\n        lines.push(\n          `${this.prefix} ${clock} Local content: ${colorize(`${localDone}`, ANSIColors.BLUE)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n        );\n      }\n    }\n\n    // Single remote line: show error, check, or progress counts\n    if (remoteTotal > 0 || this.remoteCheckInProgress || this.remoteError) {\n      if (this.remoteError) {\n        lines.push(\n          `${this.prefix} ${x} Remote content: ${colorize(\n            this.remoteError,\n            ANSIColors.RED\n          )}`\n        );\n      } else if (remoteTotal === 0) {\n        lines.push(\n          `${this.prefix} ${clock} Remote content: ${colorize('Check server', ANSIColors.BLUE)}`\n        );\n      } else if (isRemoteDone) {\n        lines.push(\n          `${this.prefix} ${v} Remote content: ${colorize(`${remoteDone}`, ANSIColors.GREEN)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n        );\n      } else {\n        lines.push(\n          `${this.prefix} ${clock} Remote content: ${colorize(`${remoteDone}`, ANSIColors.BLUE)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n        );\n      }\n    }\n\n    // Plugin line: show error or progress counts\n    if (pluginTotal > 0 || this.pluginError) {\n      if (this.pluginError) {\n        lines.push(\n          `${this.prefix} ${x} Plugin content: ${colorize(\n            this.pluginError,\n            ANSIColors.RED\n          )}`\n        );\n      } else if (isPluginDone) {\n        lines.push(\n          `${this.prefix} ${v} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.GREEN)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n        );\n      } else {\n        lines.push(\n          `${this.prefix} ${clock} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.BLUE)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n        );\n      }\n    }\n\n    // Check if the state has changed to avoid duplicate rendering\n    const currentState = lines.join('\\n');\n    if (currentState === this.lastRenderedState) {\n      return;\n    }\n    this.lastRenderedState = currentState;\n\n    if (this.renderedLines > 0) {\n      process.stdout.write(`\\x1b[${this.renderedLines}F`);\n    }\n\n    const totalLinesToClear = Math.max(this.renderedLines, lines.length);\n    for (let i = 0; i < totalLinesToClear; i++) {\n      process.stdout.write('\\x1b[2K');\n      const line = lines[i];\n      if (line !== undefined) {\n        process.stdout.write(line);\n      }\n      process.stdout.write('\\n');\n    }\n\n    this.renderedLines = lines.length;\n  }\n\n  private computeProgress() {\n    const localKeys = new Set(\n      this.statuses\n        .filter((s) => s.type === 'local')\n        .map((s) => s.dictionaryKey)\n    );\n\n    const localDoneKeys = new Set(\n      this.statuses\n        .filter(\n          (s) =>\n            s.type === 'local' && (s.status === 'built' || s.status === 'error')\n        )\n        .map((s) => s.dictionaryKey)\n    );\n\n    const remoteKeys = new Set(\n      this.statuses\n        .filter((s) => s.type === 'remote')\n        .map((s) => s.dictionaryKey)\n    );\n\n    const remoteDoneKeys = new Set(\n      this.statuses\n        .filter(\n          (s) =>\n            s.type === 'remote' &&\n            (s.status === 'fetched' ||\n              s.status === 'imported' ||\n              s.status === 'error')\n        )\n        .map((s) => s.dictionaryKey)\n    );\n\n    return {\n      localTotal: localKeys.size,\n      localDone: localDoneKeys.size,\n      remoteTotal: remoteKeys.size,\n      remoteDone: remoteDoneKeys.size,\n      pluginTotal: this.pluginTotal,\n      pluginDone: this.pluginDone,\n    } as const;\n  }\n}\n"],"mappings":"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"}