ansimax 1.2.1 → 1.2.3
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/CHANGELOG.md +110 -0
- package/README.es.md +64 -3
- package/README.md +60 -3
- package/dist/index.d.mts +67 -1
- package/dist/index.d.ts +67 -1
- package/dist/index.js +52 -6
- package/dist/index.mjs +51 -6
- package/examples/all-in-one.cjs +1 -1
- package/examples/all-in-one.mjs +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,116 @@
|
|
|
3
3
|
All notable changes to **ansimax** are documented in this file.
|
|
4
4
|
This project follows [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [1.2.3] — Gradient factory + performance
|
|
7
|
+
|
|
8
|
+
Patch release adding a new performance-oriented API and refinements. No
|
|
9
|
+
breaking changes — every 1.2.x program runs identically.
|
|
10
|
+
|
|
11
|
+
### Added — `createGradient()` factory
|
|
12
|
+
|
|
13
|
+
A pre-resolved gradient that can be applied repeatedly to different
|
|
14
|
+
strings without re-parsing hex stops on every call. Significantly
|
|
15
|
+
faster for animation loops, frame-based rendering, and bulk colorizing:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createGradient } from 'ansimax';
|
|
19
|
+
|
|
20
|
+
const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
|
|
21
|
+
|
|
22
|
+
// Reuse — hex stops are pre-resolved
|
|
23
|
+
console.log(fire('first line'));
|
|
24
|
+
console.log(fire('second line'));
|
|
25
|
+
|
|
26
|
+
// Use as colorFn for ascii.banner (matches the ColorFn signature)
|
|
27
|
+
console.log(ascii.banner('FIRE', { colorFn: fire }));
|
|
28
|
+
|
|
29
|
+
// Per-call options still work (especially useful for animation)
|
|
30
|
+
for (let p = 0; p < 1; p += 0.05) {
|
|
31
|
+
process.stdout.write('\r' + fire('flowing', { phase: p }));
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Performance**: hex→RGB conversion happens once at factory time. For
|
|
36
|
+
loops calling `gradient()` hundreds of times per frame, this can cut
|
|
37
|
+
gradient overhead by ~40–60% (depending on stop count).
|
|
38
|
+
|
|
39
|
+
**API surface**:
|
|
40
|
+
- `createGradient(stops, defaultOpts?)` returns `(text, opts?) => string`
|
|
41
|
+
- The returned function matches the `ColorFn` shape (compatible with
|
|
42
|
+
`ascii.banner({ colorFn })`, `themes.gradient`, etc.)
|
|
43
|
+
- Per-call `opts` override defaults; useful for varying `phase` per frame
|
|
44
|
+
while keeping the same colors/easing
|
|
45
|
+
|
|
46
|
+
### Improved
|
|
47
|
+
|
|
48
|
+
- **More JSDoc on `createGradient`** with three runnable `@example` blocks.
|
|
49
|
+
- All 1880 + 12 new tests pass.
|
|
50
|
+
- No new runtime dependencies — still zero.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## [1.2.2] — Quality polish
|
|
55
|
+
|
|
56
|
+
Patch release focused on API ergonomics and robustness refinements. No
|
|
57
|
+
breaking changes — every 1.2.x program runs identically.
|
|
58
|
+
|
|
59
|
+
### Improved
|
|
60
|
+
|
|
61
|
+
- **`animateGradient` controller is now thenable** — you can `await` it
|
|
62
|
+
directly instead of `await ctrl.done`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// Before (v1.2.0)
|
|
66
|
+
const ctrl = animateGradient(text, stops, { infinite: false, cycles: 1 });
|
|
67
|
+
await ctrl.done;
|
|
68
|
+
|
|
69
|
+
// After (v1.2.2) — both still work
|
|
70
|
+
await animateGradient(text, stops, { infinite: false, cycles: 1 });
|
|
71
|
+
|
|
72
|
+
// Also supports .then() / .catch() / .finally()
|
|
73
|
+
animateGradient(text, stops, opts).finally(() => cleanup());
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The `.done` property remains for backwards compatibility.
|
|
77
|
+
|
|
78
|
+
- **Stable error codes for programmatic catch.** Errors thrown by the
|
|
79
|
+
theme system now carry a `.code` property with the `ANSIMAX_*` prefix
|
|
80
|
+
for stable programmatic filtering:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
try {
|
|
84
|
+
themes.use('not-a-real-theme');
|
|
85
|
+
} catch (e) {
|
|
86
|
+
if ((e as { code?: string }).code === 'ANSIMAX_UNKNOWN_THEME') {
|
|
87
|
+
// handle gracefully
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
New codes: `ANSIMAX_INVALID_THEME`, `ANSIMAX_INVALID_THEME_NAME`,
|
|
93
|
+
`ANSIMAX_UNKNOWN_THEME`. Error messages and types
|
|
94
|
+
(`TypeError` / `RangeError`) are unchanged.
|
|
95
|
+
|
|
96
|
+
- **`animateGradient` is safer in sandboxed environments.** The default
|
|
97
|
+
stdout-write path now checks `process?.stdout?.write` before calling
|
|
98
|
+
it, so the function no longer crashes in workers, Edge runtimes, or
|
|
99
|
+
embedded sandboxes that lack a writable stdout.
|
|
100
|
+
|
|
101
|
+
- **Better JSDoc on the `gradient()` function.** IntelliSense now shows
|
|
102
|
+
parameter descriptions, return semantics, and three runnable
|
|
103
|
+
`@example` blocks (basic, with easing, with phase animation).
|
|
104
|
+
|
|
105
|
+
- **README fix: `Easing Curves` snippet.** The v1.2.0 snippet was missing
|
|
106
|
+
the `stops` variable declaration. Now copy-paste runnable.
|
|
107
|
+
|
|
108
|
+
### Notes
|
|
109
|
+
|
|
110
|
+
- 1880 + 7 new tests pass.
|
|
111
|
+
- No new dependencies — still zero runtime deps.
|
|
112
|
+
- All API additions are non-breaking and side-effect-free for existing code.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
6
116
|
## [1.2.0] — Phase 2 complete: animated, eased & conic gradients
|
|
7
117
|
|
|
8
118
|
Minor release closing the **gradient engine roadmap (Phase 2)** with three
|
package/README.es.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
_Colores • Gradientes • Animaciones • ASCII Art • Pixel Art • Árboles • Componentes • Temas_
|
|
8
8
|
|
|
9
9
|
[](LICENSE)
|
|
10
|
-
[](https://www.npmjs.com/package/ansimax)
|
|
11
11
|
[](tsconfig.json)
|
|
12
12
|
[](#testing)
|
|
13
13
|
[](#testing)
|
|
@@ -216,10 +216,17 @@ const ctrl = animateGradient('Cargando...', ['#ff79c6', '#bd93f9', '#8be9fd'], {
|
|
|
216
216
|
|
|
217
217
|
await sleep(3000);
|
|
218
218
|
ctrl.stop();
|
|
219
|
+
|
|
220
|
+
// v1.2.2: await directo (no se necesita .done)
|
|
221
|
+
await animateGradient('¡Listo!', ['#50fa7b', '#bd93f9'], {
|
|
222
|
+
infinite: false, cycles: 2, duration: 800,
|
|
223
|
+
});
|
|
219
224
|
```
|
|
220
225
|
|
|
221
226
|
### Curvas de interpolación (v1.2.0)
|
|
222
227
|
|
|
228
|
+
<img src="media/easing_curves.png" alt="Colors and gradients" />
|
|
229
|
+
|
|
223
230
|
```ts
|
|
224
231
|
import { gradient } from 'ansimax';
|
|
225
232
|
|
|
@@ -238,6 +245,8 @@ console.log(gradient('hola mundo', stops, { easing: (t) => t * t * t }));
|
|
|
238
245
|
|
|
239
246
|
### Gradientes cónicos (v1.2.0)
|
|
240
247
|
|
|
248
|
+
<img src="media/conic_gradients.png" alt="Colors and gradients" />
|
|
249
|
+
|
|
241
250
|
```ts
|
|
242
251
|
import { gradientRect } from 'ansimax';
|
|
243
252
|
|
|
@@ -251,6 +260,28 @@ console.log(gradientRect({
|
|
|
251
260
|
}));
|
|
252
261
|
```
|
|
253
262
|
|
|
263
|
+
### Gradientes reusables (v1.2.3)
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import { createGradient, ascii } from 'ansimax';
|
|
267
|
+
|
|
268
|
+
// Pre-resuelve los stops de hex una vez — significativamente más rápido para uso repetido
|
|
269
|
+
const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
|
|
270
|
+
|
|
271
|
+
console.log(fire('Primera línea'));
|
|
272
|
+
console.log(fire('Segunda línea'));
|
|
273
|
+
console.log(fire('Tercera línea'));
|
|
274
|
+
|
|
275
|
+
// Úsalo como colorFn para banners — misma firma de ColorFn
|
|
276
|
+
console.log(ascii.banner('FIRE', { colorFn: fire }));
|
|
277
|
+
|
|
278
|
+
// Las opciones por-llamada aún funcionan — perfecto para animación
|
|
279
|
+
for (let p = 0; p < 1; p += 0.05) {
|
|
280
|
+
process.stdout.write('\r' + fire('fluyendo', { phase: p }));
|
|
281
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
254
285
|
### ASCII Art
|
|
255
286
|
|
|
256
287
|
<img src="media/ascii_art.png" alt="ASCII art" />
|
|
@@ -326,7 +357,7 @@ console.log(components.table([
|
|
|
326
357
|
['loaders', color.green('● listo'), '100%'],
|
|
327
358
|
], { borderStyle: 'rounded' }));
|
|
328
359
|
|
|
329
|
-
console.log(components.badge('VERSION', 'v1.2.
|
|
360
|
+
console.log(components.badge('VERSION', 'v1.2.3'));
|
|
330
361
|
console.log(components.badge('BUILD', 'passing'));
|
|
331
362
|
```
|
|
332
363
|
|
|
@@ -728,6 +759,36 @@ ansimax/
|
|
|
728
759
|
|
|
729
760
|
## 📝 Changelog
|
|
730
761
|
|
|
762
|
+
### v1.2.3 — Factory de gradientes + performance
|
|
763
|
+
|
|
764
|
+
Release patch añadiendo una API orientada a performance:
|
|
765
|
+
|
|
766
|
+
- ⚡ **Factory `createGradient()`** — pre-resuelve los stops de hex una vez para reuso, ~40-60% más rápido en loops de animación y colorizado en bulk
|
|
767
|
+
- 📖 Más JSDoc con ejemplos ejecutables
|
|
768
|
+
- 🎯 Coincide con la firma `ColorFn` — funciona como `colorFn` en `ascii.banner`, themes, etc.
|
|
769
|
+
|
|
770
|
+
```ts
|
|
771
|
+
import { createGradient } from 'ansimax';
|
|
772
|
+
|
|
773
|
+
const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
|
|
774
|
+
console.log(fire('¡Colores reusados!'));
|
|
775
|
+
console.log(ascii.banner('FIRE', { colorFn: fire }));
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Drop-in replacement para `1.2.2`.
|
|
779
|
+
|
|
780
|
+
### v1.2.2 — Pulido de calidad
|
|
781
|
+
|
|
782
|
+
Release patch enfocado en ergonomía de API y refinamientos de robustez.
|
|
783
|
+
|
|
784
|
+
- ✨ **`animateGradient` ahora es thenable** — `await animateGradient(...)` directo sin `.done`
|
|
785
|
+
- 🎯 **Códigos de error estables** — los errores de tema llevan propiedad `.code` (`ANSIMAX_UNKNOWN_THEME`, etc.) para `catch` programático
|
|
786
|
+
- 🛡️ **Seguridad en sandboxes** — `animateGradient` ya no crashea cuando `process.stdout` no está disponible (workers, edge runtimes)
|
|
787
|
+
- 📖 **Mejor JSDoc** — `gradient()` ahora muestra IntelliSense completo con ejemplos
|
|
788
|
+
- 🐛 **Fix de README** — snippet de Easing Curves ahora es ejecutable copy-paste
|
|
789
|
+
|
|
790
|
+
Drop-in replacement para `1.2.0`.
|
|
791
|
+
|
|
731
792
|
### v1.2.0 — Fase 2 completa: gradientes animados, easing y cónicos
|
|
732
793
|
|
|
733
794
|
Release minor que cierra el roadmap del motor de gradientes con tres features potentes:
|
|
@@ -862,4 +923,4 @@ Ansimax está licenciada bajo **Apache License, Version 2.0** — una licencia p
|
|
|
862
923
|
|
|
863
924
|
Si Ansimax te ayuda a hacer mejores CLIs, ¡dale ⭐ en [GitHub](https://github.com/Brashkie/ansimax)!
|
|
864
925
|
|
|
865
|
-
</div>
|
|
926
|
+
</div>
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
_Colors • Gradients • Animations • ASCII Art • Pixel Art • Trees • Components • Themes_
|
|
8
8
|
|
|
9
9
|
[](LICENSE)
|
|
10
|
-
[](https://www.npmjs.com/package/ansimax)
|
|
11
11
|
[](tsconfig.json)
|
|
12
12
|
[](#testing)
|
|
13
13
|
[](#testing)
|
|
@@ -216,6 +216,11 @@ const ctrl = animateGradient('Loading...', ['#ff79c6', '#bd93f9', '#8be9fd'], {
|
|
|
216
216
|
|
|
217
217
|
await sleep(3000);
|
|
218
218
|
ctrl.stop();
|
|
219
|
+
|
|
220
|
+
// v1.2.2: await directly (no .done needed)
|
|
221
|
+
await animateGradient('Done!', ['#50fa7b', '#bd93f9'], {
|
|
222
|
+
infinite: false, cycles: 2, duration: 800,
|
|
223
|
+
});
|
|
219
224
|
```
|
|
220
225
|
|
|
221
226
|
### Easing Curves (v1.2.0)
|
|
@@ -255,6 +260,28 @@ console.log(gradientRect({
|
|
|
255
260
|
}));
|
|
256
261
|
```
|
|
257
262
|
|
|
263
|
+
### Reusable Gradients (v1.2.3)
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import { createGradient, ascii } from 'ansimax';
|
|
267
|
+
|
|
268
|
+
// Pre-resolve hex stops once — significantly faster for repeated use
|
|
269
|
+
const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
|
|
270
|
+
|
|
271
|
+
console.log(fire('First line'));
|
|
272
|
+
console.log(fire('Second line'));
|
|
273
|
+
console.log(fire('Third line'));
|
|
274
|
+
|
|
275
|
+
// Use as a colorFn for banners — same ColorFn signature
|
|
276
|
+
console.log(ascii.banner('FIRE', { colorFn: fire }));
|
|
277
|
+
|
|
278
|
+
// Per-call options still work — perfect for animation
|
|
279
|
+
for (let p = 0; p < 1; p += 0.05) {
|
|
280
|
+
process.stdout.write('\r' + fire('flowing', { phase: p }));
|
|
281
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
258
285
|
### ASCII Art
|
|
259
286
|
|
|
260
287
|
<img src="media/ascii_art.png" alt="ASCII art" />
|
|
@@ -330,7 +357,7 @@ console.log(components.table([
|
|
|
330
357
|
['loaders', color.green('● ready'), '100%'],
|
|
331
358
|
], { borderStyle: 'rounded' }));
|
|
332
359
|
|
|
333
|
-
console.log(components.badge('VERSION', 'v1.2.
|
|
360
|
+
console.log(components.badge('VERSION', 'v1.2.3'));
|
|
334
361
|
console.log(components.badge('BUILD', 'passing'));
|
|
335
362
|
```
|
|
336
363
|
|
|
@@ -732,6 +759,36 @@ ansimax/
|
|
|
732
759
|
|
|
733
760
|
## 📝 Changelog
|
|
734
761
|
|
|
762
|
+
### v1.2.3 — Gradient factory + performance
|
|
763
|
+
|
|
764
|
+
Patch release adding a performance-oriented API:
|
|
765
|
+
|
|
766
|
+
- ⚡ **`createGradient()` factory** — pre-resolves hex stops once for reuse, ~40-60% faster for animation loops and bulk colorizing
|
|
767
|
+
- 📖 More JSDoc with runnable examples
|
|
768
|
+
- 🎯 Matches the `ColorFn` signature — works as `colorFn` in `ascii.banner`, themes, etc.
|
|
769
|
+
|
|
770
|
+
```ts
|
|
771
|
+
import { createGradient } from 'ansimax';
|
|
772
|
+
|
|
773
|
+
const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
|
|
774
|
+
console.log(fire('Reused colors!'));
|
|
775
|
+
console.log(ascii.banner('FIRE', { colorFn: fire }));
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Drop-in replacement for `1.2.2`.
|
|
779
|
+
|
|
780
|
+
### v1.2.2 — Quality polish
|
|
781
|
+
|
|
782
|
+
Patch release focused on API ergonomics and robustness refinements.
|
|
783
|
+
|
|
784
|
+
- ✨ **`animateGradient` is now thenable** — `await animateGradient(...)` directly without `.done`
|
|
785
|
+
- 🎯 **Stable error codes** — theme errors carry `.code` properties (`ANSIMAX_UNKNOWN_THEME`, etc.) for programmatic catch
|
|
786
|
+
- 🛡️ **Sandbox safety** — `animateGradient` no longer crashes when `process.stdout` is unavailable (workers, edge runtimes)
|
|
787
|
+
- 📖 **Better JSDoc** — `gradient()` now shows full IntelliSense with examples
|
|
788
|
+
- 🐛 **README fix** — Easing Curves snippet now copy-paste runnable
|
|
789
|
+
|
|
790
|
+
Drop-in replacement for `1.2.0`.
|
|
791
|
+
|
|
735
792
|
### v1.2.0 — Phase 2 complete: animated, eased & conic gradients
|
|
736
793
|
|
|
737
794
|
Minor release closing the gradient engine roadmap with three powerful features:
|
|
@@ -866,4 +923,4 @@ Ansimax is licensed under the **Apache License, Version 2.0** — a permissive l
|
|
|
866
923
|
|
|
867
924
|
If Ansimax helps you ship better CLIs, give it a ⭐ on [GitHub](https://github.com/Brashkie/ansimax)!
|
|
868
925
|
|
|
869
|
-
</div>
|
|
926
|
+
</div>
|
package/dist/index.d.mts
CHANGED
|
@@ -565,7 +565,64 @@ interface GradientOptions {
|
|
|
565
565
|
*/
|
|
566
566
|
phase?: number;
|
|
567
567
|
}
|
|
568
|
+
/**
|
|
569
|
+
* Apply a multi-stop color gradient across the visible characters of `text`.
|
|
570
|
+
* ANSI escapes are skipped, and Unicode wide characters / graphemes are
|
|
571
|
+
* counted correctly.
|
|
572
|
+
*
|
|
573
|
+
* @param text - The text to colorize. Non-string inputs are coerced via `String(text)`.
|
|
574
|
+
* @param stops - Array of hex colors (`#rgb` or `#rrggbb`). At least 1 required.
|
|
575
|
+
* Invalid stops are silently dropped; an empty array returns input as-is.
|
|
576
|
+
* @param opts - Optional configuration. See `GradientOptions`.
|
|
577
|
+
*
|
|
578
|
+
* @returns ANSI-colorized string. Returns input unchanged if `NO_COLOR` is set
|
|
579
|
+
* or if no valid stops are provided.
|
|
580
|
+
*
|
|
581
|
+
* @example
|
|
582
|
+
* ```ts
|
|
583
|
+
* gradient('Hello world!', ['#ff0000', '#00ff00', '#0000ff']);
|
|
584
|
+
* // → ANSI-colored "Hello world!" with smooth color transition
|
|
585
|
+
* ```
|
|
586
|
+
*
|
|
587
|
+
* @example with easing curve
|
|
588
|
+
* ```ts
|
|
589
|
+
* gradient('Smooth text', ['#ff79c6', '#8be9fd'], { easing: 'ease-in-out' });
|
|
590
|
+
* ```
|
|
591
|
+
*
|
|
592
|
+
* @example animated phase shift
|
|
593
|
+
* ```ts
|
|
594
|
+
* setInterval(() => {
|
|
595
|
+
* const phase = (Date.now() / 1000) % 1;
|
|
596
|
+
* process.stdout.write('\r' + gradient('flowing', ['#f00', '#00f'], { phase }));
|
|
597
|
+
* }, 33);
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
568
600
|
declare const gradient: (text: unknown, stops: string[] | null | undefined, opts?: GradientOptions) => string;
|
|
601
|
+
/**
|
|
602
|
+
* A pre-resolved gradient that can be applied repeatedly to different
|
|
603
|
+
* strings without re-parsing hex stops. Useful for hot loops, animation
|
|
604
|
+
* frames, or any case where the same color palette colorizes many texts.
|
|
605
|
+
*
|
|
606
|
+
* The returned function accepts the same per-call options as `gradient()`
|
|
607
|
+
* (e.g. you can still override `phase` per call for animation).
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* ```ts
|
|
611
|
+
* const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
|
|
612
|
+
*
|
|
613
|
+
* console.log(fire('first line'));
|
|
614
|
+
* console.log(fire('second line'));
|
|
615
|
+
*
|
|
616
|
+
* // Use as colorFn for ascii.banner
|
|
617
|
+
* console.log(ascii.banner('FIRE', { colorFn: fire }));
|
|
618
|
+
*
|
|
619
|
+
* // Animate by overriding phase per frame
|
|
620
|
+
* for (let p = 0; p < 1; p += 0.05) {
|
|
621
|
+
* console.log(fire('flowing', { phase: p }));
|
|
622
|
+
* }
|
|
623
|
+
* ```
|
|
624
|
+
*/
|
|
625
|
+
declare const createGradient: (stops: string[] | null | undefined, defaultOpts?: Omit<GradientOptions, "phase">) => ((text: unknown, opts?: GradientOptions) => string);
|
|
569
626
|
declare const rainbow: ColorFn;
|
|
570
627
|
interface AnimateGradientOptions {
|
|
571
628
|
/** Total animation duration in ms. Default `2000`. */
|
|
@@ -614,6 +671,15 @@ interface AnimateGradientController {
|
|
|
614
671
|
stop: () => void;
|
|
615
672
|
/** Promise that resolves when animation finishes (stop / abort / cycle limit). */
|
|
616
673
|
done: Promise<void>;
|
|
674
|
+
/**
|
|
675
|
+
* Thenable hook — lets you `await animateGradient(...)` directly.
|
|
676
|
+
* Equivalent to `await ctrl.done`.
|
|
677
|
+
*/
|
|
678
|
+
then: Promise<void>['then'];
|
|
679
|
+
/** Equivalent to `ctrl.done.catch(...)`. */
|
|
680
|
+
catch: Promise<void>['catch'];
|
|
681
|
+
/** Equivalent to `ctrl.done.finally(...)`. */
|
|
682
|
+
finally: Promise<void>['finally'];
|
|
617
683
|
}
|
|
618
684
|
declare const animateGradient: (text: string, stops: string[], opts?: AnimateGradientOptions) => AnimateGradientController;
|
|
619
685
|
declare const PRESET_DEFS: {
|
|
@@ -1701,4 +1767,4 @@ declare const ansimax: {
|
|
|
1701
1767
|
configure: (opts?: AnsimaxConfig, meta?: ConfigureOptions) => void;
|
|
1702
1768
|
};
|
|
1703
1769
|
|
|
1704
|
-
export { type AnimateGradientController, type AnimateGradientOptions, type AnimationHooks, type AnimationSpeed, type AnsiCode, type AnsimaxConfig, BEL, BG, type BadgeOptions, type BallOptions, type BannerOptions, type BoxOptions, type BoxStyle, type BreatheOptions, DEFAULTS as CONFIG_DEFAULTS, CSI, type Canvas, type CanvasRenderOptions, type ColorChain, type ColorFn, type ColorLevel, type ColorMode, type ColorSupport, type ColumnsOptions, type ConfigChangeListener, type ConfigKey, type ConfigKeyListener, type ConfigureOptions, type CountdownOptions, type CustomOptions, DEFAULT_TERM_COLS, DEFAULT_TERM_ROWS, type DebounceOptions, type DiffType, type Dimensions, type DividerOptions, type DotsOptions, ESC, type EasingFn, type EasingName, type EraseMode, FG, FRAME_MS, type FadeOptions, type FontMap, type FontName, type FrameCallback, type FrameHandle, type GlitchOptions, type Glyph, type GradientOptions, type GradientRectOptions, type LineDiff, type LiveController, type LiveOptions, type LoadingBarOptions, type LogoOptions, MENU_CANCELLED, type MemoizeOptions, type MenuInput, type MenuOptions, type MenuOutput, type MenuResult, type MultiLoader, type MultiLoaderItem, OSC, type OnResizeOptions, type OutputBuffer, type ParallelOptions, type ParallelStep, type Pixel, type PixelGrid, type PlayController, type PlayOptions, type PresetName, type ProgressAnimateOptions, type ProgressBarOptions, type ProgressOptions, type PulseOptions, type RGB, type RGBA, type RegisterFontOptions, type RenderOptions, type ResizeListener, type RevealOptions, SPINNERS, SPRITES, ST, STYLE, type SectionOptions, type SleepOptions, type SlideOptions, type SpinOptions, type SpinnerType, type StatusOptions, type StatusType, type StopFn, type StreamOptions, type TableBorderStyle, type TableOptions, type Task, type TaskResult, type TasksOptions, type Theme, type BannerOpts as ThemeBannerOpts, type ThemeChangeListener, type ThemeInstance, type ThemeStyleName, type TimelineEvent, type TimelineOptions, type TreeData, type TreeDimensions, type TreeNode, type RenderOptions$1 as TreeRenderOptions, type TreeStyle, type TypeDeleteOptions, type TypewriterOptions, type WalkVisitor, type WaveOptions, type WriteAsyncOptions, animate, animateGradient, ascii, bell, bg256, bgRgb, box, canAnimate, cancelTerminalFrame, center, chain, charWidth, clamp, clearAnsiCache, clearColorCache, clearRenderCache, clearThemeColorCache, color, colorLevel, presets as colorPresets, components, compose, configure, countNodes, createCanvas, createOutputBuffer, createTheme, cursor, debounce, ansimax as default, diffLines, escapeRegex, fg256, fgRgb, filterTree, findInTree, flipHorizontal, flipVertical, frames, getConfig, getConfigValue, getRenderCacheSize, getSpeedMultiplier, getTerminalHeight, getTerminalWidth, gradient, gradientColor, gradientRect, graphemes, hasFont, hexToRgb, hideCursor, images, isHexColor, isNoColor, lerp, lerpColor, link, listFonts, listPresets, loader, mapTree, measureTree, memoize, nextTick, onConfigChange, onConfigKeyChange, onResize, once, padBoth, padEnd, padStart, pauseListeners, presetNames, rainbow, registerFont, registerPreset, renderPixelArt, renderTree, renderTreeStream, repeatVisible, requestTerminalFrame, reset, resetColorSupportCache, resetConfig, resetCursorRefCount, resetFramesCursorCount, resetLoaderCursorCount, resetNoColor, resumeListeners, rgbTo256, rgbToHex, rotate90, safeJson, screen, setNoColor, setTitle, sgr, showCursor, sleep, sleepFrame, sliceAnsi, stripAnsi$1 as stripAnsi, stripAnsi$2 as stripAnsiCodes, stripAnsi as stripAnsiColors, supportsColor, supportsColorLevel, termSize, themes, throttle, tree, trees, truncateAnsi, visibleLen, walkTree, withConfig, wordWrap, wrapAnsi, write, writeAsync, writeErr, writeln, writelnErr };
|
|
1770
|
+
export { type AnimateGradientController, type AnimateGradientOptions, type AnimationHooks, type AnimationSpeed, type AnsiCode, type AnsimaxConfig, BEL, BG, type BadgeOptions, type BallOptions, type BannerOptions, type BoxOptions, type BoxStyle, type BreatheOptions, DEFAULTS as CONFIG_DEFAULTS, CSI, type Canvas, type CanvasRenderOptions, type ColorChain, type ColorFn, type ColorLevel, type ColorMode, type ColorSupport, type ColumnsOptions, type ConfigChangeListener, type ConfigKey, type ConfigKeyListener, type ConfigureOptions, type CountdownOptions, type CustomOptions, DEFAULT_TERM_COLS, DEFAULT_TERM_ROWS, type DebounceOptions, type DiffType, type Dimensions, type DividerOptions, type DotsOptions, ESC, type EasingFn, type EasingName, type EraseMode, FG, FRAME_MS, type FadeOptions, type FontMap, type FontName, type FrameCallback, type FrameHandle, type GlitchOptions, type Glyph, type GradientOptions, type GradientRectOptions, type LineDiff, type LiveController, type LiveOptions, type LoadingBarOptions, type LogoOptions, MENU_CANCELLED, type MemoizeOptions, type MenuInput, type MenuOptions, type MenuOutput, type MenuResult, type MultiLoader, type MultiLoaderItem, OSC, type OnResizeOptions, type OutputBuffer, type ParallelOptions, type ParallelStep, type Pixel, type PixelGrid, type PlayController, type PlayOptions, type PresetName, type ProgressAnimateOptions, type ProgressBarOptions, type ProgressOptions, type PulseOptions, type RGB, type RGBA, type RegisterFontOptions, type RenderOptions, type ResizeListener, type RevealOptions, SPINNERS, SPRITES, ST, STYLE, type SectionOptions, type SleepOptions, type SlideOptions, type SpinOptions, type SpinnerType, type StatusOptions, type StatusType, type StopFn, type StreamOptions, type TableBorderStyle, type TableOptions, type Task, type TaskResult, type TasksOptions, type Theme, type BannerOpts as ThemeBannerOpts, type ThemeChangeListener, type ThemeInstance, type ThemeStyleName, type TimelineEvent, type TimelineOptions, type TreeData, type TreeDimensions, type TreeNode, type RenderOptions$1 as TreeRenderOptions, type TreeStyle, type TypeDeleteOptions, type TypewriterOptions, type WalkVisitor, type WaveOptions, type WriteAsyncOptions, animate, animateGradient, ascii, bell, bg256, bgRgb, box, canAnimate, cancelTerminalFrame, center, chain, charWidth, clamp, clearAnsiCache, clearColorCache, clearRenderCache, clearThemeColorCache, color, colorLevel, presets as colorPresets, components, compose, configure, countNodes, createCanvas, createGradient, createOutputBuffer, createTheme, cursor, debounce, ansimax as default, diffLines, escapeRegex, fg256, fgRgb, filterTree, findInTree, flipHorizontal, flipVertical, frames, getConfig, getConfigValue, getRenderCacheSize, getSpeedMultiplier, getTerminalHeight, getTerminalWidth, gradient, gradientColor, gradientRect, graphemes, hasFont, hexToRgb, hideCursor, images, isHexColor, isNoColor, lerp, lerpColor, link, listFonts, listPresets, loader, mapTree, measureTree, memoize, nextTick, onConfigChange, onConfigKeyChange, onResize, once, padBoth, padEnd, padStart, pauseListeners, presetNames, rainbow, registerFont, registerPreset, renderPixelArt, renderTree, renderTreeStream, repeatVisible, requestTerminalFrame, reset, resetColorSupportCache, resetConfig, resetCursorRefCount, resetFramesCursorCount, resetLoaderCursorCount, resetNoColor, resumeListeners, rgbTo256, rgbToHex, rotate90, safeJson, screen, setNoColor, setTitle, sgr, showCursor, sleep, sleepFrame, sliceAnsi, stripAnsi$1 as stripAnsi, stripAnsi$2 as stripAnsiCodes, stripAnsi as stripAnsiColors, supportsColor, supportsColorLevel, termSize, themes, throttle, tree, trees, truncateAnsi, visibleLen, walkTree, withConfig, wordWrap, wrapAnsi, write, writeAsync, writeErr, writeln, writelnErr };
|
package/dist/index.d.ts
CHANGED
|
@@ -565,7 +565,64 @@ interface GradientOptions {
|
|
|
565
565
|
*/
|
|
566
566
|
phase?: number;
|
|
567
567
|
}
|
|
568
|
+
/**
|
|
569
|
+
* Apply a multi-stop color gradient across the visible characters of `text`.
|
|
570
|
+
* ANSI escapes are skipped, and Unicode wide characters / graphemes are
|
|
571
|
+
* counted correctly.
|
|
572
|
+
*
|
|
573
|
+
* @param text - The text to colorize. Non-string inputs are coerced via `String(text)`.
|
|
574
|
+
* @param stops - Array of hex colors (`#rgb` or `#rrggbb`). At least 1 required.
|
|
575
|
+
* Invalid stops are silently dropped; an empty array returns input as-is.
|
|
576
|
+
* @param opts - Optional configuration. See `GradientOptions`.
|
|
577
|
+
*
|
|
578
|
+
* @returns ANSI-colorized string. Returns input unchanged if `NO_COLOR` is set
|
|
579
|
+
* or if no valid stops are provided.
|
|
580
|
+
*
|
|
581
|
+
* @example
|
|
582
|
+
* ```ts
|
|
583
|
+
* gradient('Hello world!', ['#ff0000', '#00ff00', '#0000ff']);
|
|
584
|
+
* // → ANSI-colored "Hello world!" with smooth color transition
|
|
585
|
+
* ```
|
|
586
|
+
*
|
|
587
|
+
* @example with easing curve
|
|
588
|
+
* ```ts
|
|
589
|
+
* gradient('Smooth text', ['#ff79c6', '#8be9fd'], { easing: 'ease-in-out' });
|
|
590
|
+
* ```
|
|
591
|
+
*
|
|
592
|
+
* @example animated phase shift
|
|
593
|
+
* ```ts
|
|
594
|
+
* setInterval(() => {
|
|
595
|
+
* const phase = (Date.now() / 1000) % 1;
|
|
596
|
+
* process.stdout.write('\r' + gradient('flowing', ['#f00', '#00f'], { phase }));
|
|
597
|
+
* }, 33);
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
568
600
|
declare const gradient: (text: unknown, stops: string[] | null | undefined, opts?: GradientOptions) => string;
|
|
601
|
+
/**
|
|
602
|
+
* A pre-resolved gradient that can be applied repeatedly to different
|
|
603
|
+
* strings without re-parsing hex stops. Useful for hot loops, animation
|
|
604
|
+
* frames, or any case where the same color palette colorizes many texts.
|
|
605
|
+
*
|
|
606
|
+
* The returned function accepts the same per-call options as `gradient()`
|
|
607
|
+
* (e.g. you can still override `phase` per call for animation).
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* ```ts
|
|
611
|
+
* const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
|
|
612
|
+
*
|
|
613
|
+
* console.log(fire('first line'));
|
|
614
|
+
* console.log(fire('second line'));
|
|
615
|
+
*
|
|
616
|
+
* // Use as colorFn for ascii.banner
|
|
617
|
+
* console.log(ascii.banner('FIRE', { colorFn: fire }));
|
|
618
|
+
*
|
|
619
|
+
* // Animate by overriding phase per frame
|
|
620
|
+
* for (let p = 0; p < 1; p += 0.05) {
|
|
621
|
+
* console.log(fire('flowing', { phase: p }));
|
|
622
|
+
* }
|
|
623
|
+
* ```
|
|
624
|
+
*/
|
|
625
|
+
declare const createGradient: (stops: string[] | null | undefined, defaultOpts?: Omit<GradientOptions, "phase">) => ((text: unknown, opts?: GradientOptions) => string);
|
|
569
626
|
declare const rainbow: ColorFn;
|
|
570
627
|
interface AnimateGradientOptions {
|
|
571
628
|
/** Total animation duration in ms. Default `2000`. */
|
|
@@ -614,6 +671,15 @@ interface AnimateGradientController {
|
|
|
614
671
|
stop: () => void;
|
|
615
672
|
/** Promise that resolves when animation finishes (stop / abort / cycle limit). */
|
|
616
673
|
done: Promise<void>;
|
|
674
|
+
/**
|
|
675
|
+
* Thenable hook — lets you `await animateGradient(...)` directly.
|
|
676
|
+
* Equivalent to `await ctrl.done`.
|
|
677
|
+
*/
|
|
678
|
+
then: Promise<void>['then'];
|
|
679
|
+
/** Equivalent to `ctrl.done.catch(...)`. */
|
|
680
|
+
catch: Promise<void>['catch'];
|
|
681
|
+
/** Equivalent to `ctrl.done.finally(...)`. */
|
|
682
|
+
finally: Promise<void>['finally'];
|
|
617
683
|
}
|
|
618
684
|
declare const animateGradient: (text: string, stops: string[], opts?: AnimateGradientOptions) => AnimateGradientController;
|
|
619
685
|
declare const PRESET_DEFS: {
|
|
@@ -1701,4 +1767,4 @@ declare const ansimax: {
|
|
|
1701
1767
|
configure: (opts?: AnsimaxConfig, meta?: ConfigureOptions) => void;
|
|
1702
1768
|
};
|
|
1703
1769
|
|
|
1704
|
-
export { type AnimateGradientController, type AnimateGradientOptions, type AnimationHooks, type AnimationSpeed, type AnsiCode, type AnsimaxConfig, BEL, BG, type BadgeOptions, type BallOptions, type BannerOptions, type BoxOptions, type BoxStyle, type BreatheOptions, DEFAULTS as CONFIG_DEFAULTS, CSI, type Canvas, type CanvasRenderOptions, type ColorChain, type ColorFn, type ColorLevel, type ColorMode, type ColorSupport, type ColumnsOptions, type ConfigChangeListener, type ConfigKey, type ConfigKeyListener, type ConfigureOptions, type CountdownOptions, type CustomOptions, DEFAULT_TERM_COLS, DEFAULT_TERM_ROWS, type DebounceOptions, type DiffType, type Dimensions, type DividerOptions, type DotsOptions, ESC, type EasingFn, type EasingName, type EraseMode, FG, FRAME_MS, type FadeOptions, type FontMap, type FontName, type FrameCallback, type FrameHandle, type GlitchOptions, type Glyph, type GradientOptions, type GradientRectOptions, type LineDiff, type LiveController, type LiveOptions, type LoadingBarOptions, type LogoOptions, MENU_CANCELLED, type MemoizeOptions, type MenuInput, type MenuOptions, type MenuOutput, type MenuResult, type MultiLoader, type MultiLoaderItem, OSC, type OnResizeOptions, type OutputBuffer, type ParallelOptions, type ParallelStep, type Pixel, type PixelGrid, type PlayController, type PlayOptions, type PresetName, type ProgressAnimateOptions, type ProgressBarOptions, type ProgressOptions, type PulseOptions, type RGB, type RGBA, type RegisterFontOptions, type RenderOptions, type ResizeListener, type RevealOptions, SPINNERS, SPRITES, ST, STYLE, type SectionOptions, type SleepOptions, type SlideOptions, type SpinOptions, type SpinnerType, type StatusOptions, type StatusType, type StopFn, type StreamOptions, type TableBorderStyle, type TableOptions, type Task, type TaskResult, type TasksOptions, type Theme, type BannerOpts as ThemeBannerOpts, type ThemeChangeListener, type ThemeInstance, type ThemeStyleName, type TimelineEvent, type TimelineOptions, type TreeData, type TreeDimensions, type TreeNode, type RenderOptions$1 as TreeRenderOptions, type TreeStyle, type TypeDeleteOptions, type TypewriterOptions, type WalkVisitor, type WaveOptions, type WriteAsyncOptions, animate, animateGradient, ascii, bell, bg256, bgRgb, box, canAnimate, cancelTerminalFrame, center, chain, charWidth, clamp, clearAnsiCache, clearColorCache, clearRenderCache, clearThemeColorCache, color, colorLevel, presets as colorPresets, components, compose, configure, countNodes, createCanvas, createOutputBuffer, createTheme, cursor, debounce, ansimax as default, diffLines, escapeRegex, fg256, fgRgb, filterTree, findInTree, flipHorizontal, flipVertical, frames, getConfig, getConfigValue, getRenderCacheSize, getSpeedMultiplier, getTerminalHeight, getTerminalWidth, gradient, gradientColor, gradientRect, graphemes, hasFont, hexToRgb, hideCursor, images, isHexColor, isNoColor, lerp, lerpColor, link, listFonts, listPresets, loader, mapTree, measureTree, memoize, nextTick, onConfigChange, onConfigKeyChange, onResize, once, padBoth, padEnd, padStart, pauseListeners, presetNames, rainbow, registerFont, registerPreset, renderPixelArt, renderTree, renderTreeStream, repeatVisible, requestTerminalFrame, reset, resetColorSupportCache, resetConfig, resetCursorRefCount, resetFramesCursorCount, resetLoaderCursorCount, resetNoColor, resumeListeners, rgbTo256, rgbToHex, rotate90, safeJson, screen, setNoColor, setTitle, sgr, showCursor, sleep, sleepFrame, sliceAnsi, stripAnsi$1 as stripAnsi, stripAnsi$2 as stripAnsiCodes, stripAnsi as stripAnsiColors, supportsColor, supportsColorLevel, termSize, themes, throttle, tree, trees, truncateAnsi, visibleLen, walkTree, withConfig, wordWrap, wrapAnsi, write, writeAsync, writeErr, writeln, writelnErr };
|
|
1770
|
+
export { type AnimateGradientController, type AnimateGradientOptions, type AnimationHooks, type AnimationSpeed, type AnsiCode, type AnsimaxConfig, BEL, BG, type BadgeOptions, type BallOptions, type BannerOptions, type BoxOptions, type BoxStyle, type BreatheOptions, DEFAULTS as CONFIG_DEFAULTS, CSI, type Canvas, type CanvasRenderOptions, type ColorChain, type ColorFn, type ColorLevel, type ColorMode, type ColorSupport, type ColumnsOptions, type ConfigChangeListener, type ConfigKey, type ConfigKeyListener, type ConfigureOptions, type CountdownOptions, type CustomOptions, DEFAULT_TERM_COLS, DEFAULT_TERM_ROWS, type DebounceOptions, type DiffType, type Dimensions, type DividerOptions, type DotsOptions, ESC, type EasingFn, type EasingName, type EraseMode, FG, FRAME_MS, type FadeOptions, type FontMap, type FontName, type FrameCallback, type FrameHandle, type GlitchOptions, type Glyph, type GradientOptions, type GradientRectOptions, type LineDiff, type LiveController, type LiveOptions, type LoadingBarOptions, type LogoOptions, MENU_CANCELLED, type MemoizeOptions, type MenuInput, type MenuOptions, type MenuOutput, type MenuResult, type MultiLoader, type MultiLoaderItem, OSC, type OnResizeOptions, type OutputBuffer, type ParallelOptions, type ParallelStep, type Pixel, type PixelGrid, type PlayController, type PlayOptions, type PresetName, type ProgressAnimateOptions, type ProgressBarOptions, type ProgressOptions, type PulseOptions, type RGB, type RGBA, type RegisterFontOptions, type RenderOptions, type ResizeListener, type RevealOptions, SPINNERS, SPRITES, ST, STYLE, type SectionOptions, type SleepOptions, type SlideOptions, type SpinOptions, type SpinnerType, type StatusOptions, type StatusType, type StopFn, type StreamOptions, type TableBorderStyle, type TableOptions, type Task, type TaskResult, type TasksOptions, type Theme, type BannerOpts as ThemeBannerOpts, type ThemeChangeListener, type ThemeInstance, type ThemeStyleName, type TimelineEvent, type TimelineOptions, type TreeData, type TreeDimensions, type TreeNode, type RenderOptions$1 as TreeRenderOptions, type TreeStyle, type TypeDeleteOptions, type TypewriterOptions, type WalkVisitor, type WaveOptions, type WriteAsyncOptions, animate, animateGradient, ascii, bell, bg256, bgRgb, box, canAnimate, cancelTerminalFrame, center, chain, charWidth, clamp, clearAnsiCache, clearColorCache, clearRenderCache, clearThemeColorCache, color, colorLevel, presets as colorPresets, components, compose, configure, countNodes, createCanvas, createGradient, createOutputBuffer, createTheme, cursor, debounce, ansimax as default, diffLines, escapeRegex, fg256, fgRgb, filterTree, findInTree, flipHorizontal, flipVertical, frames, getConfig, getConfigValue, getRenderCacheSize, getSpeedMultiplier, getTerminalHeight, getTerminalWidth, gradient, gradientColor, gradientRect, graphemes, hasFont, hexToRgb, hideCursor, images, isHexColor, isNoColor, lerp, lerpColor, link, listFonts, listPresets, loader, mapTree, measureTree, memoize, nextTick, onConfigChange, onConfigKeyChange, onResize, once, padBoth, padEnd, padStart, pauseListeners, presetNames, rainbow, registerFont, registerPreset, renderPixelArt, renderTree, renderTreeStream, repeatVisible, requestTerminalFrame, reset, resetColorSupportCache, resetConfig, resetCursorRefCount, resetFramesCursorCount, resetLoaderCursorCount, resetNoColor, resumeListeners, rgbTo256, rgbToHex, rotate90, safeJson, screen, setNoColor, setTitle, sgr, showCursor, sleep, sleepFrame, sliceAnsi, stripAnsi$1 as stripAnsi, stripAnsi$2 as stripAnsiCodes, stripAnsi as stripAnsiColors, supportsColor, supportsColorLevel, termSize, themes, throttle, tree, trees, truncateAnsi, visibleLen, walkTree, withConfig, wordWrap, wrapAnsi, write, writeAsync, writeErr, writeln, writelnErr };
|
package/dist/index.js
CHANGED
|
@@ -70,6 +70,7 @@ __export(index_exports, {
|
|
|
70
70
|
configure: () => configure,
|
|
71
71
|
countNodes: () => countNodes,
|
|
72
72
|
createCanvas: () => createCanvas,
|
|
73
|
+
createGradient: () => createGradient,
|
|
73
74
|
createOutputBuffer: () => createOutputBuffer,
|
|
74
75
|
createTheme: () => createTheme,
|
|
75
76
|
cursor: () => cursor,
|
|
@@ -1165,6 +1166,28 @@ var gradient = (text, stops, opts = {}) => {
|
|
|
1165
1166
|
}
|
|
1166
1167
|
return _gradientAnsiAware(s, colors, easingFn, phaseN);
|
|
1167
1168
|
};
|
|
1169
|
+
var createGradient = (stops, defaultOpts = {}) => {
|
|
1170
|
+
const colors = Array.isArray(stops) ? stops.map(safeHex).filter((c) => c !== null) : [];
|
|
1171
|
+
const defaultEasingFn = resolveEasing(defaultOpts.easing);
|
|
1172
|
+
const defaultPreserveAnsi = defaultOpts.preserveAnsi ?? false;
|
|
1173
|
+
return (text, opts = {}) => {
|
|
1174
|
+
const s = coerceText(text);
|
|
1175
|
+
if (!s || isNoColor()) return s;
|
|
1176
|
+
if (colors.length === 0) return s;
|
|
1177
|
+
if (colors.length === 1) {
|
|
1178
|
+
const c = colors[0];
|
|
1179
|
+
return adaptiveFg(c.r, c.g, c.b) + s + reset();
|
|
1180
|
+
}
|
|
1181
|
+
const easingFn = opts.easing !== void 0 ? resolveEasing(opts.easing) : defaultEasingFn;
|
|
1182
|
+
const preserveAnsi = opts.preserveAnsi ?? defaultPreserveAnsi;
|
|
1183
|
+
const phase = opts.phase ?? 0;
|
|
1184
|
+
const phaseN = Number.isFinite(phase) ? (phase % 1 + 1) % 1 : 0;
|
|
1185
|
+
if (!preserveAnsi || !s.includes("\x1B")) {
|
|
1186
|
+
return _gradientPlain(s, colors, easingFn, phaseN);
|
|
1187
|
+
}
|
|
1188
|
+
return _gradientAnsiAware(s, colors, easingFn, phaseN);
|
|
1189
|
+
};
|
|
1190
|
+
};
|
|
1168
1191
|
var _gradientPlain = (text, colors, easingFn, phase) => {
|
|
1169
1192
|
const chars = [...text];
|
|
1170
1193
|
const visible = chars.filter((c) => c !== " ").length;
|
|
@@ -1273,7 +1296,13 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1273
1296
|
if (signal) {
|
|
1274
1297
|
if (signal.aborted) {
|
|
1275
1298
|
stop();
|
|
1276
|
-
return {
|
|
1299
|
+
return {
|
|
1300
|
+
stop,
|
|
1301
|
+
done,
|
|
1302
|
+
then: done.then.bind(done),
|
|
1303
|
+
catch: done.catch.bind(done),
|
|
1304
|
+
finally: done.finally.bind(done)
|
|
1305
|
+
};
|
|
1277
1306
|
}
|
|
1278
1307
|
signal.addEventListener("abort", stop, { once: true });
|
|
1279
1308
|
}
|
|
@@ -1288,7 +1317,9 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1288
1317
|
onFrame(frame, phase);
|
|
1289
1318
|
} else {
|
|
1290
1319
|
try {
|
|
1291
|
-
process
|
|
1320
|
+
if (process?.stdout?.write) {
|
|
1321
|
+
process.stdout.write("\r" + frame);
|
|
1322
|
+
}
|
|
1292
1323
|
} catch {
|
|
1293
1324
|
}
|
|
1294
1325
|
}
|
|
@@ -1303,7 +1334,14 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1303
1334
|
if (!stopped) {
|
|
1304
1335
|
timer = setInterval(renderFrame, frameInterval2);
|
|
1305
1336
|
}
|
|
1306
|
-
return {
|
|
1337
|
+
return {
|
|
1338
|
+
stop,
|
|
1339
|
+
done,
|
|
1340
|
+
// Thenable hooks — bind to done so `await ctrl` works directly
|
|
1341
|
+
then: done.then.bind(done),
|
|
1342
|
+
catch: done.catch.bind(done),
|
|
1343
|
+
finally: done.finally.bind(done)
|
|
1344
|
+
};
|
|
1307
1345
|
};
|
|
1308
1346
|
var PRESET_DEFS = {
|
|
1309
1347
|
sunset: ["#ff6b6b", "#feca57", "#48dbfb"],
|
|
@@ -4222,13 +4260,18 @@ var STYLE_NAMES = [
|
|
|
4222
4260
|
"muted",
|
|
4223
4261
|
"text"
|
|
4224
4262
|
];
|
|
4263
|
+
var _themeError = (Ctor, code, message) => {
|
|
4264
|
+
const err = new Ctor(message);
|
|
4265
|
+
err.code = code;
|
|
4266
|
+
return err;
|
|
4267
|
+
};
|
|
4225
4268
|
var validateTheme = (t) => {
|
|
4226
4269
|
if (typeof t !== "object" || t === null || Array.isArray(t)) {
|
|
4227
|
-
throw
|
|
4270
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME", "Theme must be a non-null object.");
|
|
4228
4271
|
}
|
|
4229
4272
|
const obj = t;
|
|
4230
4273
|
if (typeof obj.name !== "string" || obj.name.length === 0) {
|
|
4231
|
-
throw
|
|
4274
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME_NAME", 'Theme must have a non-empty "name" string.');
|
|
4232
4275
|
}
|
|
4233
4276
|
for (const key of REQUIRED_COLOR_KEYS) {
|
|
4234
4277
|
const value = obj[key];
|
|
@@ -4567,7 +4610,9 @@ var themes = {
|
|
|
4567
4610
|
use(name) {
|
|
4568
4611
|
const t = _globalRegistry.get(name);
|
|
4569
4612
|
if (!t) {
|
|
4570
|
-
throw
|
|
4613
|
+
throw _themeError(
|
|
4614
|
+
RangeError,
|
|
4615
|
+
"ANSIMAX_UNKNOWN_THEME",
|
|
4571
4616
|
`Theme "${name}" not found. Available themes: ${[..._globalRegistry.keys()].join(", ")}`
|
|
4572
4617
|
);
|
|
4573
4618
|
}
|
|
@@ -5466,6 +5511,7 @@ var index_default = ansimax;
|
|
|
5466
5511
|
configure,
|
|
5467
5512
|
countNodes,
|
|
5468
5513
|
createCanvas,
|
|
5514
|
+
createGradient,
|
|
5469
5515
|
createOutputBuffer,
|
|
5470
5516
|
createTheme,
|
|
5471
5517
|
cursor,
|
package/dist/index.mjs
CHANGED
|
@@ -992,6 +992,28 @@ var gradient = (text, stops, opts = {}) => {
|
|
|
992
992
|
}
|
|
993
993
|
return _gradientAnsiAware(s, colors, easingFn, phaseN);
|
|
994
994
|
};
|
|
995
|
+
var createGradient = (stops, defaultOpts = {}) => {
|
|
996
|
+
const colors = Array.isArray(stops) ? stops.map(safeHex).filter((c) => c !== null) : [];
|
|
997
|
+
const defaultEasingFn = resolveEasing(defaultOpts.easing);
|
|
998
|
+
const defaultPreserveAnsi = defaultOpts.preserveAnsi ?? false;
|
|
999
|
+
return (text, opts = {}) => {
|
|
1000
|
+
const s = coerceText(text);
|
|
1001
|
+
if (!s || isNoColor()) return s;
|
|
1002
|
+
if (colors.length === 0) return s;
|
|
1003
|
+
if (colors.length === 1) {
|
|
1004
|
+
const c = colors[0];
|
|
1005
|
+
return adaptiveFg(c.r, c.g, c.b) + s + reset();
|
|
1006
|
+
}
|
|
1007
|
+
const easingFn = opts.easing !== void 0 ? resolveEasing(opts.easing) : defaultEasingFn;
|
|
1008
|
+
const preserveAnsi = opts.preserveAnsi ?? defaultPreserveAnsi;
|
|
1009
|
+
const phase = opts.phase ?? 0;
|
|
1010
|
+
const phaseN = Number.isFinite(phase) ? (phase % 1 + 1) % 1 : 0;
|
|
1011
|
+
if (!preserveAnsi || !s.includes("\x1B")) {
|
|
1012
|
+
return _gradientPlain(s, colors, easingFn, phaseN);
|
|
1013
|
+
}
|
|
1014
|
+
return _gradientAnsiAware(s, colors, easingFn, phaseN);
|
|
1015
|
+
};
|
|
1016
|
+
};
|
|
995
1017
|
var _gradientPlain = (text, colors, easingFn, phase) => {
|
|
996
1018
|
const chars = [...text];
|
|
997
1019
|
const visible = chars.filter((c) => c !== " ").length;
|
|
@@ -1100,7 +1122,13 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1100
1122
|
if (signal) {
|
|
1101
1123
|
if (signal.aborted) {
|
|
1102
1124
|
stop();
|
|
1103
|
-
return {
|
|
1125
|
+
return {
|
|
1126
|
+
stop,
|
|
1127
|
+
done,
|
|
1128
|
+
then: done.then.bind(done),
|
|
1129
|
+
catch: done.catch.bind(done),
|
|
1130
|
+
finally: done.finally.bind(done)
|
|
1131
|
+
};
|
|
1104
1132
|
}
|
|
1105
1133
|
signal.addEventListener("abort", stop, { once: true });
|
|
1106
1134
|
}
|
|
@@ -1115,7 +1143,9 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1115
1143
|
onFrame(frame, phase);
|
|
1116
1144
|
} else {
|
|
1117
1145
|
try {
|
|
1118
|
-
process
|
|
1146
|
+
if (process?.stdout?.write) {
|
|
1147
|
+
process.stdout.write("\r" + frame);
|
|
1148
|
+
}
|
|
1119
1149
|
} catch {
|
|
1120
1150
|
}
|
|
1121
1151
|
}
|
|
@@ -1130,7 +1160,14 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1130
1160
|
if (!stopped) {
|
|
1131
1161
|
timer = setInterval(renderFrame, frameInterval2);
|
|
1132
1162
|
}
|
|
1133
|
-
return {
|
|
1163
|
+
return {
|
|
1164
|
+
stop,
|
|
1165
|
+
done,
|
|
1166
|
+
// Thenable hooks — bind to done so `await ctrl` works directly
|
|
1167
|
+
then: done.then.bind(done),
|
|
1168
|
+
catch: done.catch.bind(done),
|
|
1169
|
+
finally: done.finally.bind(done)
|
|
1170
|
+
};
|
|
1134
1171
|
};
|
|
1135
1172
|
var PRESET_DEFS = {
|
|
1136
1173
|
sunset: ["#ff6b6b", "#feca57", "#48dbfb"],
|
|
@@ -4049,13 +4086,18 @@ var STYLE_NAMES = [
|
|
|
4049
4086
|
"muted",
|
|
4050
4087
|
"text"
|
|
4051
4088
|
];
|
|
4089
|
+
var _themeError = (Ctor, code, message) => {
|
|
4090
|
+
const err = new Ctor(message);
|
|
4091
|
+
err.code = code;
|
|
4092
|
+
return err;
|
|
4093
|
+
};
|
|
4052
4094
|
var validateTheme = (t) => {
|
|
4053
4095
|
if (typeof t !== "object" || t === null || Array.isArray(t)) {
|
|
4054
|
-
throw
|
|
4096
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME", "Theme must be a non-null object.");
|
|
4055
4097
|
}
|
|
4056
4098
|
const obj = t;
|
|
4057
4099
|
if (typeof obj.name !== "string" || obj.name.length === 0) {
|
|
4058
|
-
throw
|
|
4100
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME_NAME", 'Theme must have a non-empty "name" string.');
|
|
4059
4101
|
}
|
|
4060
4102
|
for (const key of REQUIRED_COLOR_KEYS) {
|
|
4061
4103
|
const value = obj[key];
|
|
@@ -4394,7 +4436,9 @@ var themes = {
|
|
|
4394
4436
|
use(name) {
|
|
4395
4437
|
const t = _globalRegistry.get(name);
|
|
4396
4438
|
if (!t) {
|
|
4397
|
-
throw
|
|
4439
|
+
throw _themeError(
|
|
4440
|
+
RangeError,
|
|
4441
|
+
"ANSIMAX_UNKNOWN_THEME",
|
|
4398
4442
|
`Theme "${name}" not found. Available themes: ${[..._globalRegistry.keys()].join(", ")}`
|
|
4399
4443
|
);
|
|
4400
4444
|
}
|
|
@@ -5292,6 +5336,7 @@ export {
|
|
|
5292
5336
|
configure,
|
|
5293
5337
|
countNodes,
|
|
5294
5338
|
createCanvas,
|
|
5339
|
+
createGradient,
|
|
5295
5340
|
createOutputBuffer,
|
|
5296
5341
|
createTheme,
|
|
5297
5342
|
cursor,
|
package/examples/all-in-one.cjs
CHANGED
|
@@ -118,7 +118,7 @@ async function main() {
|
|
|
118
118
|
console.log(components.section('🏷️ Badges & Status', { width: 60 }));
|
|
119
119
|
console.log();
|
|
120
120
|
console.log(' ',
|
|
121
|
-
components.badge('VERSION', 'v1.2.
|
|
121
|
+
components.badge('VERSION', 'v1.2.3'),
|
|
122
122
|
components.badge('BUILD', 'passing'),
|
|
123
123
|
components.badge('LICENSE', 'Apache 2.0'));
|
|
124
124
|
console.log();
|
package/examples/all-in-one.mjs
CHANGED
|
@@ -117,7 +117,7 @@ console.log();
|
|
|
117
117
|
console.log(components.section('🏷️ Badges & Status', { width: 60 }));
|
|
118
118
|
console.log();
|
|
119
119
|
console.log(' ',
|
|
120
|
-
components.badge('VERSION', 'v1.2.
|
|
120
|
+
components.badge('VERSION', 'v1.2.3'),
|
|
121
121
|
components.badge('BUILD', 'passing'),
|
|
122
122
|
components.badge('LICENSE', 'Apache 2.0'));
|
|
123
123
|
console.log();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ansimax",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "Zero-dependency CLI rendering library: colors, gradients, animations, ASCII art, pixel art, components, and themes
|
|
3
|
+
"version": "1.2.3",
|
|
4
|
+
"description": "Zero-dependency CLI rendering library: colors, gradients, animations, ASCII art, pixel art, components, and themes \u2014 all in TypeScript.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|