console-toolkit 1.2.8 → 1.2.10

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.
Files changed (156) hide show
  1. package/README.md +70 -25
  2. package/package.json +26 -6
  3. package/src/alphanumeric/arrows.d.ts +48 -0
  4. package/src/alphanumeric/arrows.js +23 -0
  5. package/src/alphanumeric/fractions.d.ts +65 -0
  6. package/src/alphanumeric/fractions.js +49 -0
  7. package/src/alphanumeric/number-formatters.d.ts +91 -0
  8. package/src/alphanumeric/number-formatters.js +45 -1
  9. package/src/alphanumeric/roman.d.ts +15 -0
  10. package/src/alphanumeric/roman.js +12 -0
  11. package/src/alphanumeric/unicode-cultural-numbers.d.ts +65 -0
  12. package/src/alphanumeric/unicode-cultural-numbers.js +1 -0
  13. package/src/alphanumeric/unicode-letters.d.ts +32 -0
  14. package/src/alphanumeric/unicode-letters.js +8 -0
  15. package/src/alphanumeric/unicode-numbers.d.ts +44 -0
  16. package/src/alphanumeric/unicode-numbers.js +21 -0
  17. package/src/alphanumeric/utils.d.ts +45 -0
  18. package/src/alphanumeric/utils.js +26 -0
  19. package/src/ansi/csi.d.ts +141 -0
  20. package/src/ansi/csi.js +51 -2
  21. package/src/ansi/index.d.ts +26 -0
  22. package/src/ansi/sgr-constants.d.ts +173 -0
  23. package/src/ansi/sgr-state.d.ts +91 -0
  24. package/src/ansi/sgr-state.js +45 -0
  25. package/src/ansi/sgr.d.ts +587 -0
  26. package/src/ansi/sgr.js +426 -6
  27. package/src/box.d.ts +160 -0
  28. package/src/box.js +113 -12
  29. package/src/charts/bars/block-frac-grouped.d.ts +12 -0
  30. package/src/charts/bars/block-frac-grouped.js +6 -0
  31. package/src/charts/bars/block-frac.d.ts +34 -0
  32. package/src/charts/bars/block-frac.js +13 -0
  33. package/src/charts/bars/block-grouped.d.ts +12 -0
  34. package/src/charts/bars/block-grouped.js +6 -0
  35. package/src/charts/bars/block.d.ts +43 -0
  36. package/src/charts/bars/block.js +13 -0
  37. package/src/charts/bars/draw-grouped.d.ts +41 -0
  38. package/src/charts/bars/draw-grouped.js +4 -0
  39. package/src/charts/bars/draw-stacked.d.ts +47 -0
  40. package/src/charts/bars/draw-stacked.js +4 -0
  41. package/src/charts/bars/frac-grouped.d.ts +32 -0
  42. package/src/charts/bars/frac-grouped.js +13 -0
  43. package/src/charts/bars/plain-grouped.d.ts +12 -0
  44. package/src/charts/bars/plain-grouped.js +6 -0
  45. package/src/charts/bars/plain.d.ts +75 -0
  46. package/src/charts/bars/plain.js +27 -0
  47. package/src/charts/columns/block-frac-grouped.d.ts +12 -0
  48. package/src/charts/columns/block-frac-grouped.js +6 -0
  49. package/src/charts/columns/block-frac.d.ts +39 -0
  50. package/src/charts/columns/block-frac.js +13 -0
  51. package/src/charts/columns/block-grouped.d.ts +12 -0
  52. package/src/charts/columns/block-grouped.js +6 -0
  53. package/src/charts/columns/block.d.ts +43 -0
  54. package/src/charts/columns/block.js +13 -0
  55. package/src/charts/columns/draw-grouped.d.ts +41 -0
  56. package/src/charts/columns/draw-grouped.js +4 -0
  57. package/src/charts/columns/draw-stacked.d.ts +39 -0
  58. package/src/charts/columns/draw-stacked.js +4 -0
  59. package/src/charts/columns/frac-grouped.d.ts +37 -0
  60. package/src/charts/columns/frac-grouped.js +13 -0
  61. package/src/charts/columns/plain-grouped.d.ts +12 -0
  62. package/src/charts/columns/plain-grouped.js +6 -0
  63. package/src/charts/columns/plain.d.ts +32 -0
  64. package/src/charts/columns/plain.js +13 -0
  65. package/src/charts/themes/default.d.ts +6 -0
  66. package/src/charts/themes/default.js +1 -0
  67. package/src/charts/themes/rainbow-reversed.d.ts +6 -0
  68. package/src/charts/themes/rainbow-reversed.js +2 -1
  69. package/src/charts/themes/rainbow.d.ts +6 -0
  70. package/src/charts/themes/rainbow.js +1 -0
  71. package/src/charts/utils.d.ts +79 -0
  72. package/src/charts/utils.js +32 -4
  73. package/src/draw-block-frac.d.ts +16 -0
  74. package/src/draw-block-frac.js +14 -0
  75. package/src/draw-block.d.ts +53 -0
  76. package/src/draw-block.js +25 -1
  77. package/src/meta.d.ts +84 -0
  78. package/src/meta.js +64 -0
  79. package/src/output/show.d.ts +55 -0
  80. package/src/output/show.js +28 -0
  81. package/src/output/updater.d.ts +114 -0
  82. package/src/output/updater.js +58 -4
  83. package/src/output/writer.d.ts +87 -0
  84. package/src/output/writer.js +57 -5
  85. package/src/panel.d.ts +402 -0
  86. package/src/panel.js +219 -5
  87. package/src/plot/bitmap.d.ts +80 -0
  88. package/src/plot/bitmap.js +33 -4
  89. package/src/plot/draw-line.d.ts +13 -0
  90. package/src/plot/draw-line.js +8 -0
  91. package/src/plot/draw-rect.d.ts +13 -0
  92. package/src/plot/draw-rect.js +38 -30
  93. package/src/plot/index.d.ts +39 -0
  94. package/src/plot/index.js +22 -0
  95. package/src/plot/to-quads.d.ts +10 -0
  96. package/src/plot/to-quads.js +5 -0
  97. package/src/spinner/index.d.ts +4 -0
  98. package/src/spinner/index.js +0 -2
  99. package/src/spinner/spin.d.ts +13 -0
  100. package/src/spinner/spin.js +13 -2
  101. package/src/spinner/spinner.d.ts +69 -0
  102. package/src/spinner/spinner.js +30 -2
  103. package/src/spinner/spinners.d.ts +34 -0
  104. package/src/spinner/spinners.js +23 -9
  105. package/src/strings/clip.d.ts +21 -0
  106. package/src/strings/clip.js +10 -0
  107. package/src/strings/parse.d.ts +23 -0
  108. package/src/strings/parse.js +7 -0
  109. package/src/strings/split.d.ts +38 -0
  110. package/src/strings/split.js +15 -0
  111. package/src/strings.d.ts +44 -0
  112. package/src/strings.js +34 -4
  113. package/src/style.d.ts +462 -0
  114. package/src/style.js +58 -4
  115. package/src/symbols.d.ts +167 -0
  116. package/src/symbols.js +91 -7
  117. package/src/table/draw-borders.d.ts +38 -0
  118. package/src/table/draw-borders.js +10 -2
  119. package/src/table/index.d.ts +8 -0
  120. package/src/table/index.js +1 -0
  121. package/src/table/table.d.ts +234 -0
  122. package/src/table/table.js +59 -1
  123. package/src/themes/blocks/unicode-half.d.ts +6 -0
  124. package/src/themes/blocks/unicode-half.js +1 -0
  125. package/src/themes/blocks/unicode-thin.d.ts +6 -0
  126. package/src/themes/blocks/unicode-thin.js +1 -0
  127. package/src/themes/lines/ascii-compact.d.ts +6 -0
  128. package/src/themes/lines/ascii-compact.js +1 -0
  129. package/src/themes/lines/ascii-dots.d.ts +6 -0
  130. package/src/themes/lines/ascii-dots.js +1 -0
  131. package/src/themes/lines/ascii-girder.d.ts +6 -0
  132. package/src/themes/lines/ascii-girder.js +1 -0
  133. package/src/themes/lines/ascii-github.d.ts +6 -0
  134. package/src/themes/lines/ascii-github.js +1 -0
  135. package/src/themes/lines/ascii-reddit.d.ts +6 -0
  136. package/src/themes/lines/ascii-reddit.js +1 -0
  137. package/src/themes/lines/ascii-rounded.d.ts +6 -0
  138. package/src/themes/lines/ascii-rounded.js +1 -0
  139. package/src/themes/lines/ascii.d.ts +6 -0
  140. package/src/themes/lines/ascii.js +1 -0
  141. package/src/themes/lines/unicode-bold.d.ts +6 -0
  142. package/src/themes/lines/unicode-bold.js +1 -0
  143. package/src/themes/lines/unicode-rounded.d.ts +6 -0
  144. package/src/themes/lines/unicode-rounded.js +1 -0
  145. package/src/themes/lines/unicode.d.ts +6 -0
  146. package/src/themes/lines/unicode.js +1 -0
  147. package/src/themes/utils.d.ts +33 -0
  148. package/src/themes/utils.js +7 -0
  149. package/src/turtle/draw-line-art.d.ts +19 -0
  150. package/src/turtle/draw-line-art.js +7 -0
  151. package/src/turtle/draw-unicode.d.ts +19 -0
  152. package/src/turtle/draw-unicode.js +8 -0
  153. package/src/turtle/index.d.ts +21 -0
  154. package/src/turtle/index.js +8 -0
  155. package/src/turtle/turtle.d.ts +269 -0
  156. package/src/turtle/turtle.js +124 -4
@@ -1,3 +1,11 @@
1
+ /** Draws a filled rectangle on a Bitmap by efficiently manipulating the underlying bit array.
2
+ * @param {import('./bitmap.js').Bitmap} bmp - The bitmap to draw on.
3
+ * @param {number} x0 - First corner x coordinate.
4
+ * @param {number} y0 - First corner y coordinate.
5
+ * @param {number} x1 - Opposite corner x coordinate.
6
+ * @param {number} y1 - Opposite corner y coordinate.
7
+ * @param {number} [value=1] - Bit value: positive to set, 0 to clear, negative to toggle.
8
+ */
1
9
  export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
2
10
  if (x1 < x0) [x0, x1] = [x1, x0];
3
11
  if (y1 < y0) [y0, y1] = [y1, y0];
@@ -26,8 +34,8 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
26
34
  value > 0
27
35
  ? bmp.bitmap[indexL] | fullMask
28
36
  : value < 0
29
- ? bmp.bitmap[indexL] ^ fullMask
30
- : bmp.bitmap[indexL] & ~fullMask;
37
+ ? bmp.bitmap[indexL] ^ fullMask
38
+ : bmp.bitmap[indexL] & ~fullMask;
31
39
  return;
32
40
  }
33
41
 
@@ -52,21 +60,21 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
52
60
  value > 0
53
61
  ? bmp.bitmap[indexL] | fullMaskL
54
62
  : value < 0
55
- ? bmp.bitmap[indexL] ^ fullMaskL
56
- : bmp.bitmap[indexL] & ~fullMaskL;
63
+ ? bmp.bitmap[indexL] ^ fullMaskL
64
+ : bmp.bitmap[indexL] & ~fullMaskL;
57
65
  for (let index = indexL + 1; index < indexR; ++index)
58
66
  bmp.bitmap[index] =
59
67
  value > 0
60
68
  ? bmp.bitmap[index] | fullMaskM
61
69
  : value < 0
62
- ? bmp.bitmap[index] ^ fullMaskM
63
- : bmp.bitmap[index] & ~fullMaskM;
70
+ ? bmp.bitmap[index] ^ fullMaskM
71
+ : bmp.bitmap[index] & ~fullMaskM;
64
72
  bmp.bitmap[indexR] =
65
73
  value > 0
66
74
  ? bmp.bitmap[indexR] | fullMaskR
67
75
  : value < 0
68
- ? bmp.bitmap[indexR] ^ fullMaskR
69
- : bmp.bitmap[indexR] & ~fullMaskR;
76
+ ? bmp.bitmap[indexR] ^ fullMaskR
77
+ : bmp.bitmap[indexR] & ~fullMaskR;
70
78
  return;
71
79
  }
72
80
 
@@ -86,8 +94,8 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
86
94
  value > 0
87
95
  ? bmp.bitmap[indexL] | fullMask
88
96
  : value < 0
89
- ? bmp.bitmap[indexL] ^ fullMask
90
- : bmp.bitmap[indexL] & ~fullMask;
97
+ ? bmp.bitmap[indexL] ^ fullMask
98
+ : bmp.bitmap[indexL] & ~fullMask;
91
99
  indexL += bmp.lineSize;
92
100
  }
93
101
  if (fullLines) {
@@ -100,8 +108,8 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
100
108
  value > 0
101
109
  ? bmp.bitmap[indexL] | fullMask
102
110
  : value < 0
103
- ? bmp.bitmap[indexL] ^ fullMask
104
- : bmp.bitmap[indexL] & ~fullMask;
111
+ ? bmp.bitmap[indexL] ^ fullMask
112
+ : bmp.bitmap[indexL] & ~fullMask;
105
113
  }
106
114
  if (lastRows) {
107
115
  // apply the mask to the last incomplete block
@@ -111,8 +119,8 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
111
119
  value > 0
112
120
  ? bmp.bitmap[indexL] | fullMask
113
121
  : value < 0
114
- ? bmp.bitmap[indexL] ^ fullMask
115
- : bmp.bitmap[indexL] & ~fullMask;
122
+ ? bmp.bitmap[indexL] ^ fullMask
123
+ : bmp.bitmap[indexL] & ~fullMask;
116
124
  }
117
125
  return;
118
126
  }
@@ -136,21 +144,21 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
136
144
  value > 0
137
145
  ? bmp.bitmap[indexL] | fullMaskL
138
146
  : value < 0
139
- ? bmp.bitmap[indexL] ^ fullMaskL
140
- : bmp.bitmap[indexL] & ~fullMaskL;
147
+ ? bmp.bitmap[indexL] ^ fullMaskL
148
+ : bmp.bitmap[indexL] & ~fullMaskL;
141
149
  for (let index = indexL + 1; index < indexR; ++index)
142
150
  bmp.bitmap[index] =
143
151
  value > 0
144
152
  ? bmp.bitmap[index] | fullMaskM
145
153
  : value < 0
146
- ? bmp.bitmap[index] ^ fullMaskM
147
- : bmp.bitmap[index] & ~fullMaskM;
154
+ ? bmp.bitmap[index] ^ fullMaskM
155
+ : bmp.bitmap[index] & ~fullMaskM;
148
156
  bmp.bitmap[indexR] =
149
157
  value > 0
150
158
  ? bmp.bitmap[indexR] | fullMaskR
151
159
  : value < 0
152
- ? bmp.bitmap[indexR] ^ fullMaskR
153
- : bmp.bitmap[indexR] & ~fullMaskR;
160
+ ? bmp.bitmap[indexR] ^ fullMaskR
161
+ : bmp.bitmap[indexR] & ~fullMaskR;
154
162
  indexL += bmp.lineSize;
155
163
  indexR += bmp.lineSize;
156
164
  }
@@ -169,16 +177,16 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
169
177
  value > 0
170
178
  ? bmp.bitmap[indexL] | fullMaskL
171
179
  : value < 0
172
- ? bmp.bitmap[indexL] ^ fullMaskL
173
- : bmp.bitmap[indexL] & ~fullMaskL;
180
+ ? bmp.bitmap[indexL] ^ fullMaskL
181
+ : bmp.bitmap[indexL] & ~fullMaskL;
174
182
  for (let index = indexL + 1; index < indexR; ++index)
175
183
  bmp.bitmap[index] = value > 0 ? ~0 : value < 0 ? ~bmp.bitmap[index] : 0;
176
184
  bmp.bitmap[indexR] =
177
185
  value > 0
178
186
  ? bmp.bitmap[indexR] | fullMaskR
179
187
  : value < 0
180
- ? bmp.bitmap[indexR] ^ fullMaskR
181
- : bmp.bitmap[indexR] & ~fullMaskR;
188
+ ? bmp.bitmap[indexR] ^ fullMaskR
189
+ : bmp.bitmap[indexR] & ~fullMaskR;
182
190
  }
183
191
  }
184
192
 
@@ -195,21 +203,21 @@ export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => {
195
203
  value > 0
196
204
  ? bmp.bitmap[indexL] | fullMaskL
197
205
  : value < 0
198
- ? bmp.bitmap[indexL] ^ fullMaskL
199
- : bmp.bitmap[indexL] & ~fullMaskL;
206
+ ? bmp.bitmap[indexL] ^ fullMaskL
207
+ : bmp.bitmap[indexL] & ~fullMaskL;
200
208
  for (let index = indexL + 1; index < indexR; ++index)
201
209
  bmp.bitmap[index] =
202
210
  value > 0
203
211
  ? bmp.bitmap[index] | fullMaskM
204
212
  : value < 0
205
- ? bmp.bitmap[index] ^ fullMaskM
206
- : bmp.bitmap[index] & ~fullMaskM;
213
+ ? bmp.bitmap[index] ^ fullMaskM
214
+ : bmp.bitmap[index] & ~fullMaskM;
207
215
  bmp.bitmap[indexR] =
208
216
  value > 0
209
217
  ? bmp.bitmap[indexR] | fullMaskR
210
218
  : value < 0
211
- ? bmp.bitmap[indexR] ^ fullMaskR
212
- : bmp.bitmap[indexR] & ~fullMaskR;
219
+ ? bmp.bitmap[indexR] ^ fullMaskR
220
+ : bmp.bitmap[indexR] & ~fullMaskR;
213
221
  }
214
222
  };
215
223
 
@@ -0,0 +1,39 @@
1
+ import {Bitmap} from './bitmap.js';
2
+ import {drawLine} from './draw-line.js';
3
+ import {drawRect} from './draw-rect.js';
4
+ import {toQuads} from './to-quads.js';
5
+ import Box from '../box.js';
6
+
7
+ declare module './bitmap.js' {
8
+ interface Bitmap {
9
+ /** Draws a line on this bitmap.
10
+ * @param x0 - Start X.
11
+ * @param y0 - Start Y.
12
+ * @param x1 - End X.
13
+ * @param y1 - End Y.
14
+ * @param value - Bit value.
15
+ * @returns This Bitmap.
16
+ */
17
+ line(x0: number, y0: number, x1: number, y1: number, value?: number): Bitmap;
18
+ /** Draws a filled rectangle on this bitmap.
19
+ * @param x0 - First corner x coordinate.
20
+ * @param y0 - First corner y coordinate.
21
+ * @param x1 - Opposite corner x coordinate.
22
+ * @param y1 - Opposite corner y coordinate.
23
+ * @param value - Bit value.
24
+ * @returns This Bitmap.
25
+ */
26
+ rect(x0: number, y0: number, x1: number, y1: number, value?: number): Bitmap;
27
+ /** Converts this bitmap to a Box using quadrant characters.
28
+ * @returns A Box.
29
+ */
30
+ toQuads(): Box;
31
+ /** Converts this bitmap to a string array via `toBox()`.
32
+ * @returns Array of strings.
33
+ */
34
+ toStrings(): string[];
35
+ }
36
+ }
37
+
38
+ export {Bitmap, drawLine, drawRect, toQuads};
39
+ export default Bitmap;
package/src/plot/index.js CHANGED
@@ -5,17 +5,39 @@ import toQuads from './to-quads.js';
5
5
 
6
6
  // patch Bitmap
7
7
 
8
+ /** Draws a line on this bitmap.
9
+ * @param {number} x0 - Start X.
10
+ * @param {number} y0 - Start Y.
11
+ * @param {number} x1 - End X.
12
+ * @param {number} y1 - End Y.
13
+ * @param {number} [value=1] - Bit value.
14
+ * @returns {this}
15
+ */
8
16
  Bitmap.prototype.line = function (...args) {
9
17
  drawLine(this, ...args);
10
18
  return this;
11
19
  };
20
+ /** Draws a filled rectangle on this bitmap.
21
+ * @param {number} x0 - First corner x coordinate.
22
+ * @param {number} y0 - First corner y coordinate.
23
+ * @param {number} x1 - Opposite corner x coordinate.
24
+ * @param {number} y1 - Opposite corner y coordinate.
25
+ * @param {number} [value=1] - Bit value.
26
+ * @returns {this}
27
+ */
12
28
  Bitmap.prototype.rect = function (...args) {
13
29
  drawRect(this, ...args);
14
30
  return this;
15
31
  };
32
+ /** Converts this bitmap to a Box using quadrant characters.
33
+ * @returns {import('../box.js').default}
34
+ */
16
35
  Bitmap.prototype.toQuads = function () {
17
36
  return toQuads(this);
18
37
  };
38
+ /** Converts this bitmap to a string array via `toBox()`.
39
+ * @returns {string[]}
40
+ */
19
41
  Bitmap.prototype.toStrings = function () {
20
42
  return this.toBox().toStrings();
21
43
  };
@@ -0,0 +1,10 @@
1
+ import Box from '../box.js';
2
+ import {Bitmap} from './bitmap.js';
3
+
4
+ /** Converts a Bitmap to a Box using Unicode quadrant characters (2x2 pixels per character).
5
+ * @param bmp - The source bitmap.
6
+ * @returns A Box representation using quadrant characters.
7
+ */
8
+ export function toQuads(bmp: Bitmap): Box;
9
+
10
+ export default toQuads;
@@ -1,6 +1,11 @@
1
1
  import Box from '../box.js';
2
2
  import {quadrants} from '../symbols.js';
3
3
 
4
+ /** Converts a Bitmap to a Box using Unicode quadrant characters (2x2 pixels per character).
5
+ * Provides higher resolution representation than `toBox()`.
6
+ * @param {import('./bitmap.js').Bitmap} bmp - The bitmap to convert.
7
+ * @returns {import('../box.js').Box} A Box with quadrant characters.
8
+ */
4
9
  export const toQuads = bmp => {
5
10
  const result = [],
6
11
  rowSize = Math.floor((bmp.width + 1) / 2),
@@ -0,0 +1,4 @@
1
+ export {Spinner} from './spinner.js';
2
+ export {default as spin} from './spin.js';
3
+
4
+ export default spin;
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  export {Spinner} from './spinner.js';
4
2
  import spin from './spin.js';
5
3
 
@@ -0,0 +1,13 @@
1
+ import {SpinnerBase} from './spinner.js';
2
+
3
+ /** A spinner argument: frame array, state-to-string function, SpinnerBase instance, or other value. */
4
+ type SpinArg = string[] | ((state: string) => string) | SpinnerBase | unknown;
5
+
6
+ /** Tagged template literal for creating composite spinners from multiple parts.
7
+ * @param strings - Template string parts.
8
+ * @param args - Spinner arguments interpolated between string parts.
9
+ * @returns A composite SpinnerBase.
10
+ */
11
+ declare function spin(strings: TemplateStringsArray, ...args: SpinArg[]): SpinnerBase;
12
+
13
+ export default spin;
@@ -1,8 +1,10 @@
1
- 'use strict';
2
-
3
1
  import {SpinnerBase} from './spinner.js';
4
2
 
3
+ /** Internal composite spinner that handles multiple spinner parts and functions via tagged template literals. */
5
4
  class Spinner extends SpinnerBase {
5
+ /** @param {TemplateStringsArray} strings - Template literal strings.
6
+ * @param {any[]} args - Interpolated values.
7
+ */
6
8
  constructor(strings, args) {
7
9
  super(false);
8
10
  this.strings = strings;
@@ -10,6 +12,9 @@ class Spinner extends SpinnerBase {
10
12
  this.indices = new WeakMap();
11
13
  }
12
14
 
15
+ /** Returns the current composite frame string.
16
+ * @returns {string}
17
+ */
13
18
  getFrame() {
14
19
  let result = '';
15
20
  for (let i = 0; i < this.args.length; ++i) {
@@ -46,6 +51,12 @@ class Spinner extends SpinnerBase {
46
51
  }
47
52
  }
48
53
 
54
+ /** Tagged template literal function that creates a composite spinner.
55
+ * Arguments can be string arrays (cycled through), functions `(state) => string`, or SpinnerBase instances.
56
+ * @param {TemplateStringsArray} strings - Template literal strings.
57
+ * @param {...(string[]|Function|import('./spinner.js').SpinnerBase|*)} args - Interpolated values.
58
+ * @returns {import('./spinner.js').SpinnerBase} A composite spinner.
59
+ */
49
60
  const spin = (strings, ...args) => new Spinner(strings, args);
50
61
 
51
62
  export default spin;
@@ -0,0 +1,69 @@
1
+ /** Base class for managing spinner state (active, paused, finished). */
2
+ export class SpinnerBase {
3
+ /** Whether the spinner is active. */
4
+ active: boolean;
5
+ /** Whether the spinner is paused. */
6
+ paused: boolean;
7
+ /** Whether the spinner is finished. */
8
+ finished: boolean;
9
+ /** Current frame index. */
10
+ frameIndex: number;
11
+
12
+ /**
13
+ * @param isStarted - If true, start in active state.
14
+ */
15
+ constructor(isStarted?: boolean);
16
+
17
+ /** Whether the spinner has been started. */
18
+ readonly isStarted: boolean;
19
+ /** Whether the spinner is currently active. */
20
+ readonly isActive: boolean;
21
+ /** Whether the spinner is finished. */
22
+ readonly isFinished: boolean;
23
+
24
+ /** The current state string: '', 'active', 'paused', or 'finished'. */
25
+ state: '' | 'active' | 'paused' | 'finished';
26
+
27
+ /** Resets the spinner to its initial state. */
28
+ reset(): void;
29
+ /** Advances and returns the next frame index.
30
+ * @param length - Number of frames available.
31
+ * @returns The next frame index.
32
+ */
33
+ nextFrameIndex(length: number): number;
34
+ /** Returns the current frame string.
35
+ * @returns The frame string.
36
+ */
37
+ getFrame(): string;
38
+ }
39
+
40
+ /** Definition of spinner frame sets. */
41
+ export interface SpinnerDefinition {
42
+ /** Frames for the active state. */
43
+ frames?: string[];
44
+ /** Frames for the not-started state. */
45
+ notStarted?: string[];
46
+ /** Frames for the finished state. */
47
+ finished?: string[];
48
+ }
49
+
50
+ /** A spinner with configurable frame sets for different states.
51
+ * @see {@link https://github.com/uhop/console-toolkit/wiki/Module:-spinner}
52
+ */
53
+ export class Spinner extends SpinnerBase {
54
+ /** The resolved spinner definition with all frame sets. */
55
+ spinner: Required<SpinnerDefinition>;
56
+
57
+ /**
58
+ * @param spinnerDefinition - Spinner frame definition.
59
+ * @param isStarted - If true, start in active state.
60
+ */
61
+ constructor(spinnerDefinition?: SpinnerDefinition, isStarted?: boolean);
62
+
63
+ /** Returns the current frame string based on state.
64
+ * @returns The frame string.
65
+ */
66
+ getFrame(): string;
67
+ }
68
+
69
+ export default Spinner;
@@ -1,8 +1,10 @@
1
- 'use strict';
2
-
3
1
  import {checkMarkHeavy} from '../symbols.js';
4
2
 
3
+ /** Base class for spinners. Manages spinner state (active, paused, finished) and frame index. */
5
4
  export class SpinnerBase {
5
+ /**
6
+ * @param {boolean} [isStarted=false] - Whether the spinner starts in the active state.
7
+ */
6
8
  constructor(isStarted) {
7
9
  this.active = isStarted;
8
10
  this.paused = false;
@@ -10,24 +12,31 @@ export class SpinnerBase {
10
12
  this.frameIndex = 0;
11
13
  }
12
14
 
15
+ /** Whether the spinner has been started (active or finished). */
13
16
  get isStarted() {
14
17
  return this.active || this.finished;
15
18
  }
16
19
 
20
+ /** Whether the spinner is currently active. */
17
21
  get isActive() {
18
22
  return this.active;
19
23
  }
20
24
 
25
+ /** Whether the spinner has finished. */
21
26
  get isFinished() {
22
27
  return this.finished;
23
28
  }
24
29
 
30
+ /** The current state: `''`, `'active'`, `'paused'`, or `'finished'`. */
25
31
  get state() {
26
32
  if (this.finished) return 'finished';
27
33
  if (this.active) return this.paused ? 'paused' : 'active';
28
34
  return '';
29
35
  }
30
36
 
37
+ /** Sets the spinner state.
38
+ * @param {''|'active'|'paused'|'finished'} value
39
+ */
31
40
  set state(value) {
32
41
  this.finished = this.active = this.paused = false;
33
42
  switch (value) {
@@ -43,14 +52,22 @@ export class SpinnerBase {
43
52
  }
44
53
  }
45
54
 
55
+ /** Resets the spinner to its initial (not started) state. */
46
56
  reset() {
47
57
  this.active = this.paused = this.finished = false;
48
58
  }
49
59
 
60
+ /** Advances and returns the next frame index.
61
+ * @param {number} length - The total number of frames.
62
+ * @returns {number} The new frame index.
63
+ */
50
64
  nextFrameIndex(length) {
51
65
  return (this.frameIndex = (this.frameIndex + 1) % length);
52
66
  }
53
67
 
68
+ /** Returns the current frame string. Override in subclasses.
69
+ * @returns {string}
70
+ */
54
71
  getFrame() {
55
72
  return 'X';
56
73
  }
@@ -58,12 +75,23 @@ export class SpinnerBase {
58
75
 
59
76
  const defaultSpinnerDefinition = {notStarted: [' '], finished: [checkMarkHeavy], frames: [...'⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏']};
60
77
 
78
+ /** A spinner with configurable frame sets for active, not-started, and finished states. */
61
79
  export class Spinner extends SpinnerBase {
80
+ /**
81
+ * @param {object} [spinnerDefinition] - Spinner definition with `frames`, `notStarted`, and `finished` arrays.
82
+ * @param {string[]} [spinnerDefinition.frames] - Animation frames for the active state.
83
+ * @param {string[]} [spinnerDefinition.notStarted] - Frames shown before the spinner starts.
84
+ * @param {string[]} [spinnerDefinition.finished] - Frames shown after the spinner finishes.
85
+ * @param {boolean} [isStarted=false] - Whether the spinner starts active.
86
+ */
62
87
  constructor(spinnerDefinition, isStarted) {
63
88
  super(isStarted);
64
89
  this.spinner = {...defaultSpinnerDefinition, ...spinnerDefinition};
65
90
  }
66
91
 
92
+ /** Returns the current frame based on the spinner's state.
93
+ * @returns {string}
94
+ */
67
95
  getFrame() {
68
96
  if (this.finished) return this.spinner.finished[this.nextFrameIndex(this.spinner.finished.length)];
69
97
  if (!this.active) return this.spinner.notStarted[this.nextFrameIndex(this.spinner.notStarted.length)];
@@ -0,0 +1,34 @@
1
+ import {SpinnerDefinition} from './spinner.js';
2
+
3
+ /** Braille dots spinner. */
4
+ export const dots: SpinnerDefinition;
5
+ /** Sand/hourglass spinner. */
6
+ export const sand: SpinnerDefinition;
7
+ /** Line spinner (|/-\). */
8
+ export const line: SpinnerDefinition;
9
+ /** Pipe spinner. */
10
+ export const pipe: SpinnerDefinition;
11
+ /** Vertical growing bar spinner. */
12
+ export const growVertical: SpinnerDefinition;
13
+ /** Horizontal growing bar spinner. */
14
+ export const growHorizontal: SpinnerDefinition;
15
+ /** Random noise spinner. */
16
+ export const noise: SpinnerDefinition;
17
+ /** Bouncing spinner. */
18
+ export const bounce: SpinnerDefinition;
19
+ /** Arc spinner. */
20
+ export const arc: SpinnerDefinition;
21
+ /** Square quarters spinner. */
22
+ export const squareQuarters: SpinnerDefinition;
23
+ /** Circle quarters spinner. */
24
+ export const circleQuarters: SpinnerDefinition;
25
+ /** Circle halves spinner. */
26
+ export const circleHalves: SpinnerDefinition;
27
+ /** Arrows spinner. */
28
+ export const arrows: SpinnerDefinition;
29
+ /** Clock spinner. */
30
+ export const clock: SpinnerDefinition;
31
+ /** Bouncing bar spinner. */
32
+ export const bouncingBar: SpinnerDefinition;
33
+ /** Bouncing ball spinner. */
34
+ export const bouncingBall: SpinnerDefinition;
@@ -1,29 +1,42 @@
1
- 'use strict';
2
-
3
1
  // Spinners are from https://github.com/sindresorhus/cli-spinners under the MIT license.
4
2
  // Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
5
3
  // See `cli-spinners` for more great options.
6
4
 
5
+ /** Braille dots spinner. */
7
6
  export const dots = {frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']};
7
+ /** Sand/hourglass spinner. */
8
8
  export const sand = {frames: [...'⠁⠂⠄⡀⡈⡐⡠⣀⣁⣂⣄⣌⣔⣤⣥⣦⣮⣶⣷⣿⡿⠿⢟⠟⡛⠛⠫⢋⠋⠍⡉⠉⠑⠡⢁']};
9
+ /** Line spinner (|/-\). */
9
10
  export const line = {frames: ['-', '\\', '|', '/']};
10
- export const pipe = {frame: ['┤', '┘', '┴', '└', '├', '┌', '┬', '┐']};
11
- export const growVertical = {frame: ['', '', '', '', '', '', '', '', '▄', '▃']};
12
- export const growHorizontal = {frame: ['▏', '▎', '▍', '▌', '▋', '▊', '▉', '▊', '▋', '▌', '▍', '▎']};
13
- export const noise = {frame: ['', '', '']};
14
- export const bounce = {frame: ['⠁', '⠂', '⠄', '⠂']};
15
- export const arc = {frame: ['', '', '', '', '', '']};
11
+ /** Pipe spinner. */
12
+ export const pipe = {frames: ['', '', '', '', '', '', '', '']};
13
+ /** Vertical growing bar spinner. */
14
+ export const growVertical = {frames: ['', '', '', '▅', '▆', '▇', '▆', '▅', '▄', '▃']};
15
+ /** Horizontal growing bar spinner. */
16
+ export const growHorizontal = {frames: ['', '', '', '', '', '', '▉', '▊', '▋', '▌', '▍', '▎']};
17
+ /** Random noise spinner. */
18
+ export const noise = {frames: ['▓', '▒', '░']};
19
+ /** Bouncing spinner. */
20
+ export const bounce = {frames: ['⠁', '⠂', '⠄', '⠂']};
21
+ /** Arc spinner. */
22
+ export const arc = {frames: ['◜', '◠', '◝', '◞', '◡', '◟']};
23
+ /** Square quarters spinner. */
16
24
  export const squareQuarters = {frames: ['◰', '◳', '◲', '◱']};
25
+ /** Circle quarters spinner. */
17
26
  export const circleQuarters = {frames: ['◴', '◷', '◶', '◵']};
27
+ /** Circle halves spinner. */
18
28
  export const circleHalves = {frames: ['◐', '◓', '◑', '◒']};
19
- export const arrows = {frame: ['←', '↖', '↑', '↗', '→', '↘', '↓', '↙']};
29
+ /** Arrows spinner. */
30
+ export const arrows = {frames: ['←', '↖', '↑', '↗', '→', '↘', '↓', '↙']};
20
31
 
32
+ /** Clock spinner. */
21
33
  export const clock = {
22
34
  frames: ['🕛 ', '🕐 ', '🕑 ', '🕒 ', '🕓 ', '🕔 ', '🕕 ', '🕖 ', '🕗 ', '🕘 ', '🕙 ', '🕚 '],
23
35
  notStarted: [' '],
24
36
  finished: ['✔ ']
25
37
  };
26
38
 
39
+ /** Bouncing bar spinner. */
27
40
  export const bouncingBar = {
28
41
  frames: [
29
42
  '[ ]',
@@ -47,6 +60,7 @@ export const bouncingBar = {
47
60
  finished: ['[####]']
48
61
  };
49
62
 
63
+ /** Bouncing ball spinner. */
50
64
  export const bouncingBall = {
51
65
  frames: [
52
66
  '( ● )',
@@ -0,0 +1,21 @@
1
+ /** Options for the `clip()` function. */
2
+ export interface ClipOptions {
3
+ /** If true, include the last ANSI command at the clip boundary. */
4
+ includeLastCommand?: boolean;
5
+ /** RegExp for matching escape sequences. */
6
+ matcher?: RegExp;
7
+ /** If true, ignore control symbols when calculating width. */
8
+ ignoreControlSymbols?: boolean;
9
+ /** If true, treat East Asian ambiguous-width characters as wide. */
10
+ ambiguousAsWide?: boolean;
11
+ }
12
+
13
+ /** Clips a string to a given display width, correctly handling ANSI escape codes and multi-width characters.
14
+ * @param s - The string to clip.
15
+ * @param width - Maximum display width.
16
+ * @param options - Clip options.
17
+ * @returns The clipped string.
18
+ */
19
+ export function clip(s: string, width: number, options?: ClipOptions): string;
20
+
21
+ export default clip;
@@ -1,6 +1,16 @@
1
1
  import parse, {matchCsiNoGroups} from './parse.js';
2
2
  import {split} from './split.js';
3
3
 
4
+ /** Clips a string to a specified display width, correctly handling ANSI escape codes and multi-width characters.
5
+ * @param {string} s - The string to clip.
6
+ * @param {number} width - The maximum display width.
7
+ * @param {object} [options] - Options.
8
+ * @param {boolean} [options.includeLastCommand=false] - If true, include the last (invisible) ANSI command in the clipped result.
9
+ * @param {RegExp} [options.matcher=matchCsiNoGroups] - The regular expression used to match escape sequences.
10
+ * @param {boolean} [options.ignoreControlSymbols] - If true, control symbols are ignored during width calculation.
11
+ * @param {boolean} [options.ambiguousAsWide] - If true, ambiguous East Asian characters are treated as double-wide.
12
+ * @returns {string} The clipped string.
13
+ */
4
14
  export const clip = (s, width, options = {}) => {
5
15
  const {includeLastCommand = false, matcher = matchCsiNoGroups} = options;
6
16
 
@@ -0,0 +1,23 @@
1
+ /** RegExp matching CSI sequences without capture groups. */
2
+ export const matchCsiNoGroups: RegExp;
3
+ /** RegExp matching CSI sequences excluding SGR, without capture groups. */
4
+ export const matchCsiNoSgrNoGroups: RegExp;
5
+
6
+ /** A segment yielded by the `parse()` generator. */
7
+ export interface ParseResult {
8
+ /** Start index of this segment in the original string. */
9
+ start: number;
10
+ /** The text content of this segment. */
11
+ string: string;
12
+ /** The RegExp match for an escape sequence, or `null` for plain text. */
13
+ match: RegExpMatchArray | null;
14
+ }
15
+
16
+ /** Generator that yields segments of text and matched ANSI escape sequences.
17
+ * @param s - The string to parse.
18
+ * @param matcher - RegExp for matching escape sequences (default: matchCsiNoGroups).
19
+ * @returns A generator of ParseResult segments.
20
+ */
21
+ export function parse(s: string, matcher?: RegExp): Generator<ParseResult, void, unknown>;
22
+
23
+ export default parse;
@@ -1,6 +1,13 @@
1
+ /** RegExp that matches CSI sequences with no capture groups. */
1
2
  export const matchCsiNoGroups = /\x1B\[[\x30-\x3F]*[\x20-\x2F]*[\x40-\x7E]/g;
3
+ /** RegExp that matches CSI sequences excluding SGR commands, with no capture groups. */
2
4
  export const matchCsiNoSgrNoGroups = /\x1B\[[\x30-\x3F]*[\x20-\x2F]*[\x40-\x6C\x6E-\x7E]/g;
3
5
 
6
+ /** Parses a string yielding segments of text and matched ANSI escape sequences.
7
+ * @param {string} s - The string to parse.
8
+ * @param {RegExp} [matcher=matchCsiNoGroups] - The regular expression used to match escape sequences.
9
+ * @yields {{start: number, string: string, match: RegExpMatchArray | null}} Parsed segments.
10
+ */
4
11
  export function* parse(s, matcher = matchCsiNoGroups) {
5
12
  s = String(s);
6
13
  let start = 0;