Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

multi-progress-bars

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

multi-progress-bars - npm Package Compare versions

Comparing version 1.1.4 to 2.0.1

dist/virtual-console.d.ts

18

CHANGELOG.md

@@ -5,2 +5,20 @@ # Changelog

### [2.0.1](https://github.com/kamiyo/multi-progress-bars/compare/v2.0.0...v2.0.1) (2020-08-30)
### Bug Fixes
* update demo gif ([81343fe](https://github.com/kamiyo/multi-progress-bars/commit/81343febc0b3c366584b6c0bacab1439814cbcf9))
## [2.0.0](https://github.com/kamiyo/multi-progress-bars/compare/v1.1.4...v2.0.0) (2020-08-30)
### ⚠ BREAKING CHANGES
* **behavior:** Overrides console so that console.logs can be preserved for scrollback. This requires a virtual-console class that manages fixed and dynamic rows. API technically hasn't changed, but marked as breaking since behavior is changed.
### Features
* **behavior:** Overrides console so that console.logs can be preserved for scrollback. This requires a virtual-console class that manages fixed and dynamic rows. API technically hasn't changed, but marked as breaking since behavior is changed. ([e045917](https://github.com/kamiyo/multi-progress-bars/commit/e0459174995cb17d8e0bb21d4ee09da53a089d00))
### [1.1.4](https://github.com/kamiyo/multi-progress-bars/compare/v1.1.3...v1.1.4) (2020-07-29)

@@ -7,0 +25,0 @@

233

dist/multi-progress-bars.cjs.js

@@ -10,2 +10,3 @@ 'use strict';

var stringWidth = _interopDefault(require('string-width'));
var util = require('util');

@@ -39,2 +40,144 @@ /*! *****************************************************************************

const ESC = '\x1B';
const CSI = ESC + '[';
const RESET = CSI + '0m';
const numberTo1StringHelper = (number) => (number !== undefined) ? (number + 1).toFixed(0) : '';
/** CUrsor Position
*
* @param row (required) 0-index absolute row
* @param column (optional) 0-index absolute column
*/
const CUP = (row, column) => CSI
+ numberTo1StringHelper(row)
+ ';'
+ numberTo1StringHelper(column)
+ 'H';
var EL_MODE;
(function (EL_MODE) {
EL_MODE[EL_MODE["TO_END"] = 0] = "TO_END";
EL_MODE[EL_MODE["TO_BEGINNING"] = 1] = "TO_BEGINNING";
EL_MODE[EL_MODE["ENTIRE_LINE"] = 2] = "ENTIRE_LINE";
})(EL_MODE || (EL_MODE = {}));
const EL = (mode = EL_MODE.TO_END) => {
return CSI + mode.toString() + 'K';
};
var ED_MODE;
(function (ED_MODE) {
ED_MODE[ED_MODE["TO_END"] = 0] = "TO_END";
ED_MODE[ED_MODE["TO_BEGINNING"] = 1] = "TO_BEGINNING";
ED_MODE[ED_MODE["ENTIRE_SCREEN"] = 2] = "ENTIRE_SCREEN";
ED_MODE[ED_MODE["ENTIRE_SCREEN_DELETE_SCROLLBACK"] = 3] = "ENTIRE_SCREEN_DELETE_SCROLLBACK";
})(ED_MODE || (ED_MODE = {}));
const ED = (mode = ED_MODE.TO_END) => {
return CSI + mode.toString() + 'J';
};
// Always puts a reset ANSI escape code, just in case it was stripped.
// Anyways, probably don't want any styling codes to linger past one line.
const clampString = (message, width) => {
while (stringWidth(message) > width) {
// Can't be sure we are slicing off a character vs a control sequence or colors
// so do it this way, checking each time.
message = message.slice(0, message.length - 1);
}
return message + RESET;
};
class VirtualConsole {
constructor(options) {
this.originalConsole = console;
this.stream = options.stream;
this.width = process.stdout.columns;
this.height = process.stdout.rows - 1;
this.progressHeight = 0;
this.consoleHeight = this.height;
this.progressBuffer = [];
this.consoleBuffer = [];
console = this;
this.init();
}
cleanup() {
this.stream.write('\x1b[0m');
}
init() {
process.on('SIGINT', this.cleanup);
const blank = '\n'.repeat(this.stream.rows) + CUP(0) + ED(ED_MODE.TO_END);
this.stream.write(blank);
}
/** Add or Update Progress Entry
*
* @param options
* index: number
* data: string
*/
upsertProgress(options) {
if (options.index < this.progressHeight) {
this.progressBuffer[options.index] = clampString(options.data, this.width);
if (options.refresh === undefined || options.refresh)
this.refresh();
return;
}
this.progressBuffer[options.index] = clampString(options.data, this.width);
const numToExtend = 1 + options.index - this.progressHeight;
this.progressHeight = Math.max(options.index + 1, this.progressHeight);
// this.consoleHeight = this.height - this.progressHeight;
if (numToExtend > 0) {
this.consoleHeight -= numToExtend;
const topLines = this.consoleBuffer.splice(0, numToExtend);
if (topLines.length) {
this.log(...topLines);
}
else {
this.refresh();
}
}
else {
this.refresh();
}
}
updateProgress(options) {
this.progressBuffer[options.index] = clampString(options.data, this.width);
if (options.refresh) {
this.refresh();
}
}
writeLines(...indexes) {
let writeString = indexes.reduce((prev, index) => {
return prev += CUP(index) + this.progressBuffer[index];
}, '');
this.stream.write(writeString);
}
refresh() {
const outString = CUP(0)
+ this.progressBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ (this.progressBuffer.length ? '\n' : '')
+ this.consoleBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ '\n';
this.stream.write(outString);
}
log(...data) {
const writeString = util.format.apply(null, data);
const clampedLines = writeString.split('\n').reduce((prev, curr) => {
const clamped = [];
do {
const front = curr.slice(0, this.width);
curr = curr.slice(this.width);
clamped.push(front);
} while (curr.length > this.width);
return [...prev, ...clamped];
}, []);
this.consoleBuffer.push(...clampedLines);
const topLines = (this.consoleBuffer.length > this.consoleHeight) ?
this.consoleBuffer.splice(0, this.consoleBuffer.length - this.consoleHeight) : [];
const outString = CUP(0)
+ topLines.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ (topLines.length ? '\n' : '')
+ this.progressBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ (this.progressBuffer.length ? '\n' : '')
+ this.consoleBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ '\n';
this.stream.write(outString);
}
}
const defaultTransformFn = (s) => s;
class MultiProgressBars {

@@ -54,7 +197,23 @@ /**

this.FULL_CHAR = this.CHARS[this.CHARS.length - 1];
this.endLine = 0;
this.longestNameLength = 0;
this.t = 0;
this.logger = new VirtualConsole({ stream: process.stdout });
this.resizeConsole = () => {
this.consoleSize = {
width: this.stream.columns,
height: this.stream.rows,
};
};
this.cleanup = () => {
if (this.intervalID) {
clearInterval(this.intervalID);
}
};
const { stream = process.stdout, spinnerFPS = 10, spinnerGenerator = this.hilbertSpinner, } = options || {};
let { progressWidth = 40, numCrawlers = 4, initMessage, } = options || {};
this.stream = stream;
this.stream.on('resize', () => {
this.resizeConsole();
});
this.spinnerFPS = Math.min(spinnerFPS, 60);

@@ -75,2 +234,3 @@ this.spinnerGenerator = spinnerGenerator;

this.progressWidth = progressWidth;
this.resizeConsole();
if (initMessage === undefined) {

@@ -85,21 +245,16 @@ initMessage = '$ ' + process.argv.map((arg) => {

// setup cleanup
process.on('SIGINT', () => {
if (this.intervalID) {
clearInterval(this.intervalID);
}
process.on('SIGINT', this.cleanup);
// TODO make this account for lines that wrap
const splitMessage = message.split('\n');
splitMessage.forEach((msg, idx) => {
this.logger.upsertProgress({
index: idx,
data: msg,
});
});
const splitMessage = message.split('\n').map((str) => stringWidth(str));
const cols = this.stream.columns;
const eachCols = splitMessage.map((msg) => Math.ceil(msg / cols));
this.initialLines = eachCols.reduce((prev, curr) => prev + curr, 0);
const blank = '\n'.repeat(this.stream.rows);
this.stream.write(blank);
this.stream.cursorTo(0);
this.stream.clearScreenDown();
this.stream.write(message);
const blankMinInit = '\n'.repeat(this.stream.rows - this.initialLines);
this.stream.write(blankMinInit);
this.initialLines = splitMessage.length;
}
addTask(name, _a) {
var { index } = _a, options = __rest(_a, ["index"]);
// if task exists, update fields
if (this.tasks[name] !== undefined) {

@@ -110,3 +265,8 @@ Object.keys(options).forEach((key) => options[key] === undefined && delete options[key]);

else {
const { type, barColorFn = (s) => s, percentage = 0, message = '', } = options;
// otherwise make a new task
const { type, barColorFn = defaultTransformFn, percentage = 0, message = '', } = options;
this.endLine = Math.max.apply(null, [
index,
...Object.entries(this.tasks).map(([_, task]) => task.index)
]) + 1;
this.tasks[name] = {

@@ -118,3 +278,3 @@ type,

name,
index: (index === undefined) ? Object.entries(this.tasks).length : index,
index,
done: false,

@@ -144,7 +304,5 @@ };

});
// Go to bottom of tasks and clear downwards.
this.stream.cursorTo(0, Object.entries(this.tasks).length + this.initialLines);
this.stream.clearScreenDown();
}
progressString(name, percentage, message, barColorFn = (b) => b) {
progressString(task) {
const { name, barColorFn, message, percentage, } = task;
// scale progress bar to percentage of total width

@@ -180,7 +338,11 @@ const scaled = percentage * this.progressWidth;

}
indefiniteString(task, spinner) {
const { name, barColorFn, message, } = task;
return name.padStart(this.longestNameLength) + ': ' + barColorFn(spinner) + ' ' + message;
}
writeTask(task) {
this.stream.cursorTo(0, this.initialLines + task.index);
this.stream.write(this.progressString(task.name, task.percentage, task.message, task.barColorFn).slice(0, this.stream.columns));
this.stream.clearLine(1);
this.stream.cursorTo(0, Object.entries(this.tasks).length + this.initialLines);
this.logger.upsertProgress({
index: task.index + this.initialLines,
data: this.progressString(task),
});
}

@@ -227,8 +389,7 @@ incrementTask(name, _a = {}) {

const task = this.tasks[name];
this.stream.cursorTo(0, this.initialLines + task.index);
const bar = task.barColorFn(this.FULL_CHAR.repeat(this.progressWidth));
// TODO customizable format. Maybe unify this with writeTask
this.stream.write(name.padStart(this.longestNameLength) + ': ' + bar + ' ' + message);
this.stream.clearLine(1);
this.stream.cursorTo(0, Object.entries(this.tasks).length + this.initialLines);
this.logger.upsertProgress({
index: task.index + this.initialLines,
data: name.padStart(this.longestNameLength) + ': ' + bar + ' ' + message,
});
// Stop animation if all tasks are done, and resolve the promise.

@@ -286,9 +447,13 @@ if (Object.entries(this.tasks).reduce((prev, [_, curr]) => {

const spinner = this.spinnerGenerator(this.t, this.progressWidth);
Object.entries(this.tasks).forEach(([name, task]) => {
Object.entries(this.tasks).forEach(([_, task]) => {
if (task.type === 'indefinite' && task.done === false) {
this.stream.cursorTo(0, this.initialLines + task.index);
this.stream.write(name.padStart(this.longestNameLength) + ': ' + task.barColorFn(spinner) + ' ' + task.message);
this.stream.clearLine(1);
let progressString = this.indefiniteString(task, spinner);
this.logger.upsertProgress({
index: task.index + this.initialLines,
data: progressString,
refresh: false,
});
}
});
this.logger.refresh();
this.t = this.t + 1;

@@ -295,0 +460,0 @@ }

@@ -61,2 +61,4 @@ /// <reference types="node" />

private FULL_CHAR;
private consoleSize;
private endLine;
private intervalID;

@@ -68,2 +70,3 @@ private numCrawlers;

private spinnerGenerator;
private logger;
promise: Promise<void>;

@@ -75,5 +78,8 @@ /**

constructor(options?: Partial<CtorOptions>);
private resizeConsole;
cleanup: () => void;
private init;
addTask(name: string, { index, ...options }: Omit<Task, 'name' | 'done' | 'message'> & Partial<Pick<Task, 'message'>>): void;
private progressString;
private indefiniteString;
private writeTask;

@@ -80,0 +86,0 @@ incrementTask(name: string, { percentage, ...options }?: UpdateOptions): void;

import { green } from 'chalk';
import { parse } from 'path';
import stringWidth from 'string-width';
import { format } from 'util';

@@ -32,2 +33,144 @@ /*! *****************************************************************************

const ESC = '\x1B';
const CSI = ESC + '[';
const RESET = CSI + '0m';
const numberTo1StringHelper = (number) => (number !== undefined) ? (number + 1).toFixed(0) : '';
/** CUrsor Position
*
* @param row (required) 0-index absolute row
* @param column (optional) 0-index absolute column
*/
const CUP = (row, column) => CSI
+ numberTo1StringHelper(row)
+ ';'
+ numberTo1StringHelper(column)
+ 'H';
var EL_MODE;
(function (EL_MODE) {
EL_MODE[EL_MODE["TO_END"] = 0] = "TO_END";
EL_MODE[EL_MODE["TO_BEGINNING"] = 1] = "TO_BEGINNING";
EL_MODE[EL_MODE["ENTIRE_LINE"] = 2] = "ENTIRE_LINE";
})(EL_MODE || (EL_MODE = {}));
const EL = (mode = EL_MODE.TO_END) => {
return CSI + mode.toString() + 'K';
};
var ED_MODE;
(function (ED_MODE) {
ED_MODE[ED_MODE["TO_END"] = 0] = "TO_END";
ED_MODE[ED_MODE["TO_BEGINNING"] = 1] = "TO_BEGINNING";
ED_MODE[ED_MODE["ENTIRE_SCREEN"] = 2] = "ENTIRE_SCREEN";
ED_MODE[ED_MODE["ENTIRE_SCREEN_DELETE_SCROLLBACK"] = 3] = "ENTIRE_SCREEN_DELETE_SCROLLBACK";
})(ED_MODE || (ED_MODE = {}));
const ED = (mode = ED_MODE.TO_END) => {
return CSI + mode.toString() + 'J';
};
// Always puts a reset ANSI escape code, just in case it was stripped.
// Anyways, probably don't want any styling codes to linger past one line.
const clampString = (message, width) => {
while (stringWidth(message) > width) {
// Can't be sure we are slicing off a character vs a control sequence or colors
// so do it this way, checking each time.
message = message.slice(0, message.length - 1);
}
return message + RESET;
};
class VirtualConsole {
constructor(options) {
this.originalConsole = console;
this.stream = options.stream;
this.width = process.stdout.columns;
this.height = process.stdout.rows - 1;
this.progressHeight = 0;
this.consoleHeight = this.height;
this.progressBuffer = [];
this.consoleBuffer = [];
console = this;
this.init();
}
cleanup() {
this.stream.write('\x1b[0m');
}
init() {
process.on('SIGINT', this.cleanup);
const blank = '\n'.repeat(this.stream.rows) + CUP(0) + ED(ED_MODE.TO_END);
this.stream.write(blank);
}
/** Add or Update Progress Entry
*
* @param options
* index: number
* data: string
*/
upsertProgress(options) {
if (options.index < this.progressHeight) {
this.progressBuffer[options.index] = clampString(options.data, this.width);
if (options.refresh === undefined || options.refresh)
this.refresh();
return;
}
this.progressBuffer[options.index] = clampString(options.data, this.width);
const numToExtend = 1 + options.index - this.progressHeight;
this.progressHeight = Math.max(options.index + 1, this.progressHeight);
// this.consoleHeight = this.height - this.progressHeight;
if (numToExtend > 0) {
this.consoleHeight -= numToExtend;
const topLines = this.consoleBuffer.splice(0, numToExtend);
if (topLines.length) {
this.log(...topLines);
}
else {
this.refresh();
}
}
else {
this.refresh();
}
}
updateProgress(options) {
this.progressBuffer[options.index] = clampString(options.data, this.width);
if (options.refresh) {
this.refresh();
}
}
writeLines(...indexes) {
let writeString = indexes.reduce((prev, index) => {
return prev += CUP(index) + this.progressBuffer[index];
}, '');
this.stream.write(writeString);
}
refresh() {
const outString = CUP(0)
+ this.progressBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ (this.progressBuffer.length ? '\n' : '')
+ this.consoleBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ '\n';
this.stream.write(outString);
}
log(...data) {
const writeString = format.apply(null, data);
const clampedLines = writeString.split('\n').reduce((prev, curr) => {
const clamped = [];
do {
const front = curr.slice(0, this.width);
curr = curr.slice(this.width);
clamped.push(front);
} while (curr.length > this.width);
return [...prev, ...clamped];
}, []);
this.consoleBuffer.push(...clampedLines);
const topLines = (this.consoleBuffer.length > this.consoleHeight) ?
this.consoleBuffer.splice(0, this.consoleBuffer.length - this.consoleHeight) : [];
const outString = CUP(0)
+ topLines.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ (topLines.length ? '\n' : '')
+ this.progressBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ (this.progressBuffer.length ? '\n' : '')
+ this.consoleBuffer.map((val) => val + EL(EL_MODE.TO_END)).join('\n')
+ '\n';
this.stream.write(outString);
}
}
const defaultTransformFn = (s) => s;
class MultiProgressBars {

@@ -47,7 +190,23 @@ /**

this.FULL_CHAR = this.CHARS[this.CHARS.length - 1];
this.endLine = 0;
this.longestNameLength = 0;
this.t = 0;
this.logger = new VirtualConsole({ stream: process.stdout });
this.resizeConsole = () => {
this.consoleSize = {
width: this.stream.columns,
height: this.stream.rows,
};
};
this.cleanup = () => {
if (this.intervalID) {
clearInterval(this.intervalID);
}
};
const { stream = process.stdout, spinnerFPS = 10, spinnerGenerator = this.hilbertSpinner, } = options || {};
let { progressWidth = 40, numCrawlers = 4, initMessage, } = options || {};
this.stream = stream;
this.stream.on('resize', () => {
this.resizeConsole();
});
this.spinnerFPS = Math.min(spinnerFPS, 60);

@@ -68,2 +227,3 @@ this.spinnerGenerator = spinnerGenerator;

this.progressWidth = progressWidth;
this.resizeConsole();
if (initMessage === undefined) {

@@ -78,21 +238,16 @@ initMessage = '$ ' + process.argv.map((arg) => {

// setup cleanup
process.on('SIGINT', () => {
if (this.intervalID) {
clearInterval(this.intervalID);
}
process.on('SIGINT', this.cleanup);
// TODO make this account for lines that wrap
const splitMessage = message.split('\n');
splitMessage.forEach((msg, idx) => {
this.logger.upsertProgress({
index: idx,
data: msg,
});
});
const splitMessage = message.split('\n').map((str) => stringWidth(str));
const cols = this.stream.columns;
const eachCols = splitMessage.map((msg) => Math.ceil(msg / cols));
this.initialLines = eachCols.reduce((prev, curr) => prev + curr, 0);
const blank = '\n'.repeat(this.stream.rows);
this.stream.write(blank);
this.stream.cursorTo(0);
this.stream.clearScreenDown();
this.stream.write(message);
const blankMinInit = '\n'.repeat(this.stream.rows - this.initialLines);
this.stream.write(blankMinInit);
this.initialLines = splitMessage.length;
}
addTask(name, _a) {
var { index } = _a, options = __rest(_a, ["index"]);
// if task exists, update fields
if (this.tasks[name] !== undefined) {

@@ -103,3 +258,8 @@ Object.keys(options).forEach((key) => options[key] === undefined && delete options[key]);

else {
const { type, barColorFn = (s) => s, percentage = 0, message = '', } = options;
// otherwise make a new task
const { type, barColorFn = defaultTransformFn, percentage = 0, message = '', } = options;
this.endLine = Math.max.apply(null, [
index,
...Object.entries(this.tasks).map(([_, task]) => task.index)
]) + 1;
this.tasks[name] = {

@@ -111,3 +271,3 @@ type,

name,
index: (index === undefined) ? Object.entries(this.tasks).length : index,
index,
done: false,

@@ -137,7 +297,5 @@ };

});
// Go to bottom of tasks and clear downwards.
this.stream.cursorTo(0, Object.entries(this.tasks).length + this.initialLines);
this.stream.clearScreenDown();
}
progressString(name, percentage, message, barColorFn = (b) => b) {
progressString(task) {
const { name, barColorFn, message, percentage, } = task;
// scale progress bar to percentage of total width

@@ -173,7 +331,11 @@ const scaled = percentage * this.progressWidth;

}
indefiniteString(task, spinner) {
const { name, barColorFn, message, } = task;
return name.padStart(this.longestNameLength) + ': ' + barColorFn(spinner) + ' ' + message;
}
writeTask(task) {
this.stream.cursorTo(0, this.initialLines + task.index);
this.stream.write(this.progressString(task.name, task.percentage, task.message, task.barColorFn).slice(0, this.stream.columns));
this.stream.clearLine(1);
this.stream.cursorTo(0, Object.entries(this.tasks).length + this.initialLines);
this.logger.upsertProgress({
index: task.index + this.initialLines,
data: this.progressString(task),
});
}

@@ -220,8 +382,7 @@ incrementTask(name, _a = {}) {

const task = this.tasks[name];
this.stream.cursorTo(0, this.initialLines + task.index);
const bar = task.barColorFn(this.FULL_CHAR.repeat(this.progressWidth));
// TODO customizable format. Maybe unify this with writeTask
this.stream.write(name.padStart(this.longestNameLength) + ': ' + bar + ' ' + message);
this.stream.clearLine(1);
this.stream.cursorTo(0, Object.entries(this.tasks).length + this.initialLines);
this.logger.upsertProgress({
index: task.index + this.initialLines,
data: name.padStart(this.longestNameLength) + ': ' + bar + ' ' + message,
});
// Stop animation if all tasks are done, and resolve the promise.

@@ -279,9 +440,13 @@ if (Object.entries(this.tasks).reduce((prev, [_, curr]) => {

const spinner = this.spinnerGenerator(this.t, this.progressWidth);
Object.entries(this.tasks).forEach(([name, task]) => {
Object.entries(this.tasks).forEach(([_, task]) => {
if (task.type === 'indefinite' && task.done === false) {
this.stream.cursorTo(0, this.initialLines + task.index);
this.stream.write(name.padStart(this.longestNameLength) + ': ' + task.barColorFn(spinner) + ' ' + task.message);
this.stream.clearLine(1);
let progressString = this.indefiniteString(task, spinner);
this.logger.upsertProgress({
index: task.index + this.initialLines,
data: progressString,
refresh: false,
});
}
});
this.logger.refresh();
this.t = this.t + 1;

@@ -288,0 +453,0 @@ }

@@ -0,3 +1,39 @@

export declare const RESET: string;
/** CUrsor Position
*
* @param row (required) 0-index absolute row
* @param column (optional) 0-index absolute column
*/
export declare const CUP: (row: number, column?: number) => string;
/** Cursor Horizonal Absolute
*
* @param column (optional) 0-index absolute column
*/
export declare const CHA: (column: number) => string;
/** CUrsor Up
*
* @param number (optional) 0-index rows to move up
*/
export declare const CUU: (number: number) => string;
/** CUrsor Down
*
* @param number (optional) 0-index rows to move down
*/
export declare const CUD: (number: number) => string;
/** CUrsor Forward
*
* @param number (optional) 0-index rows to move right
*/
export declare const CUF: (number: number) => string;
/** CUrsor Back
*
* @param number (optional) 0-index rows to move left
*/
export declare const CUB: (number: number) => string;
/**
*
* @param rows (required) 0-index rows to move down (can be negative for moving up)
* @param columns (optional) 0-index columns to move to the right (negative for left)
*/
export declare const MoveCursor: (rows: number, columns?: number) => string;
export declare enum EL_MODE {

@@ -16,1 +52,2 @@ TO_END = 0,

export declare const ED: (mode?: ED_MODE) => string;
export declare const clampString: (message: string, width: number) => string;

4

package.json
{
"name": "multi-progress-bars",
"version": "1.1.4",
"version": "2.0.1",
"description": "Multiple progress bars with option for indefinite spinners",

@@ -14,3 +14,3 @@ "main": "dist/multi-progress-bars.cjs.js",

"release": "standard-version",
"prepublishOnly": "yarn build",
"prepublishOnly": "yarn clean && yarn build",
"buildExample": "yarn tsc -b example",

@@ -17,0 +17,0 @@ "clean": "yarn trash 'dist/**/*' 'example/example.js'",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc