@flowscripter/dynamic-cli-framework 5.4.10 → 5.4.12

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.
@@ -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;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAkBxE,MAAM,CAAC,OAAO,OAAO,QAAQ;;IAe3B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAEM,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA4BjF;IA4BM,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;IA0JD,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
+ {"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;AAU1D,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAkBxE,MAAM,CAAC,OAAO,OAAO,QAAQ;;IAe3B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAEM,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA4BjF;IA4BM,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;IAgKD,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,9 @@
1
1
  // Weight given to each new rate sample in the exponential moving average - time constant is
2
2
  // roughly 1/RATE_SMOOTHING_FACTOR * 100ms (the render interval).
3
3
  const RATE_SMOOTHING_FACTOR = 0.3;
4
+ // A rate this close to zero (units/s) produces a meaningless (and, past a certain point,
5
+ // non-finite) "time remaining" estimate - treat it the same as no rate at all.
6
+ const MAX_REMAINING_MILLIS = 999 * 24 * 60 * 60 * 1000;
4
7
  export { ProgressStyle } from "@flowscripter/dynamic-cli-framework-api";
5
8
  import { ProgressStyle } from "@flowscripter/dynamic-cli-framework-api";
6
9
  const STYLE_CHARS = {
@@ -187,9 +190,14 @@ export default class Progress {
187
190
  Bun.stripANSI(taken).length;
188
191
  }
189
192
  else {
190
- const remaining = bar.rate === undefined || bar.rate === 0
193
+ const remainingMillis = bar.rate === undefined || bar.rate === 0
194
+ ? undefined
195
+ : ((bar.total - bar.current) / bar.rate) * 1000;
196
+ const remaining = remainingMillis === undefined ||
197
+ !Number.isFinite(remainingMillis) ||
198
+ remainingMillis > MAX_REMAINING_MILLIS
191
199
  ? "-"
192
- : this.#formatTime(((bar.total - bar.current) / bar.rate) * 1000);
200
+ : this.#formatTime(remainingMillis);
193
201
  const currentString = bar.current + "";
194
202
  const totalString = bar.total + "";
195
203
  suffix += `${this.#styler.colorText(currentString, this.#valColor)}${this.#styler.colorText("/", this.#labColor)}${this.#styler.colorText(totalString, this.#valColor)}${this.#styler.colorText(bar.units + ", rate:", this.#labColor)} ${rate}${this.#styler.colorText(bar.units + "/s, time remaining:", this.#labColor)} ${remaining}`;
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAM1D,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAEvE,MAAM,CAAC,OAAO,OAAO,OAAO;;IAY1B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAuCY,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASjD;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAajC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAUlC;IAEM,MAAM,IAAI,IAAI,CAKpB;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,YAAY,EAEnC;CACF"}
1
+ {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAQ1D,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAEvE,MAAM,CAAC,OAAO,OAAO,OAAO;;IAc1B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAoDY,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASjD;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBjC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAelC;IAEM,MAAM,IAAI,IAAI,CASpB;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,YAAY,EAEnC;CACF"}
@@ -1,12 +1,15 @@
1
1
  const BOX_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
2
2
  const STAR_FRAMES = ["★", "✶", "✷", "✹", "✷", "✶", "★", "✦"];
3
+ const SHOW_DELAY_MILLIS = 100;
3
4
  export { SpinnerStyle } from "@flowscripter/dynamic-cli-framework-api";
4
5
  import { SpinnerStyle } from "@flowscripter/dynamic-cli-framework-api";
5
6
  export default class Spinner {
6
7
  #isShown = false;
8
+ #isRendering = false;
7
9
  #message;
8
10
  #frameIndex = 0;
9
11
  #timer;
12
+ #showDelayTimer;
10
13
  #renderInFlight;
11
14
  #spinColor = 0x8a8a8a;
12
15
  #msgColor = 0x808080;
@@ -45,6 +48,17 @@ export default class Spinner {
45
48
  });
46
49
  }, 100);
47
50
  }
51
+ async #beginRendering() {
52
+ this.#isRendering = true;
53
+ this.#startTimer();
54
+ await this.#terminal.hideCursor();
55
+ }
56
+ #scheduleShow() {
57
+ this.#showDelayTimer = setTimeout(() => {
58
+ this.#showDelayTimer = undefined;
59
+ void this.#beginRendering();
60
+ }, SHOW_DELAY_MILLIS);
61
+ }
48
62
  async show(message) {
49
63
  this.#message = message;
50
64
  if (this.#isShown) {
@@ -52,14 +66,21 @@ export default class Spinner {
52
66
  }
53
67
  this.#isShown = true;
54
68
  this.#frameIndex = 0;
55
- this.#startTimer();
56
- await this.#terminal.hideCursor();
69
+ this.#scheduleShow();
70
+ return Promise.resolve();
57
71
  }
58
72
  async hide() {
59
73
  if (!this.#isShown) {
60
74
  return Promise.resolve();
61
75
  }
62
76
  this.#isShown = false;
77
+ this.#message = undefined;
78
+ if (this.#showDelayTimer) {
79
+ clearTimeout(this.#showDelayTimer);
80
+ this.#showDelayTimer = undefined;
81
+ return;
82
+ }
83
+ this.#isRendering = false;
63
84
  clearInterval(this.#timer);
64
85
  this.#timer = undefined;
65
86
  if (this.#renderInFlight) {
@@ -67,12 +88,16 @@ export default class Spinner {
67
88
  }
68
89
  await this.#terminal.clearLine();
69
90
  await this.#terminal.showCursor();
70
- this.#message = undefined;
71
91
  }
72
92
  async pause() {
73
93
  if (!this.#isShown) {
74
94
  return Promise.resolve();
75
95
  }
96
+ if (this.#showDelayTimer) {
97
+ clearTimeout(this.#showDelayTimer);
98
+ this.#showDelayTimer = undefined;
99
+ return;
100
+ }
76
101
  clearInterval(this.#timer);
77
102
  this.#timer = undefined;
78
103
  if (this.#renderInFlight) {
@@ -81,10 +106,15 @@ export default class Spinner {
81
106
  await this.#terminal.clearLine();
82
107
  }
83
108
  resume() {
84
- if (!this.#isShown || this.#timer !== undefined) {
109
+ if (!this.#isShown || this.#timer !== undefined || this.#showDelayTimer !== undefined) {
85
110
  return;
86
111
  }
87
- this.#startTimer();
112
+ if (this.#isRendering) {
113
+ this.#startTimer();
114
+ }
115
+ else {
116
+ this.#scheduleShow();
117
+ }
88
118
  }
89
119
  set spinnerColor(color) {
90
120
  this.#spinColor = color;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowscripter/dynamic-cli-framework",
3
- "version": "5.4.10",
3
+ "version": "5.4.12",
4
4
  "description": "A framework for developing CLI applications which supports dynamic discovery and installation of new commands",
5
5
  "keywords": [
6
6
  "bun",
@@ -5,6 +5,10 @@ import type Terminal from "../../../terminal/Terminal.ts";
5
5
  // roughly 1/RATE_SMOOTHING_FACTOR * 100ms (the render interval).
6
6
  const RATE_SMOOTHING_FACTOR = 0.3;
7
7
 
8
+ // A rate this close to zero (units/s) produces a meaningless (and, past a certain point,
9
+ // non-finite) "time remaining" estimate - treat it the same as no rate at all.
10
+ const MAX_REMAINING_MILLIS = 999 * 24 * 60 * 60 * 1000;
11
+
8
12
  export { ProgressStyle } from "@flowscripter/dynamic-cli-framework-api";
9
13
  import { ProgressStyle } from "@flowscripter/dynamic-cli-framework-api";
10
14
 
@@ -255,10 +259,16 @@ export default class Progress {
255
259
  1 +
256
260
  Bun.stripANSI(taken).length;
257
261
  } else {
258
- const remaining =
262
+ const remainingMillis =
259
263
  bar.rate === undefined || bar.rate === 0
264
+ ? undefined
265
+ : ((bar.total - bar.current) / bar.rate) * 1000;
266
+ const remaining =
267
+ remainingMillis === undefined ||
268
+ !Number.isFinite(remainingMillis) ||
269
+ remainingMillis > MAX_REMAINING_MILLIS
260
270
  ? "-"
261
- : this.#formatTime(((bar.total - bar.current) / bar.rate) * 1000);
271
+ : this.#formatTime(remainingMillis);
262
272
  const currentString = bar.current + "";
263
273
  const totalString = bar.total + "";
264
274
  suffix += `${this.#styler.colorText(currentString, this.#valColor)}${this.#styler.colorText(
@@ -5,14 +5,18 @@ const BOX_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇
5
5
 
6
6
  const STAR_FRAMES = ["★", "✶", "✷", "✹", "✷", "✶", "★", "✦"];
7
7
 
8
+ const SHOW_DELAY_MILLIS = 100;
9
+
8
10
  export { SpinnerStyle } from "@flowscripter/dynamic-cli-framework-api";
9
11
  import { SpinnerStyle } from "@flowscripter/dynamic-cli-framework-api";
10
12
 
11
13
  export default class Spinner {
12
14
  #isShown = false;
15
+ #isRendering = false;
13
16
  #message: string | undefined;
14
17
  #frameIndex = 0;
15
18
  #timer: Timer | undefined;
19
+ #showDelayTimer: Timer | undefined;
16
20
  #renderInFlight: Promise<void> | undefined;
17
21
  #spinColor = 0x8a8a8a;
18
22
  #msgColor = 0x808080;
@@ -62,6 +66,19 @@ export default class Spinner {
62
66
  }, 100);
63
67
  }
64
68
 
69
+ async #beginRendering(): Promise<void> {
70
+ this.#isRendering = true;
71
+ this.#startTimer();
72
+ await this.#terminal.hideCursor();
73
+ }
74
+
75
+ #scheduleShow(): void {
76
+ this.#showDelayTimer = setTimeout(() => {
77
+ this.#showDelayTimer = undefined;
78
+ void this.#beginRendering();
79
+ }, SHOW_DELAY_MILLIS);
80
+ }
81
+
65
82
  public async show(message?: string): Promise<void> {
66
83
  this.#message = message;
67
84
  if (this.#isShown) {
@@ -69,8 +86,8 @@ export default class Spinner {
69
86
  }
70
87
  this.#isShown = true;
71
88
  this.#frameIndex = 0;
72
- this.#startTimer();
73
- await this.#terminal.hideCursor();
89
+ this.#scheduleShow();
90
+ return Promise.resolve();
74
91
  }
75
92
 
76
93
  public async hide(): Promise<void> {
@@ -78,6 +95,13 @@ export default class Spinner {
78
95
  return Promise.resolve();
79
96
  }
80
97
  this.#isShown = false;
98
+ this.#message = undefined;
99
+ if (this.#showDelayTimer) {
100
+ clearTimeout(this.#showDelayTimer);
101
+ this.#showDelayTimer = undefined;
102
+ return;
103
+ }
104
+ this.#isRendering = false;
81
105
  clearInterval(this.#timer);
82
106
  this.#timer = undefined;
83
107
  if (this.#renderInFlight) {
@@ -85,13 +109,17 @@ export default class Spinner {
85
109
  }
86
110
  await this.#terminal.clearLine();
87
111
  await this.#terminal.showCursor();
88
- this.#message = undefined;
89
112
  }
90
113
 
91
114
  public async pause(): Promise<void> {
92
115
  if (!this.#isShown) {
93
116
  return Promise.resolve();
94
117
  }
118
+ if (this.#showDelayTimer) {
119
+ clearTimeout(this.#showDelayTimer);
120
+ this.#showDelayTimer = undefined;
121
+ return;
122
+ }
95
123
  clearInterval(this.#timer);
96
124
  this.#timer = undefined;
97
125
  if (this.#renderInFlight) {
@@ -101,10 +129,14 @@ export default class Spinner {
101
129
  }
102
130
 
103
131
  public resume(): void {
104
- if (!this.#isShown || this.#timer !== undefined) {
132
+ if (!this.#isShown || this.#timer !== undefined || this.#showDelayTimer !== undefined) {
105
133
  return;
106
134
  }
107
- this.#startTimer();
135
+ if (this.#isRendering) {
136
+ this.#startTimer();
137
+ } else {
138
+ this.#scheduleShow();
139
+ }
108
140
  }
109
141
 
110
142
  set spinnerColor(color: number) {