datapilot-cli
Version:
Enterprise-grade streaming multi-format data analysis with comprehensive statistical insights and intelligent relationship detection - supports CSV, JSON, Excel, TSV, Parquet - memory-efficient, cross-platform
226 lines • 6.46 kB
JavaScript
"use strict";
/**
* CLI Progress Reporter - Real-time progress updates with spinners and progress bars
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProgressReporter = void 0;
class ProgressReporter {
quiet;
verbose;
currentPhase;
spinnerInterval;
spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
spinnerIndex = 0;
progressCallback;
constructor(quiet = false, verbose = false) {
this.quiet = quiet;
this.verbose = verbose;
}
/**
* Set progress callback for external listeners (e.g., tests)
*/
setProgressCallback(callback) {
this.progressCallback = callback;
}
/**
* Start progress reporting for a phase
*/
startPhase(phase, message) {
if (this.progressCallback) {
this.progressCallback({ message: `Starting ${phase}: ${message}`, progress: 0 });
}
if (this.quiet)
return;
this.currentPhase = phase;
this.stopSpinner();
if (this.verbose) {
console.log(`\n🔄 ${phase}: ${message}`);
}
else {
process.stdout.write(`${this.getSpinnerFrame()} ${message}`);
this.startSpinner();
}
}
/**
* Update progress within a phase
*/
updateProgress(state) {
if (this.progressCallback) {
this.progressCallback({ message: state.message, progress: state.progress });
}
if (this.quiet)
return;
if (this.verbose) {
const timeStr = this.formatTime(state.timeElapsed);
const etaStr = state.estimatedTimeRemaining
? ` (ETA: ${this.formatTime(state.estimatedTimeRemaining)})`
: '';
console.log(` 📊 ${state.progress}% - ${state.message} [${timeStr}]${etaStr}`);
}
else {
// Update spinner message
this.clearLine();
process.stdout.write(`${this.getSpinnerFrame()} ${state.message} (${state.progress}%)`);
}
}
/**
* Complete current phase
*/
completePhase(message, timeElapsed) {
if (this.progressCallback) {
this.progressCallback({ message: `Complete: ${message}`, progress: 100 });
}
if (this.quiet)
return;
this.stopSpinner();
this.clearLine();
const timeStr = this.formatTime(timeElapsed);
console.log(`✅ ${message} [${timeStr}]`);
}
/**
* Report error in current phase
*/
errorPhase(message) {
if (this.quiet)
return;
this.stopSpinner();
this.clearLine();
console.log(`❌ ${message}`);
}
/**
* Report warning
*/
warning(message) {
if (this.quiet)
return;
if (this.currentPhase) {
this.pauseSpinner();
console.log(`⚠️ ${message}`);
this.resumeSpinner();
}
else {
console.log(`⚠️ ${message}`);
}
}
/**
* Report info message
*/
info(message) {
if (this.quiet || !this.verbose)
return;
if (this.currentPhase) {
this.pauseSpinner();
console.log(`ℹ️ ${message}`);
this.resumeSpinner();
}
else {
console.log(`ℹ️ ${message}`);
}
}
/**
* Show summary statistics
*/
showSummary(stats) {
if (this.quiet)
return;
console.log('\n📊 Summary:');
console.log(` • Processing time: ${this.formatTime(stats.processingTime)}`);
console.log(` • Rows processed: ${stats.rowsProcessed.toLocaleString()}`);
console.log(` • Warnings: ${stats.warnings}`);
console.log(` • Errors: ${stats.errors}`);
if (stats.processingTime > 0) {
const throughput = Math.round(stats.rowsProcessed / (stats.processingTime / 1000));
console.log(` • Throughput: ${throughput.toLocaleString()} rows/second`);
}
}
/**
* Start the spinner animation
*/
startSpinner() {
if (this.spinnerInterval)
return;
this.spinnerInterval = setInterval(() => {
this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
this.updateSpinnerFrame();
}, 100);
}
/**
* Stop the spinner animation
*/
stopSpinner() {
if (this.spinnerInterval) {
clearInterval(this.spinnerInterval);
this.spinnerInterval = undefined;
}
}
/**
* Pause spinner temporarily
*/
pauseSpinner() {
this.stopSpinner();
this.clearLine();
}
/**
* Resume spinner after pause
*/
resumeSpinner() {
if (this.currentPhase && !this.verbose) {
process.stdout.write(`${this.getSpinnerFrame()} Processing...`);
this.startSpinner();
}
}
/**
* Get current spinner frame
*/
getSpinnerFrame() {
return this.spinnerFrames[this.spinnerIndex];
}
/**
* Update spinner frame in place
*/
updateSpinnerFrame() {
if (process.stdout.isTTY) {
process.stdout.write(`\r${this.getSpinnerFrame()}`);
process.stdout.moveCursor(-1, 0);
}
}
/**
* Clear current line
*/
clearLine() {
if (process.stdout.isTTY) {
process.stdout.clearLine(0);
process.stdout.cursorTo(0);
}
else {
process.stdout.write('\n');
}
}
/**
* Format time duration
*/
formatTime(milliseconds) {
if (milliseconds < 1000) {
return `${Math.round(milliseconds)}ms`;
}
else if (milliseconds < 60000) {
return `${(milliseconds / 1000).toFixed(1)}s`;
}
else {
const minutes = Math.floor(milliseconds / 60000);
const seconds = Math.round((milliseconds % 60000) / 1000);
return `${minutes}m ${seconds}s`;
}
}
/**
* Cleanup on exit
*/
cleanup() {
this.stopSpinner();
if (process.stdout.isTTY && this.currentPhase) {
this.clearLine();
}
}
}
exports.ProgressReporter = ProgressReporter;
//# sourceMappingURL=progress-reporter.js.map