-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscreen-log.ts
More file actions
104 lines (84 loc) · 2.99 KB
/
screen-log.ts
File metadata and controls
104 lines (84 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
* Screen-backed {@link Log} implementation that pushes entries
* to an {@link OutputStore} instead of writing to stderr.
*
* @module
*/
import { match } from 'ts-pattern'
import type { Log, LogMessageOptions, NoteOptions, StreamLog } from '@/context/types.js'
import type { OutputStore } from './types.js'
// ---------------------------------------------------------------------------
// Exports
// ---------------------------------------------------------------------------
/**
* Create a {@link Log} instance that writes to an {@link OutputStore}
* for rendering by the `<Output />` component.
*
* @param store - The output store to push entries to.
* @returns A frozen Log instance compatible with `ctx.log`.
*/
export function createScreenLog(store: OutputStore): Log {
return Object.freeze({
info(message: string, _opts?: LogMessageOptions): void {
store.push({ kind: 'log', level: 'info', text: message })
},
success(message: string, _opts?: LogMessageOptions): void {
store.push({ kind: 'log', level: 'success', text: message })
},
error(message: string, _opts?: LogMessageOptions): void {
store.push({ kind: 'log', level: 'error', text: message })
},
warn(message: string, _opts?: LogMessageOptions): void {
store.push({ kind: 'log', level: 'warn', text: message })
},
step(message: string, _opts?: LogMessageOptions): void {
store.push({ kind: 'log', level: 'step', text: message })
},
message(message: string, opts?: LogMessageOptions): void {
const symbol = match(opts)
.with(undefined, () => undefined)
.otherwise((o) => o.symbol)
store.push({ kind: 'log', level: 'message', text: message, symbol })
},
intro(_title?: string): void {
// No-op in screen context — screens handle their own layout
},
outro(_message?: string): void {
// No-op in screen context — screens handle their own exit
},
note(_message?: string, _title?: string, _opts?: NoteOptions): void {
// No-op in screen context — use Box/Text for notes
},
newline(): void {
store.push({ kind: 'newline' })
},
raw(text: string): void {
store.push({ kind: 'raw', text })
},
box(_message: string, _title?: string): void {
// No-op in screen context — use Box/Text for bordered display
},
stream: createScreenStreamLog(),
}) satisfies Log
}
// ---------------------------------------------------------------------------
// Private
// ---------------------------------------------------------------------------
/**
* Create a no-op {@link StreamLog} for screen contexts.
*
* @private
*/
function createScreenStreamLog(): StreamLog {
const noop = async (_iterable: AsyncIterable<string>): Promise<void> => {
// No-op in screen context — streaming is not supported in React/Ink
}
return Object.freeze({
info: noop,
success: noop,
error: noop,
warn: noop,
step: noop,
message: noop,
}) satisfies StreamLog
}