Comparing version 1.1.8 to 2.0.0
@@ -19,7 +19,10 @@ /*! | ||
* | ||
* - `curr` 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 "-" | ||
* - `renderThrottle` minimum time between updates in milliseconds defaulting to 16 | ||
* - `callback` optional function to call when the progress bar completes | ||
@@ -36,2 +39,3 @@ * - `clear` will clear the progress bar upon termination | ||
* - `:eta` eta in seconds | ||
* - `:rate` rate of ticks per second | ||
* | ||
@@ -57,3 +61,3 @@ * @param {string} fmt | ||
this.fmt = fmt; | ||
this.curr = 0; | ||
this.curr = options.curr || 0; | ||
this.total = options.total; | ||
@@ -64,5 +68,8 @@ this.width = options.width || this.total; | ||
complete : options.complete || '=', | ||
incomplete : options.incomplete || '-' | ||
incomplete : options.incomplete || '-', | ||
head : options.head || (options.complete || '=') | ||
}; | ||
this.renderThrottle = options.renderThrottle !== 0 ? (options.renderThrottle || 16) : 0; | ||
this.callback = options.callback || function () {}; | ||
this.tokens = {}; | ||
this.lastDraw = ''; | ||
@@ -85,2 +92,3 @@ } | ||
if ('object' == typeof len) tokens = len, len = 1; | ||
if (tokens) this.tokens = tokens; | ||
@@ -91,6 +99,11 @@ // start time for eta | ||
this.curr += len | ||
this.render(tokens); | ||
// schedule render | ||
if (!this.renderThrottleTimeout) { | ||
this.renderThrottleTimeout = setTimeout(this.render.bind(this), this.renderThrottle); | ||
} | ||
// progress complete | ||
if (this.curr >= this.total) { | ||
if (this.renderThrottleTimeout) this.render(); | ||
this.complete = true; | ||
@@ -112,2 +125,7 @@ this.terminate(); | ||
ProgressBar.prototype.render = function (tokens) { | ||
clearTimeout(this.renderThrottleTimeout); | ||
this.renderThrottleTimeout = null; | ||
if (tokens) this.tokens = tokens; | ||
if (!this.stream.isTTY) return; | ||
@@ -122,2 +140,3 @@ | ||
var eta = (percent == 100) ? 0 : elapsed * (this.total / this.curr - 1); | ||
var rate = this.curr / (elapsed / 1000); | ||
@@ -131,6 +150,11 @@ /* populate the bar template with percentages and timestamps */ | ||
.toFixed(1)) | ||
.replace(':percent', percent.toFixed(0) + '%'); | ||
.replace(':percent', percent.toFixed(0) + '%') | ||
.replace(':rate', Math.round(rate)); | ||
/* compute the available space (non-zero) for the bar */ | ||
var availableSpace = Math.max(0, this.stream.columns - str.replace(':bar', '').length); | ||
if(availableSpace && process.platform === 'win32'){ | ||
availableSpace = availableSpace - 1; | ||
} | ||
var width = Math.min(this.width, availableSpace); | ||
@@ -140,5 +164,9 @@ | ||
completeLength = Math.round(width * ratio); | ||
complete = Array(completeLength + 1).join(this.chars.complete); | ||
incomplete = Array(width - completeLength + 1).join(this.chars.incomplete); | ||
complete = Array(Math.max(0, completeLength + 1)).join(this.chars.complete); | ||
incomplete = Array(Math.max(0, width - completeLength + 1)).join(this.chars.incomplete); | ||
/* add head to the complete string */ | ||
if(completeLength > 0) | ||
complete = complete.slice(0, -1) + this.chars.head; | ||
/* fill in the actual progress bar */ | ||
@@ -148,8 +176,8 @@ str = str.replace(':bar', complete + incomplete); | ||
/* replace the extra tokens */ | ||
if (tokens) for (var key in tokens) str = str.replace(':' + key, tokens[key]); | ||
if (this.tokens) for (var key in this.tokens) str = str.replace(':' + key, this.tokens[key]); | ||
if (this.lastDraw !== str) { | ||
this.stream.clearLine(); | ||
this.stream.cursorTo(0); | ||
this.stream.write(str); | ||
this.stream.clearLine(1); | ||
this.lastDraw = str; | ||
@@ -181,2 +209,21 @@ } | ||
/** | ||
* "interrupt" the progress bar and write a message above it. | ||
* @param {string} message The message to write. | ||
* @api public | ||
*/ | ||
ProgressBar.prototype.interrupt = function (message) { | ||
// clear the current line | ||
this.stream.clearLine(); | ||
// move the cursor to the start of the line | ||
this.stream.cursorTo(0); | ||
// write the message text | ||
this.stream.write(message); | ||
// terminate the line after writing the message | ||
this.stream.write('\n'); | ||
// re-display the progress bar with its lastDraw | ||
this.stream.write(this.lastDraw); | ||
}; | ||
/** | ||
* Terminates a progress bar. | ||
@@ -189,5 +236,9 @@ * | ||
if (this.clear) { | ||
this.stream.clearLine(); | ||
this.stream.cursorTo(0); | ||
} else console.log(); | ||
if (this.stream.clearLine) { | ||
this.stream.clearLine(); | ||
this.stream.cursorTo(0); | ||
} | ||
} else { | ||
this.stream.write('\n'); | ||
} | ||
}; |
{ | ||
"name": "progress" | ||
, "version": "1.1.8" | ||
, "description": "Flexible ascii progress bar" | ||
, "keywords": ["cli", "progress"] | ||
, "author": "TJ Holowaychuk <tj@vision-media.ca>" | ||
, "contributors": [ | ||
{ | ||
"name": "Christoffer Hallas" | ||
, "email": "christoffer.hallas@gmail.com" | ||
} | ||
, { | ||
"name": "Jordan Scales" | ||
, "email": "scalesjordan@gmail.com" | ||
} | ||
] | ||
, "dependencies": {} | ||
, "main": "index" | ||
, "engines": { "node": ">=0.4.0" } | ||
, "repository": "git://github.com/visionmedia/node-progress" | ||
"name": "progress", | ||
"version": "2.0.0", | ||
"description": "Flexible ascii progress bar", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/visionmedia/node-progress" | ||
}, | ||
"keywords": [ | ||
"cli", | ||
"progress" | ||
], | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
"contributors": [ | ||
"Christoffer Hallas <christoffer.hallas@gmail.com>", | ||
"Jordan Scales <scalesjordan@gmail.com>", | ||
"Andrew Rhyne <rhyneandrew@gmail.com>" | ||
], | ||
"dependencies": {}, | ||
"main": "./index.js", | ||
"engines": { | ||
"node": ">=0.4.0" | ||
}, | ||
"license": "MIT" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
15445
198
147
0
1