Initial Commit
This commit is contained in:
92
packages/devtools/tooling/cli/src/progress/progress.md
Normal file
92
packages/devtools/tooling/cli/src/progress/progress.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# progress
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
`createProgress` renders a fixed-width ASCII progress bar for tracking long-running operations with a known total. It writes bar updates to any `WritableStreamLike` output — TTY or non-TTY — using in-place line clearing on TTY terminals and newline-separated lines on non-TTY streams (CI, pipes). The bar updates are driven by explicit `update(current)` calls from the caller; no internal timer is used.
|
||||
|
||||
The instance is `AbortSignal`-aware: aborting the signal silently makes all subsequent `update()` calls no-ops, allowing calling code to cancel a long operation without crashing.
|
||||
|
||||
## Features
|
||||
|
||||
- Fixed-width block bar with configurable `width` (default 40 characters) using `█` fill and `░` empty characters
|
||||
- Percentage and `current/total` count displayed after the bar: `[████████████░░░░░░░░] 60% (60/100)`
|
||||
- TTY mode: clears the current line and re-renders in-place via `clearLine` / `cursorTo`
|
||||
- Non-TTY mode: writes each update on its own line for readable CI output
|
||||
- `render()` returns the bar string without writing to the stream — useful for embedding in larger output
|
||||
- `complete()` forces 100% and appends a newline; idempotent (safe to call multiple times)
|
||||
- `AbortSignal` support: abort event listener marks the instance done; pre-fired signal respected via guard check in `update()`
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { createProgress } from "@suaveplan/cli/progress/progress";
|
||||
|
||||
const p = createProgress({ total: 100 });
|
||||
|
||||
for (let i = 0; i <= 100; i++) {
|
||||
p.update(i);
|
||||
await sleep(20);
|
||||
}
|
||||
|
||||
p.complete();
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { createProgress } from "@suaveplan/cli/progress/progress";
|
||||
import { Writable } from "node:stream";
|
||||
|
||||
const controller = new AbortController();
|
||||
const p = createProgress({
|
||||
total: files.length,
|
||||
width: 60,
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
let processed = 0;
|
||||
for (const file of files) {
|
||||
if (controller.signal.aborted) break;
|
||||
await processFile(file);
|
||||
p.update(++processed);
|
||||
}
|
||||
|
||||
p.complete();
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `createProgress(opts: ProgressOptions): ProgressInstance`
|
||||
|
||||
Creates a progress bar instance. No output is written until `update()` or `complete()` is called.
|
||||
|
||||
**`opts.total: number`** — the maximum value (100%). Must be positive.
|
||||
|
||||
**`opts.width?: number`** — width of the bar in characters (default `40`).
|
||||
|
||||
**`opts.stream?: WritableStreamLike`** — output target (default `process.stdout`). TTY in-place rendering requires `clearLine` and `cursorTo` methods plus `isTTY === true`.
|
||||
|
||||
**`opts.signal?: AbortSignal`** — when aborted, future `update()` calls become no-ops and the bar stops advancing.
|
||||
|
||||
### `ProgressInstance`
|
||||
|
||||
**`update(current: number): void`** — updates the displayed progress to `current`. Values are clamped to `[0, total]`. No-op if `complete()` was already called or the signal was aborted.
|
||||
|
||||
**`complete(): void`** — writes a 100% bar with a trailing newline and marks the instance done. Idempotent.
|
||||
|
||||
**`render(): string`** — returns the current bar string without writing to the stream.
|
||||
|
||||
### `ProgressOptionsSchema`
|
||||
|
||||
Zod schema for `ProgressOptions` — validates `total` (positive number) and `width` (optional positive number). Excludes `stream` and `signal`.
|
||||
|
||||
### `WritableStreamLike`
|
||||
|
||||
Re-exported from `../spinner/spinner.types.js`. Any object with `write(text: string): void` satisfies this interface; `clearLine`, `cursorTo`, and `isTTY` are optional and enable TTY mode when present.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Progress percentage is computed as `Math.min(1, current / total)` to handle over-total updates gracefully. The filled block count is `Math.round(pct * width)` — rounding avoids a full-bar display at 99% on small widths. The `complete()` guard (`done` flag) prevents double-writes when called multiple times. The `AbortSignal` listener uses `{ once: true }` so it self-removes after the first event.
|
||||
Reference in New Issue
Block a user