wukong-progress 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -1,219 +1,254 @@
1
- # wukong-progress
2
-
3
- 🎨 A Node.js / ESM style CLI progress bar library that supports:
4
-
5
- - Single / multiple progress bars
6
- - Group / Stage / prefix
7
- - Concurrent task API (wrap async functions)
8
- - Automatic terminal width adaptation
9
- - Optional colored output (chalk, auto fallback)
10
- - JSON fallback (for non-TTY environments)
11
- - Full ESM + Node.js 18+ compatible
12
- - Works on Windows / Linux / macOS
13
-
14
- ---
15
- ## English | [įŽ€äŊ“中文](./README.zh-CN.md)
16
- ---
17
- ## 🚀 Installation
18
-
19
- ```bash
20
- yarn add wukong-progress chalk
21
- # or
22
- npm install wukong-progress chalk
23
- ```
24
-
25
- ---
26
-
27
- ## âšĄī¸ Basic Usage
28
-
29
- ### Single Progress Bar
30
-
31
- ```js
32
- import chalk from "chalk";
33
- import { createMultiBar } from "wukong-progress";
34
-
35
- const mb = createMultiBar();
36
- const bar = mb.create(100, {
37
- prefix: chalk.cyan("Build"),
38
- format: "Build [:bar] :percent :current/:total",
39
- });
40
-
41
- async function run() {
42
- for (let i = 0; i <= 100; i++) {
43
- await new Promise((r) => setTimeout(r, 20));
44
- bar.tick();
45
- }
46
- mb.stop();
47
- console.log(chalk.green("\nDone!\n"));
48
- }
49
-
50
- run();
51
- ```
52
-
53
- ### Multiple Progress Bars
54
-
55
- ```js
56
- import chalk from "chalk";
57
- import { createMultiBar } from "wukong-progress";
58
-
59
- const mb = createMultiBar();
60
- const build = mb.create(100, {
61
- prefix: chalk.blue("Build"),
62
- format: "Build [:bar] :percent",
63
- });
64
- const test = mb.create(50, {
65
- prefix: chalk.magenta("Test"),
66
- format: "Test [:bar] :percent",
67
- });
68
-
69
- async function run() {
70
- for (let i = 0; i <= 100; i++) {
71
- await new Promise((r) => setTimeout(r, 15));
72
- if (i <= 50) test.tick();
73
- build.tick();
74
- }
75
- mb.stop();
76
- console.log(chalk.green("\nAll tasks done!\n"));
77
- }
78
-
79
- run();
80
- ```
81
-
82
- ---
83
-
84
- ### Group / Stage / prefix
85
-
86
- ```js
87
- import chalk from "chalk";
88
- import { createMultiBar } from "wukong-progress";
89
-
90
- const mb = createMultiBar();
91
- const buildGroup = mb.group("Build Group");
92
- buildGroup.create(50, {
93
- prefix: chalk.blue("Compile"),
94
- format: "Compile [:bar] :percent",
95
- });
96
- buildGroup.create(30, {
97
- prefix: chalk.cyan("Bundle"),
98
- format: "Bundle [:bar] :percent",
99
- });
100
-
101
- const testGroup = mb.group("Test Group");
102
- testGroup.create(20, {
103
- prefix: chalk.magenta("Unit"),
104
- format: "Unit [:bar] :percent",
105
- });
106
- testGroup.create(10, {
107
- prefix: chalk.yellow("E2E"),
108
- format: "E2E [:bar] :percent",
109
- });
110
-
111
- async function run() {
112
- const allTasks = [...buildGroup.bars, ...testGroup.bars];
113
-
114
- for (let i = 0; i < 50; i++) {
115
- await new Promise((r) => setTimeout(r, 20));
116
- allTasks.forEach((bar) => {
117
- if (!bar.state.complete) bar.tick();
118
- });
119
- }
120
-
121
- mb.stop();
122
- console.log(chalk.green("\nGroups completed!\n"));
123
- }
124
-
125
- run();
126
- ```
127
-
128
- ---
129
-
130
- ### JSON Fallback (non-TTY / CI)
131
-
132
- ```js
133
- import { Writable } from "node:stream";
134
- import { createMultiBar } from "wukong-progress";
135
-
136
- let out = "";
137
- const stream = new Writable({
138
- write(chunk, _, cb) {
139
- out += chunk;
140
- cb();
141
- },
142
- });
143
-
144
- const mb = createMultiBar({ stream, json: true });
145
- const bar = mb.create(5, { prefix: "JSON" });
146
-
147
- async function run() {
148
- for (let i = 0; i <= 5; i++) {
149
- await new Promise((r) => setTimeout(r, 20));
150
- bar.tick();
151
- }
152
- mb.stop();
153
-
154
- console.log("JSON fallback output:");
155
- console.log(out);
156
- }
157
-
158
- run();
159
- ```
160
-
161
- ---
162
-
163
- ## 🎨 Colored Output (optional)
164
-
165
- - Use `chalk` to color prefixes and bar output
166
- - Auto fallback to plain text if chalk is not installed
167
- - Example:
168
-
169
- ```js
170
- prefix: chalk.green('Build'),
171
- format: chalk.green('Build [:bar] :percent')
172
- ```
173
-
174
- ---
175
-
176
- ## 📂 Examples Folder
177
-
178
- ```bash
179
- node examples/index.mjs
180
- ```
181
-
182
- - Interactive selection of examples:
183
-
184
- - Single Bar
185
- - Multi Bar
186
- - Group / Stage
187
- - JSON Fallback
188
-
189
- - Fully compatible with Windows / Linux / macOS
190
- - All examples use async/await + chalk colored output
191
-
192
- ---
193
-
194
- ## âšĄī¸ Testing
195
-
196
- ```bash
197
- # Node.js native test
198
- yarn test:node
199
-
200
- # Vitest snapshot test
201
- yarn test:vitest
202
-
203
- # Run all tests
204
- yarn test
205
- ```
206
-
207
- - ✅ Node:test for progress logic
208
- - ✅ Vitest snapshot for rendering stability
209
- - ✅ Supports mock TTY / ANSI strip / JSON fallback
210
-
211
- ---
212
-
213
- ## đŸ’ģ Use Cases
214
-
215
- - CLI tools
216
- - Automation scripts
217
- - GitHub Actions / CI
218
- - Concurrent task visualization
219
- - Progress visualization + JSON logging for analytics
1
+ # wukong-progress
2
+
3
+ 🎨 A Node.js / ESM style CLI progress bar library that supports:
4
+
5
+ - Single / multiple progress bars
6
+ - Group / Stage / prefix
7
+ - Concurrent task API (wrap async functions)
8
+ - Automatic terminal width adaptation
9
+ - Optional colored output (chalk, auto fallback)
10
+ - JSON fallback (for non-TTY environments)
11
+ - Full ESM + Node.js 18+ compatible
12
+ - Works on Windows / Linux / macOS
13
+
14
+ ---
15
+ ## English | [įŽ€äŊ“中文](./README.zh-CN.md)
16
+ ---
17
+ ## 🚀 Installation
18
+
19
+ ```bash
20
+ yarn add wukong-progress chalk
21
+ # or
22
+ npm install wukong-progress chalk
23
+ ```
24
+
25
+ ---
26
+
27
+ ## âšĄī¸ Basic Usage
28
+
29
+ ### Single Progress Bar
30
+
31
+ ```js
32
+ import chalk from "chalk";
33
+ import { createMultiBar } from "wukong-progress";
34
+
35
+ const mb = createMultiBar();
36
+ const bar = mb.create(100, {
37
+ prefix: chalk.cyan("Build"),
38
+ format: "Build [:bar] :percent :current/:total",
39
+ });
40
+
41
+ async function run() {
42
+ for (let i = 0; i <= 100; i++) {
43
+ await new Promise((r) => setTimeout(r, 20));
44
+ bar.tick();
45
+ }
46
+ mb.stop();
47
+ console.log(chalk.green("\nDone!\n"));
48
+ }
49
+
50
+ run();
51
+ ```
52
+
53
+ ### Multiple Progress Bars
54
+
55
+ ```js
56
+ import chalk from "chalk";
57
+ import { createMultiBar } from "wukong-progress";
58
+
59
+ const mb = createMultiBar();
60
+ const build = mb.create(100, {
61
+ prefix: chalk.blue("Build"),
62
+ format: "Build [:bar] :percent",
63
+ });
64
+ const test = mb.create(50, {
65
+ prefix: chalk.magenta("Test"),
66
+ format: "Test [:bar] :percent",
67
+ });
68
+
69
+ async function run() {
70
+ for (let i = 0; i <= 100; i++) {
71
+ await new Promise((r) => setTimeout(r, 15));
72
+ if (i <= 50) test.tick();
73
+ build.tick();
74
+ }
75
+ mb.stop();
76
+ console.log(chalk.green("\nAll tasks done!\n"));
77
+ }
78
+
79
+ run();
80
+ ```
81
+
82
+ ### Step with Payload
83
+
84
+ Update progress with a descriptive payload message.
85
+
86
+ ```js
87
+ import chalk from 'chalk'
88
+ import { createMultiBar } from '../src/index.mjs'
89
+
90
+ const mb = createMultiBar()
91
+
92
+ const build = mb.create(100, {
93
+ prefix: chalk.blue('Build'),
94
+ format: 'Build [:bar] :percent :payload'
95
+ })
96
+ const test = mb.create(50, {
97
+ prefix: chalk.magenta('Test'),
98
+ format: 'Test [:bar] :percent'
99
+ })
100
+
101
+ async function run() {
102
+ for (let i = 0; i <= 100; i++) {
103
+ await new Promise((r) => setTimeout(r, 15))
104
+ if (i <= 50) test.tick()
105
+ build.step(5, 'Extracting Git history...')
106
+ build.step(5, 'Parsing commits...')
107
+ build.step(5, 'Generating Changelog...')
108
+ build.step(5, 'Generating Release Info...')
109
+ }
110
+ mb.stop()
111
+ console.log(chalk.green('\nAll tasks done!\n'))
112
+ }
113
+
114
+ run()
115
+ ```
116
+
117
+ ---
118
+
119
+ ### Group / Stage / prefix
120
+
121
+ ```js
122
+ import chalk from "chalk";
123
+ import { createMultiBar } from "wukong-progress";
124
+
125
+ const mb = createMultiBar();
126
+ const buildGroup = mb.group("Build Group");
127
+ buildGroup.create(50, {
128
+ prefix: chalk.blue("Compile"),
129
+ format: "Compile [:bar] :percent",
130
+ });
131
+ buildGroup.create(30, {
132
+ prefix: chalk.cyan("Bundle"),
133
+ format: "Bundle [:bar] :percent",
134
+ });
135
+
136
+ const testGroup = mb.group("Test Group");
137
+ testGroup.create(20, {
138
+ prefix: chalk.magenta("Unit"),
139
+ format: "Unit [:bar] :percent",
140
+ });
141
+ testGroup.create(10, {
142
+ prefix: chalk.yellow("E2E"),
143
+ format: "E2E [:bar] :percent",
144
+ });
145
+
146
+ async function run() {
147
+ const allTasks = [...buildGroup.bars, ...testGroup.bars];
148
+
149
+ for (let i = 0; i < 50; i++) {
150
+ await new Promise((r) => setTimeout(r, 20));
151
+ allTasks.forEach((bar) => {
152
+ if (!bar.state.complete) bar.tick();
153
+ });
154
+ }
155
+
156
+ mb.stop();
157
+ console.log(chalk.green("\nGroups completed!\n"));
158
+ }
159
+
160
+ run();
161
+ ```
162
+
163
+ ---
164
+
165
+ ### JSON Fallback (non-TTY / CI)
166
+
167
+ ```js
168
+ import { Writable } from "node:stream";
169
+ import { createMultiBar } from "wukong-progress";
170
+
171
+ let out = "";
172
+ const stream = new Writable({
173
+ write(chunk, _, cb) {
174
+ out += chunk;
175
+ cb();
176
+ },
177
+ });
178
+
179
+ const mb = createMultiBar({ stream, json: true });
180
+ const bar = mb.create(5, { prefix: "JSON" });
181
+
182
+ async function run() {
183
+ for (let i = 0; i <= 5; i++) {
184
+ await new Promise((r) => setTimeout(r, 20));
185
+ bar.tick();
186
+ }
187
+ mb.stop();
188
+
189
+ console.log("JSON fallback output:");
190
+ console.log(out);
191
+ }
192
+
193
+ run();
194
+ ```
195
+
196
+ ---
197
+
198
+ ## 🎨 Colored Output (optional)
199
+
200
+ - Use `chalk` to color prefixes and bar output
201
+ - Auto fallback to plain text if chalk is not installed
202
+ - Example:
203
+
204
+ ```js
205
+ prefix: chalk.green('Build'),
206
+ format: chalk.green('Build [:bar] :percent')
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 📂 Examples Folder
212
+
213
+ ```bash
214
+ node examples/index.mjs
215
+ ```
216
+
217
+ - Interactive selection of examples:
218
+
219
+ - Single Bar
220
+ - Multi Bar
221
+ - Group / Stage
222
+ - JSON Fallback
223
+
224
+ - Fully compatible with Windows / Linux / macOS
225
+ - All examples use async/await + chalk colored output
226
+
227
+ ---
228
+
229
+ ## âšĄī¸ Testing
230
+
231
+ ```bash
232
+ # Node.js native test
233
+ yarn test:node
234
+
235
+ # Vitest snapshot test
236
+ yarn test:vitest
237
+
238
+ # Run all tests
239
+ yarn test
240
+ ```
241
+
242
+ - ✅ Node:test for progress logic
243
+ - ✅ Vitest snapshot for rendering stability
244
+ - ✅ Supports mock TTY / ANSI strip / JSON fallback
245
+
246
+ ---
247
+
248
+ ## đŸ’ģ Use Cases
249
+
250
+ - CLI tools
251
+ - Automation scripts
252
+ - GitHub Actions / CI
253
+ - Concurrent task visualization
254
+ - Progress visualization + JSON logging for analytics
package/README.zh-CN.md CHANGED
@@ -11,7 +11,7 @@
11
11
  - JSON fallbackīŧˆéž TTYīŧ‰
12
12
  - 厌全 ESM + Node.js 18+ å…ŧ厚
13
13
  - 可在 Windows / Linux / macOS äŊŋᔍ
14
-
14
+
15
15
  ---
16
16
  ## 中文 | [English](./README.md)
17
17
  ---
@@ -72,6 +72,41 @@ async function run() {
72
72
  run()
73
73
  ```
74
74
 
75
+ ### å¸Ļ文字提į¤ēįš„æ­ĨéĒ¤æ›´æ–°
76
+
77
+ äŊŋᔍ `step` æ–šæŗ•å¯äģĨ在更新čŋ›åēĻįš„åŒæ—ļ附加描čŋ°æ€§æ–‡å­—。
78
+
79
+ ```js
80
+ import chalk from 'chalk'
81
+ import { createMultiBar } from '../src/index.mjs'
82
+
83
+ const mb = createMultiBar()
84
+
85
+ const build = mb.create(100, {
86
+ prefix: chalk.blue('Build'),
87
+ format: 'Build [:bar] :percent :payload'
88
+ })
89
+ const test = mb.create(50, {
90
+ prefix: chalk.magenta('Test'),
91
+ format: 'Test [:bar] :percent'
92
+ })
93
+
94
+ async function run() {
95
+ for (let i = 0; i <= 100; i++) {
96
+ await new Promise((r) => setTimeout(r, 15))
97
+ if (i <= 50) test.tick()
98
+ build.step(5, 'æ­Ŗåœ¨æå– Git 提äē¤čްåŊ•...')
99
+ build.step(5, 'æ­Ŗåœ¨č§Ŗæžæäē¤čްåŊ•...')
100
+ build.step(5, 'æ­Ŗåœ¨į”Ÿæˆ Changelog...')
101
+ build.step(5, 'æ­Ŗåœ¨į”Ÿæˆ Release äŋĄæ¯...')
102
+ }
103
+ mb.stop()
104
+ console.log(chalk.green('\nAll tasks done!\n'))
105
+ }
106
+
107
+ run()
108
+ ```
109
+
75
110
  ---
76
111
 
77
112
  ### Group / Stage / prefix
@@ -144,11 +179,11 @@ run()
144
179
  ## 🎨 åŊŠč‰˛æ¸˛æŸ“īŧˆå¯é€‰īŧ‰
145
180
 
146
181
  - äŊŋᔍ `chalk` 可äģĨįģ™ prefix、bar 和提į¤ē上色
147
-
182
+
148
183
  - 不䞝čĩ–åŊŠč‰˛äšŸčƒŊ降įē§åˆ°æ™Žé€šæ–‡æœŦ
149
-
184
+
150
185
  - į¤ē例īŧš
151
-
186
+
152
187
 
153
188
  ```js
154
189
  prefix: chalk.green('Build'),
@@ -164,19 +199,19 @@ node examples/index.mjs
164
199
  ```
165
200
 
166
201
  - äē¤äē’åŧé€‰æ‹ŠčŋčĄŒį¤ē例īŧš
167
-
202
+
168
203
  - Single Bar
169
-
204
+
170
205
  - Multi Bar
171
-
206
+
172
207
  - Group / Stage
173
-
208
+
174
209
  - JSON Fallback
175
-
210
+
176
211
  - Windows / Linux / macOS å…¨åšŗå°å…ŧ厚
177
-
212
+
178
213
  - 所有į¤ē例éƒŊᔍ async/await + chalk åŊŠč‰˛æ¸˛æŸ“
179
-
214
+
180
215
 
181
216
  ---
182
217
 
@@ -194,24 +229,24 @@ yarn test
194
229
  ```
195
230
 
196
231
  - ✅ Node:test æĩ‹č¯•čŋ›åēĻæĄé€ģ辑
197
-
232
+
198
233
  - ✅ Vitest snapshot æĩ‹č¯•æ¸˛æŸ“į¨ŗåŽšæ€§
199
-
234
+
200
235
  - ✅ 支持 mock TTY / ANSI strip / JSON fallback
201
-
236
+
202
237
 
203
238
  ---
204
239
 
205
240
  ## đŸ’ģ 适ᔍåœē景
206
241
 
207
242
  - CLI åˇĨå…ˇ
208
-
243
+
209
244
  - č‡ĒåŠ¨åŒ–č„šæœŦ
210
-
245
+
211
246
  - GitHub Actions / CI
212
-
247
+
213
248
  - 多äģģåŠĄåšļ发昞į¤ē
214
-
249
+
215
250
  - å¯č§†åŒ–čŋ›åēĻ / JSON 输å‡ēįģ“合æ—Ĩåŋ—分析
216
-
251
+
217
252
 
package/dist/index.mjs CHANGED
@@ -31,6 +31,7 @@ function createBar(ctx, opts) {
31
31
  format: opts.format,
32
32
  minWidth: opts.minWidth ?? 10,
33
33
  prefix: opts.prefix ?? "",
34
+ payload: opts.payload ?? "",
34
35
  hideOnComplete: opts.hideOnComplete ?? false,
35
36
  complete: false
36
37
  };
@@ -44,10 +45,14 @@ function createBar(ctx, opts) {
44
45
  function tick(n = 1) {
45
46
  update(state.current + n);
46
47
  }
48
+ function step(n = 1, payload) {
49
+ state.payload = payload;
50
+ tick(n);
51
+ }
47
52
  function render(width) {
48
53
  const elapsed = (Date.now() - state.start) / 1e3;
49
54
  const percent = state.current / state.total;
50
- const staticLen = state.format.replace(":bar", "").replace(":percent", "100%").replace(":current", state.total).replace(":total", state.total).replace(":eta", "00s").length;
55
+ const staticLen = state.format.replace(":bar", "").replace(":percent", "100%").replace(":current", state.total).replace(":total", state.total).replace(":payload", state.payload).replace(":eta", "00s").length;
51
56
  const barWidth = Math.max(
52
57
  state.minWidth,
53
58
  width - staticLen - state.prefix.length - 4
@@ -56,11 +61,12 @@ function createBar(ctx, opts) {
56
61
  const bar = color.bar("\u2588".repeat(filled)) + color.dim("\u2591".repeat(barWidth - filled));
57
62
  const rate = state.current / elapsed;
58
63
  const eta = rate ? (state.total - state.current) / rate : Infinity;
59
- return (state.prefix ? `${state.prefix} ` : "") + state.format.replace(":bar", bar).replace(":percent", color.percent(`${Math.round(percent * 100)}%`)).replace(":current", state.current).replace(":total", state.total).replace(":elapsed", formatTime(elapsed)).replace(":eta", formatTime(eta));
64
+ return (state.prefix ? `${state.prefix} ` : "") + state.format.replace(":bar", bar).replace(":percent", color.percent(`${Math.round(percent * 100)}%`)).replace(":current", state.current).replace(":total", state.total).replace(":payload", state.payload).replace(":elapsed", formatTime(elapsed)).replace(":eta", formatTime(eta));
60
65
  }
61
66
  return {
62
67
  state,
63
68
  tick,
69
+ step,
64
70
  update,
65
71
  render
66
72
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wukong-progress",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Lightweight ESM CLI progress bar for Node.js with multiple bars, groups, stages and JSON fallback",
5
5
  "keywords": [
6
6
  "cli",
package/src/bar.mjs CHANGED
@@ -9,6 +9,7 @@ export function createBar(ctx, opts) {
9
9
  format: opts.format,
10
10
  minWidth: opts.minWidth ?? 10,
11
11
  prefix: opts.prefix ?? '',
12
+ payload: opts.payload ?? '',
12
13
  hideOnComplete: opts.hideOnComplete ?? false,
13
14
  complete: false
14
15
  }
@@ -23,6 +24,12 @@ export function createBar(ctx, opts) {
23
24
  update(state.current + n)
24
25
  }
25
26
 
27
+ // eslint-disable-next-line default-param-last
28
+ function step(n = 1, payload) {
29
+ state.payload = payload
30
+ tick(n)
31
+ }
32
+
26
33
  function render(width) {
27
34
  const elapsed = (Date.now() - state.start) / 1000
28
35
  const percent = state.current / state.total
@@ -32,6 +39,7 @@ export function createBar(ctx, opts) {
32
39
  .replace(':percent', '100%')
33
40
  .replace(':current', state.total)
34
41
  .replace(':total', state.total)
42
+ .replace(':payload', state.payload)
35
43
  .replace(':eta', '00s').length
36
44
 
37
45
  const barWidth = Math.max(
@@ -53,6 +61,7 @@ export function createBar(ctx, opts) {
53
61
  .replace(':percent', color.percent(`${Math.round(percent * 100)}%`))
54
62
  .replace(':current', state.current)
55
63
  .replace(':total', state.total)
64
+ .replace(':payload', state.payload)
56
65
  .replace(':elapsed', formatTime(elapsed))
57
66
  .replace(':eta', formatTime(eta))
58
67
  )
@@ -61,6 +70,7 @@ export function createBar(ctx, opts) {
61
70
  return {
62
71
  state,
63
72
  tick,
73
+ step,
64
74
  update,
65
75
  render
66
76
  }
package/src/group.mjs CHANGED
@@ -1,15 +1,15 @@
1
- export function createGroup(ctx, name) {
2
- const bars = []
3
-
4
- function create(total, opts = {}) {
5
- const bar = ctx._createBar({
6
- ...opts,
7
- prefix: opts.prefix ?? name,
8
- total,
9
- })
10
- bars.push(bar)
11
- return bar
12
- }
13
-
14
- return { create, bars }
15
- }
1
+ export function createGroup(ctx, name) {
2
+ const bars = []
3
+
4
+ function create(total, opts = {}) {
5
+ const bar = ctx._createBar({
6
+ ...opts,
7
+ prefix: opts.prefix ?? name,
8
+ total,
9
+ })
10
+ bars.push(bar)
11
+ return bar
12
+ }
13
+
14
+ return { create, bars }
15
+ }
package/src/index.mjs CHANGED
@@ -1 +1 @@
1
- export { createMultiBar } from './multibar.mjs'
1
+ export { createMultiBar } from './multibar.mjs'
package/src/json.mjs CHANGED
@@ -1,16 +1,16 @@
1
- export function renderJSON(stream, bars) {
2
- const payload = {
3
- type: 'progress',
4
- bars: bars.map(b => ({
5
- name: b.state.prefix,
6
- current: b.state.current,
7
- total: b.state.total,
8
- percent: Math.round(
9
- (b.state.current / b.state.total) * 100
10
- ),
11
- complete: b.state.complete,
12
- })),
13
- }
14
-
15
- stream.write(`${JSON.stringify(payload) }\n`)
16
- }
1
+ export function renderJSON(stream, bars) {
2
+ const payload = {
3
+ type: 'progress',
4
+ bars: bars.map(b => ({
5
+ name: b.state.prefix,
6
+ current: b.state.current,
7
+ total: b.state.total,
8
+ percent: Math.round(
9
+ (b.state.current / b.state.total) * 100
10
+ ),
11
+ complete: b.state.complete,
12
+ })),
13
+ }
14
+
15
+ stream.write(`${JSON.stringify(payload) }\n`)
16
+ }
@@ -0,0 +1 @@
1
+ export const wait = (time) => new Promise((res) => {setTimeout(res, time)})