terminal-model
A Node.js library for terminal emulation that handles streaming ANSI output with proper whitespace preservation. Designed to parse and process ANSI escape sequences from subprocess output, making it suitable for building terminal-based user interfaces and streaming command output with correct formatting.
Features
- ANSI Sequence Parsing: Full support for CSI commands including SGR (colors/styles), cursor positioning, and line erasure
- Cell-based Rendering: Each character stored with its styling for precise overwriting and correct whitespace handling
- Streaming Transform: Node.js transform stream wrapper for easy integration
- Flexible Line Emission: Three emission strategies:
ImmediateStrategy: Emit lines immediately on newline
TimeoutStrategy: Emit on newline or after a fixed timeout
StatefulTimeoutStrategy: Adaptive timeout based on line volatility
- Color Support: Standard (0-7), bright (8-15), 256-color, and RGB colors
- Chunk Boundary Handling: Buffers incomplete ANSI sequences across chunk boundaries
- Node.js Compatibility: Supports Node.js 0.8+ with a compatibility layer
Installation
npm install terminal-model
Quick Start
import { TerminalTransform, StatefulTimeoutStrategy } from 'terminal-model'
const terminal = new TerminalTransform({
strategy: new StatefulTimeoutStrategy()
})
terminal.onLine((line) => {
console.log('Received line:', line)
})
terminal.write('Hello, World!\n')
terminal.write('\x1b[31mRed text\x1b[0m\n')
API
StreamingTerminal
The core terminal emulator class that parses ANSI sequences and maintains terminal state.
import { StreamingTerminal } from 'terminal-model'
const terminal = new StreamingTerminal()
const state = terminal.write('some content\n')
if (terminal.hasContent()) {
const line = terminal.renderLine()
console.log(line)
}
terminal.reset()
terminal.setLineReadyCallback((line) => {
console.log('Line ready:', line)
})
terminal.dispose()
TerminalTransform
A transform stream wrapper around StreamingTerminal with configurable emission strategies.
import { TerminalTransform, TimeoutStrategy } from 'terminal-model'
const terminal = new TerminalTransform({
strategy: new TimeoutStrategy({ timeout: 50 })
})
terminal.onLine((line) => {
console.log('Emitted line:', line)
})
terminal.on('line', (line: string) => {
console.log('Line event:', line)
})
terminal.write('some content\n')
const pending = terminal.getPendingLines()
const consumed = terminal.consumePendingLines()
terminal.clearPendingLines()
SgrComposer
Static utility class for parsing SGR parameters, composing attributes, and generating ANSI sequences.
import { SgrComposer } from 'terminal-model'
const attrs = SgrComposer.parse([31, 1])
const base = SgrComposer.parse([31])
const overlay = SgrComposer.parse([1])
const combined = SgrComposer.compose(base, overlay)
const sequence = SgrComposer.toSequence(attrs)
SgrComposer.equals(attrs1, attrs2)
SgrComposer.isEmpty(attrs)
const reset = SgrComposer.reset()
AnsiParser
Static class for detecting and extracting ANSI sequences from strings.
import { AnsiParser } from 'terminal-model'
const result = AnsiParser.parseNext('\x1b[31mHello', 0)
const incomplete = AnsiParser.getIncompleteSequence('\x1b[31')
Line Emission Strategies
import {
ImmediateStrategy,
TimeoutStrategy,
StatefulTimeoutStrategy
} from 'terminal-model'
const immediate = new ImmediateStrategy()
const timeout = new TimeoutStrategy({ timeout: 100 })
const stateful = new StatefulTimeoutStrategy()
Supported ANSI Features
CSI Commands
m | SGR (colors, bold, dim, italic, underline, blink, inverse, hidden, strikethrough) | Full |
G / ` | Horizontal absolute positioning | Full |
C / D | Cursor forward/backward | Full |
K | Erase in line | Full |
X | Erase characters | Full |
P / @ | Delete/Insert characters | Full |
s / u | Save/Restore cursor position | Full |
7 / 8 | Save/Restore cursor position (DEC) | Full |
Ignored Commands
Multi-line or incompatible with streaming:
- CUP (H), HVP (f), CUU/A, CUD/B (vertical movement)
- ED (J), SU (S), SD (T), IL (L), DL (M)
Color Support
| Standard colors | 0-7 | 30-37 (fg), 40-47 (bg) |
| Bright colors | 8-15 | 90-97 (fg), 100-107 (bg) |
| 256-color | 0-255 | 38;5;N (fg), 48;5;N (bg) |
| RGB | 16,777,216 | 38;2;R;G;B (fg), 48;2;R;G;B (bg) |
Control Characters
\n (newline)
\r (carriage return)
\t (tab)
\x08 (backspace)
Architecture
┌─────────────────────────────────────────────────┐
│ terminal-model │
├─────────────────────────────────────────────────┤
│ Entry Point (src/index.ts) │
│ Exports: StreamingTerminal, TerminalTransform, │
│ SgrComposer, Strategies, Types │
└───────────────┬─────────────────────────────────┘
│
┌-----------+-----------+-----------+
▼ ▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ ANSI │ │Terminal│ │ SGR │ │Strategy│
│ Parser │ │ State │ │Composer│ │ Pattern│
└────────┘ └────────┘ └────────┘ └────────┘
│
▼
┌─────────────────────┐
│ TerminalTransform │
│ (Transform Stream) │
└─────────────────────┘
License
MIT