console-toolkit 1.0.0 → 1.1.1

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/README.md CHANGED
@@ -89,4 +89,6 @@ BSD 3-Clause License
89
89
 
90
90
  ## Release history
91
91
 
92
+ - 1.1.1: *Minor bugfixes in `Table`, some improvements, updated deps.*
93
+ - 1.1.0: *Minor improvements, enhanced `Writer` and `Updater`.*
92
94
  - 1.0.0: *Initial release.*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "console-toolkit",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Toolkit to produce a fancy console output (boxes, tables, charts, colors).",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -54,6 +54,6 @@
54
54
  ]
55
55
  },
56
56
  "devDependencies": {
57
- "tape-six": "^0.9.3"
57
+ "tape-six": "^0.9.6"
58
58
  }
59
59
  }
@@ -24,7 +24,7 @@ export const prepareTimeFormat = (values, scale = 1, useUnicode) => {
24
24
 
25
25
  export const formatTime = (value, format) => {
26
26
  let result = (value * format.scale).toFixed(format.precision);
27
- if (format.precision > 0) result = result.replace(/\.0+$/, '');
27
+ if (format.precision > 0 && !format.keepFractionAsIs) result = result.replace(/\.0+$/, '');
28
28
  return result + format.unit;
29
29
  };
30
30
 
@@ -111,7 +111,7 @@ export const compareDifference = (a, b) => {
111
111
  if (diff === Infinity) return {less, infinity: true};
112
112
 
113
113
  if (diff < 2) {
114
- const percentage = diff * 100;
114
+ const percentage = absDiff / (less ? a : b) * 100;
115
115
  if (percentage < 0.001) return {less, equality: true};
116
116
  if (percentage < 1) return {less, percentage: formatNumber(percentage, {decimals: 3})};
117
117
  if (percentage < 10) return {less, percentage: formatNumber(percentage, {decimals: 2})};
@@ -7,11 +7,15 @@ import {cursorUp, setCommands} from '../ansi/csi.js';
7
7
  const RESET = setCommands([]);
8
8
 
9
9
  export class Updater {
10
- constructor(updater, {prologue, epilogue, noLastNewLine} = {}, writer = new Writer()) {
10
+ constructor(updater, {prologue, epilogue, beforeFrame, afterFrame, beforeLine, afterLine, noLastNewLine} = {}, writer = new Writer()) {
11
11
  this.updater = updater;
12
12
  this.writer = writer;
13
13
  this.prologue = prologue || RESET;
14
14
  this.epilogue = epilogue || RESET;
15
+ this.beforeFrame = beforeFrame || '';
16
+ this.afterFrame = afterFrame || '';
17
+ this.beforeLine = beforeLine || '';
18
+ this.afterLine = afterLine || '';
15
19
  this.noLastNewLine = noLastNewLine;
16
20
  this.lastHeight = 0;
17
21
  this.isDone = false;
@@ -34,30 +38,31 @@ export class Updater {
34
38
  this.intervalHandle = null;
35
39
  }
36
40
 
37
- getFrame(state) {
38
- if (typeof this.updater == 'function') return this.updater(state);
41
+ getFrame(state, ...args) {
42
+ if (typeof this.updater == 'function') return this.updater(state, ...args);
39
43
  if (typeof this.updater?.getFrame == 'function') {
40
44
  this.updater.state = state;
41
- return this.updater.getFrame();
45
+ return this.updater.getFrame(...args);
42
46
  }
43
47
  throw new TypeError('Updater must be a function or implement getFrame()');
44
48
  }
45
49
 
46
- async writeFrame(state) {
50
+ async writeFrame(state, ...args) {
47
51
  if (this.first) {
48
52
  this.prologue && (await this.writer.writeString(this.prologue));
49
53
  this.first = false;
50
54
  }
51
55
 
52
- const frame = toStrings(this.getFrame(state));
56
+ const frame = toStrings(this.getFrame(state, ...args));
53
57
  if (!frame) return;
54
58
 
55
- if (this.lastHeight) await this.writer.writeString('\r' + cursorUp(this.lastHeight));
59
+ if (this.lastHeight) await this.writer.writeString('\r' + cursorUp(this.lastHeight) + this.beforeFrame);
56
60
 
57
61
  this.lastHeight = frame.length;
58
62
  if (this.noLastNewLine) --this.lastHeight;
59
63
 
60
- await this.writer.write(frame, false, this.noLastNewLine);
64
+ await this.writer.write(frame, {noLastNewLine: this.noLastNewLine, beforeLine: this.beforeLine, afterLine: this.afterLine});
65
+ this.afterFrame && (await this.writer.writeString(this.afterFrame));
61
66
  }
62
67
 
63
68
  async done() {
@@ -67,14 +72,14 @@ export class Updater {
67
72
  this.epilogue && (await this.writer.writeString(this.epilogue));
68
73
  }
69
74
 
70
- async update(state = 'active') {
75
+ async update(state = 'active', ...args) {
71
76
  if (this.isDone || !this.writer.isTTY) return;
72
- await this.writeFrame(state);
77
+ await this.writeFrame(state, ...args);
73
78
  }
74
79
 
75
- async final() {
80
+ async final(...args) {
76
81
  if (this.isDone) return;
77
- await this.writeFrame('finished');
82
+ await this.writeFrame('finished', ...args);
78
83
  await this.done();
79
84
  }
80
85
  }
@@ -93,12 +93,12 @@ export class Writer {
93
93
  await write(this.stream, s.replace(matchCsiNoGroups, ''));
94
94
  }
95
95
 
96
- async write(s, sameColumn, noLastNewLine) {
96
+ async write(s, {sameColumn, noLastNewLine, beforeLine = '', afterLine = ''} = {}) {
97
97
  s = toStrings(s);
98
98
 
99
99
  if (!this.isTTY) {
100
100
  const matcher = this.forceColorDepth ? matchCsiNoSgrNoGroups : matchCsiNoGroups;
101
- let lines = Array.from(s).join('\n');
101
+ let lines = Array.from(s).map(line => beforeLine + line + afterLine).join('\n');
102
102
  if (!noLastNewLine) lines += '\n';
103
103
  matcher.lastIndex = 0;
104
104
  lines = lines.replace(matcher, '');
@@ -108,21 +108,22 @@ export class Writer {
108
108
 
109
109
  if (sameColumn === 'save') {
110
110
  for (const line of s) {
111
- await write(this.stream, CURSOR_SAVE_POS + line + CURSOR_RESTORE_POS + CURSOR_DOWN1);
111
+ await write(this.stream, CURSOR_SAVE_POS + beforeLine + line + afterline + CURSOR_RESTORE_POS + CURSOR_DOWN1);
112
112
  }
113
113
  return;
114
114
  }
115
115
 
116
116
  if (sameColumn) {
117
117
  for (const line of s) {
118
- const length = getLength(line);
119
- await write(this.stream, line);
118
+ const fullLine = beforeLine + line + afterLine,
119
+ length = getLength(fullLine);
120
+ await write(this.stream, fullLine);
120
121
  await this.moveCursor(-length, 1);
121
122
  }
122
123
  return;
123
124
  }
124
125
 
125
- let lines = Array.from(s).join('\n');
126
+ let lines = Array.from(s).map(line => beforeLine + line + afterLine).join('\n');
126
127
  if (!noLastNewLine) lines += '\n';
127
128
  await write(this.stream, lines);
128
129
  }
@@ -7,17 +7,20 @@ const getCellAlign = (align, index) => (typeof align == 'string' && align[index]
7
7
 
8
8
  const ensureSize = (cellSize, cellLength, cellGap, pos, lineTheme, axis, lengths) => {
9
9
  let available = (cellSize - 1) * cellGap;
10
- for (let i = 0; i < cellSize; ++i)
11
- available += lengths[pos + i] + (!axis[pos + i] ? 0 : lineTheme ? lineTheme['w_' + axis[pos + i]] : 1);
10
+ for (let i = 0; i < cellSize; ++i) {
11
+ available += lengths[pos + i];
12
+ if (i + 1 === cellSize || !axis[pos + i]) continue;
13
+ available += lineTheme ? lineTheme['w_' + axis[pos + i]] : 1;
14
+ }
12
15
  if (cellLength > available) {
13
16
  const diff = cellLength - available,
14
17
  perCell = Math.floor(diff / cellSize),
15
18
  remainder = diff % cellSize;
16
19
  if (perCell) {
17
- for (let i = 0; i < cellSize; ++i) lengths[j + i] += perCell;
20
+ for (let i = 0; i < cellSize; ++i) lengths[pos + i] += perCell;
18
21
  }
19
22
  if (remainder) {
20
- for (let i = 0; i < remainder; ++i) ++lengths[j + i];
23
+ for (let i = 0; i < remainder; ++i) ++lengths[pos + i];
21
24
  }
22
25
  }
23
26
  };