@travetto/terminal 3.0.3 → 3.1.0-rc.0
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 +4 -4
- package/package.json +1 -1
- package/src/color-output.ts +2 -2
- package/src/operation.ts +15 -1
- package/src/query.ts +32 -33
- package/src/terminal.ts +4 -4
- package/src/types.ts +1 -1
- package/src/writer.ts +11 -5
package/README.md
CHANGED
|
@@ -38,12 +38,12 @@ const tplFn = GlobalTerminal.templateFunction({
|
|
|
38
38
|
path: 'teal',
|
|
39
39
|
success: 'green',
|
|
40
40
|
failure: 'red',
|
|
41
|
-
param: 'yellow',
|
|
41
|
+
param: ['yellow', 'goldenrod'],
|
|
42
42
|
type: 'cyan',
|
|
43
|
-
description: 'white',
|
|
44
|
-
title: 'brightWhite',
|
|
43
|
+
description: ['white', 'gray'],
|
|
44
|
+
title: ['brightWhite', 'black'],
|
|
45
45
|
identifier: 'dodgerBlue',
|
|
46
|
-
subtitle: 'lightGray',
|
|
46
|
+
subtitle: ['lightGray', 'darkGray'],
|
|
47
47
|
subsubtitle: 'darkGray'
|
|
48
48
|
});
|
|
49
49
|
|
package/package.json
CHANGED
package/src/color-output.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type TermStyle =
|
|
|
9
9
|
|
|
10
10
|
export type TermStyleInput = TermStyle | RGBInput;
|
|
11
11
|
export type Prim = string | number | boolean | Date | RegExp;
|
|
12
|
-
export type TermColorPaletteInput = Record<string, TermStyleInput | [TermStyleInput, TermStyleInput]>;
|
|
12
|
+
export type TermColorPaletteInput = Record<string, TermStyleInput | [dark: TermStyleInput, light: TermStyleInput]>;
|
|
13
13
|
export type TermColorFn = (text: Prim) => string;
|
|
14
14
|
export type TermColorPalette<T> = Record<keyof T, TermColorFn>;
|
|
15
15
|
|
|
@@ -92,7 +92,7 @@ export class ColorOutputUtil {
|
|
|
92
92
|
/**
|
|
93
93
|
* Make a simple primitive colorer
|
|
94
94
|
*/
|
|
95
|
-
static colorer(term: TermState, style: TermStyleInput | [
|
|
95
|
+
static colorer(term: TermState, style: TermStyleInput | [dark: TermStyleInput, light: TermStyleInput]): TermColorFn {
|
|
96
96
|
const schemes = {
|
|
97
97
|
light: this.getStyledLevels(Array.isArray(style) ? style[1] ?? style[0] : style),
|
|
98
98
|
dark: this.getStyledLevels(Array.isArray(style) ? style[0] : style),
|
package/src/operation.ts
CHANGED
|
@@ -32,9 +32,23 @@ export class TerminalOperation {
|
|
|
32
32
|
}
|
|
33
33
|
await batch.commit();
|
|
34
34
|
|
|
35
|
+
let start = Date.now();
|
|
36
|
+
const minDelay = config.minDelay ?? 0;
|
|
37
|
+
|
|
38
|
+
let line: string = '';
|
|
35
39
|
for await (const text of source) {
|
|
36
|
-
|
|
40
|
+
line = text;
|
|
41
|
+
if ((Date.now() - start) >= minDelay) {
|
|
42
|
+
start = Date.now();
|
|
43
|
+
await TerminalWriter.for(term).setPosition(writePos).write(line).clearLine(1).commit(true);
|
|
44
|
+
line = '';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (line) {
|
|
49
|
+
await TerminalWriter.for(term).setPosition(writePos).write(line).clearLine(1).commit(true);
|
|
37
50
|
}
|
|
51
|
+
|
|
38
52
|
if (config.clearOnFinish ?? true) {
|
|
39
53
|
await TerminalWriter.for(term).setPosition(writePos).clearLine().commit(true);
|
|
40
54
|
}
|
package/src/query.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import tty from 'tty';
|
|
1
|
+
import type tty from 'tty';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
2
3
|
|
|
3
4
|
import { ANSICodes } from './codes';
|
|
4
5
|
import { IterableUtil } from './iterable';
|
|
@@ -7,6 +8,31 @@ import { RGB, TermCoord, TermQuery } from './types';
|
|
|
7
8
|
const to256 = (x: string): number => Math.trunc(parseInt(x, 16) / (16 ** (x.length - 2)));
|
|
8
9
|
const COLOR_RESPONSE = /(?<r>][0-9a-f]+)[/](?<g>[0-9a-f]+)[/](?<b>[0-9a-f]+)[/]?(?<a>[0-9a-f]+)?/i;
|
|
9
10
|
|
|
11
|
+
// @ts-expect-error
|
|
12
|
+
const queryScript = (function (...bytes) {
|
|
13
|
+
const i = process.stdin;
|
|
14
|
+
i.setRawMode(true);
|
|
15
|
+
i.resume();
|
|
16
|
+
i.once('readable', function () {
|
|
17
|
+
const inp = i.read();
|
|
18
|
+
/* @ts-expect-error */
|
|
19
|
+
process.send(Buffer.isBuffer(inp) ? inp.toString('utf8') : inp);
|
|
20
|
+
i.setRawMode(false);
|
|
21
|
+
});
|
|
22
|
+
process.stdout.write(String.fromCharCode(...bytes));
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const runQuery = async (input: tty.ReadStream, output: tty.WriteStream, code: string): Promise<Buffer> => {
|
|
26
|
+
const script = queryScript.toString().replaceAll('\'', '"').replaceAll('\n', '');
|
|
27
|
+
const fullScript = `(${script})(${code.split('').map(x => x.charCodeAt(0))})`
|
|
28
|
+
const proc = spawn(process.argv0, ['-e', fullScript], { stdio: [input, output, 2, 'ipc'], detached: true });
|
|
29
|
+
const text = await new Promise<string>((res, rej) => {
|
|
30
|
+
proc.once('message', res);
|
|
31
|
+
proc.on('error', rej);
|
|
32
|
+
});
|
|
33
|
+
return Buffer.from(text, 'utf8');
|
|
34
|
+
};
|
|
35
|
+
|
|
10
36
|
const ANSIQueries = {
|
|
11
37
|
/** Parse xterm color response */
|
|
12
38
|
color: (field: 'background' | 'foreground'): TermQuery<RGB | undefined> => ({
|
|
@@ -43,43 +69,15 @@ export class TerminalQuerier {
|
|
|
43
69
|
#queue = IterableUtil.simpleQueue();
|
|
44
70
|
#output: tty.WriteStream;
|
|
45
71
|
#input: tty.ReadStream;
|
|
72
|
+
#restore?: () => void;
|
|
46
73
|
|
|
47
74
|
constructor(input: tty.ReadStream, output: tty.WriteStream) {
|
|
48
75
|
this.#input = input;
|
|
49
76
|
this.#output = output;
|
|
50
77
|
}
|
|
51
78
|
|
|
52
|
-
async #readInput(query: string): Promise<Buffer> {
|
|
53
|
-
const isRaw = this.#input.isRaw;
|
|
54
|
-
const isPaused = this.#input.isPaused();
|
|
55
|
-
const data = this.#input.listeners('data');
|
|
56
|
-
try {
|
|
57
|
-
this.#input.removeAllListeners('data');
|
|
58
|
-
|
|
59
|
-
if (isPaused) {
|
|
60
|
-
this.#input.resume();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this.#input.setRawMode(true);
|
|
64
|
-
// Send data, but do not wait on it
|
|
65
|
-
this.#output.write(query);
|
|
66
|
-
await new Promise(res => this.#input.once('readable', res));
|
|
67
|
-
const val: Buffer | string = this.#input.read();
|
|
68
|
-
return typeof val === 'string' ? Buffer.from(val, 'utf8') : val;
|
|
69
|
-
} finally {
|
|
70
|
-
if (isPaused) {
|
|
71
|
-
this.#input.pause();
|
|
72
|
-
}
|
|
73
|
-
this.#input.setRawMode(isRaw);
|
|
74
|
-
for (const fn of data) {
|
|
75
|
-
// @ts-ignore
|
|
76
|
-
this.#input.on('data', fn);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
79
|
query<T>(q: TermQuery<T>): Promise<T> {
|
|
82
|
-
return this.#queue.add(() => this.#
|
|
80
|
+
return this.#queue.add(() => runQuery(this.#input, this.#output, q.query()).then(q.response));
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
cursorPosition(): Promise<TermCoord> {
|
|
@@ -90,7 +88,8 @@ export class TerminalQuerier {
|
|
|
90
88
|
return this.query(ANSIQueries.color('background'));
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
close():
|
|
94
|
-
|
|
91
|
+
close(): void {
|
|
92
|
+
this.#restore?.();
|
|
93
|
+
this.#queue.close();
|
|
95
94
|
}
|
|
96
95
|
}
|
package/src/terminal.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { ColorOutputUtil, Prim, TermColorFn, TermColorPalette, TermColorPaletteI
|
|
|
13
13
|
type TerminalStreamPositionConfig = {
|
|
14
14
|
position?: TermLinePosition;
|
|
15
15
|
staticMessage?: string;
|
|
16
|
+
minDelay?: number;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
type TerminalProgressConfig = TerminalStreamPositionConfig & {
|
|
@@ -98,12 +99,11 @@ export class Terminal implements TermState {
|
|
|
98
99
|
return this.#init;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
reset(): void {
|
|
103
|
+
this.#query.close();
|
|
103
104
|
if (this.interactive) {
|
|
104
|
-
|
|
105
|
+
this.#output.write(this.writer().resetCommands());
|
|
105
106
|
}
|
|
106
|
-
return;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
getCursorPosition(): Promise<TermCoord> {
|
package/src/types.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type TerminalTableEvent = { idx: number, text: string, done?: boolean };
|
|
|
13
13
|
export type TerminalTableConfig = { header?: string[], forceNonInteractiveOrder?: boolean };
|
|
14
14
|
export type TerminalProgressEvent = { idx: number, total?: number, text?: string };
|
|
15
15
|
export type TerminalProgressRender = (ev: TerminalProgressEvent) => string;
|
|
16
|
-
export type TerminalStreamingConfig = { position?: TermLinePosition, clearOnFinish?: boolean, at?: TermCoord };
|
|
16
|
+
export type TerminalStreamingConfig = { position?: TermLinePosition, clearOnFinish?: boolean, at?: TermCoord, minDelay?: number };
|
|
17
17
|
export type TerminalWaitingConfig = { end?: boolean, committedPrefix?: string } & TerminalStreamingConfig & DelayedConfig;
|
|
18
18
|
|
|
19
19
|
export type TermColorLevel = 0 | 1 | 2 | 3;
|
package/src/writer.ts
CHANGED
|
@@ -137,10 +137,16 @@ export class TerminalWriter {
|
|
|
137
137
|
|
|
138
138
|
/** Reset */
|
|
139
139
|
reset(): this {
|
|
140
|
-
return this
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
return this.write(this.resetCommands());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Reset Commands */
|
|
144
|
+
resetCommands(): string {
|
|
145
|
+
return [
|
|
146
|
+
ANSICodes.POSITION_SAVE(),
|
|
147
|
+
ANSICodes.SHOW_CURSOR(),
|
|
148
|
+
ANSICodes.SCROLL_RANGE_CLEAR(),
|
|
149
|
+
ANSICodes.POSITION_RESTORE()
|
|
150
|
+
].join('');
|
|
145
151
|
}
|
|
146
152
|
}
|