@travetto/terminal 7.0.0-rc.1 → 7.0.0-rc.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/terminal",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.2",
4
4
  "description": "General terminal support",
5
5
  "keywords": [
6
6
  "terminal",
@@ -24,7 +24,7 @@
24
24
  "directory": "module/terminal"
25
25
  },
26
26
  "dependencies": {
27
- "@travetto/runtime": "^7.0.0-rc.1",
27
+ "@travetto/runtime": "^7.0.0-rc.2",
28
28
  "chalk": "^5.6.2"
29
29
  },
30
30
  "travetto": {
package/src/style.ts CHANGED
@@ -43,7 +43,7 @@ export class StyleUtil {
43
43
  * Read foreground/background color if env var is set
44
44
  */
45
45
  static isBackgroundDark(): boolean {
46
- const key = Env.COLORFGBG.val ?? '';
46
+ const key = Env.COLORFGBG.value ?? '';
47
47
 
48
48
  if (this.#scheme.key === key) {
49
49
  return this.#scheme.dark;
@@ -74,9 +74,9 @@ export class StyleUtil {
74
74
  /**
75
75
  * Build style palette, with support for background theme awareness
76
76
  */
77
- static getPalette<K extends string>(inp: Record<K, TermStylePairInput>): Record<K, TermStyleFn> {
77
+ static getPalette<K extends string>(input: Record<K, TermStylePairInput>): Record<K, TermStyleFn> {
78
78
  return TypedObject.fromEntries(
79
- TypedObject.entries(inp).map(([k, v]) => [k, this.getThemedStyle(v)]));
79
+ TypedObject.entries(input).map(([key, value]) => [key, this.getThemedStyle(value)]));
80
80
  }
81
81
 
82
82
  /**
@@ -89,16 +89,16 @@ export class StyleUtil {
89
89
  if (keys.length === 0) {
90
90
  return values[0];
91
91
  } else {
92
- const out = keys.map((el, i) => {
93
- let final = el;
94
- if (typeof el !== 'string') {
95
- const subKeys = TypedObject.keys(el);
92
+ const out = keys.map((item, i) => {
93
+ let final = item;
94
+ if (typeof item !== 'string') {
95
+ const subKeys = TypedObject.keys(item);
96
96
  if (subKeys.length !== 1) {
97
97
  throw new Error('Invalid template variable, one and only one key should be specified');
98
98
  }
99
- const [k] = subKeys;
100
- const v = el[k]!;
101
- final = v === undefined ? '' : palette[k](v)!;
99
+ const [key] = subKeys;
100
+ const value = item[key]!;
101
+ final = value === undefined ? '' : palette[key](value)!;
102
102
  }
103
103
  return `${values[i] ?? ''}${final ?? ''}`;
104
104
  });
package/src/terminal.ts CHANGED
@@ -10,8 +10,8 @@ type Coord = { x: number, y: number };
10
10
  export const WAIT_TOKEN = '%WAIT%';
11
11
  const STD_WAIT_STATES = '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'.split('');
12
12
 
13
- const lineStatus = (l: string): string => l.replace(WAIT_TOKEN, ' ');
14
- const lineMain = (l: string): string => l.replace(WAIT_TOKEN, '').trim();
13
+ const lineStatus = (line: string): string => line.replace(WAIT_TOKEN, ' ');
14
+ const lineMain = (line: string): string => line.replace(WAIT_TOKEN, '').trim();
15
15
 
16
16
  /** An basic tty wrapper */
17
17
  export class Terminal {
@@ -22,12 +22,12 @@ export class Terminal {
22
22
  #height: number;
23
23
  #output: tty.WriteStream;
24
24
 
25
- async #showWaitingIndicator(pos: Coord, signal: AbortSignal): Promise<void> {
25
+ async #showWaitingIndicator(position: Coord, signal: AbortSignal): Promise<void> {
26
26
  let done = false;
27
27
  signal.addEventListener('abort', () => done = true);
28
28
  let i = 0;
29
29
  while (!done) {
30
- await this.#writer.setPosition(pos).write(STD_WAIT_STATES[i++ % STD_WAIT_STATES.length]).commit(true);
30
+ await this.#writer.setPosition(position).write(STD_WAIT_STATES[i++ % STD_WAIT_STATES.length]).commit(true);
31
31
  await Util.blockingTimeout(100);
32
32
  }
33
33
  }
@@ -57,7 +57,7 @@ export class Terminal {
57
57
  }
58
58
  }
59
59
  } else {
60
- await this.streamToBottom(Util.mapAsyncItr(source, x => `%WAIT% ${x}`), { outputStreamToMain: true });
60
+ await this.streamToBottom(Util.mapAsyncIterable(source, line => `%WAIT% ${line}`), { outputStreamToMain: true });
61
61
  }
62
62
  }
63
63
 
@@ -65,10 +65,10 @@ export class Terminal {
65
65
  * Allows for writing at bottom of screen with scrolling support for main content
66
66
  */
67
67
  async streamToBottom(source: AsyncIterable<string | undefined>, config: TerminalStreamingConfig = {}): Promise<void> {
68
- const writePos = { x: 0, y: -1 };
68
+ const writePosition = { x: 0, y: -1 };
69
69
  const minDelay = config.minDelay ?? 0;
70
70
 
71
- let prev: string | undefined;
71
+ let previous: string | undefined;
72
72
  let stop: AbortController | undefined;
73
73
  let start = Date.now();
74
74
 
@@ -80,31 +80,31 @@ export class Terminal {
80
80
 
81
81
  for await (const line of source) {
82
82
  // Previous line
83
- if (prev && config.outputStreamToMain) {
84
- await this.writer.writeLine(lineMain(prev)).commit();
83
+ if (previous && config.outputStreamToMain) {
84
+ await this.writer.writeLine(lineMain(previous)).commit();
85
85
  }
86
86
 
87
87
  if (line && (Date.now() - start) >= minDelay) {
88
88
  start = Date.now();
89
89
  stop?.abort();
90
- this.writer.setPosition(writePos).write(lineStatus(line)).clearLine(1).commit(true);
90
+ this.writer.setPosition(writePosition).write(lineStatus(line)).clearLine(1).commit(true);
91
91
 
92
92
  const idx = line.indexOf(WAIT_TOKEN);
93
93
  if (idx >= 0) {
94
94
  stop = new AbortController();
95
- this.#showWaitingIndicator({ y: writePos.y, x: idx }, stop.signal);
95
+ this.#showWaitingIndicator({ y: writePosition.y, x: idx }, stop.signal);
96
96
  }
97
97
  }
98
98
 
99
- prev = line;
99
+ previous = line;
100
100
  }
101
101
 
102
102
  stop?.abort();
103
- if (prev !== undefined && config.outputStreamToMain) {
104
- await this.writer.writeLine(lineMain(prev)).commit();
103
+ if (previous !== undefined && config.outputStreamToMain) {
104
+ await this.writer.writeLine(lineMain(previous)).commit();
105
105
  }
106
106
 
107
- await this.#writer.setPosition(writePos).clearLine().commit(true);
107
+ await this.#writer.setPosition(writePosition).clearLine().commit(true);
108
108
  } finally {
109
109
  await this.#writer.reset().commit();
110
110
  }
@@ -116,9 +116,9 @@ export class Terminal {
116
116
  async streamList(source: AsyncIterable<{ idx: number, text: string, done?: boolean }>): Promise<void> {
117
117
  if (!this.#interactive) {
118
118
  const collected = [];
119
- for await (const ev of source) {
120
- if (ev.done) {
121
- collected[ev.idx] = ev.text;
119
+ for await (const event of source) {
120
+ if (event.done) {
121
+ collected[event.idx] = event.text;
122
122
  }
123
123
  }
124
124
  await this.#writer.writeLines(collected).commit();
package/src/util.ts CHANGED
@@ -11,33 +11,33 @@ export class TerminalUtil {
11
11
  */
12
12
  static progressBarUpdater(
13
13
  term: Terminal,
14
- cfg?: {
14
+ config?: {
15
15
  withWaiting?: boolean;
16
16
  style?: { complete: TermStyleInput, incomplete?: TermStyleInput } | (() => ProgressStyle);
17
17
  }
18
- ): (ev: ProgressEvent<string>) => string {
19
- const styleBase = typeof cfg?.style !== 'function' ? {
20
- complete: StyleUtil.getStyle(cfg?.style?.complete ?? { background: '#248613', text: '#ffffff' }),
21
- incomplete: cfg?.style?.incomplete ? StyleUtil.getStyle(cfg.style.incomplete) : undefined,
18
+ ): (event: ProgressEvent<string>) => string {
19
+ const styleBase = typeof config?.style !== 'function' ? {
20
+ complete: StyleUtil.getStyle(config?.style?.complete ?? { background: '#248613', text: '#ffffff' }),
21
+ incomplete: config?.style?.incomplete ? StyleUtil.getStyle(config.style.incomplete) : undefined,
22
22
  } : undefined;
23
23
 
24
- const style = typeof cfg?.style === 'function' ? cfg.style : (): ProgressStyle => styleBase!;
24
+ const style = typeof config?.style === 'function' ? config.style : (): ProgressStyle => styleBase!;
25
25
 
26
26
  let width: number;
27
- return ev => {
28
- const text = ev.value ?? (ev.total ? '%idx/%total' : '%idx');
29
- const pct = ev.total === undefined ? 0 : (ev.idx / ev.total);
30
- if (ev.total) {
31
- width ??= Math.trunc(Math.ceil(Math.log10(ev.total ?? 10000)));
27
+ return event => {
28
+ const text = event.value ?? (event.total ? '%idx/%total' : '%idx');
29
+ const progress = event.total === undefined ? 0 : (event.idx / event.total);
30
+ if (event.total) {
31
+ width ??= Math.trunc(Math.ceil(Math.log10(event.total ?? 10000)));
32
32
  }
33
- const state: Record<string, string> = { total: `${ev.total}`, idx: `${ev.idx}`.padStart(width ?? 0), pct: `${Math.trunc(pct * 100)}` };
34
- const line = ` ${text.replace(/[%](idx|total|pct)/g, (_, k) => state[k])} `;
35
- const full = term.writer.padToWidth(line, cfg?.withWaiting ? 2 : 0);
36
- const mid = Math.trunc(pct * term.width);
37
- const [l, r] = [full.substring(0, mid), full.substring(mid)];
33
+ const state: Record<string, string> = { total: `${event.total}`, idx: `${event.idx}`.padStart(width ?? 0), progress: `${Math.trunc(progress * 100)}` };
34
+ const line = ` ${text.replace(/[%](idx|total|progress)/g, (_, key) => state[key])} `;
35
+ const full = term.writer.padToWidth(line, config?.withWaiting ? 2 : 0);
36
+ const mid = Math.trunc(progress * term.width);
37
+ const [left, right] = [full.substring(0, mid), full.substring(mid)];
38
38
 
39
39
  const { complete, incomplete } = style();
40
- return `${cfg?.withWaiting ? `${WAIT_TOKEN} ` : ''}${complete(l)}${incomplete?.(r) ?? r}`;
40
+ return `${config?.withWaiting ? `${WAIT_TOKEN} ` : ''}${complete(left)}${incomplete?.(right) ?? right}`;
41
41
  };
42
42
  }
43
43
  }
package/src/writer.ts CHANGED
@@ -6,9 +6,9 @@ type State = { output: tty.WriteStream, height: number, width: number };
6
6
  type TermCoord = { x: number, y: number };
7
7
 
8
8
  const ESC = '\x1b[';
9
- const clamp = (v: number, size: number): number => Math.max(Math.min(v + (v < 0 ? size : 0), size - 1), 0);
10
- const delta = (v: number | undefined, pos: string, neg: string): string =>
11
- !v ? '' : `${ESC}${Math.abs(v)}${v < 0 ? neg : pos}`;
9
+ const clamp = (input: number, size: number): number => Math.max(Math.min(input + (input < 0 ? size : 0), size - 1), 0);
10
+ const delta = (input: number | undefined, position: string, negative: string): string =>
11
+ !input ? '' : `${ESC}${Math.abs(input)}${input < 0 ? negative : position}`;
12
12
 
13
13
  const Codes = {
14
14
  SHOW_CURSOR: `${ESC}?25h`,
@@ -73,14 +73,14 @@ export class TerminalWriter {
73
73
  }
74
74
 
75
75
  commit(restorePosition: boolean = this.#restoreOnCommit): Promise<void> {
76
- const q = this.#buffer.filter(x => x !== undefined);
76
+ const queue = this.#buffer.filter(line => line !== undefined);
77
77
  this.#buffer = [];
78
- if (q.length && restorePosition) {
79
- q.unshift(Codes.POSITION_SAVE);
80
- q.push(Codes.POSITION_RESTORE);
78
+ if (queue.length && restorePosition) {
79
+ queue.unshift(Codes.POSITION_SAVE);
80
+ queue.push(Codes.POSITION_RESTORE);
81
81
  }
82
- if (q.length && !this.#term.output.write(q.join(''))) {
83
- return new Promise<void>(r => this.#term.output.once('drain', r));
82
+ if (queue.length && !this.#term.output.write(queue.join(''))) {
83
+ return new Promise<void>(resolve => this.#term.output.once('drain', resolve));
84
84
  } else {
85
85
  return Promise.resolve();
86
86
  }
@@ -127,7 +127,7 @@ export class TerminalWriter {
127
127
 
128
128
  /** Write multiple lines */
129
129
  writeLines(lines: (string | undefined)[], clear = false): this {
130
- lines = lines.filter(x => x !== undefined);
130
+ lines = lines.filter(line => line !== undefined);
131
131
  let text = lines.join('\n');
132
132
  if (text.length > 0) {
133
133
  if (clear) {