ansimax 1.2.0 → 1.2.2
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 +62 -0
- package/README.es.md +31 -8
- package/README.md +31 -8
- package/dist/index.d.mts +41 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +28 -6
- package/dist/index.mjs +28 -6
- package/examples/all-in-one.cjs +1 -1
- package/examples/all-in-one.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,68 @@
|
|
|
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.2] — Quality polish
|
|
7
|
+
|
|
8
|
+
Patch release focused on API ergonomics and robustness refinements. No
|
|
9
|
+
breaking changes — every 1.2.x program runs identically.
|
|
10
|
+
|
|
11
|
+
### Improved
|
|
12
|
+
|
|
13
|
+
- **`animateGradient` controller is now thenable** — you can `await` it
|
|
14
|
+
directly instead of `await ctrl.done`:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// Before (v1.2.0)
|
|
18
|
+
const ctrl = animateGradient(text, stops, { infinite: false, cycles: 1 });
|
|
19
|
+
await ctrl.done;
|
|
20
|
+
|
|
21
|
+
// After (v1.2.2) — both still work
|
|
22
|
+
await animateGradient(text, stops, { infinite: false, cycles: 1 });
|
|
23
|
+
|
|
24
|
+
// Also supports .then() / .catch() / .finally()
|
|
25
|
+
animateGradient(text, stops, opts).finally(() => cleanup());
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The `.done` property remains for backwards compatibility.
|
|
29
|
+
|
|
30
|
+
- **Stable error codes for programmatic catch.** Errors thrown by the
|
|
31
|
+
theme system now carry a `.code` property with the `ANSIMAX_*` prefix
|
|
32
|
+
for stable programmatic filtering:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
try {
|
|
36
|
+
themes.use('not-a-real-theme');
|
|
37
|
+
} catch (e) {
|
|
38
|
+
if ((e as { code?: string }).code === 'ANSIMAX_UNKNOWN_THEME') {
|
|
39
|
+
// handle gracefully
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
New codes: `ANSIMAX_INVALID_THEME`, `ANSIMAX_INVALID_THEME_NAME`,
|
|
45
|
+
`ANSIMAX_UNKNOWN_THEME`. Error messages and types
|
|
46
|
+
(`TypeError` / `RangeError`) are unchanged.
|
|
47
|
+
|
|
48
|
+
- **`animateGradient` is safer in sandboxed environments.** The default
|
|
49
|
+
stdout-write path now checks `process?.stdout?.write` before calling
|
|
50
|
+
it, so the function no longer crashes in workers, Edge runtimes, or
|
|
51
|
+
embedded sandboxes that lack a writable stdout.
|
|
52
|
+
|
|
53
|
+
- **Better JSDoc on the `gradient()` function.** IntelliSense now shows
|
|
54
|
+
parameter descriptions, return semantics, and three runnable
|
|
55
|
+
`@example` blocks (basic, with easing, with phase animation).
|
|
56
|
+
|
|
57
|
+
- **README fix: `Easing Curves` snippet.** The v1.2.0 snippet was missing
|
|
58
|
+
the `stops` variable declaration. Now copy-paste runnable.
|
|
59
|
+
|
|
60
|
+
### Notes
|
|
61
|
+
|
|
62
|
+
- 1880 + 7 new tests pass.
|
|
63
|
+
- No new dependencies — still zero runtime deps.
|
|
64
|
+
- All API additions are non-breaking and side-effect-free for existing code.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
6
68
|
## [1.2.0] — Phase 2 complete: animated, eased & conic gradients
|
|
7
69
|
|
|
8
70
|
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,26 +216,37 @@ 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
|
|
|
233
|
+
const stops = ['#ff79c6', '#bd93f9', '#8be9fd'];
|
|
234
|
+
|
|
226
235
|
// Cinco easings built-in + soporte para funciones personalizadas
|
|
227
|
-
gradient('hola mundo', stops, { easing: 'linear' });
|
|
228
|
-
gradient('hola mundo', stops, { easing: 'ease-in' });
|
|
229
|
-
gradient('hola mundo', stops, { easing: 'ease-out' });
|
|
230
|
-
gradient('hola mundo', stops, { easing: 'ease-in-out' });
|
|
231
|
-
gradient('hola mundo', stops, { easing: 'cubic-bezier' });
|
|
236
|
+
console.log(gradient('hola mundo', stops, { easing: 'linear' }));
|
|
237
|
+
console.log(gradient('hola mundo', stops, { easing: 'ease-in' }));
|
|
238
|
+
console.log(gradient('hola mundo', stops, { easing: 'ease-out' }));
|
|
239
|
+
console.log(gradient('hola mundo', stops, { easing: 'ease-in-out' }));
|
|
240
|
+
console.log(gradient('hola mundo', stops, { easing: 'cubic-bezier' }));
|
|
232
241
|
|
|
233
242
|
// O tu propia función de easing (t → t suavizado, ambos en [0,1])
|
|
234
|
-
gradient('hola mundo', stops, { easing: (t) => t * t * t });
|
|
243
|
+
console.log(gradient('hola mundo', stops, { easing: (t) => t * t * t }));
|
|
235
244
|
```
|
|
236
245
|
|
|
237
246
|
### Gradientes cónicos (v1.2.0)
|
|
238
247
|
|
|
248
|
+
<img src="media/conic_gradients.png" alt="Colors and gradients" />
|
|
249
|
+
|
|
239
250
|
```ts
|
|
240
251
|
import { gradientRect } from 'ansimax';
|
|
241
252
|
|
|
@@ -324,7 +335,7 @@ console.log(components.table([
|
|
|
324
335
|
['loaders', color.green('● listo'), '100%'],
|
|
325
336
|
], { borderStyle: 'rounded' }));
|
|
326
337
|
|
|
327
|
-
console.log(components.badge('VERSION', 'v1.2.
|
|
338
|
+
console.log(components.badge('VERSION', 'v1.2.2'));
|
|
328
339
|
console.log(components.badge('BUILD', 'passing'));
|
|
329
340
|
```
|
|
330
341
|
|
|
@@ -726,6 +737,18 @@ ansimax/
|
|
|
726
737
|
|
|
727
738
|
## 📝 Changelog
|
|
728
739
|
|
|
740
|
+
### v1.2.2 — Pulido de calidad
|
|
741
|
+
|
|
742
|
+
Release patch enfocado en ergonomía de API y refinamientos de robustez.
|
|
743
|
+
|
|
744
|
+
- ✨ **`animateGradient` ahora es thenable** — `await animateGradient(...)` directo sin `.done`
|
|
745
|
+
- 🎯 **Códigos de error estables** — los errores de tema llevan propiedad `.code` (`ANSIMAX_UNKNOWN_THEME`, etc.) para `catch` programático
|
|
746
|
+
- 🛡️ **Seguridad en sandboxes** — `animateGradient` ya no crashea cuando `process.stdout` no está disponible (workers, edge runtimes)
|
|
747
|
+
- 📖 **Mejor JSDoc** — `gradient()` ahora muestra IntelliSense completo con ejemplos
|
|
748
|
+
- 🐛 **Fix de README** — snippet de Easing Curves ahora es ejecutable copy-paste
|
|
749
|
+
|
|
750
|
+
Drop-in replacement para `1.2.0`.
|
|
751
|
+
|
|
729
752
|
### v1.2.0 — Fase 2 completa: gradientes animados, easing y cónicos
|
|
730
753
|
|
|
731
754
|
Release minor que cierra el roadmap del motor de gradientes con tres features potentes:
|
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,26 +216,37 @@ 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)
|
|
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
|
|
|
233
|
+
const stops = ['#ff79c6', '#bd93f9', '#8be9fd'];
|
|
234
|
+
|
|
226
235
|
// Five built-in easings + custom function support
|
|
227
|
-
gradient('hello world', stops, { easing: 'linear' });
|
|
228
|
-
gradient('hello world', stops, { easing: 'ease-in' });
|
|
229
|
-
gradient('hello world', stops, { easing: 'ease-out' });
|
|
230
|
-
gradient('hello world', stops, { easing: 'ease-in-out' });
|
|
231
|
-
gradient('hello world', stops, { easing: 'cubic-bezier' });
|
|
236
|
+
console.log(gradient('hello world', stops, { easing: 'linear' }));
|
|
237
|
+
console.log(gradient('hello world', stops, { easing: 'ease-in' }));
|
|
238
|
+
console.log(gradient('hello world', stops, { easing: 'ease-out' }));
|
|
239
|
+
console.log(gradient('hello world', stops, { easing: 'ease-in-out' }));
|
|
240
|
+
console.log(gradient('hello world', stops, { easing: 'cubic-bezier' }));
|
|
232
241
|
|
|
233
242
|
// Or pass your own easing function (t → eased t, both in [0,1])
|
|
234
|
-
gradient('hello world', stops, { easing: (t) => t * t * t });
|
|
243
|
+
console.log(gradient('hello world', stops, { easing: (t) => t * t * t }));
|
|
235
244
|
```
|
|
236
245
|
|
|
237
246
|
### Conic Gradients (v1.2.0)
|
|
238
247
|
|
|
248
|
+
<img src="media/conic_gradients.png" alt="Colors and gradients" />
|
|
249
|
+
|
|
239
250
|
```ts
|
|
240
251
|
import { gradientRect } from 'ansimax';
|
|
241
252
|
|
|
@@ -324,7 +335,7 @@ console.log(components.table([
|
|
|
324
335
|
['loaders', color.green('● ready'), '100%'],
|
|
325
336
|
], { borderStyle: 'rounded' }));
|
|
326
337
|
|
|
327
|
-
console.log(components.badge('VERSION', 'v1.2.
|
|
338
|
+
console.log(components.badge('VERSION', 'v1.2.2'));
|
|
328
339
|
console.log(components.badge('BUILD', 'passing'));
|
|
329
340
|
```
|
|
330
341
|
|
|
@@ -726,6 +737,18 @@ ansimax/
|
|
|
726
737
|
|
|
727
738
|
## 📝 Changelog
|
|
728
739
|
|
|
740
|
+
### v1.2.2 — Quality polish
|
|
741
|
+
|
|
742
|
+
Patch release focused on API ergonomics and robustness refinements.
|
|
743
|
+
|
|
744
|
+
- ✨ **`animateGradient` is now thenable** — `await animateGradient(...)` directly without `.done`
|
|
745
|
+
- 🎯 **Stable error codes** — theme errors carry `.code` properties (`ANSIMAX_UNKNOWN_THEME`, etc.) for programmatic catch
|
|
746
|
+
- 🛡️ **Sandbox safety** — `animateGradient` no longer crashes when `process.stdout` is unavailable (workers, edge runtimes)
|
|
747
|
+
- 📖 **Better JSDoc** — `gradient()` now shows full IntelliSense with examples
|
|
748
|
+
- 🐛 **README fix** — Easing Curves snippet now copy-paste runnable
|
|
749
|
+
|
|
750
|
+
Drop-in replacement for `1.2.0`.
|
|
751
|
+
|
|
729
752
|
### v1.2.0 — Phase 2 complete: animated, eased & conic gradients
|
|
730
753
|
|
|
731
754
|
Minor release closing the gradient engine roadmap with three powerful features:
|
package/dist/index.d.mts
CHANGED
|
@@ -565,6 +565,38 @@ 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;
|
|
569
601
|
declare const rainbow: ColorFn;
|
|
570
602
|
interface AnimateGradientOptions {
|
|
@@ -614,6 +646,15 @@ interface AnimateGradientController {
|
|
|
614
646
|
stop: () => void;
|
|
615
647
|
/** Promise that resolves when animation finishes (stop / abort / cycle limit). */
|
|
616
648
|
done: Promise<void>;
|
|
649
|
+
/**
|
|
650
|
+
* Thenable hook — lets you `await animateGradient(...)` directly.
|
|
651
|
+
* Equivalent to `await ctrl.done`.
|
|
652
|
+
*/
|
|
653
|
+
then: Promise<void>['then'];
|
|
654
|
+
/** Equivalent to `ctrl.done.catch(...)`. */
|
|
655
|
+
catch: Promise<void>['catch'];
|
|
656
|
+
/** Equivalent to `ctrl.done.finally(...)`. */
|
|
657
|
+
finally: Promise<void>['finally'];
|
|
617
658
|
}
|
|
618
659
|
declare const animateGradient: (text: string, stops: string[], opts?: AnimateGradientOptions) => AnimateGradientController;
|
|
619
660
|
declare const PRESET_DEFS: {
|
package/dist/index.d.ts
CHANGED
|
@@ -565,6 +565,38 @@ 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;
|
|
569
601
|
declare const rainbow: ColorFn;
|
|
570
602
|
interface AnimateGradientOptions {
|
|
@@ -614,6 +646,15 @@ interface AnimateGradientController {
|
|
|
614
646
|
stop: () => void;
|
|
615
647
|
/** Promise that resolves when animation finishes (stop / abort / cycle limit). */
|
|
616
648
|
done: Promise<void>;
|
|
649
|
+
/**
|
|
650
|
+
* Thenable hook — lets you `await animateGradient(...)` directly.
|
|
651
|
+
* Equivalent to `await ctrl.done`.
|
|
652
|
+
*/
|
|
653
|
+
then: Promise<void>['then'];
|
|
654
|
+
/** Equivalent to `ctrl.done.catch(...)`. */
|
|
655
|
+
catch: Promise<void>['catch'];
|
|
656
|
+
/** Equivalent to `ctrl.done.finally(...)`. */
|
|
657
|
+
finally: Promise<void>['finally'];
|
|
617
658
|
}
|
|
618
659
|
declare const animateGradient: (text: string, stops: string[], opts?: AnimateGradientOptions) => AnimateGradientController;
|
|
619
660
|
declare const PRESET_DEFS: {
|
package/dist/index.js
CHANGED
|
@@ -1273,7 +1273,13 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1273
1273
|
if (signal) {
|
|
1274
1274
|
if (signal.aborted) {
|
|
1275
1275
|
stop();
|
|
1276
|
-
return {
|
|
1276
|
+
return {
|
|
1277
|
+
stop,
|
|
1278
|
+
done,
|
|
1279
|
+
then: done.then.bind(done),
|
|
1280
|
+
catch: done.catch.bind(done),
|
|
1281
|
+
finally: done.finally.bind(done)
|
|
1282
|
+
};
|
|
1277
1283
|
}
|
|
1278
1284
|
signal.addEventListener("abort", stop, { once: true });
|
|
1279
1285
|
}
|
|
@@ -1288,7 +1294,9 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1288
1294
|
onFrame(frame, phase);
|
|
1289
1295
|
} else {
|
|
1290
1296
|
try {
|
|
1291
|
-
process
|
|
1297
|
+
if (process?.stdout?.write) {
|
|
1298
|
+
process.stdout.write("\r" + frame);
|
|
1299
|
+
}
|
|
1292
1300
|
} catch {
|
|
1293
1301
|
}
|
|
1294
1302
|
}
|
|
@@ -1303,7 +1311,14 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1303
1311
|
if (!stopped) {
|
|
1304
1312
|
timer = setInterval(renderFrame, frameInterval2);
|
|
1305
1313
|
}
|
|
1306
|
-
return {
|
|
1314
|
+
return {
|
|
1315
|
+
stop,
|
|
1316
|
+
done,
|
|
1317
|
+
// Thenable hooks — bind to done so `await ctrl` works directly
|
|
1318
|
+
then: done.then.bind(done),
|
|
1319
|
+
catch: done.catch.bind(done),
|
|
1320
|
+
finally: done.finally.bind(done)
|
|
1321
|
+
};
|
|
1307
1322
|
};
|
|
1308
1323
|
var PRESET_DEFS = {
|
|
1309
1324
|
sunset: ["#ff6b6b", "#feca57", "#48dbfb"],
|
|
@@ -4222,13 +4237,18 @@ var STYLE_NAMES = [
|
|
|
4222
4237
|
"muted",
|
|
4223
4238
|
"text"
|
|
4224
4239
|
];
|
|
4240
|
+
var _themeError = (Ctor, code, message) => {
|
|
4241
|
+
const err = new Ctor(message);
|
|
4242
|
+
err.code = code;
|
|
4243
|
+
return err;
|
|
4244
|
+
};
|
|
4225
4245
|
var validateTheme = (t) => {
|
|
4226
4246
|
if (typeof t !== "object" || t === null || Array.isArray(t)) {
|
|
4227
|
-
throw
|
|
4247
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME", "Theme must be a non-null object.");
|
|
4228
4248
|
}
|
|
4229
4249
|
const obj = t;
|
|
4230
4250
|
if (typeof obj.name !== "string" || obj.name.length === 0) {
|
|
4231
|
-
throw
|
|
4251
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME_NAME", 'Theme must have a non-empty "name" string.');
|
|
4232
4252
|
}
|
|
4233
4253
|
for (const key of REQUIRED_COLOR_KEYS) {
|
|
4234
4254
|
const value = obj[key];
|
|
@@ -4567,7 +4587,9 @@ var themes = {
|
|
|
4567
4587
|
use(name) {
|
|
4568
4588
|
const t = _globalRegistry.get(name);
|
|
4569
4589
|
if (!t) {
|
|
4570
|
-
throw
|
|
4590
|
+
throw _themeError(
|
|
4591
|
+
RangeError,
|
|
4592
|
+
"ANSIMAX_UNKNOWN_THEME",
|
|
4571
4593
|
`Theme "${name}" not found. Available themes: ${[..._globalRegistry.keys()].join(", ")}`
|
|
4572
4594
|
);
|
|
4573
4595
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1100,7 +1100,13 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1100
1100
|
if (signal) {
|
|
1101
1101
|
if (signal.aborted) {
|
|
1102
1102
|
stop();
|
|
1103
|
-
return {
|
|
1103
|
+
return {
|
|
1104
|
+
stop,
|
|
1105
|
+
done,
|
|
1106
|
+
then: done.then.bind(done),
|
|
1107
|
+
catch: done.catch.bind(done),
|
|
1108
|
+
finally: done.finally.bind(done)
|
|
1109
|
+
};
|
|
1104
1110
|
}
|
|
1105
1111
|
signal.addEventListener("abort", stop, { once: true });
|
|
1106
1112
|
}
|
|
@@ -1115,7 +1121,9 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1115
1121
|
onFrame(frame, phase);
|
|
1116
1122
|
} else {
|
|
1117
1123
|
try {
|
|
1118
|
-
process
|
|
1124
|
+
if (process?.stdout?.write) {
|
|
1125
|
+
process.stdout.write("\r" + frame);
|
|
1126
|
+
}
|
|
1119
1127
|
} catch {
|
|
1120
1128
|
}
|
|
1121
1129
|
}
|
|
@@ -1130,7 +1138,14 @@ var animateGradient = (text, stops, opts = {}) => {
|
|
|
1130
1138
|
if (!stopped) {
|
|
1131
1139
|
timer = setInterval(renderFrame, frameInterval2);
|
|
1132
1140
|
}
|
|
1133
|
-
return {
|
|
1141
|
+
return {
|
|
1142
|
+
stop,
|
|
1143
|
+
done,
|
|
1144
|
+
// Thenable hooks — bind to done so `await ctrl` works directly
|
|
1145
|
+
then: done.then.bind(done),
|
|
1146
|
+
catch: done.catch.bind(done),
|
|
1147
|
+
finally: done.finally.bind(done)
|
|
1148
|
+
};
|
|
1134
1149
|
};
|
|
1135
1150
|
var PRESET_DEFS = {
|
|
1136
1151
|
sunset: ["#ff6b6b", "#feca57", "#48dbfb"],
|
|
@@ -4049,13 +4064,18 @@ var STYLE_NAMES = [
|
|
|
4049
4064
|
"muted",
|
|
4050
4065
|
"text"
|
|
4051
4066
|
];
|
|
4067
|
+
var _themeError = (Ctor, code, message) => {
|
|
4068
|
+
const err = new Ctor(message);
|
|
4069
|
+
err.code = code;
|
|
4070
|
+
return err;
|
|
4071
|
+
};
|
|
4052
4072
|
var validateTheme = (t) => {
|
|
4053
4073
|
if (typeof t !== "object" || t === null || Array.isArray(t)) {
|
|
4054
|
-
throw
|
|
4074
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME", "Theme must be a non-null object.");
|
|
4055
4075
|
}
|
|
4056
4076
|
const obj = t;
|
|
4057
4077
|
if (typeof obj.name !== "string" || obj.name.length === 0) {
|
|
4058
|
-
throw
|
|
4078
|
+
throw _themeError(TypeError, "ANSIMAX_INVALID_THEME_NAME", 'Theme must have a non-empty "name" string.');
|
|
4059
4079
|
}
|
|
4060
4080
|
for (const key of REQUIRED_COLOR_KEYS) {
|
|
4061
4081
|
const value = obj[key];
|
|
@@ -4394,7 +4414,9 @@ var themes = {
|
|
|
4394
4414
|
use(name) {
|
|
4395
4415
|
const t = _globalRegistry.get(name);
|
|
4396
4416
|
if (!t) {
|
|
4397
|
-
throw
|
|
4417
|
+
throw _themeError(
|
|
4418
|
+
RangeError,
|
|
4419
|
+
"ANSIMAX_UNKNOWN_THEME",
|
|
4398
4420
|
`Theme "${name}" not found. Available themes: ${[..._globalRegistry.keys()].join(", ")}`
|
|
4399
4421
|
);
|
|
4400
4422
|
}
|
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.2'),
|
|
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.2'),
|
|
121
121
|
components.badge('BUILD', 'passing'),
|
|
122
122
|
components.badge('LICENSE', 'Apache 2.0'));
|
|
123
123
|
console.log();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ansimax",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
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",
|