ansimax 1.3.0 β†’ 1.3.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/dist/index.mjs CHANGED
@@ -1162,13 +1162,13 @@ var animateGradient = (text, stops, opts = {}) => {
1162
1162
  const elapsed = Date.now() - startTime;
1163
1163
  let phase = elapsed / safeDuration2 % 1;
1164
1164
  if (direction === "reverse") phase = 1 - phase;
1165
- const frame = gradient(text, stops, { preserveAnsi, easing, phase });
1165
+ const frame2 = gradient(text, stops, { preserveAnsi, easing, phase });
1166
1166
  if (onFrame) {
1167
- onFrame(frame, phase);
1167
+ onFrame(frame2, phase);
1168
1168
  } else {
1169
1169
  try {
1170
1170
  if (process?.stdout?.write) {
1171
- process.stdout.write("\r" + frame);
1171
+ process.stdout.write("\r" + frame2);
1172
1172
  }
1173
1173
  } catch {
1174
1174
  }
@@ -1458,9 +1458,9 @@ var safeWrite = (data) => {
1458
1458
  } catch {
1459
1459
  }
1460
1460
  };
1461
- var fireFrame = (hooks, frame) => {
1461
+ var fireFrame = (hooks, frame2) => {
1462
1462
  try {
1463
- hooks?.onFrame?.(frame);
1463
+ hooks?.onFrame?.(frame2);
1464
1464
  } catch {
1465
1465
  }
1466
1466
  };
@@ -1492,7 +1492,7 @@ var typewriter = async (text, opts = {}) => {
1492
1492
  registerCrashHandlers();
1493
1493
  hideCursorSafe();
1494
1494
  let aborted = false;
1495
- let frame = 0;
1495
+ let frame2 = 0;
1496
1496
  try {
1497
1497
  for (const ch of text) {
1498
1498
  if (isAborted(signal)) {
@@ -1500,7 +1500,7 @@ var typewriter = async (text, opts = {}) => {
1500
1500
  break;
1501
1501
  }
1502
1502
  await safeWriteAsync(colorFn ? colorFn(ch) : ch);
1503
- fireFrame(hooks, frame++);
1503
+ fireFrame(hooks, frame2++);
1504
1504
  await sleep(ch === " " ? speed * 0.3 : speed, { signal });
1505
1505
  }
1506
1506
  } finally {
@@ -1671,7 +1671,7 @@ var pulse = async (text, opts = {}) => {
1671
1671
  registerCrashHandlers();
1672
1672
  hideCursorSafe();
1673
1673
  let aborted = false;
1674
- let frame = 0;
1674
+ let frame2 = 0;
1675
1675
  try {
1676
1676
  for (let t = 0; t < cycles; t++) {
1677
1677
  if (isAborted(signal)) {
@@ -1681,7 +1681,7 @@ var pulse = async (text, opts = {}) => {
1681
1681
  await safeWriteAsync(
1682
1682
  cursor.save() + fgRgb(c1.r, c1.g, c1.b) + text + reset() + cursor.restore()
1683
1683
  );
1684
- fireFrame(hooks, frame++);
1684
+ fireFrame(hooks, frame2++);
1685
1685
  await sleep(halfInterval, { signal });
1686
1686
  if (isAborted(signal)) {
1687
1687
  aborted = true;
@@ -1690,7 +1690,7 @@ var pulse = async (text, opts = {}) => {
1690
1690
  await safeWriteAsync(
1691
1691
  cursor.save() + fgRgb(c2.r, c2.g, c2.b) + text + reset() + cursor.restore()
1692
1692
  );
1693
- fireFrame(hooks, frame++);
1693
+ fireFrame(hooks, frame2++);
1694
1694
  await sleep(halfInterval, { signal });
1695
1695
  }
1696
1696
  if (!aborted) {
@@ -2835,7 +2835,7 @@ var spin = (text = "Loading", opts = {}) => {
2835
2835
  }
2836
2836
  };
2837
2837
  }
2838
- let frame = 0;
2838
+ let frame2 = 0;
2839
2839
  let stopped = false;
2840
2840
  let timer = null;
2841
2841
  const animInterval = Math.max(FRAME_MS, safeInterval);
@@ -2844,8 +2844,8 @@ var spin = (text = "Loading", opts = {}) => {
2844
2844
  const render = () => {
2845
2845
  if (stopped) return;
2846
2846
  const elapsed = Date.now() - startTime;
2847
- frame = Math.floor(elapsed / animInterval) % frames2.length;
2848
- const f = frames2[frame] ?? "";
2847
+ frame2 = Math.floor(elapsed / animInterval) % frames2.length;
2848
+ const f = frames2[frame2] ?? "";
2849
2849
  const colored = applyColor(f, hex);
2850
2850
  const line = padToTerminalWidth(`${safePrefix}${colored} ${safeText}${safeSuffix}`);
2851
2851
  const buf = createOutputBuffer().push("\r").push(screen.clearLine()).push(line).toString();
@@ -3058,7 +3058,7 @@ var custom = (frames2, text = "", opts = {}) => {
3058
3058
  }
3059
3059
  registerCrashHandlers2();
3060
3060
  acquireCursor();
3061
- let frame = 0;
3061
+ let frame2 = 0;
3062
3062
  let stopped = false;
3063
3063
  let timer = null;
3064
3064
  const safeInterval = Math.max(FRAME_MS, interval);
@@ -3066,8 +3066,8 @@ var custom = (frames2, text = "", opts = {}) => {
3066
3066
  const render = () => {
3067
3067
  if (stopped) return;
3068
3068
  const elapsed = Date.now() - startTime;
3069
- frame = Math.floor(elapsed / safeInterval) % frames2.length;
3070
- const f = frames2[frame] ?? "";
3069
+ frame2 = Math.floor(elapsed / safeInterval) % frames2.length;
3070
+ const f = frames2[frame2] ?? "";
3071
3071
  write("\r" + screen.clearLine() + applyColor(f, hex) + " " + text);
3072
3072
  };
3073
3073
  render();
@@ -3175,7 +3175,7 @@ var multi = (opts = {}) => {
3175
3175
  registerCrashHandlers2();
3176
3176
  let nextId = 0;
3177
3177
  const items = /* @__PURE__ */ new Map();
3178
- let frame = 0;
3178
+ let frame2 = 0;
3179
3179
  let timer = null;
3180
3180
  let lastLineCount = 0;
3181
3181
  const render = () => {
@@ -3189,13 +3189,13 @@ var multi = (opts = {}) => {
3189
3189
  let glyph;
3190
3190
  if (item.state === "success") glyph = applyColor("\u2713", "#00ff88");
3191
3191
  else if (item.state === "fail") glyph = applyColor("\u2717", "#ff6b6b");
3192
- else glyph = applyColor(frames2[frame % frames2.length] ?? "", item.color ?? null);
3192
+ else glyph = applyColor(frames2[frame2 % frames2.length] ?? "", item.color ?? null);
3193
3193
  const text = item.finalText ?? item.text;
3194
3194
  buf.pushln(padToTerminalWidth(`${glyph} ${text}`));
3195
3195
  }
3196
3196
  write(buf.toString());
3197
3197
  lastLineCount = itemsArr.length;
3198
- frame++;
3198
+ frame2++;
3199
3199
  };
3200
3200
  const start = () => {
3201
3201
  if (timer) return;
@@ -3356,9 +3356,9 @@ var registerCrashHandlers3 = () => {
3356
3356
  if (isTestEnv3()) return;
3357
3357
  installCrashHandlersImpl3();
3358
3358
  };
3359
- var lineCount = (frame) => {
3360
- if (typeof frame !== "string" || frame.length === 0) return 0;
3361
- const normalized = frame.replace(/\r\n/g, "\n").replace(/\r/g, "");
3359
+ var lineCount = (frame2) => {
3360
+ if (typeof frame2 !== "string" || frame2.length === 0) return 0;
3361
+ const normalized = frame2.replace(/\r\n/g, "\n").replace(/\r/g, "");
3362
3362
  return normalized.split("\n").length;
3363
3363
  };
3364
3364
  var clearLines = (n) => {
@@ -3369,7 +3369,7 @@ var clearLines = (n) => {
3369
3369
  }
3370
3370
  };
3371
3371
  var isColorless2 = () => supportsColor() === "none";
3372
- var defaultOnFrame = (frame) => isColorless2() ? stripAnsi(frame) : frame;
3372
+ var defaultOnFrame = (frame2) => isColorless2() ? stripAnsi(frame2) : frame2;
3373
3373
  var play = (frames2, opts = {}) => {
3374
3374
  if (!Array.isArray(frames2)) {
3375
3375
  const resolved = Promise.resolve();
@@ -3430,13 +3430,13 @@ var play = (frames2, opts = {}) => {
3430
3430
  const done = new Promise((r) => {
3431
3431
  resolveDone = r;
3432
3432
  });
3433
- const renderFrame = (frame, idx) => {
3433
+ const renderFrame = (frame2, idx) => {
3434
3434
  if (lastLines > 0) clearLines(lastLines);
3435
3435
  let rendered;
3436
3436
  try {
3437
- rendered = userOnFrame(frame, idx);
3437
+ rendered = userOnFrame(frame2, idx);
3438
3438
  } catch {
3439
- rendered = frame;
3439
+ rendered = frame2;
3440
3440
  }
3441
3441
  const safe = ensureString4(rendered);
3442
3442
  try {
@@ -3565,13 +3565,13 @@ var live = (opts = {}) => {
3565
3565
  let abortHandler = null;
3566
3566
  const render = () => {
3567
3567
  if (lastLines > 0) clearLines(lastLines);
3568
- const frame = isColorless2() ? stripAnsi(currentFrame) : currentFrame;
3568
+ const frame2 = isColorless2() ? stripAnsi(currentFrame) : currentFrame;
3569
3569
  try {
3570
- write(frame);
3570
+ write(frame2);
3571
3571
  } catch {
3572
3572
  }
3573
- lastLines = lineCount(frame);
3574
- if (!frame.endsWith("\n")) writeln();
3573
+ lastLines = lineCount(frame2);
3574
+ if (!frame2.endsWith("\n")) writeln();
3575
3575
  };
3576
3576
  const start = () => {
3577
3577
  if (running) return;
@@ -5515,9 +5515,82 @@ var hsplit = (blocks, opts = {}) => {
5515
5515
  }
5516
5516
  return parts.join("\n");
5517
5517
  };
5518
+ var center2 = (block, opts) => {
5519
+ if (!opts || typeof opts !== "object") return block;
5520
+ const width = Math.max(0, Math.floor(opts.width ?? 0));
5521
+ if (width === 0) return block;
5522
+ const { lines, maxWidth } = _splitBlock(block);
5523
+ const hCentered = lines.map((line) => {
5524
+ const w = visibleLen(line);
5525
+ const space = Math.max(0, width - w);
5526
+ if (space === 0) return line.slice(0, width);
5527
+ const left = Math.floor(space / 2);
5528
+ const right = space - left;
5529
+ return " ".repeat(left) + line + " ".repeat(right);
5530
+ });
5531
+ if (opts.height != null) {
5532
+ const targetH = Math.max(1, Math.floor(opts.height));
5533
+ return _alignVertical(hCentered, targetH, width, opts.align ?? "center").join("\n");
5534
+ }
5535
+ void maxWidth;
5536
+ return hCentered.join("\n");
5537
+ };
5538
+ var frame = (block, opts = {}) => {
5539
+ const {
5540
+ padding = 0,
5541
+ paddingY,
5542
+ paddingX,
5543
+ topChar = "\u2500",
5544
+ bottomChar,
5545
+ title
5546
+ } = opts;
5547
+ const safePadY = Math.max(0, Math.floor(paddingY ?? padding));
5548
+ const safePadX = Math.max(0, Math.floor(paddingX ?? padding));
5549
+ const safeTop = typeof topChar === "string" && topChar.length > 0 ? topChar.charAt(0) : "\u2500";
5550
+ const safeBot = typeof bottomChar === "string" && bottomChar.length > 0 ? bottomChar.charAt(0) : safeTop;
5551
+ const { lines, maxWidth } = _splitBlock(block);
5552
+ const contentInnerW = maxWidth + 2 * safePadX;
5553
+ let innerW = contentInnerW;
5554
+ let titleStr = "";
5555
+ let titleW = 0;
5556
+ if (typeof title === "string" && title.length > 0) {
5557
+ titleStr = ` ${title} `;
5558
+ titleW = visibleLen(titleStr);
5559
+ const titleNeededW = titleW + 2;
5560
+ if (titleNeededW > innerW) {
5561
+ innerW = titleNeededW;
5562
+ }
5563
+ }
5564
+ let topLine;
5565
+ if (titleStr.length > 0 && titleW < innerW) {
5566
+ const before = Math.floor((innerW - titleW) / 2);
5567
+ const after = innerW - titleW - before;
5568
+ topLine = safeTop.repeat(before) + titleStr + safeTop.repeat(after);
5569
+ } else {
5570
+ topLine = safeTop.repeat(innerW);
5571
+ }
5572
+ const bottomLine = safeBot.repeat(innerW);
5573
+ const padX = " ".repeat(safePadX);
5574
+ const padded = lines.map((line) => {
5575
+ const w = visibleLen(line);
5576
+ const tail = " ".repeat(Math.max(0, innerW - safePadX - w - safePadX));
5577
+ return padX + line + tail + padX;
5578
+ });
5579
+ const blank = " ".repeat(innerW);
5580
+ const out = [];
5581
+ out.push(topLine);
5582
+ for (let i = 0; i < safePadY; i++) out.push(blank);
5583
+ out.push(...padded);
5584
+ for (let i = 0; i < safePadY; i++) out.push(blank);
5585
+ out.push(bottomLine);
5586
+ return out.join("\n");
5587
+ };
5518
5588
  var panels = {
5519
5589
  vsplit,
5520
- hsplit
5590
+ hsplit,
5591
+ // v1.3.1
5592
+ center: center2,
5593
+ frame
5521
5594
  };
5522
5595
 
5523
5596
  // src/json/index.ts
@@ -5572,7 +5645,16 @@ var _formatPrimitive = (value, opts) => {
5572
5645
  return _c(String(value), COLORS.comment, useColor);
5573
5646
  };
5574
5647
  var _renderValue = (value, depth, config) => {
5575
- const { indent, maxDepth, maxItems, maxStringLength, useColor, seen } = config;
5648
+ const {
5649
+ indent,
5650
+ maxDepth,
5651
+ maxItems,
5652
+ maxStringLength,
5653
+ useColor,
5654
+ seen,
5655
+ sortKeys,
5656
+ inlineArrayMaxLength
5657
+ } = config;
5576
5658
  if (value === null || typeof value !== "object") {
5577
5659
  return _formatPrimitive(value, { useColor, maxStringLength });
5578
5660
  }
@@ -5592,6 +5674,25 @@ var _renderValue = (value, depth, config) => {
5592
5674
  if (value.length === 0) {
5593
5675
  return _c("[]", COLORS.bracket, useColor);
5594
5676
  }
5677
+ if (inlineArrayMaxLength > 0) {
5678
+ const allPrimitive = value.every((v) => v === null || typeof v !== "object");
5679
+ if (allPrimitive) {
5680
+ const displayCount2 = Math.min(value.length, maxItems);
5681
+ const inlineItems = [];
5682
+ for (let i = 0; i < displayCount2; i++) {
5683
+ inlineItems.push(_formatPrimitive(value[i], { useColor, maxStringLength }));
5684
+ }
5685
+ if (value.length > maxItems) {
5686
+ const remaining = value.length - maxItems;
5687
+ inlineItems.push(_c(`... (${remaining} more)`, COLORS.comment, useColor));
5688
+ }
5689
+ const candidate = _c("[", COLORS.bracket, useColor) + inlineItems.join(", ") + _c("]", COLORS.bracket, useColor);
5690
+ const visibleLen2 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
5691
+ if (visibleLen2 <= inlineArrayMaxLength) {
5692
+ return candidate;
5693
+ }
5694
+ }
5695
+ }
5595
5696
  const items = [];
5596
5697
  const displayCount = Math.min(value.length, maxItems);
5597
5698
  for (let i = 0; i < displayCount; i++) {
@@ -5604,10 +5705,13 @@ var _renderValue = (value, depth, config) => {
5604
5705
  }
5605
5706
  return _c("[", COLORS.bracket, useColor) + "\n" + items.join(",\n") + "\n" + closePad + _c("]", COLORS.bracket, useColor);
5606
5707
  }
5607
- const keys = Object.keys(value);
5708
+ let keys = Object.keys(value);
5608
5709
  if (keys.length === 0) {
5609
5710
  return _c("{}", COLORS.bracket, useColor);
5610
5711
  }
5712
+ if (sortKeys) {
5713
+ keys = [...keys].sort((a, b) => a.localeCompare(b));
5714
+ }
5611
5715
  const entries = [];
5612
5716
  for (const key of keys) {
5613
5717
  const keyStr = JSON.stringify(key);
@@ -5627,12 +5731,16 @@ var pretty = (value, opts = {}) => {
5627
5731
  colors = true,
5628
5732
  maxDepth = Infinity,
5629
5733
  maxItems = Infinity,
5630
- maxStringLength = Infinity
5734
+ maxStringLength = Infinity,
5735
+ // v1.3.1
5736
+ sortKeys = false,
5737
+ inlineArrayMaxLength = 60
5631
5738
  } = opts;
5632
5739
  const safeIndent = Math.max(0, Math.floor(Number(indent) || 0));
5633
5740
  const safeMaxDepth = Number.isFinite(maxDepth) ? Math.max(0, Math.floor(maxDepth)) : Infinity;
5634
5741
  const safeMaxItems = Number.isFinite(maxItems) ? Math.max(0, Math.floor(maxItems)) : Infinity;
5635
5742
  const safeMaxStrLen = Number.isFinite(maxStringLength) ? Math.max(0, Math.floor(maxStringLength)) : Infinity;
5743
+ const safeInlineMax = Number.isFinite(inlineArrayMaxLength) ? Math.max(0, Math.floor(inlineArrayMaxLength)) : 60;
5636
5744
  const useColor = colors && !isNoColor();
5637
5745
  return _renderValue(value, 0, {
5638
5746
  indent: safeIndent,
@@ -5640,7 +5748,9 @@ var pretty = (value, opts = {}) => {
5640
5748
  maxItems: safeMaxItems,
5641
5749
  maxStringLength: safeMaxStrLen,
5642
5750
  useColor,
5643
- seen: /* @__PURE__ */ new WeakSet()
5751
+ seen: /* @__PURE__ */ new WeakSet(),
5752
+ sortKeys: Boolean(sortKeys),
5753
+ inlineArrayMaxLength: safeInlineMax
5644
5754
  });
5645
5755
  };
5646
5756
  var json = {
@@ -5890,6 +6000,7 @@ export {
5890
6000
  canAnimate,
5891
6001
  cancelTerminalFrame,
5892
6002
  center,
6003
+ center2 as centerBlock,
5893
6004
  chain,
5894
6005
  charWidth,
5895
6006
  clamp,
@@ -5920,6 +6031,7 @@ export {
5920
6031
  findInTree,
5921
6032
  flipHorizontal,
5922
6033
  flipVertical,
6034
+ frame,
5923
6035
  frames,
5924
6036
  fromImage,
5925
6037
  getConfig,
package/docs/README.md ADDED
@@ -0,0 +1,110 @@
1
+ <div align="center">
2
+
3
+ # πŸ“š ansimax β€” Documentation
4
+
5
+ Detailed examples covering every module in **ansimax**, with copy-paste runnable code in three formats.
6
+
7
+ </div>
8
+
9
+ ---
10
+
11
+ ## πŸ“– Where to start
12
+
13
+ Pick the document that matches your project setup:
14
+
15
+ | File | Format | Use when… |
16
+ |---|---|---|
17
+ | [`examples-ts.md`](./examples-ts.md) | **TypeScript** (`.ts`) | Your project uses TypeScript (with `ts-node`, `tsx`, or compiled output) |
18
+ | [`examples-mjs.md`](./examples-mjs.md) | **JavaScript ESM** (`.mjs` / `"type":"module"`) | Modern JavaScript with `import`/`export` |
19
+ | [`examples-cjs.md`](./examples-cjs.md) | **JavaScript CommonJS** (`.cjs` / classic Node) | Legacy or simple Node scripts with `require()` |
20
+ | [`showcase.md`](./showcase.md) | **Complete app** | A single end-to-end JavaScript app combining all modules |
21
+
22
+ Each `examples-*.md` file covers **all 11 modules** with **3 runnable examples each** (33 examples per file).
23
+
24
+ ---
25
+
26
+ ## 🧩 Modules covered in every file
27
+
28
+ Each examples file is organized in this order:
29
+
30
+ 1. **`color`** β€” basic colors, ANSI styling, gradients
31
+ 2. **`gradient`** β€” multi-stop, animated, eased, conic gradients
32
+ 3. **`ascii`** β€” boxes, banners (figlet), image-to-ASCII
33
+ 4. **`animations`** β€” typewriter, fadeIn, fadeOut
34
+ 5. **`loaders`** β€” spinners, tasks, progress bars
35
+ 6. **`components`** β€” table, badge, status, timeline
36
+ 7. **`themes`** β€” built-in themes, custom themes, registry
37
+ 8. **`trees`** β€” hierarchical rendering, max-depth, cycles
38
+ 9. **`frames`** β€” frame-by-frame animation, morphing
39
+ 10. **`images`** β€” pixel art, canvas, gradient rectangles
40
+ 11. **`panels`** + **`json`** β€” split layouts + pretty-printing (v1.3.0+)
41
+
42
+ ---
43
+
44
+ ## πŸ’‘ Running the examples
45
+
46
+ ### TypeScript (`examples-ts.md`)
47
+
48
+ ```bash
49
+ # Quickest: tsx (no compile step)
50
+ npx tsx my-example.ts
51
+
52
+ # Or with ts-node
53
+ npx ts-node my-example.ts
54
+
55
+ # Or compile then run
56
+ npx tsc my-example.ts && node my-example.js
57
+ ```
58
+
59
+ ### JavaScript ESM (`examples-mjs.md`)
60
+
61
+ Either:
62
+ - Save the file with `.mjs` extension, OR
63
+ - Set `"type": "module"` in your `package.json` and use `.js`
64
+
65
+ ```bash
66
+ node my-example.mjs
67
+ ```
68
+
69
+ ### JavaScript CommonJS (`examples-cjs.md`)
70
+
71
+ ```bash
72
+ node my-example.cjs
73
+ ```
74
+
75
+ ### Showcase (`showcase.md`)
76
+
77
+ A complete demo app. Save as `.mjs`, run with `node`. Demonstrates how multiple modules compose in a real CLI.
78
+
79
+ ---
80
+
81
+ ## βš™οΈ Project setup
82
+
83
+ For any of these, your `package.json` needs:
84
+
85
+ ```json
86
+ {
87
+ "dependencies": {
88
+ "ansimax": "^1.3.2"
89
+ }
90
+ }
91
+ ```
92
+
93
+ Then `npm install` and pick an example.
94
+
95
+ ---
96
+
97
+ ## πŸ”— More resources
98
+
99
+ - [Main README](../README.md) β€” overview, badges, comparison table, roadmap
100
+ - [CHANGELOG](../CHANGELOG.md) β€” version history
101
+ - [npm package](https://www.npmjs.com/package/ansimax)
102
+ - [GitHub](https://github.com/Brashkie/ansimax)
103
+
104
+ ---
105
+
106
+ <div align="center">
107
+
108
+ If any example doesn't work, [open an issue](https://github.com/Brashkie/ansimax/issues) β€” we'll fix it.
109
+
110
+ </div>