0Z4C0
// navigation
// @ozaco/cli

Table

Streaming, auto-fitting terminal tables that redraw live or append in a pipe.

import from@ozaco/cli/table

@ozaco/cli/table is the default implementation of the Table protocol. It renders columnar data that you feed row by row through a handle, so tables can grow while a job runs rather than being assembled all at once.

On an interactive terminal it keeps every row, auto-fits column widths, and re-renders the whole table in place — so any row stays editable via update/set until end(). When the table outgrows the viewport, only the last rows that fit are shown plus a +N more note; end() clears the live window and commits the full, fully-aligned table to the scrollback.

In a pipe or CI (non-interactive), output is fixed-width and append-only: a row is committed once the next one arrives (or on end()), so the most-recent row stays editable while earlier lines are already written. Updating an already-committed row can’t rewrite it, so its new state is re-appended as a fresh line. Column widths shrink to fit the terminal, cells are truncated with an ellipsis, and the border style (full, header, or none), gutter, header visibility and live window are all configurable. Requires Terminal and Palette.

01

Implementation

const

DefaultTable

The table implementation providing the `table` action.

signature
const DefaultTable: TableDef

Install it alongside Terminal and Palette, then open a table with Table.actions.table(options) and drive it through the returned handle.

example
import { install } from '@ozaco/std/plugin'
import { Table } from '@ozaco/cli/core'
import { DefaultTable } from '@ozaco/cli/table'

yield* install(DefaultTable)
const t = yield* Table.actions.table({
  columns: [
    { header: 'Name', key: 'name' },
    { header: 'Size', key: 'size', align: 'right' },
  ],
})
yield* t.rows(files.map(f => ({ name: f.name, size: f.size })))
yield* t.end()
02

Action

Available on the `Table` protocol once `DefaultTable` is installed.

fn

table

Open a streaming table; returns a `Handle` to feed rows and close it.

signature
table(options: TableDef.Options): Future<TableDef.Handle>

options.columns defines the shape; border (default full), gutter (default 2), head (default true) and window tune rendering. Each Column may set header, key, fixed width or min/max bounds, align, a color style, and a format function. The table is bound to the current scope: it commits on end() or on teardown.

// parameters
options: TableDef.Options
Column definitions plus `border`/`gutter`/`head`/`window`.
// returns A `TableDef.Handle` for streaming rows into the table.
03

Handle

The interface returned by the `table` action.

iface

Handle

Feed rows into an open table and commit it (`TableDef.Handle`).

signature
interface Handle {
  row(row: TableDef.Row): Future<number>
  rows(rows: TableDef.Row[]): Future<number[]>
  update(index: number, row: TableDef.Row): Future<void>
  set(index: number, column: string | number, value: TableDef.Cell): Future<void>
  end(): Future<void>
}

row appends one row and returns its index; rows appends many and returns their indices. update replaces a whole row by index; set replaces one cell by column key (object rows) or index (array rows). end commits the full, aligned table to the scrollback. A Row is a tuple of cells or a keyed record.

example
const i = yield* t.row({ name: 'build', size: 0 })
// … work happens …
yield* t.set(i, 'size', 2048)
yield* t.end()