99 lines
5.6 KiB
Markdown
99 lines
5.6 KiB
Markdown
# @suaveplan/readline - Terminal I/O primitive: AsyncGenerator line reader and interactive prompt interface
|
|
|
|
## Summary
|
|
|
|
AsyncGenerator line reader and interactive prompt interface for Node.js streams, file paths, and Web Streams.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
<!-- end:auto-docs --> - [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_ - [interface](./src/interface/interface.md) — <!-- begin:auto-docs --> _(no submodules)_- [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_ - [reader](./src/reader/reader.md) — <!-- begin:auto-docs --> _(no submodules)_- [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_ - [scanner](./src/scanner/scanner.md) — <!-- begin:auto-docs --> _(no submodules)_
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/readline
|
|
```
|
|
|
|
## Modules
|
|
|
|
| Module | Description | Docs |
|
|
|--------|-------------|------|
|
|
| `reader` | `readLines()` — multi-source AsyncGenerator line reader | [reader.md](src/reader/reader.md) |
|
|
| `interface` | `createInterface()` — interactive prompt / REPL interface | [interface.md](src/interface/interface.md) |
|
|
| `errors` | `ReadlineError` and stable error-code registry | [errors.md](src/errors/errors.md) |
|
|
|
|
## Quick Start
|
|
|
|
### `readLines()` — iterate lines from any source
|
|
|
|
```ts
|
|
import { readLines } from "@suaveplan/readline/reader/reader";
|
|
|
|
// From a file path
|
|
for await (const line of readLines("/var/log/app.log")) {
|
|
console.log(line);
|
|
}
|
|
|
|
// From a Node.js Readable
|
|
import { createReadStream } from "node:fs";
|
|
for await (const line of readLines(createReadStream("data.csv"), { skipEmpty: true })) {
|
|
process(line);
|
|
}
|
|
|
|
// With abort support and line-length guard
|
|
const ac = new AbortController();
|
|
setTimeout(() => ac.abort(), 5_000);
|
|
for await (const line of readLines("huge.txt", { maxLineLength: 4096, signal: ac.signal })) {
|
|
console.log(line);
|
|
}
|
|
```
|
|
|
|
### `createInterface()` — interactive prompt
|
|
|
|
```ts
|
|
import { createInterface } from "@suaveplan/readline/interface/interface";
|
|
|
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
|
|
const name = await rl.question("Your name: ");
|
|
console.log(`Hello, ${name}!`);
|
|
|
|
// Iterate all lines (useful for piped input)
|
|
for await (const line of rl) {
|
|
if (line === "quit") break;
|
|
console.log(`echo: ${line}`);
|
|
}
|
|
|
|
rl.close();
|
|
```
|
|
|
|
## Benchmarks
|
|
|
|
Measured on Linux 6.6 / WSL2, Bun v1.x, AMD Ryzen 9 5900X.
|
|
|
|
### Scanner throughput (`createScanner`)
|
|
|
|
| Benchmark | ops/sec | avg latency |
|
|
|-----------|---------|-------------|
|
|
| scanner 1 MB (50 k lines) | PLACEHOLDER | PLACEHOLDER |
|
|
| scanner 10 MB (500 k lines) | PLACEHOLDER | PLACEHOLDER |
|
|
|
|
### Reader throughput (`readLines`)
|
|
|
|
| Benchmark | ops/sec | avg latency |
|
|
|-----------|---------|-------------|
|
|
| readLines() file path (10 k lines) | PLACEHOLDER | PLACEHOLDER |
|
|
| readLines() Readable (10 k lines) | PLACEHOLDER | PLACEHOLDER |
|
|
|
|
## License
|
|
|
|
MIT
|