@ima/cli
Version:
IMA.js CLI tool to build, develop and work with IMA.js applications.
126 lines (125 loc) • 4.19 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createProgress = createProgress;
exports.getProgress = getProgress;
const logger_1 = require("@ima/dev-utils/logger");
const chalk_1 = __importDefault(require("chalk"));
const cli_progress_1 = __importDefault(require("cli-progress"));
const webpack_1 = __importDefault(require("webpack"));
/**
* Helper class to track and display progress in the webpack.ProgressPlugin
* across multiple configuration contexts. All configuration contexts are
* tracked using one progress bar.
*/
class ProgressTracker {
_hasStarted;
_elapsed;
_trackedEntries;
_percentageTracker;
_progressBar;
constructor() {
this._hasStarted = false;
this._elapsed = null;
this._trackedEntries = 0;
this._percentageTracker = {};
this._progressBar = new cli_progress_1.default.SingleBar({
format: `${chalk_1.default.bold.cyan('info:')} ${chalk_1.default.gray('[{bar}]')} ${chalk_1.default.magenta('{percentage}%')} ${chalk_1.default.gray('[{time}]')} ${chalk_1.default.green('{msg}')} {other}`,
barCompleteChar: '\u25A0',
barIncompleteChar: ' ',
barsize: 10,
fps: 30,
hideCursor: true,
});
}
/**
* Register new webpack.PluginProgress instance.
*/
register(name) {
this._trackedEntries++;
this._percentageTracker[name] = 0;
}
/**
* Custom handler for webpack.ProgressPlugin, this should be called
* from within the webpack.ProgressPlugin instance and handles all styling
* and progress reporting.
*/
handler(name, percentage, msg, ...args) {
// Track total progress across all
this._percentageTracker[name] = percentage;
const normPercentage = this._getPercentage();
if (!this._hasStarted) {
this.start();
}
this.update(normPercentage, msg, args.join(' '));
}
/**
* Returns percentage between 0-100 computed across all tracked configurations.
*/
_getPercentage() {
const percentageSum = Object.values(this._percentageTracker).reduce((acc, cur) => acc + cur, 0);
return Number(((percentageSum / this._trackedEntries) * 100).toFixed(0));
}
/**
* Start progress bar reporting (renders progress bar with specified size).
*/
start() {
this._hasStarted = true;
this._elapsed = (0, logger_1.time)();
this._progressBar.start(100, 0, {
msg: chalk_1.default.green('initializing'),
});
}
/**
* Update progress bar with new data.
*/
update(percentage, msg, other) {
this._progressBar.update(percentage, {
time: this._elapsed?.(),
msg,
other,
});
}
/**
* Stop progress bar rendering and end compilation reporting.
*/
stop() {
// Don't do anything if the progress is not running
if (!this._hasStarted) {
return;
}
this._progressBar.update(100, {
time: this._elapsed?.(),
msg: 'done',
other: `(${Object.keys(this._percentageTracker).join(', ')})`,
});
this._progressBar.stop();
// Update tracking flags
this._hasStarted = false;
this._elapsed = null;
}
}
const progressTracker = new ProgressTracker();
/**
* Initializes wrapped webpack.ProgressPlugin
* to track compilation progress.
*/
function createProgress(name) {
// Register new progress to tracker
progressTracker.register(name);
// Return new progress plugin instance
return new webpack_1.default.ProgressPlugin({
entries: true,
percentBy: 'dependencies',
handler: (percentage, msg, ...args) => progressTracker.handler(name, percentage, msg, ...args),
});
}
/**
* Provides access to the singleton progress instance
* so i can be modified externally.
*/
function getProgress() {
return progressTracker;
}