UNPKG

2.66 kBJavaScriptView Raw
1var readline = require('readline');
2
3var defaultSpinnerString = 0;
4var defaultSpinnerDelay = 60;
5
6function defaultOnTick(msg) {
7 this.clearLine(this.stream);
8 this.stream.write(msg);
9};
10
11var Spinner = function(options){
12 if(!(this instanceof Spinner)) return new Spinner(options)
13
14 if(typeof options === "string"){
15 options = { text: options };
16 } else if(!options){
17 options = {};
18 }
19
20 this.text = options.text || '';
21 this.setSpinnerString(defaultSpinnerString);
22 this.setSpinnerDelay(defaultSpinnerDelay);
23 this.onTick = options.onTick || defaultOnTick;
24 this.stream = options.stream || process.stdout;
25};
26
27Spinner.spinners = require('./spinners.json');
28
29Spinner.setDefaultSpinnerString = function(value) {
30 defaultSpinnerString = value;
31
32 return this;
33};
34
35Spinner.setDefaultSpinnerDelay = function(value) {
36 defaultSpinnerDelay = value;
37
38 return this;
39};
40
41Spinner.prototype.start = function() {
42 if(this.stream === process.stdout && this.stream.isTTY !== true) {
43 return this;
44 }
45
46 var current = 0;
47 var self = this;
48
49 var iteration = function() {
50 var msg = self.text.indexOf('%s') > -1
51 ? self.text.replace('%s', self.chars[current])
52 : self.chars[current] + ' ' + self.text;
53
54 self.onTick(msg);
55
56 current = ++current % self.chars.length;
57 };
58
59 iteration();
60 this.id = setInterval(iteration, this.delay);
61
62 return this;
63};
64
65Spinner.prototype.isSpinning = function() {
66 return this.id !== undefined;
67}
68
69Spinner.prototype.setSpinnerDelay = function(n) {
70 this.delay = n;
71
72 return this;
73};
74
75Spinner.prototype.setSpinnerString = function(str) {
76 const map = mapToSpinner(str, this.spinners);
77 this.chars = Array.isArray(map) ? map : map.split('');
78
79 return this;
80};
81
82Spinner.prototype.setSpinnerTitle = function(str) {
83 this.text = str;
84
85 return this;
86}
87
88Spinner.prototype.stop = function(clear) {
89 if(this.isSpinning === false) {
90 return this;
91 }
92
93 clearInterval(this.id);
94 this.id = undefined;
95
96 if (clear) {
97 this.clearLine(this.stream);
98 }
99
100 return this;
101};
102
103Spinner.prototype.clearLine = function(stream) {
104 readline.clearLine(stream, 0);
105 readline.cursorTo(stream, 0);
106
107 return this;
108}
109
110// Helpers
111
112function isInt(value) {
113 return (typeof value==='number' && (value%1)===0);
114}
115
116function mapToSpinner(value, spinners) {
117 // Not an integer, return as strng
118 if (!isInt(value)) {
119 return value + '';
120 }
121
122 var length = Spinner.spinners.length;
123
124 // Check if index is within bounds
125 value = (value >= length) ? 0 : value;
126 // If negative, count from the end
127 value = (value < 0) ? length + value : value;
128
129 return Spinner.spinners[value];
130}
131
132exports.Spinner = Spinner;