trzsz2 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 +21 -0
- package/README.cn.md +64 -0
- package/README.md +70 -0
- package/dist/browser/buffer.d.ts +76 -0
- package/dist/browser/comm.d.ts +162 -0
- package/dist/browser/escape.d.ts +33 -0
- package/dist/browser/index.d.ts +17 -0
- package/dist/browser/options.d.ts +57 -0
- package/dist/browser/progress.d.ts +100 -0
- package/dist/browser/transfer.d.ts +259 -0
- package/dist/browser/trzsz2.js +6147 -0
- package/dist/browser/trzsz2.js.map +1 -0
- package/dist/browser/trzsz2.min.js +19 -0
- package/dist/buffer.d.ts +76 -0
- package/dist/cjs/buffer.cjs +252 -0
- package/dist/cjs/buffer.cjs.map +1 -0
- package/dist/cjs/buffer.d.ts +76 -0
- package/dist/cjs/comm.cjs +292 -0
- package/dist/cjs/comm.cjs.map +1 -0
- package/dist/cjs/comm.d.ts +162 -0
- package/dist/cjs/escape.cjs +86 -0
- package/dist/cjs/escape.cjs.map +1 -0
- package/dist/cjs/escape.d.ts +33 -0
- package/dist/cjs/index.cjs +30 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.ts +17 -0
- package/dist/cjs/node_modules/pako/dist/pako.esm.cjs +4177 -0
- package/dist/cjs/node_modules/pako/dist/pako.esm.cjs.map +1 -0
- package/dist/cjs/node_modules/ts-md5/dist/esm/md5.cjs +353 -0
- package/dist/cjs/node_modules/ts-md5/dist/esm/md5.cjs.map +1 -0
- package/dist/cjs/options.d.ts +57 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/progress.cjs +313 -0
- package/dist/cjs/progress.cjs.map +1 -0
- package/dist/cjs/progress.d.ts +100 -0
- package/dist/cjs/transfer.cjs +706 -0
- package/dist/cjs/transfer.cjs.map +1 -0
- package/dist/cjs/transfer.d.ts +259 -0
- package/dist/cjs-full/buffer.d.ts +76 -0
- package/dist/cjs-full/comm.d.ts +162 -0
- package/dist/cjs-full/escape.d.ts +33 -0
- package/dist/cjs-full/index.cjs +6144 -0
- package/dist/cjs-full/index.cjs.map +1 -0
- package/dist/cjs-full/index.d.ts +17 -0
- package/dist/cjs-full/options.d.ts +57 -0
- package/dist/cjs-full/package.json +3 -0
- package/dist/cjs-full/progress.d.ts +100 -0
- package/dist/cjs-full/transfer.d.ts +259 -0
- package/dist/comm.d.ts +162 -0
- package/dist/escape.d.ts +33 -0
- package/dist/esm/buffer.d.ts +76 -0
- package/dist/esm/buffer.js +252 -0
- package/dist/esm/buffer.js.map +1 -0
- package/dist/esm/comm.d.ts +162 -0
- package/dist/esm/comm.js +292 -0
- package/dist/esm/comm.js.map +1 -0
- package/dist/esm/escape.d.ts +33 -0
- package/dist/esm/escape.js +86 -0
- package/dist/esm/escape.js.map +1 -0
- package/dist/esm/index.d.ts +17 -0
- package/dist/esm/index.js +30 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/node_modules/pako/dist/pako.esm.js +4177 -0
- package/dist/esm/node_modules/pako/dist/pako.esm.js.map +1 -0
- package/dist/esm/node_modules/ts-md5/dist/esm/md5.js +353 -0
- package/dist/esm/node_modules/ts-md5/dist/esm/md5.js.map +1 -0
- package/dist/esm/options.d.ts +57 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/progress.d.ts +100 -0
- package/dist/esm/progress.js +313 -0
- package/dist/esm/progress.js.map +1 -0
- package/dist/esm/transfer.d.ts +259 -0
- package/dist/esm/transfer.js +706 -0
- package/dist/esm/transfer.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/options.d.ts +57 -0
- package/dist/progress.d.ts +100 -0
- package/dist/transfer.d.ts +259 -0
- package/package.json +108 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
/**
|
|
4
|
+
* trzsz2: https://github.com/zxdong262/trzsz2
|
|
5
|
+
* Copyright(c) 2024 Lonny Wong
|
|
6
|
+
* @license MIT
|
|
7
|
+
*
|
|
8
|
+
* Pure protocol implementation without fs/browser dependencies.
|
|
9
|
+
*/
|
|
10
|
+
function getLength(str) {
|
|
11
|
+
return str.replace(/[\u4e00-\u9fa5]/g, "**").length;
|
|
12
|
+
}
|
|
13
|
+
function getEllipsisString(str, max) {
|
|
14
|
+
max -= 3;
|
|
15
|
+
let len = 0;
|
|
16
|
+
let sub = "";
|
|
17
|
+
for (let i = 0; i < str.length; i++) {
|
|
18
|
+
if (str.charCodeAt(i) >= 19968 && str.charCodeAt(i) <= 40869) {
|
|
19
|
+
if (len + 2 > max) {
|
|
20
|
+
return { sub: sub + "...", len: len + 3 };
|
|
21
|
+
}
|
|
22
|
+
len += 2;
|
|
23
|
+
} else {
|
|
24
|
+
if (len + 1 > max) {
|
|
25
|
+
return { sub: sub + "...", len: len + 3 };
|
|
26
|
+
}
|
|
27
|
+
len += 1;
|
|
28
|
+
}
|
|
29
|
+
sub += str[i];
|
|
30
|
+
}
|
|
31
|
+
return { sub: sub + "...", len: len + 3 };
|
|
32
|
+
}
|
|
33
|
+
function convertSizeToString(size) {
|
|
34
|
+
let unit = "B";
|
|
35
|
+
do {
|
|
36
|
+
if (size < 1024) {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
size = size / 1024;
|
|
40
|
+
unit = "KB";
|
|
41
|
+
if (size < 1024) {
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
size = size / 1024;
|
|
45
|
+
unit = "MB";
|
|
46
|
+
if (size < 1024) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
size = size / 1024;
|
|
50
|
+
unit = "GB";
|
|
51
|
+
if (size < 1024) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
size = size / 1024;
|
|
55
|
+
unit = "TB";
|
|
56
|
+
} while (false);
|
|
57
|
+
if (size >= 100) {
|
|
58
|
+
return `${size.toFixed(0)} ${unit}`;
|
|
59
|
+
} else if (size >= 10) {
|
|
60
|
+
return `${size.toFixed(1)} ${unit}`;
|
|
61
|
+
} else {
|
|
62
|
+
return `${size.toFixed(2)} ${unit}`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function convertTimeToString(seconds) {
|
|
66
|
+
let result = "";
|
|
67
|
+
if (seconds >= 3600) {
|
|
68
|
+
result += Math.floor(seconds / 3600).toString() + ":";
|
|
69
|
+
seconds %= 3600;
|
|
70
|
+
}
|
|
71
|
+
const minute = Math.floor(seconds / 60);
|
|
72
|
+
result += minute >= 10 ? minute.toString() : "0" + minute.toString();
|
|
73
|
+
result += ":";
|
|
74
|
+
const second = Math.round(seconds % 60);
|
|
75
|
+
result += second >= 10 ? second.toString() : "0" + second.toString();
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
const kSpeedArraySize = 30;
|
|
79
|
+
class TextProgressBar {
|
|
80
|
+
/**
|
|
81
|
+
* Create a TextProgressBar.
|
|
82
|
+
* @param writer - The output writer function.
|
|
83
|
+
* @param columns - The terminal columns.
|
|
84
|
+
* @param tmuxPaneColumns - The tmux pane columns (optional).
|
|
85
|
+
*/
|
|
86
|
+
constructor(writer, columns, tmuxPaneColumns = void 0) {
|
|
87
|
+
this.lastUpdateTime = 0;
|
|
88
|
+
this.fileCount = 0;
|
|
89
|
+
this.fileIdx = 0;
|
|
90
|
+
this.fileName = "";
|
|
91
|
+
this.fileSize = 0;
|
|
92
|
+
this.fileStep = 0;
|
|
93
|
+
this.startTime = 0;
|
|
94
|
+
this.firstWrite = true;
|
|
95
|
+
this.speedCnt = 0;
|
|
96
|
+
this.speedIdx = 0;
|
|
97
|
+
this.timeArray = new Array(kSpeedArraySize);
|
|
98
|
+
this.stepArray = new Array(kSpeedArraySize);
|
|
99
|
+
this.writer = writer;
|
|
100
|
+
this.tmuxPaneColumns = tmuxPaneColumns ?? 0;
|
|
101
|
+
this.columns = this.tmuxPaneColumns > 1 ? this.tmuxPaneColumns - 1 : columns;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Set the terminal columns.
|
|
105
|
+
* @param columns - The terminal columns.
|
|
106
|
+
*/
|
|
107
|
+
setTerminalColumns(columns) {
|
|
108
|
+
this.columns = columns;
|
|
109
|
+
if (this.tmuxPaneColumns > 0) {
|
|
110
|
+
this.tmuxPaneColumns = 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Called when the number of files is known.
|
|
115
|
+
* @param num - The number of files.
|
|
116
|
+
*/
|
|
117
|
+
onNum(num) {
|
|
118
|
+
this.fileCount = num;
|
|
119
|
+
this.fileIdx = 0;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Called when a file name is known.
|
|
123
|
+
* @param name - The file name.
|
|
124
|
+
*/
|
|
125
|
+
onName(name) {
|
|
126
|
+
this.fileName = name;
|
|
127
|
+
this.fileIdx += 1;
|
|
128
|
+
this.startTime = Date.now();
|
|
129
|
+
this.timeArray[0] = this.startTime;
|
|
130
|
+
this.stepArray[0] = 0;
|
|
131
|
+
this.speedCnt = 1;
|
|
132
|
+
this.speedIdx = 1;
|
|
133
|
+
this.fileStep = -1;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Called when the file size is known.
|
|
137
|
+
* @param size - The file size.
|
|
138
|
+
*/
|
|
139
|
+
onSize(size) {
|
|
140
|
+
this.fileSize = size;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Called when a step is completed.
|
|
144
|
+
* @param step - The step number.
|
|
145
|
+
*/
|
|
146
|
+
onStep(step) {
|
|
147
|
+
if (step <= this.fileStep) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.fileStep = step;
|
|
151
|
+
this.showProgress();
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Hide the cursor.
|
|
155
|
+
*/
|
|
156
|
+
hideCursor() {
|
|
157
|
+
this.writer("\x1B[?25l");
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Show the cursor.
|
|
161
|
+
*/
|
|
162
|
+
showCursor() {
|
|
163
|
+
this.writer("\x1B[?25h");
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Show the progress.
|
|
167
|
+
*/
|
|
168
|
+
showProgress() {
|
|
169
|
+
const now = Date.now();
|
|
170
|
+
if (now - this.lastUpdateTime < 200) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
this.lastUpdateTime = now;
|
|
174
|
+
let percentage = "100%";
|
|
175
|
+
if (this.fileSize !== 0) {
|
|
176
|
+
percentage = Math.round(this.fileStep * 100 / this.fileSize).toString() + "%";
|
|
177
|
+
}
|
|
178
|
+
const total = convertSizeToString(this.fileStep);
|
|
179
|
+
const speed = this.getSpeed(now);
|
|
180
|
+
let speedStr = "--- B/s";
|
|
181
|
+
let etaStr = "--- ETA";
|
|
182
|
+
if (speed > 0) {
|
|
183
|
+
speedStr = convertSizeToString(speed) + "/s";
|
|
184
|
+
etaStr = convertTimeToString(Math.round((this.fileSize - this.fileStep) / speed)) + " ETA";
|
|
185
|
+
}
|
|
186
|
+
const progressText = this.getProgressText(percentage, total, speedStr, etaStr);
|
|
187
|
+
if (this.firstWrite) {
|
|
188
|
+
this.firstWrite = false;
|
|
189
|
+
this.writer(progressText);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (this.tmuxPaneColumns > 0) {
|
|
193
|
+
this.writer(`\x1B[${this.columns}D${progressText}`);
|
|
194
|
+
} else {
|
|
195
|
+
this.writer(`\r${progressText}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get the current transfer speed.
|
|
200
|
+
* @param now - The current time.
|
|
201
|
+
* @return The speed in bytes per second.
|
|
202
|
+
*/
|
|
203
|
+
getSpeed(now) {
|
|
204
|
+
let speed;
|
|
205
|
+
if (this.speedCnt <= kSpeedArraySize) {
|
|
206
|
+
this.speedCnt++;
|
|
207
|
+
speed = (this.fileStep - this.stepArray[0]) * 1e3 / (now - this.timeArray[0]);
|
|
208
|
+
} else {
|
|
209
|
+
speed = (this.fileStep - this.stepArray[this.speedIdx]) * 1e3 / (now - this.timeArray[this.speedIdx]);
|
|
210
|
+
}
|
|
211
|
+
this.timeArray[this.speedIdx] = now;
|
|
212
|
+
this.stepArray[this.speedIdx] = this.fileStep;
|
|
213
|
+
this.speedIdx++;
|
|
214
|
+
if (this.speedIdx >= kSpeedArraySize) {
|
|
215
|
+
this.speedIdx %= kSpeedArraySize;
|
|
216
|
+
}
|
|
217
|
+
return isFinite(speed) ? speed : -1;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get the progress text.
|
|
221
|
+
* @param percentage - The percentage string.
|
|
222
|
+
* @param total - The total string.
|
|
223
|
+
* @param speed - The speed string.
|
|
224
|
+
* @param eta - The ETA string.
|
|
225
|
+
* @return The progress text.
|
|
226
|
+
*/
|
|
227
|
+
getProgressText(percentage, total, speed, eta) {
|
|
228
|
+
const barMinLength = 24;
|
|
229
|
+
let left = this.fileCount > 1 ? `(${this.fileIdx}/${this.fileCount}) ${this.fileName}` : this.fileName;
|
|
230
|
+
let leftLength = getLength(left);
|
|
231
|
+
let right = ` ${percentage} | ${total} | ${speed} | ${eta}`;
|
|
232
|
+
do {
|
|
233
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
if (leftLength > 50) {
|
|
237
|
+
({ sub: left, len: leftLength } = getEllipsisString(left, 50));
|
|
238
|
+
}
|
|
239
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
if (leftLength > 40) {
|
|
243
|
+
({ sub: left, len: leftLength } = getEllipsisString(left, 40));
|
|
244
|
+
}
|
|
245
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
right = ` ${percentage} | ${speed} | ${eta}`;
|
|
249
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
if (leftLength > 30) {
|
|
253
|
+
({ sub: left, len: leftLength } = getEllipsisString(left, 30));
|
|
254
|
+
}
|
|
255
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
right = ` ${percentage} | ${eta}`;
|
|
259
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
right = ` ${percentage}`;
|
|
263
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
if (leftLength > 20) {
|
|
267
|
+
({ sub: left, len: leftLength } = getEllipsisString(left, 20));
|
|
268
|
+
}
|
|
269
|
+
if (this.columns - leftLength - right.length >= barMinLength) {
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
left = "";
|
|
273
|
+
leftLength = 0;
|
|
274
|
+
} while (false);
|
|
275
|
+
let barLength = this.columns - right.length;
|
|
276
|
+
if (leftLength > 0) {
|
|
277
|
+
barLength -= leftLength + 1;
|
|
278
|
+
left += " ";
|
|
279
|
+
}
|
|
280
|
+
const bar = this.getProgressBar(barLength);
|
|
281
|
+
return (left + bar + right).trim();
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get the progress bar string.
|
|
285
|
+
* @param len - The length of the bar.
|
|
286
|
+
* @return The progress bar string.
|
|
287
|
+
*/
|
|
288
|
+
getProgressBar(len) {
|
|
289
|
+
if (len < 12) {
|
|
290
|
+
return "";
|
|
291
|
+
}
|
|
292
|
+
const total = len - 2;
|
|
293
|
+
let complete = total;
|
|
294
|
+
if (this.fileSize !== 0) {
|
|
295
|
+
complete = Math.round(total * this.fileStep / this.fileSize);
|
|
296
|
+
}
|
|
297
|
+
return "[\x1B[36m" + "█".repeat(complete) + "░".repeat(total - complete) + "\x1B[0m]";
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Called when the transfer is done.
|
|
301
|
+
*/
|
|
302
|
+
onDone() {
|
|
303
|
+
if (this.fileSize === 0) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
this.fileStep = this.fileSize;
|
|
307
|
+
this.lastUpdateTime = 0;
|
|
308
|
+
this.showProgress();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
exports.TextProgressBar = TextProgressBar;
|
|
312
|
+
exports.getEllipsisString = getEllipsisString;
|
|
313
|
+
//# sourceMappingURL=progress.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.cjs","sources":["../../src/progress.ts"],"sourcesContent":["/**\n * trzsz2: https://github.com/zxdong262/trzsz2\n * Copyright(c) 2024 Lonny Wong\n * @license MIT\n *\n * Pure protocol implementation without fs/browser dependencies.\n */\n\nimport type { ProgressCallback } from './comm'\n\n/**\n * Get the display length of a string (Chinese characters count as 2).\n * @param str - The input string.\n * @return The display length.\n */\nfunction getLength (str: string): number {\n return str.replace(/[\\u4e00-\\u9fa5]/g, '**').length\n}\n\n/**\n * Get ellipsis string if the string is too long.\n * @param str - The input string.\n * @param max - The maximum length.\n * @return The ellipsis string and its length.\n */\nexport function getEllipsisString (str: string, max: number): { sub: string, len: number } {\n max -= 3\n let len = 0\n let sub = ''\n for (let i = 0; i < str.length; i++) {\n if (str.charCodeAt(i) >= 0x4e00 && str.charCodeAt(i) <= 0x9fa5) {\n if (len + 2 > max) {\n return { sub: sub + '...', len: len + 3 }\n }\n len += 2\n } else {\n if (len + 1 > max) {\n return { sub: sub + '...', len: len + 3 }\n }\n len += 1\n }\n sub += str[i]\n }\n return { sub: sub + '...', len: len + 3 }\n}\n\n/**\n * Convert size to human-readable string.\n * @param size - The size in bytes.\n * @return The human-readable string.\n */\nfunction convertSizeToString (size: number): string {\n let unit = 'B'\n do {\n if (size < 1024) {\n break\n }\n size = size / 1024\n unit = 'KB'\n\n if (size < 1024) {\n break\n }\n size = size / 1024\n unit = 'MB'\n\n if (size < 1024) {\n break\n }\n size = size / 1024\n unit = 'GB'\n\n if (size < 1024) {\n break\n }\n size = size / 1024\n unit = 'TB'\n } while (false)\n\n if (size >= 100) {\n return `${size.toFixed(0)} ${unit}`\n } else if (size >= 10) {\n return `${size.toFixed(1)} ${unit}`\n } else {\n return `${size.toFixed(2)} ${unit}`\n }\n}\n\n/**\n * Convert time to human-readable string.\n * @param seconds - The time in seconds.\n * @return The human-readable string.\n */\nfunction convertTimeToString (seconds: number): string {\n let result = ''\n if (seconds >= 3600) {\n result += Math.floor(seconds / 3600).toString() + ':'\n seconds %= 3600\n }\n\n const minute = Math.floor(seconds / 60)\n result += minute >= 10 ? minute.toString() : '0' + minute.toString()\n result += ':'\n\n const second = Math.round(seconds % 60)\n result += second >= 10 ? second.toString() : '0' + second.toString()\n\n return result\n}\n\nconst kSpeedArraySize: number = 30\n\n/**\n * TextProgressBar class for displaying file transfer progress.\n */\nexport class TextProgressBar implements ProgressCallback {\n private readonly writer: (output: string) => void\n private lastUpdateTime: number = 0\n private columns: number\n private fileCount: number = 0\n private fileIdx: number = 0\n private fileName: string = ''\n private fileSize: number = 0\n private fileStep: number = 0\n private startTime: number = 0\n private tmuxPaneColumns: number\n private firstWrite: boolean = true\n private speedCnt: number = 0\n private speedIdx: number = 0\n private timeArray: number[] = new Array(kSpeedArraySize)\n private stepArray: number[] = new Array(kSpeedArraySize)\n\n /**\n * Create a TextProgressBar.\n * @param writer - The output writer function.\n * @param columns - The terminal columns.\n * @param tmuxPaneColumns - The tmux pane columns (optional).\n */\n public constructor (\n writer: (output: string) => void,\n columns: number,\n tmuxPaneColumns: number | undefined = undefined\n ) {\n this.writer = writer\n this.tmuxPaneColumns = tmuxPaneColumns ?? 0\n // -1 to avoid xterm.js messing up the tmux pane\n this.columns = this.tmuxPaneColumns > 1 ? this.tmuxPaneColumns - 1 : columns\n }\n\n /**\n * Set the terminal columns.\n * @param columns - The terminal columns.\n */\n public setTerminalColumns (columns: number): void {\n this.columns = columns\n // resizing tmux panes is not supported\n if (this.tmuxPaneColumns > 0) {\n this.tmuxPaneColumns = 0\n }\n }\n\n /**\n * Called when the number of files is known.\n * @param num - The number of files.\n */\n public onNum (num: number): void {\n this.fileCount = num\n this.fileIdx = 0\n }\n\n /**\n * Called when a file name is known.\n * @param name - The file name.\n */\n public onName (name: string): void {\n this.fileName = name\n this.fileIdx += 1\n this.startTime = Date.now()\n this.timeArray[0] = this.startTime\n this.stepArray[0] = 0\n this.speedCnt = 1\n this.speedIdx = 1\n this.fileStep = -1\n }\n\n /**\n * Called when the file size is known.\n * @param size - The file size.\n */\n public onSize (size: number): void {\n this.fileSize = size\n }\n\n /**\n * Called when a step is completed.\n * @param step - The step number.\n */\n public onStep (step: number): void {\n if (step <= this.fileStep) {\n return\n }\n this.fileStep = step\n this.showProgress()\n }\n\n /**\n * Hide the cursor.\n */\n public hideCursor (): void {\n this.writer('\\x1b[?25l')\n }\n\n /**\n * Show the cursor.\n */\n public showCursor (): void {\n this.writer('\\x1b[?25h')\n }\n\n /**\n * Show the progress.\n */\n private showProgress (): void {\n const now = Date.now()\n if (now - this.lastUpdateTime < 200) {\n return\n }\n this.lastUpdateTime = now\n\n let percentage = '100%'\n if (this.fileSize !== 0) {\n percentage = Math.round((this.fileStep * 100) / this.fileSize).toString() + '%'\n }\n const total = convertSizeToString(this.fileStep)\n const speed = this.getSpeed(now)\n let speedStr = '--- B/s'\n let etaStr = '--- ETA'\n if (speed > 0) {\n speedStr = convertSizeToString(speed) + '/s'\n etaStr = convertTimeToString(Math.round((this.fileSize - this.fileStep) / speed)) + ' ETA'\n }\n\n const progressText = this.getProgressText(percentage, total, speedStr, etaStr)\n\n if (this.firstWrite) {\n this.firstWrite = false\n this.writer(progressText)\n return\n }\n\n if (this.tmuxPaneColumns > 0) {\n this.writer(`\\x1b[${this.columns}D${progressText}`)\n } else {\n this.writer(`\\r${progressText}`)\n }\n }\n\n /**\n * Get the current transfer speed.\n * @param now - The current time.\n * @return The speed in bytes per second.\n */\n private getSpeed (now: number): number {\n let speed: number\n if (this.speedCnt <= kSpeedArraySize) {\n this.speedCnt++\n speed = ((this.fileStep - this.stepArray[0]) * 1000) / (now - this.timeArray[0])\n } else {\n speed =\n ((this.fileStep - this.stepArray[this.speedIdx]) * 1000) /\n (now - this.timeArray[this.speedIdx])\n }\n\n this.timeArray[this.speedIdx] = now\n this.stepArray[this.speedIdx] = this.fileStep\n\n this.speedIdx++\n if (this.speedIdx >= kSpeedArraySize) {\n this.speedIdx %= kSpeedArraySize\n }\n\n return isFinite(speed) ? speed : -1\n }\n\n /**\n * Get the progress text.\n * @param percentage - The percentage string.\n * @param total - The total string.\n * @param speed - The speed string.\n * @param eta - The ETA string.\n * @return The progress text.\n */\n private getProgressText (\n percentage: string,\n total: string,\n speed: string,\n eta: string\n ): string {\n const barMinLength = 24\n let left =\n this.fileCount > 1 ? `(${this.fileIdx}/${this.fileCount}) ${this.fileName}` : this.fileName\n let leftLength = getLength(left)\n let right = ` ${percentage} | ${total} | ${speed} | ${eta}`\n\n do {\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n if (leftLength > 50) {\n ;({ sub: left, len: leftLength } = getEllipsisString(left, 50))\n }\n\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n if (leftLength > 40) {\n ;({ sub: left, len: leftLength } = getEllipsisString(left, 40))\n }\n\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n right = ` ${percentage} | ${speed} | ${eta}`\n\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n if (leftLength > 30) {\n ;({ sub: left, len: leftLength } = getEllipsisString(left, 30))\n }\n\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n right = ` ${percentage} | ${eta}`\n\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n right = ` ${percentage}`\n\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n if (leftLength > 20) {\n ;({ sub: left, len: leftLength } = getEllipsisString(left, 20))\n }\n\n if (this.columns - leftLength - right.length >= barMinLength) {\n break\n }\n left = ''\n leftLength = 0\n } while (false)\n\n let barLength = this.columns - right.length\n if (leftLength > 0) {\n barLength -= leftLength + 1\n left += ' '\n }\n\n const bar = this.getProgressBar(barLength)\n return (left + bar + right).trim()\n }\n\n /**\n * Get the progress bar string.\n * @param len - The length of the bar.\n * @return The progress bar string.\n */\n private getProgressBar (len: number): string {\n if (len < 12) {\n return ''\n }\n const total = len - 2\n let complete = total\n if (this.fileSize !== 0) {\n complete = Math.round((total * this.fileStep) / this.fileSize)\n }\n return '[\\u001b[36m' + '\\u2588'.repeat(complete) + '\\u2591'.repeat(total - complete) + '\\u001b[0m]'\n }\n\n /**\n * Called when the transfer is done.\n */\n public onDone (): void {\n if (this.fileSize === 0) {\n return\n }\n this.fileStep = this.fileSize\n this.lastUpdateTime = 0\n this.showProgress()\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ProgressCallback } from './comm';
|
|
2
|
+
/**
|
|
3
|
+
* Get ellipsis string if the string is too long.
|
|
4
|
+
* @param str - The input string.
|
|
5
|
+
* @param max - The maximum length.
|
|
6
|
+
* @return The ellipsis string and its length.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getEllipsisString(str: string, max: number): {
|
|
9
|
+
sub: string;
|
|
10
|
+
len: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* TextProgressBar class for displaying file transfer progress.
|
|
14
|
+
*/
|
|
15
|
+
export declare class TextProgressBar implements ProgressCallback {
|
|
16
|
+
private readonly writer;
|
|
17
|
+
private lastUpdateTime;
|
|
18
|
+
private columns;
|
|
19
|
+
private fileCount;
|
|
20
|
+
private fileIdx;
|
|
21
|
+
private fileName;
|
|
22
|
+
private fileSize;
|
|
23
|
+
private fileStep;
|
|
24
|
+
private startTime;
|
|
25
|
+
private tmuxPaneColumns;
|
|
26
|
+
private firstWrite;
|
|
27
|
+
private speedCnt;
|
|
28
|
+
private speedIdx;
|
|
29
|
+
private timeArray;
|
|
30
|
+
private stepArray;
|
|
31
|
+
/**
|
|
32
|
+
* Create a TextProgressBar.
|
|
33
|
+
* @param writer - The output writer function.
|
|
34
|
+
* @param columns - The terminal columns.
|
|
35
|
+
* @param tmuxPaneColumns - The tmux pane columns (optional).
|
|
36
|
+
*/
|
|
37
|
+
constructor(writer: (output: string) => void, columns: number, tmuxPaneColumns?: number | undefined);
|
|
38
|
+
/**
|
|
39
|
+
* Set the terminal columns.
|
|
40
|
+
* @param columns - The terminal columns.
|
|
41
|
+
*/
|
|
42
|
+
setTerminalColumns(columns: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Called when the number of files is known.
|
|
45
|
+
* @param num - The number of files.
|
|
46
|
+
*/
|
|
47
|
+
onNum(num: number): void;
|
|
48
|
+
/**
|
|
49
|
+
* Called when a file name is known.
|
|
50
|
+
* @param name - The file name.
|
|
51
|
+
*/
|
|
52
|
+
onName(name: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Called when the file size is known.
|
|
55
|
+
* @param size - The file size.
|
|
56
|
+
*/
|
|
57
|
+
onSize(size: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Called when a step is completed.
|
|
60
|
+
* @param step - The step number.
|
|
61
|
+
*/
|
|
62
|
+
onStep(step: number): void;
|
|
63
|
+
/**
|
|
64
|
+
* Hide the cursor.
|
|
65
|
+
*/
|
|
66
|
+
hideCursor(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Show the cursor.
|
|
69
|
+
*/
|
|
70
|
+
showCursor(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Show the progress.
|
|
73
|
+
*/
|
|
74
|
+
private showProgress;
|
|
75
|
+
/**
|
|
76
|
+
* Get the current transfer speed.
|
|
77
|
+
* @param now - The current time.
|
|
78
|
+
* @return The speed in bytes per second.
|
|
79
|
+
*/
|
|
80
|
+
private getSpeed;
|
|
81
|
+
/**
|
|
82
|
+
* Get the progress text.
|
|
83
|
+
* @param percentage - The percentage string.
|
|
84
|
+
* @param total - The total string.
|
|
85
|
+
* @param speed - The speed string.
|
|
86
|
+
* @param eta - The ETA string.
|
|
87
|
+
* @return The progress text.
|
|
88
|
+
*/
|
|
89
|
+
private getProgressText;
|
|
90
|
+
/**
|
|
91
|
+
* Get the progress bar string.
|
|
92
|
+
* @param len - The length of the bar.
|
|
93
|
+
* @return The progress bar string.
|
|
94
|
+
*/
|
|
95
|
+
private getProgressBar;
|
|
96
|
+
/**
|
|
97
|
+
* Called when the transfer is done.
|
|
98
|
+
*/
|
|
99
|
+
onDone(): void;
|
|
100
|
+
}
|