UNPKG

arela

Version:

AI-powered CTO with multi-agent orchestration, code summarization, visual testing (web + mobile) for blazing fast development.

114 lines 3.41 kB
import pc from "picocolors"; export class ProgressBar { total; current = 0; label; width; startTime; lastUpdate = 0; lastUpdateTime; constructor(options) { this.total = options.total; this.label = options.label || "Progress"; this.width = options.width || 40; this.startTime = Date.now(); this.lastUpdateTime = Date.now(); } /** * Update progress */ update(current) { this.current = current; // Throttle updates to every 100ms const now = Date.now(); if (now - this.lastUpdate < 100 && current < this.total) { return; } this.lastUpdate = now; this.render(); } /** * Increment progress by 1 */ increment() { this.update(this.current + 1); } /** * Complete the progress bar */ complete() { this.current = this.total; this.render(); process.stdout.write("\n"); } /** * Render the progress bar */ render() { const percentage = Math.min(100, (this.current / this.total) * 100); const filled = Math.floor((this.width * this.current) / this.total); const empty = this.width - filled; const bar = "█".repeat(filled) + "░".repeat(empty); const percent = percentage.toFixed(0).padStart(3); const count = `${this.current}/${this.total}`; // Calculate ETA and speed const elapsed = Date.now() - this.startTime; const elapsedSeconds = elapsed / 1000; const rate = this.current / elapsedSeconds; const remaining = this.total - this.current; const eta = remaining / rate; const etaStr = this.formatTime(eta); // Calculate files/second (speed metric for ARELA-003) const speed = rate.toFixed(1); const line = `${this.label}: [${pc.cyan(bar)}] ${percent}% (${count}) - ETA: ${etaStr} - ${speed} files/sec`; // Clear line and write process.stdout.write(`\r${line}`); } /** * Format time in seconds to human readable */ formatTime(seconds) { if (!isFinite(seconds) || seconds < 0) { return "--:--"; } const mins = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); if (mins > 0) { return `${mins}m ${secs}s`; } return `${secs}s`; } } /** * Create a simple spinner */ export class Spinner { frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; current = 0; interval = null; message; constructor(message) { this.message = message; } start() { this.interval = setInterval(() => { const frame = this.frames[this.current]; process.stdout.write(`\r${pc.cyan(frame)} ${this.message}`); this.current = (this.current + 1) % this.frames.length; }, 80); } stop(finalMessage) { if (this.interval) { clearInterval(this.interval); this.interval = null; } process.stdout.write(`\r${finalMessage || this.message}\n`); } succeed(message) { this.stop(pc.green(`✓ ${message || this.message}`)); } fail(message) { this.stop(pc.red(`✗ ${message || this.message}`)); } } //# sourceMappingURL=progress.js.map