Comparing version 2.2.1 to 2.3.0
@@ -0,1 +1,22 @@ | ||
### v2.3.0 | ||
#### FEATURES | ||
* Add setTemplate & setTheme back in. | ||
* Add support for named themes, you can now ask for things like 'colorASCII' | ||
and 'brailleSpinner'. Of course, you can still pass in theme objects. | ||
Additionally you can now pass in an object with `hasUnicode`, `hasColor` and | ||
`platform` keys in order to override our guesses as to those values when | ||
selecting a default theme from the themeset. | ||
* Make the output stream optional (it defaults to `process.stderr` now). | ||
* Add `setWriteTo(stream[, tty])` to change the output stream and, | ||
optionally, tty. | ||
#### BUG FIXES & REFACTORING | ||
* Abort the display phase early if we're supposed to be hidden and we are. | ||
* Stop printing a bunch of spaces at the end of lines, since we're already | ||
using an erase-to-end-of-line code anyway. | ||
* The unicode themes were missing the subsection separator. | ||
### v2.2.1 | ||
@@ -2,0 +23,0 @@ |
138
index.js
'use strict' | ||
var validate = require('aproba') | ||
var Plumbing = require('./plumbing.js') | ||
@@ -19,7 +18,16 @@ var hasUnicode = require('has-unicode') | ||
function Gauge (writeTo, options) { | ||
if (!options) options = {} | ||
validate('OO', [writeTo, options]) | ||
function Gauge (arg1, arg2) { | ||
var options, writeTo | ||
if (arg1 && arg1.write) { | ||
writeTo = arg1 | ||
options = arg2 || {} | ||
} else if (arg2 && arg2.write) { | ||
writeTo = arg2 | ||
options = arg1 || {} | ||
} else { | ||
writeTo = process.stderr | ||
options = arg1 || arg2 || {} | ||
} | ||
this.status = { | ||
this._status = { | ||
spun: 0, | ||
@@ -29,18 +37,16 @@ section: '', | ||
} | ||
this._showing = false | ||
this._onScreen = false | ||
this._paused = false // are we paused for back pressure? | ||
this._disabled = true // are all progress bar updates disabled? | ||
this._showing = false // do we WANT the progress bar on screen | ||
this._onScreen = false // IS the progress bar on screen | ||
this._needsRedraw = false // should we print something at next tick? | ||
this._hideCursor = options.hideCursor == null ? true : options.hideCursor | ||
this._needsRedraw = false | ||
this.fixedFramerate = options.fixedFramerate == null | ||
this._fixedFramerate = options.fixedFramerate == null | ||
? !(/^v0\.8\./.test(process.version)) | ||
: options.fixedFramerate | ||
this._lastUpdateAt = null | ||
this.updateInterval = options.updateInterval == null ? 50 : options.updateInterval | ||
this._paused = false | ||
this.tty = options.tty || | ||
(writeTo === process.stderr && process.stdout.isTTY && process.stdout) || | ||
(writeTo.isTTY && writeTo) | ||
this._updateInterval = options.updateInterval == null ? 50 : options.updateInterval | ||
var themes = options.themes || defaultThemes | ||
var theme = options.theme || themes({hasUnicode: hasUnicode(), hasColor: hasColor}) | ||
this._themes = options.themes || defaultThemes | ||
var theme = this._computeTheme(options.theme) | ||
var template = options.template || [ | ||
@@ -52,5 +58,5 @@ {type: 'progressbar', length: 20}, | ||
] | ||
this.setWriteTo(writeTo, options.tty) | ||
var PlumbingClass = options.Plumbing || Plumbing | ||
this._gauge = new PlumbingClass(theme, template, ((this.tty && this.tty.columns) || 80) - 1) | ||
this._writeTo = writeTo | ||
this._gauge = new PlumbingClass(theme, template, this.getWidth()) | ||
@@ -72,5 +78,48 @@ this._$$doRedraw = callWith(this, this._doRedraw) | ||
Gauge.prototype.setTemplate = function (template) { | ||
this._gauge.setTemplate(template) | ||
if (this._showing) this._requestRedraw() | ||
} | ||
Gauge.prototype._computeTheme = function (theme) { | ||
if (!theme) theme = {} | ||
if (theme && (Object.keys(theme).length === 0 || theme.hasUnicode != null || theme.hasColor != null)) { | ||
var useUnicode = theme.hasUnicode == null ? hasUnicode() : theme.hasUnicode | ||
var useColor = theme.hasColor == null ? hasColor : theme.hasColor | ||
theme = this._themes.getDefault({hasUnicode: useUnicode, hasColor: useColor, platform: theme.platform}) | ||
} else if (typeof theme === 'string') { | ||
theme = this._themes.getTheme(theme) | ||
} | ||
return theme | ||
} | ||
Gauge.prototype.setTheme = function (theme) { | ||
this._gauge.setTheme(theme) | ||
if (this._showing) this._requestRedraw() | ||
} | ||
Gauge.prototype._requestRedraw = function () { | ||
this._needsRedraw = true | ||
if (!this._fixedFramerate) this._doRedraw() | ||
} | ||
Gauge.prototype.getWidth = function () { | ||
return ((this._tty && this._tty.columns) || 80) - 1 | ||
} | ||
Gauge.prototype.setWriteTo = function (writeTo, tty) { | ||
var enabled = !this._disabled | ||
if (enabled) this.disable() | ||
this._writeTo = writeTo | ||
this._tty = tty || | ||
(writeTo === process.stderr && process.stdout.isTTY && process.stdout) || | ||
(writeTo.isTTY && writeTo) || | ||
this._tty | ||
if (this._gauge) this._gauge.setWidth(this.getWidth()) | ||
if (enabled) this.enable() | ||
} | ||
Gauge.prototype.enable = function () { | ||
this.disabled = false | ||
if (this.tty) this._enableEvents() | ||
this._disabled = false | ||
if (this._tty) this._enableEvents() | ||
if (this._showing) this.show() | ||
@@ -86,10 +135,10 @@ } | ||
} | ||
this.disabled = true | ||
if (this.tty) this._disableEvents() | ||
this._disabled = true | ||
if (this._tty) this._disableEvents() | ||
} | ||
Gauge.prototype._enableEvents = function () { | ||
this.tty.on('resize', this._$$handleSizeChange) | ||
if (this.fixedFramerate) { | ||
this.redrawTracker = setInterval(this._$$doRedraw, this.updateInterval) | ||
this._tty.on('resize', this._$$handleSizeChange) | ||
if (this._fixedFramerate) { | ||
this.redrawTracker = setInterval(this._$$doRedraw, this._updateInterval) | ||
if (this.redrawTracker.unref) this.redrawTracker.unref() | ||
@@ -100,8 +149,8 @@ } | ||
Gauge.prototype._disableEvents = function () { | ||
this.tty.removeListener('resize', this._$$handleSizeChange) | ||
if (this.fixedFramerate) clearInterval(this.redrawTracker) | ||
this._tty.removeListener('resize', this._$$handleSizeChange) | ||
if (this._fixedFramerate) clearInterval(this.redrawTracker) | ||
} | ||
Gauge.prototype.hide = function () { | ||
if (this.disabled) return | ||
if (this._disabled) return | ||
if (!this._showing) return | ||
@@ -113,6 +162,6 @@ this._showing = false | ||
Gauge.prototype.show = function (section, completed) { | ||
if (this.disabled) return | ||
if (this._disabled) return | ||
this._showing = true | ||
if (typeof section === 'string') { | ||
this.status.section = section | ||
this._status.section = section | ||
} else if (typeof section === 'object') { | ||
@@ -122,29 +171,27 @@ var sectionKeys = Object.keys(section) | ||
var key = sectionKeys[ii] | ||
this.status[key] = section[key] | ||
this._status[key] = section[key] | ||
} | ||
} | ||
if (completed != null) this.status.completed = completed | ||
this._needsRedraw = true | ||
if (!this.fixedFramerate) this._doRedraw() | ||
if (completed != null) this._status.completed = completed | ||
this._requestRedraw() | ||
} | ||
Gauge.prototype.pulse = function (subsection) { | ||
if (this.disabled) return | ||
if (this._disabled) return | ||
if (!this._showing) return | ||
this.status.subsection = subsection || '' | ||
this.status.spun ++ | ||
this._needsRedraw = true | ||
if (!this.fixedFramerate) this._doRedraw() | ||
this._status.subsection = subsection || '' | ||
this._status.spun ++ | ||
this._requestRedraw() | ||
} | ||
Gauge.prototype._handleSizeChange = function () { | ||
this._gauge.setWidth(this.tty.columns - 1) | ||
this._needsRedraw = true | ||
this._gauge.setWidth(this._tty.columns - 1) | ||
this._requestRedraw() | ||
} | ||
Gauge.prototype._doRedraw = function () { | ||
if (this.disabled || this._paused) return | ||
if (!this.fixedFramerate) { | ||
if (this._disabled || this._paused) return | ||
if (!this._fixedFramerate) { | ||
var now = Date.now() | ||
if (this._lastUpdateAt && now - this._lastUpdateAt < this.updateInterval) return | ||
if (this._lastUpdateAt && now - this._lastUpdateAt < this._updateInterval) return | ||
this._lastUpdateAt = now | ||
@@ -160,2 +207,3 @@ } | ||
} | ||
if (!this._showing && !this._onScreen) return | ||
if (this._showing && !this._onScreen) { | ||
@@ -169,3 +217,3 @@ this._onScreen = true | ||
if (!this._needsRedraw) return | ||
if (!this._writeTo.write(this._gauge.show(this.status))) { | ||
if (!this._writeTo.write(this._gauge.show(this._status))) { | ||
this._paused = true | ||
@@ -172,0 +220,0 @@ this._writeTo.on('drain', callWith(this, function () { |
{ | ||
"name": "gauge", | ||
"version": "2.2.1", | ||
"version": "2.3.0", | ||
"description": "A terminal based horizontal guage", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -45,4 +45,4 @@ 'use strict' | ||
return renderTemplate(this.width, this.template, values) + | ||
return renderTemplate(this.width, this.template, values).trim() + | ||
consoleStrings.eraseLine() + consoleStrings.gotoSOL() | ||
} |
@@ -36,11 +36,12 @@ gauge | ||
var gauge = new Gauge(stream, [options]) | ||
var gauge = new Gauge([stream], [options]) | ||
``` | ||
* **stream** – A stream that progress bar updates are to be written to. Gauge honors | ||
backpressure and will pause most writing if it is indicated. | ||
* **stream** – *(optional, default STDERR)* A stream that progress bar | ||
updates are to be written to. Gauge honors backpressure and will pause | ||
most writing if it is indicated. | ||
* **options** – *(optional)* An option object. | ||
Constructs a new gauge. Gauges are drawn on a single line, and are not drawn | ||
if the current terminal isn't a tty. | ||
if **stream** isn't a tty and a tty isn't explicitly provided. | ||
@@ -54,2 +55,8 @@ If **stream** is a terminal or if you pass in **tty** to **options** then we | ||
**IMPORTANT:** If you prevously were passing in a non-tty stream but you still | ||
want output (for example, a stream wrapped by the `ansi` module) then you | ||
need to pass in the **tty** option below, as `gauge` needs access to | ||
the underlying tty in order to do things like terminal resizes and terminal | ||
width detection. | ||
The **options** object can have the following properties, all of which are | ||
@@ -69,9 +76,12 @@ optional: | ||
to `gauge/themes`, see the [themes] documentation for details. | ||
* **theme**: Alternatively you can specificy a specific theme to use. If you | ||
use this, there's no reason to use **themes**. | ||
* **theme**: Select a theme for use, it can be a: | ||
* Theme object, in which case the **themes** is not used. | ||
* The name of a theme, which will be looked up in the current *themes* | ||
object. | ||
* A configuration object with any of `hasUnicode`, `hasColor` or | ||
`platform` keys, which if wlll be used to override our guesses when making | ||
a default theme selection. | ||
The default theme is selected using **themes** to something usable on your | ||
combination of OS, color and unicode support. Unicode support is detected | ||
with [has-unicode] and color is detected by checking platform and TERM env | ||
var. | ||
If no theme is selected then a default is picked using a combination of our | ||
best guesses at your OS, color support and unicode support. | ||
* **template**: Describes what you want your gauge to look like. The | ||
@@ -78,0 +88,0 @@ default is what npm uses. Detailed [documentation] is later in this |
@@ -38,13 +38,13 @@ 'use strict' | ||
var gauge = new Gauge(process.stdout) | ||
t.is(gauge.disabled, false, 'disabled') | ||
t.is(gauge.updateInterval, 50, 'updateInterval') | ||
t.is(gauge._disabled, false, 'disabled') | ||
t.is(gauge._updateInterval, 50, 'updateInterval') | ||
if (process.stdout.isTTY) { | ||
t.is(gauge.tty, process.stdout, 'tty') | ||
t.is(gauge._tty, process.stdout, 'tty') | ||
gauge.disable() | ||
gauge = new Gauge(process.stderr) | ||
t.is(gauge.tty, process.stdout, 'tty is stdout when writeTo is stderr') | ||
t.is(gauge._tty, process.stdout, 'tty is stdout when writeTo is stderr') | ||
} | ||
gauge.disable() | ||
gauge = new Gauge(new Sink()) | ||
t.is(gauge.tty, undefined, 'non-tty stream is not tty') | ||
t.is(gauge._tty, undefined, 'non-tty stream is not tty') | ||
gauge.disable() | ||
@@ -60,4 +60,4 @@ t.end() | ||
Plumbing: MockPlumbing, | ||
theme: 'THEME', | ||
template: 'TEMPLATE', | ||
theme: ['THEME'], | ||
template: ['TEMPLATE'], | ||
enabled: false, | ||
@@ -69,4 +69,4 @@ updateInterval: 0, | ||
t.is(results.columns, 15, 'width passed through') | ||
t.is(results.theme, 'THEME', 'theme passed through') | ||
t.is(results.template, 'TEMPLATE', 'template passed through') | ||
t.same(results.theme, ['THEME'], 'theme passed through') | ||
t.same(results.template, ['TEMPLATE'], 'template passed through') | ||
@@ -183,4 +183,4 @@ t.done() | ||
Plumbing: MockPlumbing, | ||
theme: 'THEME', | ||
template: 'TEMPLATE', | ||
theme: ['THEME'], | ||
template: ['TEMPLATE'], | ||
enabled: true, | ||
@@ -215,4 +215,4 @@ updateInterval: 10, | ||
Plumbing: MockPlumbing, | ||
theme: 'THEME', | ||
template: 'TEMPLATE', | ||
theme: ['THEME'], | ||
template: ['TEMPLATE'], | ||
enabled: true, | ||
@@ -219,0 +219,0 @@ updateInterval: 10, |
@@ -36,3 +36,4 @@ 'use strict' | ||
}, | ||
activityIndicatorTheme: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' | ||
activityIndicatorTheme: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏', | ||
preSubsection: '>' | ||
}) | ||
@@ -39,0 +40,0 @@ |
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
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
1561
366
299102
35