File size: 3,902 Bytes
1070765
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
const _GenericBar = require('./generic-bar');
const _options = require('./options');

// Progress-Bar constructor
module.exports = class SingleBar extends _GenericBar{

    constructor(options, preset){
        super(_options.parse(options, preset));

        // the update timer
        this.timer = null;

        // disable synchronous updates in notty mode
        if (this.options.noTTYOutput && this.terminal.isTTY() === false){
            this.options.synchronousUpdate = false;
        }

        // update interval
        this.schedulingRate = (this.terminal.isTTY() ? this.options.throttleTime : this.options.notTTYSchedule);

        // callback used for gracefulExit
        this.sigintCallback = null;
    }

    // internal render function
    render(){
        // stop timer
        if (this.timer){
            clearTimeout(this.timer);
            this.timer = null;
        }

        // run internal rendering
        super.render();

        // add new line in notty mode!
        if (this.options.noTTYOutput && this.terminal.isTTY() === false){
            this.terminal.newline();
        }

        // next update
        this.timer = setTimeout(this.render.bind(this), this.schedulingRate);
    }

    update(current, payload){
        // timer inactive ?
        if (!this.timer) {
            return;
        }

        super.update(current, payload);

        // trigger synchronous update ?
        // check for throttle time 
        if (this.options.synchronousUpdate && (this.lastRedraw + this.options.throttleTime*2) < Date.now()){
            // force update
            this.render();
        }
    }

    // start the progress bar
    start(total, startValue, payload){
        // progress updates are only visible in TTY mode!
        if (this.options.noTTYOutput === false && this.terminal.isTTY() === false){
            return;
        }

        // add handler to restore cursor settings (stop the bar) on SIGINT/SIGTERM ?
        if (this.sigintCallback === null && this.options.gracefulExit){
            this.sigintCallback = this.stop.bind(this);
            process.once('SIGINT', this.sigintCallback);
            process.once('SIGTERM', this.sigintCallback);
        }

        // save current cursor settings
        this.terminal.cursorSave();

        // hide the cursor ?
        if (this.options.hideCursor === true){
            this.terminal.cursor(false);
        }

        // disable line wrapping ?
        if (this.options.linewrap === false){
            this.terminal.lineWrapping(false);
        }

        // initialize bar
        super.start(total, startValue, payload);

        // redraw on start!
        this.render();
    }

    // stop the bar
    stop(){
        // timer inactive ?
        if (!this.timer) {
            return;
        }
        
        // remove sigint listener
        if (this.sigintCallback){
            process.removeListener('SIGINT', this.sigintCallback);
            process.removeListener('SIGTERM', this.sigintCallback);
            this.sigintCallback = null;
        }

        // trigger final rendering
        this.render();

        // restore state
        super.stop();

        // stop timer
        clearTimeout(this.timer);
        this.timer = null;

        // cursor hidden ?
        if (this.options.hideCursor === true){
            this.terminal.cursor(true);
        }

        // re-enable line wrapping ?
        if (this.options.linewrap === false){
            this.terminal.lineWrapping(true);
        }

        // restore cursor on complete (position + settings)
        this.terminal.cursorRestore();

        // clear line on complete ?
        if (this.options.clearOnComplete){
            this.terminal.cursorTo(0, null);
            this.terminal.clearLine();
        }else{
            // new line on complete
            this.terminal.newline();
        }
    }
}