@ayonli/jsext
Version:
A JavaScript extension package for building strong and modern applications.
118 lines (114 loc) • 3.92 kB
JavaScript
;
var bytes = require('../../bytes.js');
require('../../string/constants.js');
require('../../env.js');
require('../../external/event-target-polyfill/index.js');
require('../../path.js');
var cli_constants = require('../../cli/constants.js');
var cli_common = require('../../cli/common.js');
const { CTRL_C, ESC, LF } = cli_constants.ControlKeys;
const { CLR } = cli_constants.ControlSequences;
const ongoingIndicators = [
" ",
"= ",
"== ",
"=== ",
" === ",
" === ",
" ===",
" ==",
" =",
" ",
];
async function handleTerminalProgress(message, fn, options) {
const { signal, abort, listenForAbort } = options;
let lastMessage = message;
let lastPosition = 0;
let lastPercent = undefined;
const renderSimpleBar = (position = undefined) => {
position !== null && position !== void 0 ? position : (position = lastPosition++);
const ongoingIndicator = ongoingIndicators[position];
cli_common.writeStdoutSync(CLR);
cli_common.writeStdoutSync(bytes.default(`${lastMessage} [${ongoingIndicator}]`));
if (lastPosition === ongoingIndicators.length) {
lastPosition = 0;
}
};
const renderPercentageBar = (percent) => {
const { width } = cli_common.getWindowSize();
const percentage = percent + "%";
const barWidth = width - cli_common.stringWidth(lastMessage) - percentage.length - 5;
const filled = "".padStart(Math.floor(barWidth * percent / 100), "#");
const empty = "".padStart(barWidth - filled.length, "-");
cli_common.writeStdoutSync(CLR);
cli_common.writeStdoutSync(bytes.default(`${lastMessage} [${filled}${empty}] ${percentage}`));
};
renderSimpleBar();
const waitingTimer = setInterval(renderSimpleBar, 200);
const set = (state) => {
if (signal.aborted) {
return;
}
if (state.message) {
lastMessage = state.message;
}
if (state.percent !== undefined) {
lastPercent = state.percent;
}
if (lastPercent !== undefined) {
renderPercentageBar(lastPercent);
clearInterval(waitingTimer);
}
else if (state.message) {
renderSimpleBar(lastPosition);
}
};
const nodeReader = typeof Deno === "object" ? null : (buf) => {
if (bytes.equals(buf, ESC) || bytes.equals(buf, CTRL_C)) {
abort === null || abort === void 0 ? void 0 : abort();
}
};
const denoReader = typeof Deno === "object" ? Deno.stdin.readable.getReader() : null;
if (abort) {
if (nodeReader) {
process.stdin.on("data", nodeReader);
}
else if (denoReader) {
(async () => {
while (true) {
try {
const { done, value } = await denoReader.read();
if (done || bytes.equals(value, ESC) || bytes.equals(value, CTRL_C)) {
signal.aborted || abort();
break;
}
}
catch (_a) {
signal.aborted || abort();
break;
}
}
denoReader.releaseLock();
})();
}
}
let job = fn(set, signal);
if (listenForAbort) {
job = Promise.race([job, listenForAbort()]);
}
try {
return await job;
}
finally {
cli_common.writeStdoutSync(LF);
clearInterval(waitingTimer);
if (nodeReader) {
process.stdin.off("data", nodeReader);
}
else if (denoReader) {
denoReader.releaseLock();
}
}
}
exports.handleTerminalProgress = handleTerminalProgress;
//# sourceMappingURL=progress.js.map