@intlayer/chokidar 3.4.8 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,10 +46,10 @@ const watch = (options) => {
46
46
  const { content } = (0, import_config.getConfiguration)({
47
47
  verbose: true
48
48
  });
49
- const { watchedFilesPatternWithPath, baseDir } = content;
49
+ const { watchedFilesPatternWithPath, baseDir, watch: isWatchMode } = content;
50
50
  const files = import_fast_glob.default.sync(watchedFilesPatternWithPath);
51
51
  return (0, import_chokidar.watch)(watchedFilesPatternWithPath, {
52
- persistent: false,
52
+ persistent: isWatchMode,
53
53
  // Make the watcher persistent
54
54
  ignoreInitial: true,
55
55
  // Process existing files
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/chokidar/watcher.ts"],"sourcesContent":["import { relative } from 'path';\nimport { getConfiguration } from '@intlayer/config';\n/** @ts-ignore remove error Module '\"chokidar\"' has no exported member 'ChokidarOptions' */\nimport { type ChokidarOptions, watch as chokidarWatch } from 'chokidar';\nimport fg from 'fast-glob';\nimport { cleanOutputDir } from '../cleanOutputDir';\nimport { loadDictionaries } from '../loadDictionaries/loadDictionaries';\nimport { loadLocalDictionaries } from '../loadDictionaries/loadLocalDictionaries';\nimport { buildDictionary } from '../transpiler/declaration_file_to_dictionary/index';\nimport { createDictionaryList } from '../transpiler/dictionary_to_main/createDictionaryList';\nimport {\n createTypes,\n createModuleAugmentation,\n} from '../transpiler/dictionary_to_type/index';\n\nconst LOG_PREFIX = '[intlayer] ';\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = (options?: ChokidarOptions) => {\n const { content } = getConfiguration({\n verbose: true,\n });\n\n const { watchedFilesPatternWithPath, baseDir } = content;\n\n const files: string[] = fg.sync(watchedFilesPatternWithPath);\n\n /** @ts-ignore remove error Expected 0-1 arguments, but got 2. */\n return chokidarWatch(watchedFilesPatternWithPath, {\n persistent: false, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n ...options,\n })\n .on('ready', async () => {\n cleanOutputDir();\n\n const dictionaries = await loadDictionaries(files);\n\n // Build locale dictionaries\n const dictionariesPaths = await buildDictionary(dictionaries);\n\n await createTypes(dictionariesPaths);\n\n console.info(\n `${LOG_PREFIX}${dictionariesPaths.length} dictionaries built`\n );\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('add', async (filePath) => {\n // Process the file with the functionToRun\n console.info(\n `${LOG_PREFIX}Additional file detected: `,\n relative(baseDir, filePath)\n );\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('change', async (filePath) => {\n // Process the file with the functionToRun\n console.info('Change detected: ', relative(baseDir, filePath));\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n console.info(`${LOG_PREFIX}TypeScript types built`);\n })\n .on('error', (error) => {\n console.error('Watcher error:', error);\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAyB;AACzB,oBAAiC;AAEjC,sBAA6D;AAC7D,uBAAe;AACf,4BAA+B;AAC/B,8BAAiC;AACjC,mCAAsC;AACtC,4CAAgC;AAChC,kCAAqC;AACrC,gCAGO;AAEP,MAAM,aAAa;AAGZ,MAAM,QAAQ,CAAC,YAA8B;AAClD,QAAM,EAAE,QAAQ,QAAI,gCAAiB;AAAA,IACnC,SAAS;AAAA,EACX,CAAC;AAED,QAAM,EAAE,6BAA6B,QAAQ,IAAI;AAEjD,QAAM,QAAkB,iBAAAA,QAAG,KAAK,2BAA2B;AAG3D,aAAO,gBAAAC,OAAc,6BAA6B;AAAA,IAChD,YAAY;AAAA;AAAA,IACZ,eAAe;AAAA;AAAA,IACf,GAAG;AAAA,EACL,CAAC,EACE,GAAG,SAAS,YAAY;AACvB,8CAAe;AAEf,UAAM,eAAe,UAAM,0CAAiB,KAAK;AAGjD,UAAM,oBAAoB,UAAM,uDAAgB,YAAY;AAE5D,cAAM,uCAAY,iBAAiB;AAEnC,YAAQ;AAAA,MACN,GAAG,UAAU,GAAG,kBAAkB,MAAM;AAAA,IAC1C;AAEA,4DAAyB;AAEzB,0DAAqB;AAAA,EACvB,CAAC,EACA,GAAG,OAAO,OAAO,aAAa;AAE7B,YAAQ;AAAA,MACN,GAAG,UAAU;AAAA,UACb,sBAAS,SAAS,QAAQ;AAAA,IAC5B;AAEA,UAAM,qBAAqB,UAAM,oDAAsB,QAAQ;AAE/D,UAAM,eAAe,UAAM,uDAAgB,kBAAkB;AAE7D,cAAM,uCAAY,YAAY;AAE9B,4DAAyB;AAEzB,0DAAqB;AAAA,EACvB,CAAC,EACA,GAAG,UAAU,OAAO,aAAa;AAEhC,YAAQ,KAAK,yBAAqB,sBAAS,SAAS,QAAQ,CAAC;AAE7D,UAAM,qBAAqB,UAAM,oDAAsB,QAAQ;AAC/D,UAAM,eAAe,UAAM,uDAAgB,kBAAkB;AAE7D,cAAM,uCAAY,YAAY;AAC9B,YAAQ,KAAK,GAAG,UAAU,wBAAwB;AAAA,EACpD,CAAC,EACA,GAAG,SAAS,CAAC,UAAU;AACtB,YAAQ,MAAM,kBAAkB,KAAK;AAAA,EACvC,CAAC;AACL;","names":["fg","chokidarWatch"]}
1
+ {"version":3,"sources":["../../../src/chokidar/watcher.ts"],"sourcesContent":["import { relative } from 'path';\nimport { getConfiguration } from '@intlayer/config';\n/** @ts-ignore remove error Module '\"chokidar\"' has no exported member 'ChokidarOptions' */\nimport { type ChokidarOptions, watch as chokidarWatch } from 'chokidar';\nimport fg from 'fast-glob';\nimport { cleanOutputDir } from '../cleanOutputDir';\nimport { loadDictionaries } from '../loadDictionaries/loadDictionaries';\nimport { loadLocalDictionaries } from '../loadDictionaries/loadLocalDictionaries';\nimport { buildDictionary } from '../transpiler/declaration_file_to_dictionary/index';\nimport { createDictionaryList } from '../transpiler/dictionary_to_main/createDictionaryList';\nimport {\n createTypes,\n createModuleAugmentation,\n} from '../transpiler/dictionary_to_type/index';\n\nconst LOG_PREFIX = '[intlayer] ';\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = (options?: ChokidarOptions) => {\n const { content } = getConfiguration({\n verbose: true,\n });\n\n const { watchedFilesPatternWithPath, baseDir, watch: isWatchMode } = content;\n\n const files: string[] = fg.sync(watchedFilesPatternWithPath);\n\n /** @ts-ignore remove error Expected 0-1 arguments, but got 2. */\n return chokidarWatch(watchedFilesPatternWithPath, {\n persistent: isWatchMode, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n ...options,\n })\n .on('ready', async () => {\n cleanOutputDir();\n\n const dictionaries = await loadDictionaries(files);\n\n // Build locale dictionaries\n const dictionariesPaths = await buildDictionary(dictionaries);\n\n await createTypes(dictionariesPaths);\n\n console.info(\n `${LOG_PREFIX}${dictionariesPaths.length} dictionaries built`\n );\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('add', async (filePath) => {\n // Process the file with the functionToRun\n console.info(\n `${LOG_PREFIX}Additional file detected: `,\n relative(baseDir, filePath)\n );\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('change', async (filePath) => {\n // Process the file with the functionToRun\n console.info('Change detected: ', relative(baseDir, filePath));\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n console.info(`${LOG_PREFIX}TypeScript types built`);\n })\n .on('error', (error) => {\n console.error('Watcher error:', error);\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAyB;AACzB,oBAAiC;AAEjC,sBAA6D;AAC7D,uBAAe;AACf,4BAA+B;AAC/B,8BAAiC;AACjC,mCAAsC;AACtC,4CAAgC;AAChC,kCAAqC;AACrC,gCAGO;AAEP,MAAM,aAAa;AAGZ,MAAM,QAAQ,CAAC,YAA8B;AAClD,QAAM,EAAE,QAAQ,QAAI,gCAAiB;AAAA,IACnC,SAAS;AAAA,EACX,CAAC;AAED,QAAM,EAAE,6BAA6B,SAAS,OAAO,YAAY,IAAI;AAErE,QAAM,QAAkB,iBAAAA,QAAG,KAAK,2BAA2B;AAG3D,aAAO,gBAAAC,OAAc,6BAA6B;AAAA,IAChD,YAAY;AAAA;AAAA,IACZ,eAAe;AAAA;AAAA,IACf,GAAG;AAAA,EACL,CAAC,EACE,GAAG,SAAS,YAAY;AACvB,8CAAe;AAEf,UAAM,eAAe,UAAM,0CAAiB,KAAK;AAGjD,UAAM,oBAAoB,UAAM,uDAAgB,YAAY;AAE5D,cAAM,uCAAY,iBAAiB;AAEnC,YAAQ;AAAA,MACN,GAAG,UAAU,GAAG,kBAAkB,MAAM;AAAA,IAC1C;AAEA,4DAAyB;AAEzB,0DAAqB;AAAA,EACvB,CAAC,EACA,GAAG,OAAO,OAAO,aAAa;AAE7B,YAAQ;AAAA,MACN,GAAG,UAAU;AAAA,UACb,sBAAS,SAAS,QAAQ;AAAA,IAC5B;AAEA,UAAM,qBAAqB,UAAM,oDAAsB,QAAQ;AAE/D,UAAM,eAAe,UAAM,uDAAgB,kBAAkB;AAE7D,cAAM,uCAAY,YAAY;AAE9B,4DAAyB;AAEzB,0DAAqB;AAAA,EACvB,CAAC,EACA,GAAG,UAAU,OAAO,aAAa;AAEhC,YAAQ,KAAK,yBAAqB,sBAAS,SAAS,QAAQ,CAAC;AAE7D,UAAM,qBAAqB,UAAM,oDAAsB,QAAQ;AAC/D,UAAM,eAAe,UAAM,uDAAgB,kBAAkB;AAE7D,cAAM,uCAAY,YAAY;AAC9B,YAAQ,KAAK,GAAG,UAAU,wBAAwB;AAAA,EACpD,CAAC,EACA,GAAG,SAAS,CAAC,UAAU;AACtB,YAAQ,MAAM,kBAAkB,KAAK;AAAA,EACvC,CAAC;AACL;","names":["fg","chokidarWatch"]}
package/dist/cjs/log.cjs CHANGED
@@ -273,7 +273,7 @@ class Logger {
273
273
  let content;
274
274
  if (lines.length > maxVisibleLines) {
275
275
  const visibleLines = lines.slice(0, maxVisibleLines - 5);
276
- const summary = `... and ${lines.length - visibleLines.length} more lines`;
276
+ const summary = `... and ${lines.length - visibleLines.length} more`;
277
277
  content = LINE_DETECTOR + visibleLines.join("\n") + "\n" + summary;
278
278
  } else {
279
279
  content = lines.join("\n");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/log.ts"],"sourcesContent":["import readline from 'readline';\nimport { sortAlphabetically } from './utils';\n\nexport type State = {\n type: 'local' | 'distant';\n status: 'pending' | 'fetching' | 'fetched' | 'error' | 'imported' | 'built';\n icon?: string;\n error?: Error;\n errorMessage?: string;\n spinnerFrameIndex?: number;\n};\n\nexport type DictionariesStatus = {\n dictionaryKey: string;\n state: State[];\n};\n\nconst LINE_DETECTOR = '\\u200B\\u200B\\u200B'; // Three zero-width spaces\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n// ANSI color codes\nconst RESET = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst RED = '\\x1b[31m';\nconst BLUE = '\\x1b[34m';\nconst GREY = '\\x1b[90m';\nconst GREY_DARK = '\\x1b[90m';\n\nclass Logger {\n private dictionariesStatuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private maxDictionaryKeyLength: number = 0;\n private previousLineCount: number = 0;\n private lineDifCounter: number = 0;\n private originalStdoutWrite:\n | ((\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => boolean)\n | null = null;\n private extraLines: number = 0;\n private isUpdating: boolean = false;\n\n // Singleton instance\n private static instance: Logger;\n\n private constructor() {}\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n\n public init(\n localDictionariesKeys: string[],\n distantDictionariesKeys: string[]\n ) {\n const allKeys = Array.from(\n new Set(\n [...localDictionariesKeys, ...distantDictionariesKeys].sort(\n sortAlphabetically\n )\n )\n );\n\n this.maxDictionaryKeyLength = allKeys.reduce(\n (max, key) => (key.length > max ? key.length : max),\n 0\n );\n\n this.dictionariesStatuses = allKeys.map((dictionaryKey) => {\n const states: State[] = [];\n\n if (localDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'local',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n if (distantDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'distant',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n\n return {\n dictionaryKey,\n state: states,\n };\n });\n\n // Start spinner timer\n this.startSpinner();\n\n // Update all status lines (this will output the initial statuses)\n this.updateAllStatusLines();\n }\n\n // New method to add dictionary keys after initialization\n public addDictionaryKeys(\n type: 'local' | 'distant',\n dictionaryKeys: string[]\n ) {\n for (const dictionaryKey of dictionaryKeys) {\n // Update maxDictionaryKeyLength if the new key is longer\n if (dictionaryKey.length > this.maxDictionaryKeyLength) {\n this.maxDictionaryKeyLength = dictionaryKey.length;\n }\n\n let statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n\n if (!statusObj) {\n // If the dictionaryKey doesn't exist yet, create a new DictionariesStatus\n\n statusObj = {\n dictionaryKey,\n state: [],\n };\n this.dictionariesStatuses.push(statusObj);\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n } else {\n const existingState = statusObj.state.find((s) => s.type === type);\n if (!existingState) {\n // Add new state for the type\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n }\n }\n }\n\n // Call updateAllStatusLines() to refresh the output\n this.updateAllStatusLines();\n }\n\n private startSpinner() {\n if (!this.spinnerTimer) {\n this.spinnerTimer = setInterval(() => {\n this.updateAllStatusLines();\n }, 100); // Update every 100ms\n }\n }\n\n private stopSpinner() {\n if (this.spinnerTimer) {\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n }\n\n // Method to update the terminal output\n private updateOutput(content: string) {\n // Monkey-patch process.stdout.write to keep track of extra lines\n if (!this.originalStdoutWrite) {\n this.originalStdoutWrite = process.stdout.write.bind(process.stdout);\n this.extraLines = 0;\n\n const write = (\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => {\n const str = typeof chunk === 'string' ? chunk : chunk.toString();\n const newLines = (str.match(/\\n/g) ?? []).length;\n\n // If the write is not initiated by Logger's updateOutput method\n if (!this.isUpdating) {\n this.extraLines += newLines;\n }\n\n return this.originalStdoutWrite!(chunk, encoding, callback);\n };\n\n process.stdout.write = write as typeof process.stdout.write;\n }\n\n // Set a flag to indicate that updateOutput is running\n this.isUpdating = true;\n\n // Adjust lineDifCounter if LINE_DETECTOR is not the first line\n const contentLines = content.split('\\n');\n const indexOfLineDetector = contentLines.indexOf(LINE_DETECTOR.trim());\n\n if (indexOfLineDetector > 0) {\n // LINE_DETECTOR is not at the first line\n this.lineDifCounter = indexOfLineDetector;\n } else {\n this.lineDifCounter = 0;\n }\n\n // Calculate total lines to move up\n const totalLinesToMoveUp =\n this.previousLineCount + this.lineDifCounter + this.extraLines;\n\n // Move cursor up by totalLinesToMoveUp\n readline.moveCursor(process.stdout, 0, -totalLinesToMoveUp);\n\n // Clear all lines downwards\n readline.clearScreenDown(process.stdout);\n\n // Write the updated content\n contentLines.forEach((line) => {\n process.stdout.write(`${line}\\x1b[K\\n`);\n });\n\n // Update previousLineCount\n this.previousLineCount = contentLines.length;\n\n // Reset extraLines counter and updating flag\n this.extraLines = 0;\n this.isUpdating = false;\n }\n\n public stop() {\n this.stopSpinner();\n }\n\n public updateStatus(\n dictionaries: {\n dictionaryKey: string;\n type: 'local' | 'distant';\n status: Partial<State>;\n }[]\n ) {\n for (const { dictionaryKey, type, status } of dictionaries) {\n const statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n if (statusObj) {\n const state = statusObj.state.find((s) => s.type === type);\n if (state) {\n // Update existing state\n Object.assign(state, status);\n } else {\n // If the state for this type doesn't exist yet, add it\n if (status.status === undefined) {\n status.status = 'pending'; // Provide default status\n }\n const newState: State = {\n type,\n status: status.status,\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n statusObj.state.push(newState);\n }\n } else {\n // If the status object doesn't exist, create it\n const newState: State = {\n type,\n status: status.status ?? 'pending',\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n this.dictionariesStatuses.push({\n dictionaryKey,\n state: [newState],\n });\n }\n }\n\n // Update the display after status change\n this.updateAllStatusLines();\n }\n\n private getStatusIcon(status: string): string {\n const statusIcons: Record<string, string> = {\n pending: '⏲',\n fetching: '', // Spinner handled separately\n built: '✔',\n imported: '✔',\n error: '✖',\n };\n return statusIcons[status] ?? '';\n }\n\n private getStatusLine(statusObj: DictionariesStatus): string {\n const keyPadding =\n this.maxDictionaryKeyLength - statusObj.dictionaryKey.length;\n const paddedKey = `${statusObj.dictionaryKey}${' '.repeat(keyPadding)}`;\n\n const states = statusObj.state.map((state) => {\n let colorStart = '';\n let colorEnd = '';\n let icon = this.getStatusIcon(state.status);\n if (state.status === 'fetching') {\n // Use spinner frame\n icon = SPINNER_FRAMES[state.spinnerFrameIndex! % SPINNER_FRAMES.length];\n colorStart = BLUE;\n colorEnd = RESET;\n } else if (state.status === 'error') {\n colorStart = RED;\n colorEnd = RESET;\n } else if (state.status === 'imported' || state.status === 'built') {\n colorStart = GREEN;\n colorEnd = RESET;\n } else {\n colorStart = GREY;\n colorEnd = RESET;\n }\n\n // Format the status block\n const statusBlock = `${GREY_DARK}[${state.type}: ${colorStart}${icon} ${state.status}${GREY_DARK}]${colorEnd}`;\n\n return `${colorStart}${statusBlock}${colorEnd}`;\n });\n\n return `- ${paddedKey} ${states.join(' ')}`;\n }\n\n // Replace logUpdate calls with your custom methods\n private updateAllStatusLines() {\n const terminalHeight = process.stdout.rows;\n const maxVisibleLines = terminalHeight - 1;\n\n const lines = this.dictionariesStatuses.map((statusObj) => {\n statusObj.state.forEach((state) => {\n if (state.status === 'fetching') {\n // Update spinner frame\n state.spinnerFrameIndex =\n (state.spinnerFrameIndex! + 1) % SPINNER_FRAMES.length;\n }\n });\n return this.getStatusLine(statusObj);\n });\n\n let content;\n\n if (lines.length > maxVisibleLines) {\n const visibleLines = lines.slice(0, maxVisibleLines - 5);\n const summary = `... and ${lines.length - visibleLines.length} more lines`;\n content = LINE_DETECTOR + visibleLines.join('\\n') + '\\n' + summary;\n } else {\n content = lines.join('\\n');\n }\n\n this.updateOutput(content);\n }\n\n public getStatuses() {\n return this.dictionariesStatuses;\n }\n}\n\nexport const logger = Logger.getInstance();\n"],"mappings":"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","names":["readline"]}
1
+ {"version":3,"sources":["../../src/log.ts"],"sourcesContent":["import readline from 'readline';\nimport { sortAlphabetically } from './utils';\n\nexport type State = {\n type: 'local' | 'distant';\n status: 'pending' | 'fetching' | 'fetched' | 'error' | 'imported' | 'built';\n icon?: string;\n error?: Error;\n errorMessage?: string;\n spinnerFrameIndex?: number;\n};\n\nexport type DictionariesStatus = {\n dictionaryKey: string;\n state: State[];\n};\n\nconst LINE_DETECTOR = '\\u200B\\u200B\\u200B'; // Three zero-width spaces\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n// ANSI color codes\nconst RESET = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst RED = '\\x1b[31m';\nconst BLUE = '\\x1b[34m';\nconst GREY = '\\x1b[90m';\nconst GREY_DARK = '\\x1b[90m';\n\nclass Logger {\n private dictionariesStatuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private maxDictionaryKeyLength: number = 0;\n private previousLineCount: number = 0;\n private lineDifCounter: number = 0;\n private originalStdoutWrite:\n | ((\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => boolean)\n | null = null;\n private extraLines: number = 0;\n private isUpdating: boolean = false;\n\n // Singleton instance\n private static instance: Logger;\n\n private constructor() {}\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n\n public init(\n localDictionariesKeys: string[],\n distantDictionariesKeys: string[]\n ) {\n const allKeys = Array.from(\n new Set(\n [...localDictionariesKeys, ...distantDictionariesKeys].sort(\n sortAlphabetically\n )\n )\n );\n\n this.maxDictionaryKeyLength = allKeys.reduce(\n (max, key) => (key.length > max ? key.length : max),\n 0\n );\n\n this.dictionariesStatuses = allKeys.map((dictionaryKey) => {\n const states: State[] = [];\n\n if (localDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'local',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n if (distantDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'distant',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n\n return {\n dictionaryKey,\n state: states,\n };\n });\n\n // Start spinner timer\n this.startSpinner();\n\n // Update all status lines (this will output the initial statuses)\n this.updateAllStatusLines();\n }\n\n // New method to add dictionary keys after initialization\n public addDictionaryKeys(\n type: 'local' | 'distant',\n dictionaryKeys: string[]\n ) {\n for (const dictionaryKey of dictionaryKeys) {\n // Update maxDictionaryKeyLength if the new key is longer\n if (dictionaryKey.length > this.maxDictionaryKeyLength) {\n this.maxDictionaryKeyLength = dictionaryKey.length;\n }\n\n let statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n\n if (!statusObj) {\n // If the dictionaryKey doesn't exist yet, create a new DictionariesStatus\n\n statusObj = {\n dictionaryKey,\n state: [],\n };\n this.dictionariesStatuses.push(statusObj);\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n } else {\n const existingState = statusObj.state.find((s) => s.type === type);\n if (!existingState) {\n // Add new state for the type\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n }\n }\n }\n\n // Call updateAllStatusLines() to refresh the output\n this.updateAllStatusLines();\n }\n\n private startSpinner() {\n if (!this.spinnerTimer) {\n this.spinnerTimer = setInterval(() => {\n this.updateAllStatusLines();\n }, 100); // Update every 100ms\n }\n }\n\n private stopSpinner() {\n if (this.spinnerTimer) {\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n }\n\n // Method to update the terminal output\n private updateOutput(content: string) {\n // Monkey-patch process.stdout.write to keep track of extra lines\n if (!this.originalStdoutWrite) {\n this.originalStdoutWrite = process.stdout.write.bind(process.stdout);\n this.extraLines = 0;\n\n const write = (\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => {\n const str = typeof chunk === 'string' ? chunk : chunk.toString();\n const newLines = (str.match(/\\n/g) ?? []).length;\n\n // If the write is not initiated by Logger's updateOutput method\n if (!this.isUpdating) {\n this.extraLines += newLines;\n }\n\n return this.originalStdoutWrite!(chunk, encoding, callback);\n };\n\n process.stdout.write = write as typeof process.stdout.write;\n }\n\n // Set a flag to indicate that updateOutput is running\n this.isUpdating = true;\n\n // Adjust lineDifCounter if LINE_DETECTOR is not the first line\n const contentLines = content.split('\\n');\n const indexOfLineDetector = contentLines.indexOf(LINE_DETECTOR.trim());\n\n if (indexOfLineDetector > 0) {\n // LINE_DETECTOR is not at the first line\n this.lineDifCounter = indexOfLineDetector;\n } else {\n this.lineDifCounter = 0;\n }\n\n // Calculate total lines to move up\n const totalLinesToMoveUp =\n this.previousLineCount + this.lineDifCounter + this.extraLines;\n\n // Move cursor up by totalLinesToMoveUp\n readline.moveCursor(process.stdout, 0, -totalLinesToMoveUp);\n\n // Clear all lines downwards\n readline.clearScreenDown(process.stdout);\n\n // Write the updated content\n contentLines.forEach((line) => {\n process.stdout.write(`${line}\\x1b[K\\n`);\n });\n\n // Update previousLineCount\n this.previousLineCount = contentLines.length;\n\n // Reset extraLines counter and updating flag\n this.extraLines = 0;\n this.isUpdating = false;\n }\n\n public stop() {\n this.stopSpinner();\n }\n\n public updateStatus(\n dictionaries: {\n dictionaryKey: string;\n type: 'local' | 'distant';\n status: Partial<State>;\n }[]\n ) {\n for (const { dictionaryKey, type, status } of dictionaries) {\n const statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n if (statusObj) {\n const state = statusObj.state.find((s) => s.type === type);\n if (state) {\n // Update existing state\n Object.assign(state, status);\n } else {\n // If the state for this type doesn't exist yet, add it\n if (status.status === undefined) {\n status.status = 'pending'; // Provide default status\n }\n const newState: State = {\n type,\n status: status.status,\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n statusObj.state.push(newState);\n }\n } else {\n // If the status object doesn't exist, create it\n const newState: State = {\n type,\n status: status.status ?? 'pending',\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n this.dictionariesStatuses.push({\n dictionaryKey,\n state: [newState],\n });\n }\n }\n\n // Update the display after status change\n this.updateAllStatusLines();\n }\n\n private getStatusIcon(status: string): string {\n const statusIcons: Record<string, string> = {\n pending: '⏲',\n fetching: '', // Spinner handled separately\n built: '✔',\n imported: '✔',\n error: '✖',\n };\n return statusIcons[status] ?? '';\n }\n\n private getStatusLine(statusObj: DictionariesStatus): string {\n const keyPadding =\n this.maxDictionaryKeyLength - statusObj.dictionaryKey.length;\n const paddedKey = `${statusObj.dictionaryKey}${' '.repeat(keyPadding)}`;\n\n const states = statusObj.state.map((state) => {\n let colorStart = '';\n let colorEnd = '';\n let icon = this.getStatusIcon(state.status);\n if (state.status === 'fetching') {\n // Use spinner frame\n icon = SPINNER_FRAMES[state.spinnerFrameIndex! % SPINNER_FRAMES.length];\n colorStart = BLUE;\n colorEnd = RESET;\n } else if (state.status === 'error') {\n colorStart = RED;\n colorEnd = RESET;\n } else if (state.status === 'imported' || state.status === 'built') {\n colorStart = GREEN;\n colorEnd = RESET;\n } else {\n colorStart = GREY;\n colorEnd = RESET;\n }\n\n // Format the status block\n const statusBlock = `${GREY_DARK}[${state.type}: ${colorStart}${icon} ${state.status}${GREY_DARK}]${colorEnd}`;\n\n return `${colorStart}${statusBlock}${colorEnd}`;\n });\n\n return `- ${paddedKey} ${states.join(' ')}`;\n }\n\n // Replace logUpdate calls with your custom methods\n private updateAllStatusLines() {\n const terminalHeight = process.stdout.rows;\n const maxVisibleLines = terminalHeight - 1;\n\n const lines = this.dictionariesStatuses.map((statusObj) => {\n statusObj.state.forEach((state) => {\n if (state.status === 'fetching') {\n // Update spinner frame\n state.spinnerFrameIndex =\n (state.spinnerFrameIndex! + 1) % SPINNER_FRAMES.length;\n }\n });\n return this.getStatusLine(statusObj);\n });\n\n let content;\n\n if (lines.length > maxVisibleLines) {\n const visibleLines = lines.slice(0, maxVisibleLines - 5);\n const summary = `... and ${lines.length - visibleLines.length} more`;\n content = LINE_DETECTOR + visibleLines.join('\\n') + '\\n' + summary;\n } else {\n content = lines.join('\\n');\n }\n\n this.updateOutput(content);\n }\n\n public getStatuses() {\n return this.dictionariesStatuses;\n }\n}\n\nexport const logger = Logger.getInstance();\n"],"mappings":"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","names":["readline"]}
@@ -16,10 +16,10 @@ const watch = (options) => {
16
16
  const { content } = getConfiguration({
17
17
  verbose: true
18
18
  });
19
- const { watchedFilesPatternWithPath, baseDir } = content;
19
+ const { watchedFilesPatternWithPath, baseDir, watch: isWatchMode } = content;
20
20
  const files = fg.sync(watchedFilesPatternWithPath);
21
21
  return chokidarWatch(watchedFilesPatternWithPath, {
22
- persistent: false,
22
+ persistent: isWatchMode,
23
23
  // Make the watcher persistent
24
24
  ignoreInitial: true,
25
25
  // Process existing files
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/chokidar/watcher.ts"],"sourcesContent":["import { relative } from 'path';\nimport { getConfiguration } from '@intlayer/config';\n/** @ts-ignore remove error Module '\"chokidar\"' has no exported member 'ChokidarOptions' */\nimport { type ChokidarOptions, watch as chokidarWatch } from 'chokidar';\nimport fg from 'fast-glob';\nimport { cleanOutputDir } from '../cleanOutputDir';\nimport { loadDictionaries } from '../loadDictionaries/loadDictionaries';\nimport { loadLocalDictionaries } from '../loadDictionaries/loadLocalDictionaries';\nimport { buildDictionary } from '../transpiler/declaration_file_to_dictionary/index';\nimport { createDictionaryList } from '../transpiler/dictionary_to_main/createDictionaryList';\nimport {\n createTypes,\n createModuleAugmentation,\n} from '../transpiler/dictionary_to_type/index';\n\nconst LOG_PREFIX = '[intlayer] ';\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = (options?: ChokidarOptions) => {\n const { content } = getConfiguration({\n verbose: true,\n });\n\n const { watchedFilesPatternWithPath, baseDir } = content;\n\n const files: string[] = fg.sync(watchedFilesPatternWithPath);\n\n /** @ts-ignore remove error Expected 0-1 arguments, but got 2. */\n return chokidarWatch(watchedFilesPatternWithPath, {\n persistent: false, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n ...options,\n })\n .on('ready', async () => {\n cleanOutputDir();\n\n const dictionaries = await loadDictionaries(files);\n\n // Build locale dictionaries\n const dictionariesPaths = await buildDictionary(dictionaries);\n\n await createTypes(dictionariesPaths);\n\n console.info(\n `${LOG_PREFIX}${dictionariesPaths.length} dictionaries built`\n );\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('add', async (filePath) => {\n // Process the file with the functionToRun\n console.info(\n `${LOG_PREFIX}Additional file detected: `,\n relative(baseDir, filePath)\n );\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('change', async (filePath) => {\n // Process the file with the functionToRun\n console.info('Change detected: ', relative(baseDir, filePath));\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n console.info(`${LOG_PREFIX}TypeScript types built`);\n })\n .on('error', (error) => {\n console.error('Watcher error:', error);\n });\n};\n"],"mappings":"AAAA,SAAS,gBAAgB;AACzB,SAAS,wBAAwB;AAEjC,SAA+B,SAAS,qBAAqB;AAC7D,OAAO,QAAQ;AACf,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,6BAA6B;AACtC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,MAAM,aAAa;AAGZ,MAAM,QAAQ,CAAC,YAA8B;AAClD,QAAM,EAAE,QAAQ,IAAI,iBAAiB;AAAA,IACnC,SAAS;AAAA,EACX,CAAC;AAED,QAAM,EAAE,6BAA6B,QAAQ,IAAI;AAEjD,QAAM,QAAkB,GAAG,KAAK,2BAA2B;AAG3D,SAAO,cAAc,6BAA6B;AAAA,IAChD,YAAY;AAAA;AAAA,IACZ,eAAe;AAAA;AAAA,IACf,GAAG;AAAA,EACL,CAAC,EACE,GAAG,SAAS,YAAY;AACvB,mBAAe;AAEf,UAAM,eAAe,MAAM,iBAAiB,KAAK;AAGjD,UAAM,oBAAoB,MAAM,gBAAgB,YAAY;AAE5D,UAAM,YAAY,iBAAiB;AAEnC,YAAQ;AAAA,MACN,GAAG,UAAU,GAAG,kBAAkB,MAAM;AAAA,IAC1C;AAEA,6BAAyB;AAEzB,yBAAqB;AAAA,EACvB,CAAC,EACA,GAAG,OAAO,OAAO,aAAa;AAE7B,YAAQ;AAAA,MACN,GAAG,UAAU;AAAA,MACb,SAAS,SAAS,QAAQ;AAAA,IAC5B;AAEA,UAAM,qBAAqB,MAAM,sBAAsB,QAAQ;AAE/D,UAAM,eAAe,MAAM,gBAAgB,kBAAkB;AAE7D,UAAM,YAAY,YAAY;AAE9B,6BAAyB;AAEzB,yBAAqB;AAAA,EACvB,CAAC,EACA,GAAG,UAAU,OAAO,aAAa;AAEhC,YAAQ,KAAK,qBAAqB,SAAS,SAAS,QAAQ,CAAC;AAE7D,UAAM,qBAAqB,MAAM,sBAAsB,QAAQ;AAC/D,UAAM,eAAe,MAAM,gBAAgB,kBAAkB;AAE7D,UAAM,YAAY,YAAY;AAC9B,YAAQ,KAAK,GAAG,UAAU,wBAAwB;AAAA,EACpD,CAAC,EACA,GAAG,SAAS,CAAC,UAAU;AACtB,YAAQ,MAAM,kBAAkB,KAAK;AAAA,EACvC,CAAC;AACL;","names":[]}
1
+ {"version":3,"sources":["../../../src/chokidar/watcher.ts"],"sourcesContent":["import { relative } from 'path';\nimport { getConfiguration } from '@intlayer/config';\n/** @ts-ignore remove error Module '\"chokidar\"' has no exported member 'ChokidarOptions' */\nimport { type ChokidarOptions, watch as chokidarWatch } from 'chokidar';\nimport fg from 'fast-glob';\nimport { cleanOutputDir } from '../cleanOutputDir';\nimport { loadDictionaries } from '../loadDictionaries/loadDictionaries';\nimport { loadLocalDictionaries } from '../loadDictionaries/loadLocalDictionaries';\nimport { buildDictionary } from '../transpiler/declaration_file_to_dictionary/index';\nimport { createDictionaryList } from '../transpiler/dictionary_to_main/createDictionaryList';\nimport {\n createTypes,\n createModuleAugmentation,\n} from '../transpiler/dictionary_to_type/index';\n\nconst LOG_PREFIX = '[intlayer] ';\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = (options?: ChokidarOptions) => {\n const { content } = getConfiguration({\n verbose: true,\n });\n\n const { watchedFilesPatternWithPath, baseDir, watch: isWatchMode } = content;\n\n const files: string[] = fg.sync(watchedFilesPatternWithPath);\n\n /** @ts-ignore remove error Expected 0-1 arguments, but got 2. */\n return chokidarWatch(watchedFilesPatternWithPath, {\n persistent: isWatchMode, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n ...options,\n })\n .on('ready', async () => {\n cleanOutputDir();\n\n const dictionaries = await loadDictionaries(files);\n\n // Build locale dictionaries\n const dictionariesPaths = await buildDictionary(dictionaries);\n\n await createTypes(dictionariesPaths);\n\n console.info(\n `${LOG_PREFIX}${dictionariesPaths.length} dictionaries built`\n );\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('add', async (filePath) => {\n // Process the file with the functionToRun\n console.info(\n `${LOG_PREFIX}Additional file detected: `,\n relative(baseDir, filePath)\n );\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n\n createModuleAugmentation();\n\n createDictionaryList();\n })\n .on('change', async (filePath) => {\n // Process the file with the functionToRun\n console.info('Change detected: ', relative(baseDir, filePath));\n\n const localeDictionaries = await loadLocalDictionaries(filePath);\n const dictionaries = await buildDictionary(localeDictionaries);\n\n await createTypes(dictionaries);\n console.info(`${LOG_PREFIX}TypeScript types built`);\n })\n .on('error', (error) => {\n console.error('Watcher error:', error);\n });\n};\n"],"mappings":"AAAA,SAAS,gBAAgB;AACzB,SAAS,wBAAwB;AAEjC,SAA+B,SAAS,qBAAqB;AAC7D,OAAO,QAAQ;AACf,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,6BAA6B;AACtC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,MAAM,aAAa;AAGZ,MAAM,QAAQ,CAAC,YAA8B;AAClD,QAAM,EAAE,QAAQ,IAAI,iBAAiB;AAAA,IACnC,SAAS;AAAA,EACX,CAAC;AAED,QAAM,EAAE,6BAA6B,SAAS,OAAO,YAAY,IAAI;AAErE,QAAM,QAAkB,GAAG,KAAK,2BAA2B;AAG3D,SAAO,cAAc,6BAA6B;AAAA,IAChD,YAAY;AAAA;AAAA,IACZ,eAAe;AAAA;AAAA,IACf,GAAG;AAAA,EACL,CAAC,EACE,GAAG,SAAS,YAAY;AACvB,mBAAe;AAEf,UAAM,eAAe,MAAM,iBAAiB,KAAK;AAGjD,UAAM,oBAAoB,MAAM,gBAAgB,YAAY;AAE5D,UAAM,YAAY,iBAAiB;AAEnC,YAAQ;AAAA,MACN,GAAG,UAAU,GAAG,kBAAkB,MAAM;AAAA,IAC1C;AAEA,6BAAyB;AAEzB,yBAAqB;AAAA,EACvB,CAAC,EACA,GAAG,OAAO,OAAO,aAAa;AAE7B,YAAQ;AAAA,MACN,GAAG,UAAU;AAAA,MACb,SAAS,SAAS,QAAQ;AAAA,IAC5B;AAEA,UAAM,qBAAqB,MAAM,sBAAsB,QAAQ;AAE/D,UAAM,eAAe,MAAM,gBAAgB,kBAAkB;AAE7D,UAAM,YAAY,YAAY;AAE9B,6BAAyB;AAEzB,yBAAqB;AAAA,EACvB,CAAC,EACA,GAAG,UAAU,OAAO,aAAa;AAEhC,YAAQ,KAAK,qBAAqB,SAAS,SAAS,QAAQ,CAAC;AAE7D,UAAM,qBAAqB,MAAM,sBAAsB,QAAQ;AAC/D,UAAM,eAAe,MAAM,gBAAgB,kBAAkB;AAE7D,UAAM,YAAY,YAAY;AAC9B,YAAQ,KAAK,GAAG,UAAU,wBAAwB;AAAA,EACpD,CAAC,EACA,GAAG,SAAS,CAAC,UAAU;AACtB,YAAQ,MAAM,kBAAkB,KAAK;AAAA,EACvC,CAAC;AACL;","names":[]}
package/dist/esm/log.mjs CHANGED
@@ -240,7 +240,7 @@ class Logger {
240
240
  let content;
241
241
  if (lines.length > maxVisibleLines) {
242
242
  const visibleLines = lines.slice(0, maxVisibleLines - 5);
243
- const summary = `... and ${lines.length - visibleLines.length} more lines`;
243
+ const summary = `... and ${lines.length - visibleLines.length} more`;
244
244
  content = LINE_DETECTOR + visibleLines.join("\n") + "\n" + summary;
245
245
  } else {
246
246
  content = lines.join("\n");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/log.ts"],"sourcesContent":["import readline from 'readline';\nimport { sortAlphabetically } from './utils';\n\nexport type State = {\n type: 'local' | 'distant';\n status: 'pending' | 'fetching' | 'fetched' | 'error' | 'imported' | 'built';\n icon?: string;\n error?: Error;\n errorMessage?: string;\n spinnerFrameIndex?: number;\n};\n\nexport type DictionariesStatus = {\n dictionaryKey: string;\n state: State[];\n};\n\nconst LINE_DETECTOR = '\\u200B\\u200B\\u200B'; // Three zero-width spaces\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n// ANSI color codes\nconst RESET = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst RED = '\\x1b[31m';\nconst BLUE = '\\x1b[34m';\nconst GREY = '\\x1b[90m';\nconst GREY_DARK = '\\x1b[90m';\n\nclass Logger {\n private dictionariesStatuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private maxDictionaryKeyLength: number = 0;\n private previousLineCount: number = 0;\n private lineDifCounter: number = 0;\n private originalStdoutWrite:\n | ((\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => boolean)\n | null = null;\n private extraLines: number = 0;\n private isUpdating: boolean = false;\n\n // Singleton instance\n private static instance: Logger;\n\n private constructor() {}\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n\n public init(\n localDictionariesKeys: string[],\n distantDictionariesKeys: string[]\n ) {\n const allKeys = Array.from(\n new Set(\n [...localDictionariesKeys, ...distantDictionariesKeys].sort(\n sortAlphabetically\n )\n )\n );\n\n this.maxDictionaryKeyLength = allKeys.reduce(\n (max, key) => (key.length > max ? key.length : max),\n 0\n );\n\n this.dictionariesStatuses = allKeys.map((dictionaryKey) => {\n const states: State[] = [];\n\n if (localDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'local',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n if (distantDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'distant',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n\n return {\n dictionaryKey,\n state: states,\n };\n });\n\n // Start spinner timer\n this.startSpinner();\n\n // Update all status lines (this will output the initial statuses)\n this.updateAllStatusLines();\n }\n\n // New method to add dictionary keys after initialization\n public addDictionaryKeys(\n type: 'local' | 'distant',\n dictionaryKeys: string[]\n ) {\n for (const dictionaryKey of dictionaryKeys) {\n // Update maxDictionaryKeyLength if the new key is longer\n if (dictionaryKey.length > this.maxDictionaryKeyLength) {\n this.maxDictionaryKeyLength = dictionaryKey.length;\n }\n\n let statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n\n if (!statusObj) {\n // If the dictionaryKey doesn't exist yet, create a new DictionariesStatus\n\n statusObj = {\n dictionaryKey,\n state: [],\n };\n this.dictionariesStatuses.push(statusObj);\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n } else {\n const existingState = statusObj.state.find((s) => s.type === type);\n if (!existingState) {\n // Add new state for the type\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n }\n }\n }\n\n // Call updateAllStatusLines() to refresh the output\n this.updateAllStatusLines();\n }\n\n private startSpinner() {\n if (!this.spinnerTimer) {\n this.spinnerTimer = setInterval(() => {\n this.updateAllStatusLines();\n }, 100); // Update every 100ms\n }\n }\n\n private stopSpinner() {\n if (this.spinnerTimer) {\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n }\n\n // Method to update the terminal output\n private updateOutput(content: string) {\n // Monkey-patch process.stdout.write to keep track of extra lines\n if (!this.originalStdoutWrite) {\n this.originalStdoutWrite = process.stdout.write.bind(process.stdout);\n this.extraLines = 0;\n\n const write = (\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => {\n const str = typeof chunk === 'string' ? chunk : chunk.toString();\n const newLines = (str.match(/\\n/g) ?? []).length;\n\n // If the write is not initiated by Logger's updateOutput method\n if (!this.isUpdating) {\n this.extraLines += newLines;\n }\n\n return this.originalStdoutWrite!(chunk, encoding, callback);\n };\n\n process.stdout.write = write as typeof process.stdout.write;\n }\n\n // Set a flag to indicate that updateOutput is running\n this.isUpdating = true;\n\n // Adjust lineDifCounter if LINE_DETECTOR is not the first line\n const contentLines = content.split('\\n');\n const indexOfLineDetector = contentLines.indexOf(LINE_DETECTOR.trim());\n\n if (indexOfLineDetector > 0) {\n // LINE_DETECTOR is not at the first line\n this.lineDifCounter = indexOfLineDetector;\n } else {\n this.lineDifCounter = 0;\n }\n\n // Calculate total lines to move up\n const totalLinesToMoveUp =\n this.previousLineCount + this.lineDifCounter + this.extraLines;\n\n // Move cursor up by totalLinesToMoveUp\n readline.moveCursor(process.stdout, 0, -totalLinesToMoveUp);\n\n // Clear all lines downwards\n readline.clearScreenDown(process.stdout);\n\n // Write the updated content\n contentLines.forEach((line) => {\n process.stdout.write(`${line}\\x1b[K\\n`);\n });\n\n // Update previousLineCount\n this.previousLineCount = contentLines.length;\n\n // Reset extraLines counter and updating flag\n this.extraLines = 0;\n this.isUpdating = false;\n }\n\n public stop() {\n this.stopSpinner();\n }\n\n public updateStatus(\n dictionaries: {\n dictionaryKey: string;\n type: 'local' | 'distant';\n status: Partial<State>;\n }[]\n ) {\n for (const { dictionaryKey, type, status } of dictionaries) {\n const statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n if (statusObj) {\n const state = statusObj.state.find((s) => s.type === type);\n if (state) {\n // Update existing state\n Object.assign(state, status);\n } else {\n // If the state for this type doesn't exist yet, add it\n if (status.status === undefined) {\n status.status = 'pending'; // Provide default status\n }\n const newState: State = {\n type,\n status: status.status,\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n statusObj.state.push(newState);\n }\n } else {\n // If the status object doesn't exist, create it\n const newState: State = {\n type,\n status: status.status ?? 'pending',\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n this.dictionariesStatuses.push({\n dictionaryKey,\n state: [newState],\n });\n }\n }\n\n // Update the display after status change\n this.updateAllStatusLines();\n }\n\n private getStatusIcon(status: string): string {\n const statusIcons: Record<string, string> = {\n pending: '⏲',\n fetching: '', // Spinner handled separately\n built: '✔',\n imported: '✔',\n error: '✖',\n };\n return statusIcons[status] ?? '';\n }\n\n private getStatusLine(statusObj: DictionariesStatus): string {\n const keyPadding =\n this.maxDictionaryKeyLength - statusObj.dictionaryKey.length;\n const paddedKey = `${statusObj.dictionaryKey}${' '.repeat(keyPadding)}`;\n\n const states = statusObj.state.map((state) => {\n let colorStart = '';\n let colorEnd = '';\n let icon = this.getStatusIcon(state.status);\n if (state.status === 'fetching') {\n // Use spinner frame\n icon = SPINNER_FRAMES[state.spinnerFrameIndex! % SPINNER_FRAMES.length];\n colorStart = BLUE;\n colorEnd = RESET;\n } else if (state.status === 'error') {\n colorStart = RED;\n colorEnd = RESET;\n } else if (state.status === 'imported' || state.status === 'built') {\n colorStart = GREEN;\n colorEnd = RESET;\n } else {\n colorStart = GREY;\n colorEnd = RESET;\n }\n\n // Format the status block\n const statusBlock = `${GREY_DARK}[${state.type}: ${colorStart}${icon} ${state.status}${GREY_DARK}]${colorEnd}`;\n\n return `${colorStart}${statusBlock}${colorEnd}`;\n });\n\n return `- ${paddedKey} ${states.join(' ')}`;\n }\n\n // Replace logUpdate calls with your custom methods\n private updateAllStatusLines() {\n const terminalHeight = process.stdout.rows;\n const maxVisibleLines = terminalHeight - 1;\n\n const lines = this.dictionariesStatuses.map((statusObj) => {\n statusObj.state.forEach((state) => {\n if (state.status === 'fetching') {\n // Update spinner frame\n state.spinnerFrameIndex =\n (state.spinnerFrameIndex! + 1) % SPINNER_FRAMES.length;\n }\n });\n return this.getStatusLine(statusObj);\n });\n\n let content;\n\n if (lines.length > maxVisibleLines) {\n const visibleLines = lines.slice(0, maxVisibleLines - 5);\n const summary = `... and ${lines.length - visibleLines.length} more lines`;\n content = LINE_DETECTOR + visibleLines.join('\\n') + '\\n' + summary;\n } else {\n content = lines.join('\\n');\n }\n\n this.updateOutput(content);\n }\n\n public getStatuses() {\n return this.dictionariesStatuses;\n }\n}\n\nexport const logger = Logger.getInstance();\n"],"mappings":"AAAA,OAAO,cAAc;AACrB,SAAS,0BAA0B;AAgBnC,MAAM,gBAAgB;AACtB,MAAM,iBAAiB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAGxE,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM,MAAM;AACZ,MAAM,OAAO;AACb,MAAM,OAAO;AACb,MAAM,YAAY;AAElB,MAAM,OAAO;AAAA,EACH,uBAA6C,CAAC;AAAA,EAC9C,eAAsC;AAAA,EACtC,yBAAiC;AAAA,EACjC,oBAA4B;AAAA,EAC5B,iBAAyB;AAAA,EACzB,sBAMG;AAAA,EACH,aAAqB;AAAA,EACrB,aAAsB;AAAA;AAAA,EAG9B,OAAe;AAAA,EAEP,cAAc;AAAA,EAAC;AAAA,EAEvB,OAAc,cAAsB;AAClC,QAAI,CAAC,OAAO,UAAU;AACpB,aAAO,WAAW,IAAI,OAAO;AAAA,IAC/B;AACA,WAAO,OAAO;AAAA,EAChB;AAAA,EAEO,KACL,uBACA,yBACA;AACA,UAAM,UAAU,MAAM;AAAA,MACpB,IAAI;AAAA,QACF,CAAC,GAAG,uBAAuB,GAAG,uBAAuB,EAAE;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,yBAAyB,QAAQ;AAAA,MACpC,CAAC,KAAK,QAAS,IAAI,SAAS,MAAM,IAAI,SAAS;AAAA,MAC/C;AAAA,IACF;AAEA,SAAK,uBAAuB,QAAQ,IAAI,CAAC,kBAAkB;AACzD,YAAM,SAAkB,CAAC;AAEzB,UAAI,sBAAsB,SAAS,aAAa,GAAG;AACjD,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,mBAAmB;AAAA,QACrB,CAAC;AAAA,MACH;AACA,UAAI,wBAAwB,SAAS,aAAa,GAAG;AACnD,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,mBAAmB;AAAA,QACrB,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAGD,SAAK,aAAa;AAGlB,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA,EAGO,kBACL,MACA,gBACA;AACA,eAAW,iBAAiB,gBAAgB;AAE1C,UAAI,cAAc,SAAS,KAAK,wBAAwB;AACtD,aAAK,yBAAyB,cAAc;AAAA,MAC9C;AAEA,UAAI,YAAY,KAAK,qBAAqB;AAAA,QACxC,CAAC,OAAO,GAAG,kBAAkB;AAAA,MAC/B;AAEA,UAAI,CAAC,WAAW;AAGd,oBAAY;AAAA,UACV;AAAA,UACA,OAAO,CAAC;AAAA,QACV;AACA,aAAK,qBAAqB,KAAK,SAAS;AAExC,cAAM,WAAkB;AAAA,UACtB;AAAA,UACA,QAAQ;AAAA,UACR,mBAAmB;AAAA,QACrB;AACA,kBAAU,MAAM,KAAK,QAAQ;AAAA,MAC/B,OAAO;AACL,cAAM,gBAAgB,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACjE,YAAI,CAAC,eAAe;AAGlB,gBAAM,WAAkB;AAAA,YACtB;AAAA,YACA,QAAQ;AAAA,YACR,mBAAmB;AAAA,UACrB;AACA,oBAAU,MAAM,KAAK,QAAQ;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAGA,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEQ,eAAe;AACrB,QAAI,CAAC,KAAK,cAAc;AACtB,WAAK,eAAe,YAAY,MAAM;AACpC,aAAK,qBAAqB;AAAA,MAC5B,GAAG,GAAG;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,cAAc;AACpB,QAAI,KAAK,cAAc;AACrB,oBAAc,KAAK,YAAY;AAC/B,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGQ,aAAa,SAAiB;AAEpC,QAAI,CAAC,KAAK,qBAAqB;AAC7B,WAAK,sBAAsB,QAAQ,OAAO,MAAM,KAAK,QAAQ,MAAM;AACnE,WAAK,aAAa;AAElB,YAAM,QAAQ,CACZ,OACA,UACA,aACG;AACH,cAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS;AAC/D,cAAM,YAAY,IAAI,MAAM,KAAK,KAAK,CAAC,GAAG;AAG1C,YAAI,CAAC,KAAK,YAAY;AACpB,eAAK,cAAc;AAAA,QACrB;AAEA,eAAO,KAAK,oBAAqB,OAAO,UAAU,QAAQ;AAAA,MAC5D;AAEA,cAAQ,OAAO,QAAQ;AAAA,IACzB;AAGA,SAAK,aAAa;AAGlB,UAAM,eAAe,QAAQ,MAAM,IAAI;AACvC,UAAM,sBAAsB,aAAa,QAAQ,cAAc,KAAK,CAAC;AAErE,QAAI,sBAAsB,GAAG;AAE3B,WAAK,iBAAiB;AAAA,IACxB,OAAO;AACL,WAAK,iBAAiB;AAAA,IACxB;AAGA,UAAM,qBACJ,KAAK,oBAAoB,KAAK,iBAAiB,KAAK;AAGtD,aAAS,WAAW,QAAQ,QAAQ,GAAG,CAAC,kBAAkB;AAG1D,aAAS,gBAAgB,QAAQ,MAAM;AAGvC,iBAAa,QAAQ,CAAC,SAAS;AAC7B,cAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAU;AAAA,IACxC,CAAC;AAGD,SAAK,oBAAoB,aAAa;AAGtC,SAAK,aAAa;AAClB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEO,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,aACL,cAKA;AACA,eAAW,EAAE,eAAe,MAAM,OAAO,KAAK,cAAc;AAC1D,YAAM,YAAY,KAAK,qBAAqB;AAAA,QAC1C,CAAC,OAAO,GAAG,kBAAkB;AAAA,MAC/B;AACA,UAAI,WAAW;AACb,cAAM,QAAQ,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACzD,YAAI,OAAO;AAET,iBAAO,OAAO,OAAO,MAAM;AAAA,QAC7B,OAAO;AAEL,cAAI,OAAO,WAAW,QAAW;AAC/B,mBAAO,SAAS;AAAA,UAClB;AACA,gBAAM,WAAkB;AAAA,YACtB;AAAA,YACA,QAAQ,OAAO;AAAA,YACf,MAAM,OAAO,QAAQ;AAAA,YACrB,OAAO,OAAO;AAAA,YACd,cAAc,OAAO;AAAA,YACrB,mBAAmB,OAAO,qBAAqB;AAAA,UACjD;AACA,oBAAU,MAAM,KAAK,QAAQ;AAAA,QAC/B;AAAA,MACF,OAAO;AAEL,cAAM,WAAkB;AAAA,UACtB;AAAA,UACA,QAAQ,OAAO,UAAU;AAAA,UACzB,MAAM,OAAO,QAAQ;AAAA,UACrB,OAAO,OAAO;AAAA,UACd,cAAc,OAAO;AAAA,UACrB,mBAAmB,OAAO,qBAAqB;AAAA,QACjD;AACA,aAAK,qBAAqB,KAAK;AAAA,UAC7B;AAAA,UACA,OAAO,CAAC,QAAQ;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEQ,cAAc,QAAwB;AAC5C,UAAM,cAAsC;AAAA,MAC1C,SAAS;AAAA,MACT,UAAU;AAAA;AAAA,MACV,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AACA,WAAO,YAAY,MAAM,KAAK;AAAA,EAChC;AAAA,EAEQ,cAAc,WAAuC;AAC3D,UAAM,aACJ,KAAK,yBAAyB,UAAU,cAAc;AACxD,UAAM,YAAY,GAAG,UAAU,aAAa,GAAG,IAAI,OAAO,UAAU,CAAC;AAErE,UAAM,SAAS,UAAU,MAAM,IAAI,CAAC,UAAU;AAC5C,UAAI,aAAa;AACjB,UAAI,WAAW;AACf,UAAI,OAAO,KAAK,cAAc,MAAM,MAAM;AAC1C,UAAI,MAAM,WAAW,YAAY;AAE/B,eAAO,eAAe,MAAM,oBAAqB,eAAe,MAAM;AACtE,qBAAa;AACb,mBAAW;AAAA,MACb,WAAW,MAAM,WAAW,SAAS;AACnC,qBAAa;AACb,mBAAW;AAAA,MACb,WAAW,MAAM,WAAW,cAAc,MAAM,WAAW,SAAS;AAClE,qBAAa;AACb,mBAAW;AAAA,MACb,OAAO;AACL,qBAAa;AACb,mBAAW;AAAA,MACb;AAGA,YAAM,cAAc,GAAG,SAAS,IAAI,MAAM,IAAI,KAAK,UAAU,GAAG,IAAI,IAAI,MAAM,MAAM,GAAG,SAAS,IAAI,QAAQ;AAE5G,aAAO,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ;AAAA,IAC/C,CAAC;AAED,WAAO,KAAK,SAAS,IAAI,OAAO,KAAK,GAAG,CAAC;AAAA,EAC3C;AAAA;AAAA,EAGQ,uBAAuB;AAC7B,UAAM,iBAAiB,QAAQ,OAAO;AACtC,UAAM,kBAAkB,iBAAiB;AAEzC,UAAM,QAAQ,KAAK,qBAAqB,IAAI,CAAC,cAAc;AACzD,gBAAU,MAAM,QAAQ,CAAC,UAAU;AACjC,YAAI,MAAM,WAAW,YAAY;AAE/B,gBAAM,qBACH,MAAM,oBAAqB,KAAK,eAAe;AAAA,QACpD;AAAA,MACF,CAAC;AACD,aAAO,KAAK,cAAc,SAAS;AAAA,IACrC,CAAC;AAED,QAAI;AAEJ,QAAI,MAAM,SAAS,iBAAiB;AAClC,YAAM,eAAe,MAAM,MAAM,GAAG,kBAAkB,CAAC;AACvD,YAAM,UAAU,WAAW,MAAM,SAAS,aAAa,MAAM;AAC7D,gBAAU,gBAAgB,aAAa,KAAK,IAAI,IAAI,OAAO;AAAA,IAC7D,OAAO;AACL,gBAAU,MAAM,KAAK,IAAI;AAAA,IAC3B;AAEA,SAAK,aAAa,OAAO;AAAA,EAC3B;AAAA,EAEO,cAAc;AACnB,WAAO,KAAK;AAAA,EACd;AACF;AAEO,MAAM,SAAS,OAAO,YAAY;","names":[]}
1
+ {"version":3,"sources":["../../src/log.ts"],"sourcesContent":["import readline from 'readline';\nimport { sortAlphabetically } from './utils';\n\nexport type State = {\n type: 'local' | 'distant';\n status: 'pending' | 'fetching' | 'fetched' | 'error' | 'imported' | 'built';\n icon?: string;\n error?: Error;\n errorMessage?: string;\n spinnerFrameIndex?: number;\n};\n\nexport type DictionariesStatus = {\n dictionaryKey: string;\n state: State[];\n};\n\nconst LINE_DETECTOR = '\\u200B\\u200B\\u200B'; // Three zero-width spaces\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n// ANSI color codes\nconst RESET = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst RED = '\\x1b[31m';\nconst BLUE = '\\x1b[34m';\nconst GREY = '\\x1b[90m';\nconst GREY_DARK = '\\x1b[90m';\n\nclass Logger {\n private dictionariesStatuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private maxDictionaryKeyLength: number = 0;\n private previousLineCount: number = 0;\n private lineDifCounter: number = 0;\n private originalStdoutWrite:\n | ((\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => boolean)\n | null = null;\n private extraLines: number = 0;\n private isUpdating: boolean = false;\n\n // Singleton instance\n private static instance: Logger;\n\n private constructor() {}\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n\n public init(\n localDictionariesKeys: string[],\n distantDictionariesKeys: string[]\n ) {\n const allKeys = Array.from(\n new Set(\n [...localDictionariesKeys, ...distantDictionariesKeys].sort(\n sortAlphabetically\n )\n )\n );\n\n this.maxDictionaryKeyLength = allKeys.reduce(\n (max, key) => (key.length > max ? key.length : max),\n 0\n );\n\n this.dictionariesStatuses = allKeys.map((dictionaryKey) => {\n const states: State[] = [];\n\n if (localDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'local',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n if (distantDictionariesKeys.includes(dictionaryKey)) {\n states.push({\n type: 'distant',\n status: 'pending',\n spinnerFrameIndex: 0,\n });\n }\n\n return {\n dictionaryKey,\n state: states,\n };\n });\n\n // Start spinner timer\n this.startSpinner();\n\n // Update all status lines (this will output the initial statuses)\n this.updateAllStatusLines();\n }\n\n // New method to add dictionary keys after initialization\n public addDictionaryKeys(\n type: 'local' | 'distant',\n dictionaryKeys: string[]\n ) {\n for (const dictionaryKey of dictionaryKeys) {\n // Update maxDictionaryKeyLength if the new key is longer\n if (dictionaryKey.length > this.maxDictionaryKeyLength) {\n this.maxDictionaryKeyLength = dictionaryKey.length;\n }\n\n let statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n\n if (!statusObj) {\n // If the dictionaryKey doesn't exist yet, create a new DictionariesStatus\n\n statusObj = {\n dictionaryKey,\n state: [],\n };\n this.dictionariesStatuses.push(statusObj);\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n } else {\n const existingState = statusObj.state.find((s) => s.type === type);\n if (!existingState) {\n // Add new state for the type\n\n const newState: State = {\n type,\n status: 'pending',\n spinnerFrameIndex: 0,\n };\n statusObj.state.push(newState);\n }\n }\n }\n\n // Call updateAllStatusLines() to refresh the output\n this.updateAllStatusLines();\n }\n\n private startSpinner() {\n if (!this.spinnerTimer) {\n this.spinnerTimer = setInterval(() => {\n this.updateAllStatusLines();\n }, 100); // Update every 100ms\n }\n }\n\n private stopSpinner() {\n if (this.spinnerTimer) {\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n }\n\n // Method to update the terminal output\n private updateOutput(content: string) {\n // Monkey-patch process.stdout.write to keep track of extra lines\n if (!this.originalStdoutWrite) {\n this.originalStdoutWrite = process.stdout.write.bind(process.stdout);\n this.extraLines = 0;\n\n const write = (\n chunk: string | Uint8Array, // `chunk` can be either a string or a Uint8Array\n encoding?: BufferEncoding, // `encoding` is optional and should be a BufferEncoding\n callback?: (err?: Error | null) => void // `callback` is optional and a function\n ) => {\n const str = typeof chunk === 'string' ? chunk : chunk.toString();\n const newLines = (str.match(/\\n/g) ?? []).length;\n\n // If the write is not initiated by Logger's updateOutput method\n if (!this.isUpdating) {\n this.extraLines += newLines;\n }\n\n return this.originalStdoutWrite!(chunk, encoding, callback);\n };\n\n process.stdout.write = write as typeof process.stdout.write;\n }\n\n // Set a flag to indicate that updateOutput is running\n this.isUpdating = true;\n\n // Adjust lineDifCounter if LINE_DETECTOR is not the first line\n const contentLines = content.split('\\n');\n const indexOfLineDetector = contentLines.indexOf(LINE_DETECTOR.trim());\n\n if (indexOfLineDetector > 0) {\n // LINE_DETECTOR is not at the first line\n this.lineDifCounter = indexOfLineDetector;\n } else {\n this.lineDifCounter = 0;\n }\n\n // Calculate total lines to move up\n const totalLinesToMoveUp =\n this.previousLineCount + this.lineDifCounter + this.extraLines;\n\n // Move cursor up by totalLinesToMoveUp\n readline.moveCursor(process.stdout, 0, -totalLinesToMoveUp);\n\n // Clear all lines downwards\n readline.clearScreenDown(process.stdout);\n\n // Write the updated content\n contentLines.forEach((line) => {\n process.stdout.write(`${line}\\x1b[K\\n`);\n });\n\n // Update previousLineCount\n this.previousLineCount = contentLines.length;\n\n // Reset extraLines counter and updating flag\n this.extraLines = 0;\n this.isUpdating = false;\n }\n\n public stop() {\n this.stopSpinner();\n }\n\n public updateStatus(\n dictionaries: {\n dictionaryKey: string;\n type: 'local' | 'distant';\n status: Partial<State>;\n }[]\n ) {\n for (const { dictionaryKey, type, status } of dictionaries) {\n const statusObj = this.dictionariesStatuses.find(\n (ds) => ds.dictionaryKey === dictionaryKey\n );\n if (statusObj) {\n const state = statusObj.state.find((s) => s.type === type);\n if (state) {\n // Update existing state\n Object.assign(state, status);\n } else {\n // If the state for this type doesn't exist yet, add it\n if (status.status === undefined) {\n status.status = 'pending'; // Provide default status\n }\n const newState: State = {\n type,\n status: status.status,\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n statusObj.state.push(newState);\n }\n } else {\n // If the status object doesn't exist, create it\n const newState: State = {\n type,\n status: status.status ?? 'pending',\n icon: status.icon ?? '',\n error: status.error,\n errorMessage: status.errorMessage,\n spinnerFrameIndex: status.spinnerFrameIndex ?? 0,\n };\n this.dictionariesStatuses.push({\n dictionaryKey,\n state: [newState],\n });\n }\n }\n\n // Update the display after status change\n this.updateAllStatusLines();\n }\n\n private getStatusIcon(status: string): string {\n const statusIcons: Record<string, string> = {\n pending: '⏲',\n fetching: '', // Spinner handled separately\n built: '✔',\n imported: '✔',\n error: '✖',\n };\n return statusIcons[status] ?? '';\n }\n\n private getStatusLine(statusObj: DictionariesStatus): string {\n const keyPadding =\n this.maxDictionaryKeyLength - statusObj.dictionaryKey.length;\n const paddedKey = `${statusObj.dictionaryKey}${' '.repeat(keyPadding)}`;\n\n const states = statusObj.state.map((state) => {\n let colorStart = '';\n let colorEnd = '';\n let icon = this.getStatusIcon(state.status);\n if (state.status === 'fetching') {\n // Use spinner frame\n icon = SPINNER_FRAMES[state.spinnerFrameIndex! % SPINNER_FRAMES.length];\n colorStart = BLUE;\n colorEnd = RESET;\n } else if (state.status === 'error') {\n colorStart = RED;\n colorEnd = RESET;\n } else if (state.status === 'imported' || state.status === 'built') {\n colorStart = GREEN;\n colorEnd = RESET;\n } else {\n colorStart = GREY;\n colorEnd = RESET;\n }\n\n // Format the status block\n const statusBlock = `${GREY_DARK}[${state.type}: ${colorStart}${icon} ${state.status}${GREY_DARK}]${colorEnd}`;\n\n return `${colorStart}${statusBlock}${colorEnd}`;\n });\n\n return `- ${paddedKey} ${states.join(' ')}`;\n }\n\n // Replace logUpdate calls with your custom methods\n private updateAllStatusLines() {\n const terminalHeight = process.stdout.rows;\n const maxVisibleLines = terminalHeight - 1;\n\n const lines = this.dictionariesStatuses.map((statusObj) => {\n statusObj.state.forEach((state) => {\n if (state.status === 'fetching') {\n // Update spinner frame\n state.spinnerFrameIndex =\n (state.spinnerFrameIndex! + 1) % SPINNER_FRAMES.length;\n }\n });\n return this.getStatusLine(statusObj);\n });\n\n let content;\n\n if (lines.length > maxVisibleLines) {\n const visibleLines = lines.slice(0, maxVisibleLines - 5);\n const summary = `... and ${lines.length - visibleLines.length} more`;\n content = LINE_DETECTOR + visibleLines.join('\\n') + '\\n' + summary;\n } else {\n content = lines.join('\\n');\n }\n\n this.updateOutput(content);\n }\n\n public getStatuses() {\n return this.dictionariesStatuses;\n }\n}\n\nexport const logger = Logger.getInstance();\n"],"mappings":"AAAA,OAAO,cAAc;AACrB,SAAS,0BAA0B;AAgBnC,MAAM,gBAAgB;AACtB,MAAM,iBAAiB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAGxE,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM,MAAM;AACZ,MAAM,OAAO;AACb,MAAM,OAAO;AACb,MAAM,YAAY;AAElB,MAAM,OAAO;AAAA,EACH,uBAA6C,CAAC;AAAA,EAC9C,eAAsC;AAAA,EACtC,yBAAiC;AAAA,EACjC,oBAA4B;AAAA,EAC5B,iBAAyB;AAAA,EACzB,sBAMG;AAAA,EACH,aAAqB;AAAA,EACrB,aAAsB;AAAA;AAAA,EAG9B,OAAe;AAAA,EAEP,cAAc;AAAA,EAAC;AAAA,EAEvB,OAAc,cAAsB;AAClC,QAAI,CAAC,OAAO,UAAU;AACpB,aAAO,WAAW,IAAI,OAAO;AAAA,IAC/B;AACA,WAAO,OAAO;AAAA,EAChB;AAAA,EAEO,KACL,uBACA,yBACA;AACA,UAAM,UAAU,MAAM;AAAA,MACpB,IAAI;AAAA,QACF,CAAC,GAAG,uBAAuB,GAAG,uBAAuB,EAAE;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,yBAAyB,QAAQ;AAAA,MACpC,CAAC,KAAK,QAAS,IAAI,SAAS,MAAM,IAAI,SAAS;AAAA,MAC/C;AAAA,IACF;AAEA,SAAK,uBAAuB,QAAQ,IAAI,CAAC,kBAAkB;AACzD,YAAM,SAAkB,CAAC;AAEzB,UAAI,sBAAsB,SAAS,aAAa,GAAG;AACjD,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,mBAAmB;AAAA,QACrB,CAAC;AAAA,MACH;AACA,UAAI,wBAAwB,SAAS,aAAa,GAAG;AACnD,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,mBAAmB;AAAA,QACrB,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAGD,SAAK,aAAa;AAGlB,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA,EAGO,kBACL,MACA,gBACA;AACA,eAAW,iBAAiB,gBAAgB;AAE1C,UAAI,cAAc,SAAS,KAAK,wBAAwB;AACtD,aAAK,yBAAyB,cAAc;AAAA,MAC9C;AAEA,UAAI,YAAY,KAAK,qBAAqB;AAAA,QACxC,CAAC,OAAO,GAAG,kBAAkB;AAAA,MAC/B;AAEA,UAAI,CAAC,WAAW;AAGd,oBAAY;AAAA,UACV;AAAA,UACA,OAAO,CAAC;AAAA,QACV;AACA,aAAK,qBAAqB,KAAK,SAAS;AAExC,cAAM,WAAkB;AAAA,UACtB;AAAA,UACA,QAAQ;AAAA,UACR,mBAAmB;AAAA,QACrB;AACA,kBAAU,MAAM,KAAK,QAAQ;AAAA,MAC/B,OAAO;AACL,cAAM,gBAAgB,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACjE,YAAI,CAAC,eAAe;AAGlB,gBAAM,WAAkB;AAAA,YACtB;AAAA,YACA,QAAQ;AAAA,YACR,mBAAmB;AAAA,UACrB;AACA,oBAAU,MAAM,KAAK,QAAQ;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAGA,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEQ,eAAe;AACrB,QAAI,CAAC,KAAK,cAAc;AACtB,WAAK,eAAe,YAAY,MAAM;AACpC,aAAK,qBAAqB;AAAA,MAC5B,GAAG,GAAG;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,cAAc;AACpB,QAAI,KAAK,cAAc;AACrB,oBAAc,KAAK,YAAY;AAC/B,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGQ,aAAa,SAAiB;AAEpC,QAAI,CAAC,KAAK,qBAAqB;AAC7B,WAAK,sBAAsB,QAAQ,OAAO,MAAM,KAAK,QAAQ,MAAM;AACnE,WAAK,aAAa;AAElB,YAAM,QAAQ,CACZ,OACA,UACA,aACG;AACH,cAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS;AAC/D,cAAM,YAAY,IAAI,MAAM,KAAK,KAAK,CAAC,GAAG;AAG1C,YAAI,CAAC,KAAK,YAAY;AACpB,eAAK,cAAc;AAAA,QACrB;AAEA,eAAO,KAAK,oBAAqB,OAAO,UAAU,QAAQ;AAAA,MAC5D;AAEA,cAAQ,OAAO,QAAQ;AAAA,IACzB;AAGA,SAAK,aAAa;AAGlB,UAAM,eAAe,QAAQ,MAAM,IAAI;AACvC,UAAM,sBAAsB,aAAa,QAAQ,cAAc,KAAK,CAAC;AAErE,QAAI,sBAAsB,GAAG;AAE3B,WAAK,iBAAiB;AAAA,IACxB,OAAO;AACL,WAAK,iBAAiB;AAAA,IACxB;AAGA,UAAM,qBACJ,KAAK,oBAAoB,KAAK,iBAAiB,KAAK;AAGtD,aAAS,WAAW,QAAQ,QAAQ,GAAG,CAAC,kBAAkB;AAG1D,aAAS,gBAAgB,QAAQ,MAAM;AAGvC,iBAAa,QAAQ,CAAC,SAAS;AAC7B,cAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAU;AAAA,IACxC,CAAC;AAGD,SAAK,oBAAoB,aAAa;AAGtC,SAAK,aAAa;AAClB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEO,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,aACL,cAKA;AACA,eAAW,EAAE,eAAe,MAAM,OAAO,KAAK,cAAc;AAC1D,YAAM,YAAY,KAAK,qBAAqB;AAAA,QAC1C,CAAC,OAAO,GAAG,kBAAkB;AAAA,MAC/B;AACA,UAAI,WAAW;AACb,cAAM,QAAQ,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACzD,YAAI,OAAO;AAET,iBAAO,OAAO,OAAO,MAAM;AAAA,QAC7B,OAAO;AAEL,cAAI,OAAO,WAAW,QAAW;AAC/B,mBAAO,SAAS;AAAA,UAClB;AACA,gBAAM,WAAkB;AAAA,YACtB;AAAA,YACA,QAAQ,OAAO;AAAA,YACf,MAAM,OAAO,QAAQ;AAAA,YACrB,OAAO,OAAO;AAAA,YACd,cAAc,OAAO;AAAA,YACrB,mBAAmB,OAAO,qBAAqB;AAAA,UACjD;AACA,oBAAU,MAAM,KAAK,QAAQ;AAAA,QAC/B;AAAA,MACF,OAAO;AAEL,cAAM,WAAkB;AAAA,UACtB;AAAA,UACA,QAAQ,OAAO,UAAU;AAAA,UACzB,MAAM,OAAO,QAAQ;AAAA,UACrB,OAAO,OAAO;AAAA,UACd,cAAc,OAAO;AAAA,UACrB,mBAAmB,OAAO,qBAAqB;AAAA,QACjD;AACA,aAAK,qBAAqB,KAAK;AAAA,UAC7B;AAAA,UACA,OAAO,CAAC,QAAQ;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEQ,cAAc,QAAwB;AAC5C,UAAM,cAAsC;AAAA,MAC1C,SAAS;AAAA,MACT,UAAU;AAAA;AAAA,MACV,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AACA,WAAO,YAAY,MAAM,KAAK;AAAA,EAChC;AAAA,EAEQ,cAAc,WAAuC;AAC3D,UAAM,aACJ,KAAK,yBAAyB,UAAU,cAAc;AACxD,UAAM,YAAY,GAAG,UAAU,aAAa,GAAG,IAAI,OAAO,UAAU,CAAC;AAErE,UAAM,SAAS,UAAU,MAAM,IAAI,CAAC,UAAU;AAC5C,UAAI,aAAa;AACjB,UAAI,WAAW;AACf,UAAI,OAAO,KAAK,cAAc,MAAM,MAAM;AAC1C,UAAI,MAAM,WAAW,YAAY;AAE/B,eAAO,eAAe,MAAM,oBAAqB,eAAe,MAAM;AACtE,qBAAa;AACb,mBAAW;AAAA,MACb,WAAW,MAAM,WAAW,SAAS;AACnC,qBAAa;AACb,mBAAW;AAAA,MACb,WAAW,MAAM,WAAW,cAAc,MAAM,WAAW,SAAS;AAClE,qBAAa;AACb,mBAAW;AAAA,MACb,OAAO;AACL,qBAAa;AACb,mBAAW;AAAA,MACb;AAGA,YAAM,cAAc,GAAG,SAAS,IAAI,MAAM,IAAI,KAAK,UAAU,GAAG,IAAI,IAAI,MAAM,MAAM,GAAG,SAAS,IAAI,QAAQ;AAE5G,aAAO,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ;AAAA,IAC/C,CAAC;AAED,WAAO,KAAK,SAAS,IAAI,OAAO,KAAK,GAAG,CAAC;AAAA,EAC3C;AAAA;AAAA,EAGQ,uBAAuB;AAC7B,UAAM,iBAAiB,QAAQ,OAAO;AACtC,UAAM,kBAAkB,iBAAiB;AAEzC,UAAM,QAAQ,KAAK,qBAAqB,IAAI,CAAC,cAAc;AACzD,gBAAU,MAAM,QAAQ,CAAC,UAAU;AACjC,YAAI,MAAM,WAAW,YAAY;AAE/B,gBAAM,qBACH,MAAM,oBAAqB,KAAK,eAAe;AAAA,QACpD;AAAA,MACF,CAAC;AACD,aAAO,KAAK,cAAc,SAAS;AAAA,IACrC,CAAC;AAED,QAAI;AAEJ,QAAI,MAAM,SAAS,iBAAiB;AAClC,YAAM,eAAe,MAAM,MAAM,GAAG,kBAAkB,CAAC;AACvD,YAAM,UAAU,WAAW,MAAM,SAAS,aAAa,MAAM;AAC7D,gBAAU,gBAAgB,aAAa,KAAK,IAAI,IAAI,OAAO;AAAA,IAC7D,OAAO;AACL,gBAAU,MAAM,KAAK,IAAI;AAAA,IAC3B;AAEA,SAAK,aAAa,OAAO;AAAA,EAC3B;AAAA,EAEO,cAAc;AACnB,WAAO,KAAK;AAAA,EACd;AACF;AAEO,MAAM,SAAS,OAAO,YAAY;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/chokidar",
3
- "version": "3.4.8",
3
+ "version": "3.5.0",
4
4
  "private": false,
5
5
  "description": "Chokidar application for IntLayer - Transpile IntLayer declaration files into dictionaries.",
6
6
  "keywords": [
@@ -67,11 +67,11 @@
67
67
  "quicktype-core": "^23.0.170",
68
68
  "react": "^18.3.1",
69
69
  "rimraf": "^6.0.1",
70
- "@intlayer/backend": "^3.4.8",
71
- "@intlayer/config": "^3.4.8",
72
- "@intlayer/core": "^3.4.8",
73
- "@intlayer/design-system": "^3.4.8",
74
- "intlayer": "^3.4.8"
70
+ "@intlayer/backend": "^3.5.0",
71
+ "@intlayer/config": "^3.5.0",
72
+ "@intlayer/core": "^3.5.0",
73
+ "@intlayer/design-system": "^3.5.0",
74
+ "intlayer": "^3.5.0"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@changesets/cli": "2.27.10",
@@ -91,11 +91,11 @@
91
91
  "@utils/tsup-config": "^1.0.4"
92
92
  },
93
93
  "peerDependencies": {
94
- "@intlayer/backend": "^3.4.8",
95
- "@intlayer/core": "^3.4.8",
96
- "@intlayer/design-system": "^3.4.8",
97
- "intlayer": "^3.4.8",
98
- "@intlayer/config": "^3.4.8"
94
+ "@intlayer/config": "^3.5.0",
95
+ "intlayer": "^3.5.0",
96
+ "@intlayer/design-system": "^3.5.0",
97
+ "@intlayer/backend": "^3.5.0",
98
+ "@intlayer/core": "^3.5.0"
99
99
  },
100
100
  "engines": {
101
101
  "node": ">=14.18"