@flowscripter/dynamic-cli-framework 7.0.5 → 7.0.7
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/dist/src/cli/BaseCLI.d.ts +3 -0
- package/dist/src/cli/BaseCLI.d.ts.map +1 -1
- package/dist/src/cli/BaseCLI.js +6 -1
- package/dist/src/service/printer/terminal/Progress.d.ts.map +1 -1
- package/dist/src/service/printer/terminal/Progress.js +19 -12
- package/package.json +2 -2
- package/src/cli/BaseCLI.ts +6 -1
- package/src/service/printer/terminal/Progress.ts +24 -14
|
@@ -31,6 +31,9 @@ import type BaseCLIFeatureOptions from "./BaseCLIFeatureOptions.ts";
|
|
|
31
31
|
* * {@link UpgradeServiceProvider}
|
|
32
32
|
* * {@link PluginServiceProvider}
|
|
33
33
|
*
|
|
34
|
+
* Enabling the plugin service also registers {@link SpawnServiceProvider}, as plugin installation
|
|
35
|
+
* spawns the package manager via the spawn service.
|
|
36
|
+
*
|
|
34
37
|
* `keyReader` is optional. If omitted, or if the stderr {@link Terminal} is not a TTY, prompting is
|
|
35
38
|
* unavailable: {@link PrompterServiceProvider} (and {@link ArgumentPrompterServiceProvider}, if
|
|
36
39
|
* enabled) are simply not registered. If `promptingEnabled` is `true` in that situation, {@link run}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsBzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAS3E,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AAkBpE
|
|
1
|
+
{"version":3,"file":"BaseCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsBzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAS3E,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AAkBpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,YAAW,GAAG;;IAazC,YACE,SAAS,EAAE,SAAS,EACpB,oBAAoB,EAAE,cAAc,EACpC,oBAAoB,EAAE,cAAc,EACpC,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,OAAO,EACtB,cAAc,EAAE,QAAQ,EACxB,cAAc,EAAE,QAAQ,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,OAAO,CAAC,EAAE,qBAAqB,EAoEhC;IAED;;;;;;;OAOG;IACI,kBAAkB,CAAC,eAAe,EAAE,eAAe,QAEzD;IAED;;;;;;;;OAQG;IACH;;;;;OAKG;IACI,cAAc,CAAC,IAAI,EAAE,WAAW,QAEtC;IAEM,UAAU,CAAC,OAAO,EAAE,OAAO,QAQjC;IAEK,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAwOzD;CACF"}
|
package/dist/src/cli/BaseCLI.js
CHANGED
|
@@ -54,6 +54,9 @@ const logger = getLogger("BaseCLI");
|
|
|
54
54
|
* * {@link UpgradeServiceProvider}
|
|
55
55
|
* * {@link PluginServiceProvider}
|
|
56
56
|
*
|
|
57
|
+
* Enabling the plugin service also registers {@link SpawnServiceProvider}, as plugin installation
|
|
58
|
+
* spawns the package manager via the spawn service.
|
|
59
|
+
*
|
|
57
60
|
* `keyReader` is optional. If omitted, or if the stderr {@link Terminal} is not a TTY, prompting is
|
|
58
61
|
* unavailable: {@link PrompterServiceProvider} (and {@link ArgumentPrompterServiceProvider}, if
|
|
59
62
|
* enabled) are simply not registered. If `promptingEnabled` is `true` in that situation, {@link run}
|
|
@@ -213,7 +216,9 @@ export default class BaseCLI {
|
|
|
213
216
|
logger.debug("Skipping ImagePrinterServiceProvider: imagePrinterServiceEnabled is true but stdout is not a TTY");
|
|
214
217
|
}
|
|
215
218
|
}
|
|
216
|
-
|
|
219
|
+
// The plugin service routes package manager output through SpawnService so that it is
|
|
220
|
+
// quoted, marked and cleared on success; enabling plugins therefore also enables spawning.
|
|
221
|
+
if (this.#options.spawnServiceEnabled || this.#options.pluginServiceEnabled) {
|
|
217
222
|
this.addServiceProvider(new SpawnServiceProvider(58));
|
|
218
223
|
}
|
|
219
224
|
if (this.#options.fetchServiceEnabled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAe1D,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAoBxE,MAAM,CAAC,OAAO,OAAO,QAAQ;;IAe3B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAEM,GAAG,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACjC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACnC,MAAM,CAgCR;IA6BM,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAyBrE;IAEY,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe/C;IAEY,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAKpC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBlC;IAEM,MAAM,IAAI,IAAI,CAapB;IAkID,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,EAE9B;IAED,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,EAE/B;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,IAAI,aAAa,CAAC,KAAK,EAAE,aAAa,EAErC;CAmDF"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// Weight given to each new rate sample in the exponential moving average - time constant is
|
|
2
|
-
// roughly 1/RATE_SMOOTHING_FACTOR *
|
|
2
|
+
// roughly 1/RATE_SMOOTHING_FACTOR * RATE_SAMPLE_INTERVAL_MILLIS.
|
|
3
3
|
const RATE_SMOOTHING_FACTOR = 0.3;
|
|
4
|
+
// Minimum time between rate samples. Updates arriving more often than this only advance the
|
|
5
|
+
// current value; the next sample then measures the total progress made across the whole window,
|
|
6
|
+
// so rapid, fine-grained or coarsely stepped updates still yield an accurate rate.
|
|
7
|
+
const RATE_SAMPLE_INTERVAL_MILLIS = 100;
|
|
4
8
|
// A rate this close to zero (units/s) produces a meaningless (and, past a certain point,
|
|
5
9
|
// non-finite) "time remaining" estimate - treat it the same as no rate at all.
|
|
6
10
|
const MAX_REMAINING_MILLIS = 999 * 24 * 60 * 60 * 1000;
|
|
@@ -38,13 +42,16 @@ export default class Progress {
|
|
|
38
42
|
if (current > total) {
|
|
39
43
|
current = total;
|
|
40
44
|
}
|
|
45
|
+
const now = Date.now();
|
|
41
46
|
this.#bars.set(this.#bars.size + 1, {
|
|
42
47
|
name: message,
|
|
43
48
|
current,
|
|
44
49
|
total,
|
|
45
50
|
format,
|
|
46
51
|
formatRate,
|
|
47
|
-
|
|
52
|
+
sampleMillis: now,
|
|
53
|
+
sampleCurrent: current,
|
|
54
|
+
startMillis: now,
|
|
48
55
|
});
|
|
49
56
|
// force render on next timeout
|
|
50
57
|
this.#isDirty = true;
|
|
@@ -67,17 +74,17 @@ export default class Progress {
|
|
|
67
74
|
}
|
|
68
75
|
#updateRate(bar, current) {
|
|
69
76
|
const now = Date.now();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
else {
|
|
74
|
-
let currentRate = ((current - bar.current) * 1000) / (now - bar.lastMillis);
|
|
75
|
-
if (!isFinite(currentRate)) {
|
|
76
|
-
currentRate = 0;
|
|
77
|
-
}
|
|
78
|
-
bar.rate = currentRate * RATE_SMOOTHING_FACTOR + bar.rate * (1 - RATE_SMOOTHING_FACTOR);
|
|
77
|
+
const elapsed = now - bar.sampleMillis;
|
|
78
|
+
if (elapsed < RATE_SAMPLE_INTERVAL_MILLIS) {
|
|
79
|
+
return;
|
|
79
80
|
}
|
|
80
|
-
bar.
|
|
81
|
+
const sampleRate = ((current - bar.sampleCurrent) * 1000) / elapsed;
|
|
82
|
+
bar.rate =
|
|
83
|
+
bar.rate === undefined
|
|
84
|
+
? sampleRate
|
|
85
|
+
: sampleRate * RATE_SMOOTHING_FACTOR + bar.rate * (1 - RATE_SMOOTHING_FACTOR);
|
|
86
|
+
bar.sampleMillis = now;
|
|
87
|
+
bar.sampleCurrent = current;
|
|
81
88
|
}
|
|
82
89
|
update(handle, current, message) {
|
|
83
90
|
if (!this.#bars.has(handle)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowscripter/dynamic-cli-framework",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.7",
|
|
4
4
|
"description": "A framework for developing CLI applications which supports dynamic discovery and installation of new commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@flowscripter/dynamic-cli-framework-api": "^4.0.4",
|
|
52
|
-
"@flowscripter/dynamic-plugin-framework": "^2.2.
|
|
52
|
+
"@flowscripter/dynamic-plugin-framework": "^2.2.14",
|
|
53
53
|
"emphasize": "^7.0.0",
|
|
54
54
|
"fastest-levenshtein": "^1.0.16",
|
|
55
55
|
"figlet": "^1.12.0",
|
package/src/cli/BaseCLI.ts
CHANGED
|
@@ -84,6 +84,9 @@ const logger = getLogger("BaseCLI");
|
|
|
84
84
|
* * {@link UpgradeServiceProvider}
|
|
85
85
|
* * {@link PluginServiceProvider}
|
|
86
86
|
*
|
|
87
|
+
* Enabling the plugin service also registers {@link SpawnServiceProvider}, as plugin installation
|
|
88
|
+
* spawns the package manager via the spawn service.
|
|
89
|
+
*
|
|
87
90
|
* `keyReader` is optional. If omitted, or if the stderr {@link Terminal} is not a TTY, prompting is
|
|
88
91
|
* unavailable: {@link PrompterServiceProvider} (and {@link ArgumentPrompterServiceProvider}, if
|
|
89
92
|
* enabled) are simply not registered. If `promptingEnabled` is `true` in that situation, {@link run}
|
|
@@ -299,7 +302,9 @@ export default class BaseCLI implements CLI {
|
|
|
299
302
|
}
|
|
300
303
|
}
|
|
301
304
|
|
|
302
|
-
|
|
305
|
+
// The plugin service routes package manager output through SpawnService so that it is
|
|
306
|
+
// quoted, marked and cleared on success; enabling plugins therefore also enables spawning.
|
|
307
|
+
if (this.#options.spawnServiceEnabled || this.#options.pluginServiceEnabled) {
|
|
303
308
|
this.addServiceProvider(new SpawnServiceProvider(58));
|
|
304
309
|
}
|
|
305
310
|
|
|
@@ -2,9 +2,14 @@ import type Styler from "../../../terminal/Styler.ts";
|
|
|
2
2
|
import type Terminal from "../../../terminal/Terminal.ts";
|
|
3
3
|
|
|
4
4
|
// Weight given to each new rate sample in the exponential moving average - time constant is
|
|
5
|
-
// roughly 1/RATE_SMOOTHING_FACTOR *
|
|
5
|
+
// roughly 1/RATE_SMOOTHING_FACTOR * RATE_SAMPLE_INTERVAL_MILLIS.
|
|
6
6
|
const RATE_SMOOTHING_FACTOR = 0.3;
|
|
7
7
|
|
|
8
|
+
// Minimum time between rate samples. Updates arriving more often than this only advance the
|
|
9
|
+
// current value; the next sample then measures the total progress made across the whole window,
|
|
10
|
+
// so rapid, fine-grained or coarsely stepped updates still yield an accurate rate.
|
|
11
|
+
const RATE_SAMPLE_INTERVAL_MILLIS = 100;
|
|
12
|
+
|
|
8
13
|
// A rate this close to zero (units/s) produces a meaningless (and, past a certain point,
|
|
9
14
|
// non-finite) "time remaining" estimate - treat it the same as no rate at all.
|
|
10
15
|
const MAX_REMAINING_MILLIS = 999 * 24 * 60 * 60 * 1000;
|
|
@@ -23,8 +28,9 @@ interface Bar {
|
|
|
23
28
|
total: number;
|
|
24
29
|
format: (value: number) => string;
|
|
25
30
|
formatRate: (rate: number) => string;
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
sampleMillis: number;
|
|
32
|
+
sampleCurrent: number;
|
|
33
|
+
startMillis: number;
|
|
28
34
|
endMillis?: number;
|
|
29
35
|
rate?: number;
|
|
30
36
|
}
|
|
@@ -66,13 +72,16 @@ export default class Progress {
|
|
|
66
72
|
current = total;
|
|
67
73
|
}
|
|
68
74
|
|
|
75
|
+
const now = Date.now();
|
|
69
76
|
this.#bars.set(this.#bars.size + 1, {
|
|
70
77
|
name: message,
|
|
71
78
|
current,
|
|
72
79
|
total,
|
|
73
80
|
format,
|
|
74
81
|
formatRate,
|
|
75
|
-
|
|
82
|
+
sampleMillis: now,
|
|
83
|
+
sampleCurrent: current,
|
|
84
|
+
startMillis: now,
|
|
76
85
|
});
|
|
77
86
|
|
|
78
87
|
// force render on next timeout
|
|
@@ -100,16 +109,17 @@ export default class Progress {
|
|
|
100
109
|
|
|
101
110
|
#updateRate(bar: Bar, current: number): void {
|
|
102
111
|
const now = Date.now();
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
let currentRate = ((current - bar.current) * 1000) / (now - bar.lastMillis!);
|
|
107
|
-
if (!isFinite(currentRate)) {
|
|
108
|
-
currentRate = 0;
|
|
109
|
-
}
|
|
110
|
-
bar.rate = currentRate * RATE_SMOOTHING_FACTOR + bar.rate! * (1 - RATE_SMOOTHING_FACTOR);
|
|
112
|
+
const elapsed = now - bar.sampleMillis;
|
|
113
|
+
if (elapsed < RATE_SAMPLE_INTERVAL_MILLIS) {
|
|
114
|
+
return;
|
|
111
115
|
}
|
|
112
|
-
bar.
|
|
116
|
+
const sampleRate = ((current - bar.sampleCurrent) * 1000) / elapsed;
|
|
117
|
+
bar.rate =
|
|
118
|
+
bar.rate === undefined
|
|
119
|
+
? sampleRate
|
|
120
|
+
: sampleRate * RATE_SMOOTHING_FACTOR + bar.rate * (1 - RATE_SMOOTHING_FACTOR);
|
|
121
|
+
bar.sampleMillis = now;
|
|
122
|
+
bar.sampleCurrent = current;
|
|
113
123
|
}
|
|
114
124
|
|
|
115
125
|
public update(handle: number, current: number, message?: string): void {
|
|
@@ -244,7 +254,7 @@ export default class Progress {
|
|
|
244
254
|
|
|
245
255
|
let suffix = `${this.#styler.colorText("]", this.#labColor)} ${percent} `;
|
|
246
256
|
if (bar.current === bar.total) {
|
|
247
|
-
const taken = this.#formatTime(bar.endMillis! - bar.startMillis
|
|
257
|
+
const taken = this.#formatTime(bar.endMillis! - bar.startMillis);
|
|
248
258
|
const totalText = bar.format(bar.total);
|
|
249
259
|
suffix += `${this.#styler.colorText(totalText, this.#valColor)}${this.#styler.colorText(
|
|
250
260
|
", rate:",
|