@k1e1n04/mav 0.1.18 → 0.1.19

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.
@@ -0,0 +1,104 @@
1
+ import { EventEmitter } from 'node:events'
2
+ import { emitKeypressEvents } from 'node:readline'
3
+
4
+ export interface KeyInfo {
5
+ name?: string
6
+ ctrl?: boolean
7
+ meta?: boolean
8
+ shift?: boolean
9
+ sequence?: string
10
+ }
11
+
12
+ type KeypressHandler = (str: string, key: KeyInfo) => void
13
+ type DataHandler = (chunk: string | Buffer) => void
14
+ type ResizeHandler = () => void
15
+
16
+ export class TerminalUI {
17
+ readonly input: NodeJS.ReadStream
18
+ readonly output: NodeJS.WriteStream
19
+ private resizeEmitter = new EventEmitter()
20
+
21
+ constructor(
22
+ input: NodeJS.ReadStream = process.stdin,
23
+ output: NodeJS.WriteStream = process.stdout
24
+ ) {
25
+ this.input = input
26
+ this.output = output
27
+
28
+ emitKeypressEvents(this.input)
29
+ if (this.input.isTTY && typeof this.input.setRawMode === 'function') {
30
+ this.input.setRawMode(true)
31
+ }
32
+ this.input.resume()
33
+
34
+ if ('on' in this.output) {
35
+ this.output.on('resize', () => {
36
+ this.resizeEmitter.emit('resize')
37
+ })
38
+ }
39
+
40
+ this.write('\x1b]0;mav\x07')
41
+ }
42
+
43
+ get cols(): number {
44
+ return ('columns' in this.output && typeof this.output.columns === 'number')
45
+ ? this.output.columns
46
+ : 80
47
+ }
48
+
49
+ get rows(): number {
50
+ return ('rows' in this.output && typeof this.output.rows === 'number')
51
+ ? this.output.rows
52
+ : 24
53
+ }
54
+
55
+ onKeypress(handler: KeypressHandler): () => void {
56
+ const wrapped = (str: string, key: KeyInfo) => handler(str, key)
57
+ this.input.on('keypress', wrapped)
58
+ return () => {
59
+ this.input.off('keypress', wrapped)
60
+ }
61
+ }
62
+
63
+ onData(handler: DataHandler): () => void {
64
+ this.input.on('data', handler)
65
+ return () => {
66
+ this.input.off('data', handler)
67
+ }
68
+ }
69
+
70
+ onResize(handler: ResizeHandler): () => void {
71
+ this.resizeEmitter.on('resize', handler)
72
+ return () => {
73
+ this.resizeEmitter.off('resize', handler)
74
+ }
75
+ }
76
+
77
+ write(data: string): void {
78
+ this.output.write(data)
79
+ }
80
+
81
+ clearScreen(): void {
82
+ this.write('\x1b[H\x1b[2J')
83
+ }
84
+
85
+ render(content: string): void {
86
+ this.clearScreen()
87
+ this.write(content)
88
+ }
89
+
90
+ enterAlternateScreen(): void {
91
+ this.write('\x1b[?1049h')
92
+ }
93
+
94
+ exitAlternateScreen(): void {
95
+ this.write('\x1b[?1049l')
96
+ }
97
+
98
+ destroy(): void {
99
+ this.exitAlternateScreen()
100
+ if (this.input.isTTY && typeof this.input.setRawMode === 'function') {
101
+ this.input.setRawMode(false)
102
+ }
103
+ }
104
+ }
@@ -1,5 +0,0 @@
1
- declare module 'neo-blessed' {
2
- export * from 'blessed'
3
- declare const _default: typeof import('blessed')
4
- export { _default as default }
5
- }