kodevu 0.1.17 → 0.1.18
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/package.json +1 -1
- package/src/progress-ui.js +78 -4
package/package.json
CHANGED
package/src/progress-ui.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import readline from "node:readline";
|
|
2
2
|
|
|
3
3
|
const SPINNER_FRAMES = ["|", "/", "-", "\\"];
|
|
4
|
+
const ELLIPSIS = "...";
|
|
4
5
|
|
|
5
6
|
function clampProgress(value) {
|
|
6
7
|
if (!Number.isFinite(value)) {
|
|
@@ -10,12 +11,53 @@ function clampProgress(value) {
|
|
|
10
11
|
return Math.max(0, Math.min(1, value));
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
function getCharacterWidth(character) {
|
|
15
|
+
const codePoint = character.codePointAt(0);
|
|
16
|
+
|
|
17
|
+
if (!codePoint || codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f)) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (
|
|
22
|
+
codePoint >= 0x1100 &&
|
|
23
|
+
(
|
|
24
|
+
codePoint <= 0x115f ||
|
|
25
|
+
codePoint === 0x2329 ||
|
|
26
|
+
codePoint === 0x232a ||
|
|
27
|
+
(codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||
|
|
28
|
+
(codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
|
|
29
|
+
(codePoint >= 0xf900 && codePoint <= 0xfaff) ||
|
|
30
|
+
(codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
|
|
31
|
+
(codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
|
|
32
|
+
(codePoint >= 0xff00 && codePoint <= 0xff60) ||
|
|
33
|
+
(codePoint >= 0xffe0 && codePoint <= 0xffe6) ||
|
|
34
|
+
(codePoint >= 0x1f300 && codePoint <= 0x1f64f) ||
|
|
35
|
+
(codePoint >= 0x1f900 && codePoint <= 0x1f9ff) ||
|
|
36
|
+
(codePoint >= 0x20000 && codePoint <= 0x3fffd)
|
|
37
|
+
)
|
|
38
|
+
) {
|
|
39
|
+
return 2;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getDisplayWidth(text) {
|
|
46
|
+
let width = 0;
|
|
47
|
+
|
|
48
|
+
for (const character of text) {
|
|
49
|
+
width += getCharacterWidth(character);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return width;
|
|
53
|
+
}
|
|
54
|
+
|
|
13
55
|
function truncateLine(line, maxWidth) {
|
|
14
56
|
if (!Number.isFinite(maxWidth) || maxWidth <= 0) {
|
|
15
57
|
return "";
|
|
16
58
|
}
|
|
17
59
|
|
|
18
|
-
if (line
|
|
60
|
+
if (getDisplayWidth(line) <= maxWidth) {
|
|
19
61
|
return line;
|
|
20
62
|
}
|
|
21
63
|
|
|
@@ -23,7 +65,22 @@ function truncateLine(line, maxWidth) {
|
|
|
23
65
|
return ".".repeat(maxWidth);
|
|
24
66
|
}
|
|
25
67
|
|
|
26
|
-
|
|
68
|
+
const targetWidth = maxWidth - getDisplayWidth(ELLIPSIS);
|
|
69
|
+
let result = "";
|
|
70
|
+
let width = 0;
|
|
71
|
+
|
|
72
|
+
for (const character of line) {
|
|
73
|
+
const nextWidth = width + getCharacterWidth(character);
|
|
74
|
+
|
|
75
|
+
if (nextWidth > targetWidth) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
result += character;
|
|
80
|
+
width = nextWidth;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return `${result}${ELLIPSIS}`;
|
|
27
84
|
}
|
|
28
85
|
|
|
29
86
|
class ProgressItem {
|
|
@@ -117,6 +174,7 @@ export class ProgressDisplay {
|
|
|
117
174
|
this.items = [];
|
|
118
175
|
this.currentItem = null;
|
|
119
176
|
this.statusVisible = false;
|
|
177
|
+
this.lastStatusWidth = 0;
|
|
120
178
|
this.resizeAttached = false;
|
|
121
179
|
this.handleResize = this.handleResize.bind(this);
|
|
122
180
|
}
|
|
@@ -185,8 +243,10 @@ export class ProgressDisplay {
|
|
|
185
243
|
}
|
|
186
244
|
|
|
187
245
|
this.clearStatusLine();
|
|
188
|
-
this.
|
|
246
|
+
const line = this.currentItem.renderLine(this.frameIndex);
|
|
247
|
+
this.stream.write(line);
|
|
189
248
|
this.statusVisible = true;
|
|
249
|
+
this.lastStatusWidth = getDisplayWidth(line);
|
|
190
250
|
}
|
|
191
251
|
|
|
192
252
|
clearStatusLine() {
|
|
@@ -194,9 +254,23 @@ export class ProgressDisplay {
|
|
|
194
254
|
return;
|
|
195
255
|
}
|
|
196
256
|
|
|
197
|
-
|
|
257
|
+
const rows = Math.max(1, Math.ceil(this.lastStatusWidth / Math.max(this.stream.columns || 1, 1)));
|
|
258
|
+
|
|
259
|
+
readline.moveCursor(this.stream, 0, -Math.max(rows - 1, 0));
|
|
260
|
+
|
|
261
|
+
for (let index = 0; index < rows; index += 1) {
|
|
262
|
+
readline.clearLine(this.stream, 0);
|
|
263
|
+
readline.cursorTo(this.stream, 0);
|
|
264
|
+
|
|
265
|
+
if (index < rows - 1) {
|
|
266
|
+
readline.moveCursor(this.stream, 0, 1);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
readline.moveCursor(this.stream, 0, -Math.max(rows - 1, 0));
|
|
198
271
|
readline.cursorTo(this.stream, 0);
|
|
199
272
|
this.statusVisible = false;
|
|
273
|
+
this.lastStatusWidth = 0;
|
|
200
274
|
}
|
|
201
275
|
|
|
202
276
|
stopIfIdle() {
|