@devteks/progress
v0.0.5
Published
node ascii progress bar
Downloads
6
Readme
Node ascii progress bar
Installation
$ npm install @devteks/progress
Usage
First we create a ProgressBar
, giving it a format string
as well as the total
, telling the progress bar when it will
be considered complete. After that all we need to do is tick()
appropriately.
Example 1:
const { ProgressBar } = require('@devteks/progress');
const bar = new ProgressBar({
format: '{bar} {percent}',
total: 100
});
let timer = setInterval(() => {
bar.tick();
if (bar.complete) {
console.log('\ncomplete\n');
clearInterval(timer);
}
}, 100);
Example 2:
import { join, parse } from 'path';
import { IncomingMessage } from 'http';
import { createWriteStream } from 'fs';
import { pipeline } from 'node:stream/promises';
import axios from 'axios';
import { fmtSize } from '../src/utils';
import { ProgressBar, ProgressStream } from '@devteks/progress';
async function download(url: string, dir: string) {
const response = await axios({ url, responseType: 'stream' });
const inputStream = response.data as IncomingMessage;
const outputStream = createWriteStream(join(dir, parse(url).base));
const report = new ProgressStream({
interval: 500,
onTotal: x => bar.total = x, // or use `total` event
onProgress: x => bar.tick(x.current), // or use progress event
});
const bar = new ProgressBar({
format: '{percent} {bar} {current} / {total} {speed} {elapsed}s',
formatValue: fmtSize,
});
//report.on('total', total => bar.total = total);
//report.on('progress', progress => bar.tick(progress.current));
await pipeline(inputStream, report, outputStream);
console.log('\nDONE...');
}
async function main() {
const url = 'https://proof.ovh.net/files/1Mb.dat';
const dir = join(process.cwd(), '/_output/');
download(url, dir);
}
main();
Example 3:
import { join, parse } from 'path';
import { IncomingMessage } from 'http';
import { createWriteStream } from 'fs';
import { PassThrough } from 'node:stream';
import { pipeline } from 'node:stream/promises';
import axios from 'axios';
import { fmtSize } from '../src/utils';
import { ProgressBar } from '@devteks/progress';
async function download(url: string, dir: string) {
const response = await axios({ url, responseType: 'stream' });
const inputStream = response.data as IncomingMessage;
const outputStream = createWriteStream(join(dir, parse(url).base));
const total = parseInt(response.headers['content-length'] as string, 10) ?? undefined;
const progressStream = new PassThrough();
let current = 0;
progressStream.on('data', (chunk: Buffer) => {
current += chunk.length;
bar.tick(current);
});
const bar = new ProgressBar({
format: '{percent} {bar} {current} / {total} {speed} {elapsed}s',
formatValue: fmtSize,
total,
minWidth: 20,
});
await pipeline(inputStream, progressStream, outputStream);
console.log('\nDONE...');
}
async function main() {
const url = 'https://proof.ovh.net/files/1Mb.dat';
const dir = join(process.cwd(), '/_output/');
download(url, dir);
}
main();
Options
| Option | Description |
|--------------|-------------|
| format
| format of progress with tokens |
| current
| current completed index |
| total
| total number of ticks to complete |
| width
| the displayed width of the progress bar defaulting to total |
| stream
| the output stream defaulting to stderr |
| head
| head character defaulting to complete character |
| complete
| completion character defaulting to "=" |
| incomplete
| incomplete character defaulting to "-" |
| throttle
| minimum time between updates in milliseconds defaulting to 16 |
| onComplete
| optional function to call when the progress bar completes |
| clear
| will clear the progress bar upon termination |
| line
| terminal line |
Tokens: (builtin tokens)
These are tokens you can use in the format of your progress bar.
| Token | Description |
|-------------|-------------|
| {bar}
| the progress bar |
| {current}
| current tick number |
| {total}
| total ticks |
| {elapsed}
| time elapsed in seconds |
| {percent}
| completion percentage |
| {eta}
| estimated completion time in seconds |
| {speed}
| speed of ticks per second |
Custom Tokens
You can define custom tokens by adding a {'name': value}
object parameter to your method (tick()
) calls.
const bar = new ProgressBar({
format: '{current}: [token1] [token2]',
total: 3
});
bar.tick({ 'token1': "Hello", 'token2': "World!\n" });
bar.tick(2, { 'token1': "Goodbye", 'token2': "World!" });
The above example would result in the output below.
1: Hello World!
3: Goodbye World!
Examples
Download
In our download example each tick has a variable influence, so we pass the chunk length which adjusts the progress bar appropriately relative to the total length.
const { ProgressBar } = require('@devteks/progress');
const https = require('https');
const req = https.request({
host: 'example.com',
port: 443,
path: '/somefile.zip'
});
req.on('response', function(res){
const total = parseInt(res.headers['content-length'], 10);
let current = 0;
console.log();
var bar = new ProgressBar({
format: 'Downloading [{bar}] {speed} {percent} {etas}',
complete: '=',
incomplete: ' ',
width: 40,
total: total
});
res.on('data', (chunk) => {
current += chunk.length;
bar.tick(current);
});
res.on('end', function () {
console.log('\n');
});
});
req.end();
The above example result in a progress bar like the one below.
downloading [===== ] 39/bps 29% 3.7s
Interrupt
To display a message during progress bar execution, use interrupt()
const { ProgressBar } = require('@devteks/progress');
const bar = new ProgressBar({ format: '{bar} {current}/{total}', total: 10 });
let timer = setInterval(() => {
bar.tick();
if (bar.complete) {
clearInterval(timer);
} else if (bar.curr === 5) {
bar.interrupt(`this message appears above the progress bar\ncurrent progress is ${bar.current}/${bar.total}`);
}
}, 1000);
You can see more examples in the examples
folder.
License
MIT