gauge-v2 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +20 -0
- package/README.md +404 -0
- package/lib/base-theme.js +18 -0
- package/lib/console-control.js +64 -0
- package/lib/error.js +24 -0
- package/lib/has-color.js +4 -0
- package/lib/index.js +289 -0
- package/lib/index.mjs +288 -0
- package/lib/plumbing.js +50 -0
- package/lib/plumbing.mjs +50 -0
- package/lib/process.js +3 -0
- package/lib/progress-bar.js +41 -0
- package/lib/render-template.js +222 -0
- package/lib/set-immediate.js +7 -0
- package/lib/set-interval.js +3 -0
- package/lib/spin.js +5 -0
- package/lib/template-item.js +87 -0
- package/lib/theme-set.js +122 -0
- package/lib/themes.js +57 -0
- package/lib/themes.mjs +57 -0
- package/lib/validate.js +54 -0
- package/lib/wide-truncate.js +31 -0
- package/package.json +78 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
var Plumbing = require('./plumbing.js')
|
|
3
|
+
var hasUnicode = require('has-unicode')
|
|
4
|
+
var hasColor = require('./has-color.js')
|
|
5
|
+
var onExit = require('signal-exit').onExit
|
|
6
|
+
var defaultThemes = require('./themes')
|
|
7
|
+
var setInterval = require('./set-interval.js')
|
|
8
|
+
var process = require('./process.js')
|
|
9
|
+
var setImmediate = require('./set-immediate')
|
|
10
|
+
|
|
11
|
+
module.exports = Gauge
|
|
12
|
+
|
|
13
|
+
function callWith (obj, method) {
|
|
14
|
+
return function () {
|
|
15
|
+
return method.call(obj)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function Gauge (arg1, arg2) {
|
|
20
|
+
var options, writeTo
|
|
21
|
+
if (arg1 && arg1.write) {
|
|
22
|
+
writeTo = arg1
|
|
23
|
+
options = arg2 || {}
|
|
24
|
+
} else if (arg2 && arg2.write) {
|
|
25
|
+
writeTo = arg2
|
|
26
|
+
options = arg1 || {}
|
|
27
|
+
} else {
|
|
28
|
+
writeTo = process.stderr
|
|
29
|
+
options = arg1 || arg2 || {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this._status = {
|
|
33
|
+
spun: 0,
|
|
34
|
+
section: '',
|
|
35
|
+
subsection: '',
|
|
36
|
+
}
|
|
37
|
+
this._paused = false // are we paused for back pressure?
|
|
38
|
+
this._disabled = true // are all progress bar updates disabled?
|
|
39
|
+
this._showing = false // do we WANT the progress bar on screen
|
|
40
|
+
this._onScreen = false // IS the progress bar on screen
|
|
41
|
+
this._needsRedraw = false // should we print something at next tick?
|
|
42
|
+
this._hideCursor = options.hideCursor == null ? true : options.hideCursor
|
|
43
|
+
this._fixedFramerate = options.fixedFramerate == null
|
|
44
|
+
? !(/^v0\.8\./.test(process.version))
|
|
45
|
+
: options.fixedFramerate
|
|
46
|
+
this._lastUpdateAt = null
|
|
47
|
+
this._updateInterval = options.updateInterval == null ? 50 : options.updateInterval
|
|
48
|
+
|
|
49
|
+
this._themes = options.themes || defaultThemes
|
|
50
|
+
this._theme = options.theme
|
|
51
|
+
var theme = this._computeTheme(options.theme)
|
|
52
|
+
var template = options.template || [
|
|
53
|
+
{ type: 'progressbar', length: 20 },
|
|
54
|
+
{ type: 'activityIndicator', kerning: 1, length: 1 },
|
|
55
|
+
{ type: 'section', kerning: 1, default: '' },
|
|
56
|
+
{ type: 'subsection', kerning: 1, default: '' },
|
|
57
|
+
]
|
|
58
|
+
this.setWriteTo(writeTo, options.tty)
|
|
59
|
+
var PlumbingClass = options.Plumbing || Plumbing
|
|
60
|
+
this._gauge = new PlumbingClass(theme, template, this.getWidth())
|
|
61
|
+
|
|
62
|
+
this._$$doRedraw = callWith(this, this._doRedraw)
|
|
63
|
+
this._$$handleSizeChange = callWith(this, this._handleSizeChange)
|
|
64
|
+
|
|
65
|
+
this._cleanupOnExit = options.cleanupOnExit == null || options.cleanupOnExit
|
|
66
|
+
this._removeOnExit = null
|
|
67
|
+
|
|
68
|
+
if (options.enabled || (options.enabled == null && this._tty && this._tty.isTTY)) {
|
|
69
|
+
this.enable()
|
|
70
|
+
} else {
|
|
71
|
+
this.disable()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
Gauge.prototype = {}
|
|
75
|
+
|
|
76
|
+
Gauge.prototype.isEnabled = function () {
|
|
77
|
+
return !this._disabled
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
Gauge.prototype.setTemplate = function (template) {
|
|
81
|
+
this._gauge.setTemplate(template)
|
|
82
|
+
if (this._showing) {
|
|
83
|
+
this._requestRedraw()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Gauge.prototype._computeTheme = function (theme) {
|
|
88
|
+
if (!theme) {
|
|
89
|
+
theme = {}
|
|
90
|
+
}
|
|
91
|
+
if (typeof theme === 'string') {
|
|
92
|
+
theme = this._themes.getTheme(theme)
|
|
93
|
+
} else if (
|
|
94
|
+
Object.keys(theme).length === 0 || theme.hasUnicode != null || theme.hasColor != null
|
|
95
|
+
) {
|
|
96
|
+
var useUnicode = theme.hasUnicode == null ? hasUnicode() : theme.hasUnicode
|
|
97
|
+
var useColor = theme.hasColor == null ? hasColor : theme.hasColor
|
|
98
|
+
theme = this._themes.getDefault({
|
|
99
|
+
hasUnicode: useUnicode,
|
|
100
|
+
hasColor: useColor,
|
|
101
|
+
platform: theme.platform,
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
return theme
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
Gauge.prototype.setThemeset = function (themes) {
|
|
108
|
+
this._themes = themes
|
|
109
|
+
this.setTheme(this._theme)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Gauge.prototype.setTheme = function (theme) {
|
|
113
|
+
this._gauge.setTheme(this._computeTheme(theme))
|
|
114
|
+
if (this._showing) {
|
|
115
|
+
this._requestRedraw()
|
|
116
|
+
}
|
|
117
|
+
this._theme = theme
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Gauge.prototype._requestRedraw = function () {
|
|
121
|
+
this._needsRedraw = true
|
|
122
|
+
if (!this._fixedFramerate) {
|
|
123
|
+
this._doRedraw()
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
Gauge.prototype.getWidth = function () {
|
|
128
|
+
return ((this._tty && this._tty.columns) || 80) - 1
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
Gauge.prototype.setWriteTo = function (writeTo, tty) {
|
|
132
|
+
var enabled = !this._disabled
|
|
133
|
+
if (enabled) {
|
|
134
|
+
this.disable()
|
|
135
|
+
}
|
|
136
|
+
this._writeTo = writeTo
|
|
137
|
+
this._tty = tty ||
|
|
138
|
+
(writeTo === process.stderr && process.stdout.isTTY && process.stdout) ||
|
|
139
|
+
(writeTo.isTTY && writeTo) ||
|
|
140
|
+
this._tty
|
|
141
|
+
if (this._gauge) {
|
|
142
|
+
this._gauge.setWidth(this.getWidth())
|
|
143
|
+
}
|
|
144
|
+
if (enabled) {
|
|
145
|
+
this.enable()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
Gauge.prototype.enable = function () {
|
|
150
|
+
if (!this._disabled) {
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
this._disabled = false
|
|
154
|
+
if (this._tty) {
|
|
155
|
+
this._enableEvents()
|
|
156
|
+
}
|
|
157
|
+
if (this._showing) {
|
|
158
|
+
this.show()
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
Gauge.prototype.disable = function () {
|
|
163
|
+
if (this._disabled) {
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
if (this._showing) {
|
|
167
|
+
this._lastUpdateAt = null
|
|
168
|
+
this._showing = false
|
|
169
|
+
this._doRedraw()
|
|
170
|
+
this._showing = true
|
|
171
|
+
}
|
|
172
|
+
this._disabled = true
|
|
173
|
+
if (this._tty) {
|
|
174
|
+
this._disableEvents()
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Gauge.prototype._enableEvents = function () {
|
|
179
|
+
if (this._cleanupOnExit) {
|
|
180
|
+
this._removeOnExit = onExit(callWith(this, this.disable))
|
|
181
|
+
}
|
|
182
|
+
this._tty.on('resize', this._$$handleSizeChange)
|
|
183
|
+
if (this._fixedFramerate) {
|
|
184
|
+
this.redrawTracker = setInterval(this._$$doRedraw, this._updateInterval)
|
|
185
|
+
if (this.redrawTracker.unref) {
|
|
186
|
+
this.redrawTracker.unref()
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
Gauge.prototype._disableEvents = function () {
|
|
192
|
+
this._tty.removeListener('resize', this._$$handleSizeChange)
|
|
193
|
+
if (this._fixedFramerate) {
|
|
194
|
+
clearInterval(this.redrawTracker)
|
|
195
|
+
}
|
|
196
|
+
if (this._removeOnExit) {
|
|
197
|
+
this._removeOnExit()
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
Gauge.prototype.hide = function (cb) {
|
|
202
|
+
if (this._disabled) {
|
|
203
|
+
return cb && process.nextTick(cb)
|
|
204
|
+
}
|
|
205
|
+
if (!this._showing) {
|
|
206
|
+
return cb && process.nextTick(cb)
|
|
207
|
+
}
|
|
208
|
+
this._showing = false
|
|
209
|
+
this._doRedraw()
|
|
210
|
+
cb && setImmediate(cb)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
Gauge.prototype.show = function (section, completed) {
|
|
214
|
+
this._showing = true
|
|
215
|
+
if (typeof section === 'string') {
|
|
216
|
+
this._status.section = section
|
|
217
|
+
} else if (typeof section === 'object') {
|
|
218
|
+
var sectionKeys = Object.keys(section)
|
|
219
|
+
for (var ii = 0; ii < sectionKeys.length; ++ii) {
|
|
220
|
+
var key = sectionKeys[ii]
|
|
221
|
+
this._status[key] = section[key]
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (completed != null) {
|
|
225
|
+
this._status.completed = completed
|
|
226
|
+
}
|
|
227
|
+
if (this._disabled) {
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
this._requestRedraw()
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
Gauge.prototype.pulse = function (subsection) {
|
|
234
|
+
this._status.subsection = subsection || ''
|
|
235
|
+
this._status.spun++
|
|
236
|
+
if (this._disabled) {
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
if (!this._showing) {
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
this._requestRedraw()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
Gauge.prototype._handleSizeChange = function () {
|
|
246
|
+
this._gauge.setWidth(this._tty.columns - 1)
|
|
247
|
+
this._requestRedraw()
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
Gauge.prototype._doRedraw = function () {
|
|
251
|
+
if (this._disabled || this._paused) {
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
if (!this._fixedFramerate) {
|
|
255
|
+
var now = Date.now()
|
|
256
|
+
if (this._lastUpdateAt && now - this._lastUpdateAt < this._updateInterval) {
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
this._lastUpdateAt = now
|
|
260
|
+
}
|
|
261
|
+
if (!this._showing && this._onScreen) {
|
|
262
|
+
this._onScreen = false
|
|
263
|
+
var result = this._gauge.hide()
|
|
264
|
+
if (this._hideCursor) {
|
|
265
|
+
result += this._gauge.showCursor()
|
|
266
|
+
}
|
|
267
|
+
return this._writeTo.write(result)
|
|
268
|
+
}
|
|
269
|
+
if (!this._showing && !this._onScreen) {
|
|
270
|
+
return
|
|
271
|
+
}
|
|
272
|
+
if (this._showing && !this._onScreen) {
|
|
273
|
+
this._onScreen = true
|
|
274
|
+
this._needsRedraw = true
|
|
275
|
+
if (this._hideCursor) {
|
|
276
|
+
this._writeTo.write(this._gauge.hideCursor())
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (!this._needsRedraw) {
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
if (!this._writeTo.write(this._gauge.show(this._status))) {
|
|
283
|
+
this._paused = true
|
|
284
|
+
this._writeTo.on('drain', callWith(this, function () {
|
|
285
|
+
this._paused = false
|
|
286
|
+
this._doRedraw()
|
|
287
|
+
}))
|
|
288
|
+
}
|
|
289
|
+
}
|
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import Plumbing from './plumbing.js'
|
|
2
|
+
import hasUnicode from 'has-unicode'
|
|
3
|
+
import hasColor from './has-color.js'
|
|
4
|
+
import { onExit } from 'signal-exit'
|
|
5
|
+
import defaultThemes from './themes.js'
|
|
6
|
+
import setInterval from './set-interval.js'
|
|
7
|
+
import process from './process.js'
|
|
8
|
+
import setImmediate from './set-immediate.js'
|
|
9
|
+
|
|
10
|
+
export default Gauge
|
|
11
|
+
|
|
12
|
+
function callWith (obj, method) {
|
|
13
|
+
return function () {
|
|
14
|
+
return method.call(obj)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function Gauge (arg1, arg2) {
|
|
19
|
+
var options, writeTo
|
|
20
|
+
if (arg1 && arg1.write) {
|
|
21
|
+
writeTo = arg1
|
|
22
|
+
options = arg2 || {}
|
|
23
|
+
} else if (arg2 && arg2.write) {
|
|
24
|
+
writeTo = arg2
|
|
25
|
+
options = arg1 || {}
|
|
26
|
+
} else {
|
|
27
|
+
writeTo = process.stderr
|
|
28
|
+
options = arg1 || arg2 || {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this._status = {
|
|
32
|
+
spun: 0,
|
|
33
|
+
section: '',
|
|
34
|
+
subsection: '',
|
|
35
|
+
}
|
|
36
|
+
this._paused = false // are we paused for back pressure?
|
|
37
|
+
this._disabled = true // are all progress bar updates disabled?
|
|
38
|
+
this._showing = false // do we WANT the progress bar on screen
|
|
39
|
+
this._onScreen = false // IS the progress bar on screen
|
|
40
|
+
this._needsRedraw = false // should we print something at next tick?
|
|
41
|
+
this._hideCursor = options.hideCursor == null ? true : options.hideCursor
|
|
42
|
+
this._fixedFramerate = options.fixedFramerate == null
|
|
43
|
+
? !(/^v0\.8\./.test(process.version))
|
|
44
|
+
: options.fixedFramerate
|
|
45
|
+
this._lastUpdateAt = null
|
|
46
|
+
this._updateInterval = options.updateInterval == null ? 50 : options.updateInterval
|
|
47
|
+
|
|
48
|
+
this._themes = options.themes || defaultThemes
|
|
49
|
+
this._theme = options.theme
|
|
50
|
+
var theme = this._computeTheme(options.theme)
|
|
51
|
+
var template = options.template || [
|
|
52
|
+
{ type: 'progressbar', length: 20 },
|
|
53
|
+
{ type: 'activityIndicator', kerning: 1, length: 1 },
|
|
54
|
+
{ type: 'section', kerning: 1, default: '' },
|
|
55
|
+
{ type: 'subsection', kerning: 1, default: '' },
|
|
56
|
+
]
|
|
57
|
+
this.setWriteTo(writeTo, options.tty)
|
|
58
|
+
var PlumbingClass = options.Plumbing || Plumbing
|
|
59
|
+
this._gauge = new PlumbingClass(theme, template, this.getWidth())
|
|
60
|
+
|
|
61
|
+
this._$$doRedraw = callWith(this, this._doRedraw)
|
|
62
|
+
this._$$handleSizeChange = callWith(this, this._handleSizeChange)
|
|
63
|
+
|
|
64
|
+
this._cleanupOnExit = options.cleanupOnExit == null || options.cleanupOnExit
|
|
65
|
+
this._removeOnExit = null
|
|
66
|
+
|
|
67
|
+
if (options.enabled || (options.enabled == null && this._tty && this._tty.isTTY)) {
|
|
68
|
+
this.enable()
|
|
69
|
+
} else {
|
|
70
|
+
this.disable()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
Gauge.prototype = {}
|
|
74
|
+
|
|
75
|
+
Gauge.prototype.isEnabled = function () {
|
|
76
|
+
return !this._disabled
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Gauge.prototype.setTemplate = function (template) {
|
|
80
|
+
this._gauge.setTemplate(template)
|
|
81
|
+
if (this._showing) {
|
|
82
|
+
this._requestRedraw()
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
Gauge.prototype._computeTheme = function (theme) {
|
|
87
|
+
if (!theme) {
|
|
88
|
+
theme = {}
|
|
89
|
+
}
|
|
90
|
+
if (typeof theme === 'string') {
|
|
91
|
+
theme = this._themes.getTheme(theme)
|
|
92
|
+
} else if (
|
|
93
|
+
Object.keys(theme).length === 0 || theme.hasUnicode != null || theme.hasColor != null
|
|
94
|
+
) {
|
|
95
|
+
var useUnicode = theme.hasUnicode == null ? hasUnicode() : theme.hasUnicode
|
|
96
|
+
var useColor = theme.hasColor == null ? hasColor : theme.hasColor
|
|
97
|
+
theme = this._themes.getDefault({
|
|
98
|
+
hasUnicode: useUnicode,
|
|
99
|
+
hasColor: useColor,
|
|
100
|
+
platform: theme.platform,
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
return theme
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Gauge.prototype.setThemeset = function (themes) {
|
|
107
|
+
this._themes = themes
|
|
108
|
+
this.setTheme(this._theme)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
Gauge.prototype.setTheme = function (theme) {
|
|
112
|
+
this._gauge.setTheme(this._computeTheme(theme))
|
|
113
|
+
if (this._showing) {
|
|
114
|
+
this._requestRedraw()
|
|
115
|
+
}
|
|
116
|
+
this._theme = theme
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
Gauge.prototype._requestRedraw = function () {
|
|
120
|
+
this._needsRedraw = true
|
|
121
|
+
if (!this._fixedFramerate) {
|
|
122
|
+
this._doRedraw()
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Gauge.prototype.getWidth = function () {
|
|
127
|
+
return ((this._tty && this._tty.columns) || 80) - 1
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
Gauge.prototype.setWriteTo = function (writeTo, tty) {
|
|
131
|
+
var enabled = !this._disabled
|
|
132
|
+
if (enabled) {
|
|
133
|
+
this.disable()
|
|
134
|
+
}
|
|
135
|
+
this._writeTo = writeTo
|
|
136
|
+
this._tty = tty ||
|
|
137
|
+
(writeTo === process.stderr && process.stdout.isTTY && process.stdout) ||
|
|
138
|
+
(writeTo.isTTY && writeTo) ||
|
|
139
|
+
this._tty
|
|
140
|
+
if (this._gauge) {
|
|
141
|
+
this._gauge.setWidth(this.getWidth())
|
|
142
|
+
}
|
|
143
|
+
if (enabled) {
|
|
144
|
+
this.enable()
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
Gauge.prototype.enable = function () {
|
|
149
|
+
if (!this._disabled) {
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
this._disabled = false
|
|
153
|
+
if (this._tty) {
|
|
154
|
+
this._enableEvents()
|
|
155
|
+
}
|
|
156
|
+
if (this._showing) {
|
|
157
|
+
this.show()
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
Gauge.prototype.disable = function () {
|
|
162
|
+
if (this._disabled) {
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
if (this._showing) {
|
|
166
|
+
this._lastUpdateAt = null
|
|
167
|
+
this._showing = false
|
|
168
|
+
this._doRedraw()
|
|
169
|
+
this._showing = true
|
|
170
|
+
}
|
|
171
|
+
this._disabled = true
|
|
172
|
+
if (this._tty) {
|
|
173
|
+
this._disableEvents()
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
Gauge.prototype._enableEvents = function () {
|
|
178
|
+
if (this._cleanupOnExit) {
|
|
179
|
+
this._removeOnExit = onExit(callWith(this, this.disable))
|
|
180
|
+
}
|
|
181
|
+
this._tty.on('resize', this._$$handleSizeChange)
|
|
182
|
+
if (this._fixedFramerate) {
|
|
183
|
+
this.redrawTracker = setInterval(this._$$doRedraw, this._updateInterval)
|
|
184
|
+
if (this.redrawTracker.unref) {
|
|
185
|
+
this.redrawTracker.unref()
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
Gauge.prototype._disableEvents = function () {
|
|
191
|
+
this._tty.removeListener('resize', this._$$handleSizeChange)
|
|
192
|
+
if (this._fixedFramerate) {
|
|
193
|
+
clearInterval(this.redrawTracker)
|
|
194
|
+
}
|
|
195
|
+
if (this._removeOnExit) {
|
|
196
|
+
this._removeOnExit()
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
Gauge.prototype.hide = function (cb) {
|
|
201
|
+
if (this._disabled) {
|
|
202
|
+
return cb && process.nextTick(cb)
|
|
203
|
+
}
|
|
204
|
+
if (!this._showing) {
|
|
205
|
+
return cb && process.nextTick(cb)
|
|
206
|
+
}
|
|
207
|
+
this._showing = false
|
|
208
|
+
this._doRedraw()
|
|
209
|
+
cb && setImmediate(cb)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
Gauge.prototype.show = function (section, completed) {
|
|
213
|
+
this._showing = true
|
|
214
|
+
if (typeof section === 'string') {
|
|
215
|
+
this._status.section = section
|
|
216
|
+
} else if (typeof section === 'object') {
|
|
217
|
+
var sectionKeys = Object.keys(section)
|
|
218
|
+
for (var ii = 0; ii < sectionKeys.length; ++ii) {
|
|
219
|
+
var key = sectionKeys[ii]
|
|
220
|
+
this._status[key] = section[key]
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (completed != null) {
|
|
224
|
+
this._status.completed = completed
|
|
225
|
+
}
|
|
226
|
+
if (this._disabled) {
|
|
227
|
+
return
|
|
228
|
+
}
|
|
229
|
+
this._requestRedraw()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
Gauge.prototype.pulse = function (subsection) {
|
|
233
|
+
this._status.subsection = subsection || ''
|
|
234
|
+
this._status.spun++
|
|
235
|
+
if (this._disabled) {
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
if (!this._showing) {
|
|
239
|
+
return
|
|
240
|
+
}
|
|
241
|
+
this._requestRedraw()
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
Gauge.prototype._handleSizeChange = function () {
|
|
245
|
+
this._gauge.setWidth(this._tty.columns - 1)
|
|
246
|
+
this._requestRedraw()
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
Gauge.prototype._doRedraw = function () {
|
|
250
|
+
if (this._disabled || this._paused) {
|
|
251
|
+
return
|
|
252
|
+
}
|
|
253
|
+
if (!this._fixedFramerate) {
|
|
254
|
+
var now = Date.now()
|
|
255
|
+
if (this._lastUpdateAt && now - this._lastUpdateAt < this._updateInterval) {
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
this._lastUpdateAt = now
|
|
259
|
+
}
|
|
260
|
+
if (!this._showing && this._onScreen) {
|
|
261
|
+
this._onScreen = false
|
|
262
|
+
var result = this._gauge.hide()
|
|
263
|
+
if (this._hideCursor) {
|
|
264
|
+
result += this._gauge.showCursor()
|
|
265
|
+
}
|
|
266
|
+
return this._writeTo.write(result)
|
|
267
|
+
}
|
|
268
|
+
if (!this._showing && !this._onScreen) {
|
|
269
|
+
return
|
|
270
|
+
}
|
|
271
|
+
if (this._showing && !this._onScreen) {
|
|
272
|
+
this._onScreen = true
|
|
273
|
+
this._needsRedraw = true
|
|
274
|
+
if (this._hideCursor) {
|
|
275
|
+
this._writeTo.write(this._gauge.hideCursor())
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!this._needsRedraw) {
|
|
279
|
+
return
|
|
280
|
+
}
|
|
281
|
+
if (!this._writeTo.write(this._gauge.show(this._status))) {
|
|
282
|
+
this._paused = true
|
|
283
|
+
this._writeTo.on('drain', callWith(this, function () {
|
|
284
|
+
this._paused = false
|
|
285
|
+
this._doRedraw()
|
|
286
|
+
}))
|
|
287
|
+
}
|
|
288
|
+
}
|
package/lib/plumbing.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
var consoleControl = require('./console-control.js')
|
|
3
|
+
var renderTemplate = require('./render-template.js')
|
|
4
|
+
var validate = require('./validate.js')
|
|
5
|
+
|
|
6
|
+
var Plumbing = module.exports = function (theme, template, width) {
|
|
7
|
+
if (!width) {
|
|
8
|
+
width = 80
|
|
9
|
+
}
|
|
10
|
+
validate('OAN', [theme, template, width])
|
|
11
|
+
this.showing = false
|
|
12
|
+
this.theme = theme
|
|
13
|
+
this.width = width
|
|
14
|
+
this.template = template
|
|
15
|
+
}
|
|
16
|
+
Plumbing.prototype = {}
|
|
17
|
+
|
|
18
|
+
Plumbing.prototype.setTheme = function (theme) {
|
|
19
|
+
validate('O', [theme])
|
|
20
|
+
this.theme = theme
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Plumbing.prototype.setTemplate = function (template) {
|
|
24
|
+
validate('A', [template])
|
|
25
|
+
this.template = template
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Plumbing.prototype.setWidth = function (width) {
|
|
29
|
+
validate('N', [width])
|
|
30
|
+
this.width = width
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Plumbing.prototype.hide = function () {
|
|
34
|
+
return consoleControl.gotoSOL() + consoleControl.eraseLine()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Plumbing.prototype.hideCursor = consoleControl.hideCursor
|
|
38
|
+
|
|
39
|
+
Plumbing.prototype.showCursor = consoleControl.showCursor
|
|
40
|
+
|
|
41
|
+
Plumbing.prototype.show = function (status) {
|
|
42
|
+
var values = Object.create(this.theme)
|
|
43
|
+
for (var key in status) {
|
|
44
|
+
values[key] = status[key]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return renderTemplate(this.width, this.template, values).trim() +
|
|
48
|
+
consoleControl.color('reset') +
|
|
49
|
+
consoleControl.eraseLine() + consoleControl.gotoSOL()
|
|
50
|
+
}
|
package/lib/plumbing.mjs
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import consoleControl from './console-control.js'
|
|
2
|
+
import renderTemplate from './render-template.js'
|
|
3
|
+
import validate from './validate.js'
|
|
4
|
+
|
|
5
|
+
export default function Plumbing(theme, template, width) {
|
|
6
|
+
if (!width) {
|
|
7
|
+
width = 80
|
|
8
|
+
}
|
|
9
|
+
validate('OAN', [theme, template, width])
|
|
10
|
+
this.showing = false
|
|
11
|
+
this.theme = theme
|
|
12
|
+
this.width = width
|
|
13
|
+
this.template = template
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
Plumbing.prototype = {}
|
|
17
|
+
|
|
18
|
+
Plumbing.prototype.setTheme = function (theme) {
|
|
19
|
+
validate('O', [theme])
|
|
20
|
+
this.theme = theme
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Plumbing.prototype.setTemplate = function (template) {
|
|
24
|
+
validate('A', [template])
|
|
25
|
+
this.template = template
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Plumbing.prototype.setWidth = function (width) {
|
|
29
|
+
validate('N', [width])
|
|
30
|
+
this.width = width
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Plumbing.prototype.hide = function () {
|
|
34
|
+
return consoleControl.gotoSOL() + consoleControl.eraseLine()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Plumbing.prototype.hideCursor = consoleControl.hideCursor
|
|
38
|
+
|
|
39
|
+
Plumbing.prototype.showCursor = consoleControl.showCursor
|
|
40
|
+
|
|
41
|
+
Plumbing.prototype.show = function (status) {
|
|
42
|
+
var values = Object.create(this.theme)
|
|
43
|
+
for (var key in status) {
|
|
44
|
+
values[key] = status[key]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return renderTemplate(this.width, this.template, values).trim() +
|
|
48
|
+
consoleControl.color('reset') +
|
|
49
|
+
consoleControl.eraseLine() + consoleControl.gotoSOL()
|
|
50
|
+
}
|
package/lib/process.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
var validate = require('./validate.js')
|
|
3
|
+
var renderTemplate = require('./render-template.js')
|
|
4
|
+
var wideTruncate = require('./wide-truncate')
|
|
5
|
+
var stringWidth = require('string-width')
|
|
6
|
+
|
|
7
|
+
module.exports = function (theme, width, completed) {
|
|
8
|
+
validate('ONN', [theme, width, completed])
|
|
9
|
+
if (completed < 0) {
|
|
10
|
+
completed = 0
|
|
11
|
+
}
|
|
12
|
+
if (completed > 1) {
|
|
13
|
+
completed = 1
|
|
14
|
+
}
|
|
15
|
+
if (width <= 0) {
|
|
16
|
+
return ''
|
|
17
|
+
}
|
|
18
|
+
var sofar = Math.round(width * completed)
|
|
19
|
+
var rest = width - sofar
|
|
20
|
+
var template = [
|
|
21
|
+
{ type: 'complete', value: repeat(theme.complete, sofar), length: sofar },
|
|
22
|
+
{ type: 'remaining', value: repeat(theme.remaining, rest), length: rest },
|
|
23
|
+
]
|
|
24
|
+
return renderTemplate(width, template, theme)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// lodash's way of repeating
|
|
28
|
+
function repeat (string, width) {
|
|
29
|
+
var result = ''
|
|
30
|
+
var n = width
|
|
31
|
+
do {
|
|
32
|
+
if (n % 2) {
|
|
33
|
+
result += string
|
|
34
|
+
}
|
|
35
|
+
n = Math.floor(n / 2)
|
|
36
|
+
/* eslint no-self-assign: 0 */
|
|
37
|
+
string += string
|
|
38
|
+
} while (n && stringWidth(result) < width)
|
|
39
|
+
|
|
40
|
+
return wideTruncate(result, width)
|
|
41
|
+
}
|