@devteks/progress
TypeScript icon, indicating that this package has built-in type declarations

0.0.5 • Public • Published

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

Package Sidebar

Install

npm i @devteks/progress

Weekly Downloads

2

Version

0.0.5

License

MIT

Unpacked Size

1.09 MB

Total Files

10

Last publish

Collaborators

  • samikhaled2010
  • mosa.muhana