()
| 86 | let currentCount = 0; |
| 87 | |
| 88 | function render(): void { |
| 89 | if (!currentMessage) return; |
| 90 | const frame = animFrame(); |
| 91 | const glyphIdx = Math.floor(frame / FRAMES_PER_GLYPH) % SPINNER_GLYPHS.length; |
| 92 | const glyph = SPINNER_GLYPHS[glyphIdx] ?? SPINNER_GLYPHS[0] ?? '.'; |
| 93 | const color = shimmerColor(frame); |
| 94 | |
| 95 | let line: string; |
| 96 | if (currentPercent >= 0) { |
| 97 | const barWidth = 25; |
| 98 | const filled = Math.round(barWidth * currentPercent / 100); |
| 99 | const empty = barWidth - filled; |
| 100 | line = `${DM}${G.rail}${RST} ${color}${glyph}${RST} ${currentMessage} ${renderBar(frame, filled, empty)} ${currentPercent}%`; |
| 101 | } else if (currentCount > 0) { |
| 102 | line = `${DM}${G.rail}${RST} ${color}${glyph}${RST} ${currentMessage}... ${formatNumber(currentCount)} found`; |
| 103 | } else { |
| 104 | line = `${DM}${G.rail}${RST} ${color}${glyph}${RST} ${currentMessage}...`; |
| 105 | } |
| 106 | |
| 107 | writeStdout(`\r\x1b[K${line}`); |
| 108 | } |
| 109 | |
| 110 | // Clear the in-flight animation line. The persistent "phase done" line is |
| 111 | // printed by the PARENT on the main thread (TTY-aware, codepage-immune) — |
no test coverage detected