Package: output - uhop/console-toolkit GitHub Wiki

The output package provides helpers to output text to the console.

output/show.js

The output/show.js module provides simple helpers to output text to the console.

Function log()

The log() function is a simple wrapper around console.log().

log(text, options) outputs text to the console:

  • text β€” the text to output it can be any valid value that can be converted to a Box.
  • options β€” an object with the following properties:
    • endOfLineCommand β€” a string, which is appended at the end of the line but before the new line. Defaults to \x1B[m (RESET_ALL).
    • colorDepth β€” the number of colors to use. Defaults to 24.

If colorDepth is less than 4 (16 colors), all CSI sequences will be removed from the output.

Function out()

out(text, options) outputs text to the console. It is very similar to log(), but can output to any Writable stream. For that purpose, options has an additional property:

  • stream β€” the Writable stream to output to. Defaults to process.stdout.

Class Out

Out is a class that can be used to output text to any Writable stream. Essentially, it is a repackaged version of out() described above.

The class has the following members:

Name Return type Description
constructor(stream) Out Creates a new Out object with the specified stream.
stream Writable The Writable stream to output to.
colorDepth number The number of colors to use.
out(text, options) this Outputs text to the stream.

For TTY streams colorDepth is initialized using stream.getColorDepth(). For other streams it is assumed to be 1.

out() is the same as the stand-alone out() function above with the same parameters. The difference is that options.stream is overridden with this.stream, and if options.colorDepth is not specified, this.colorDepth is used.

Function debug()

The debug(string) function is used to debug escape sequences. It prints non-printable characters in the hexadecimal format using console.log().

Exports

All functions and classes are exported by name. There is no default export.

output/writer.js

The output/writer.js module provides a Writer class that can be used to write text to any Writable stream. It wraps TTY streams and streams. It is the souped-up version of Out described above.

When writing to a non-TTY stream, e.g., a file, all CSI escape sequences are removed automatically. It is possible to preserve colors and styles using the forceColorDepth option.

Class Writer

The Writer class has the following members:

Name Return type Description
constructor(stream = process.stdout, forceColorDepth) Writer Creates a new Writer object with the specified stream.
stream Writable The Writable stream to output to.
forceColorDepth number or undefined The number of colors to use.
isTTY boolean Whether the stream is a TTY stream.
rows number or undefined The number of rows in the terminal.
columns number or undefined The number of columns in the terminal.
size object The size of the terminal as {columns, rows}.
getColorDepth(...args) number The number of colors to use.
hasColors(count, ...args) boolean Whether the stream has a required number of colors.
async clearLine(dir) this Clears the current line according to dir.
async clearScreenDown() this Clears the screen down from the current cursor position.
async cursorTo(x, y) this Moves the cursor to the specified position using absolute coordinates.
async moveCursor(dx, dy) this Moves the cursor to the specified position using relative coordinates.
async writeString(s) this Writes s to the stream respecting TTY and colors.
async write(text, options) this Writes text to the stream.

forceColorDepth is used to override the number of colors. If forceColorDepth is defined, SGR sequences (responsible for colors and styles) are used even for non-TTY streams.

For non-TTY streams rows, columns, the result of getColorDepth() and properties of size are undefined. forceColorDepth overrides the result of getColorDepth().

For TTY streams, practically all accessors and methods delegate to the corresponding TTY stream methods:

Name TTY method
isTTY isTTY
rows rows
columns columns
size getWindowSize()
getColorDepth() getColorDepth()
hasColors() hasColors()
clearLine() clearLine()
clearScreenDown() clearScreenDown()
cursorTo() cursorTo()
moveCursor() moveCursor()

Read the corresponding TTY documentation for more details, e.g., what arguments are required and what return values are expected. The documentation explains how to watch for the resize event if you ever need to update text on the terminal after resizing.

cleanLine(dir) interprets dir as a direction for clearLine():

  • 0 β€” clear the entire line.
  • 1 β€” clear from the cursor to the end of the line.
  • -1 β€” clear from the beginning of the line to the cursor.

writeString() allows all CSI commands for TTY streams. If forceColorDepth is set, SGR sequences are preserved but other CSI sequences are removed. Otherwise, all CSI sequences are removed.

write(text, options) is a function to output a text container (strings, a Box, or a Panel β€” see Concepts for more details). It can stream lines to the steam as usual or it can draw lines on the screen in the same column advancing rows.

  • text β€” the text to output it can be any valid value that can be converted to strings.
  • options β€” an object with the following properties:
    • sameColumn β€” This argument is used only for TTY streams. If true, the text is written in the same column as the previous line. If false, the text is streamed as is. If 'save', it is treated as true but the internal mechanism is different. See below for more details.
    • noLastNewLine β€” if true, the last line is not ended with a new line character.
    • beforeLine β€” the text to output before each line. Defaults to ''.
    • afterLine β€” the text to output after each line. Defaults to ''.

When using sameColumn in TTY streams, write() is usually preceded with cursorTo() or moveCursor() to specify the position where the text should be written. When sameColumn is true, the text is written line by line. After each line the cursor is moved to the beginning of the line and one row down. When sameColumn is 'save', before writing a line CURSOR_SAVE_POS is issued and after writing CURSOR_RESTORE_POS is issued, then CURSOR_DOWN1.

While the 'save' option seems universal and can deal with accidental line wrapping, in some cases it may not be appropriate. Terminals do not support a stack for saved positions, so if your code already uses CURSOR_SAVE_POS and CURSOR_RESTORE_POS you should use the true value instead to avoid breaking your code.

Exports

The Writer class is exported by name and as the default export.

output/updater.js

The output/updater.js module provides an Updater class that can be used to update the text on the console in place.

Class Updater

The Updater class is the main mechanism to create CLI UI with updatable sections of text. It can be used with TTY and non-TTY streams.

Name Return type Description
constructor(updater, options = {}, writer = new Writer()) this Creates a new Updater object.
updater object or function The source of updated frames.
writer Writer The Writer instance to use.
prologue string The text to output at the beginning.
epilogue string The text to output at the end.
beforeFrame string The text to output before each frame.
afterFrame string The text to output after each frame.
beforeLine string The text to output before each line.
afterLine string The text to output after each line.
noLastNewLine boolean If true, the last line is not ended with a new line character.
isDone boolean true if the updater is done.
isRefreshing boolean true if the updater is periodically refreshing by timer.
startRefreshing(ms = 100) this Starts refreshing the updater by timer.
stopRefreshing() this Stops refreshing the updater by timer.
reset() this Resets the updater to the initial state.
getFrame(state, ...args) string Gets the current frame hinting the updater state.
async writeFrame(state, ...args) undefined Writes the current frame hinting the updater state.
async done() undefined Finishes updating: writes the epilogue and stops refreshing the updater.
async update(state = 'active', ...args) this Updates the terminal with the current frame.
async final(...args) this Writes the final update and calls done().

updater can be either a function or an object. If it is an object, it must implement the following methods:

  • state β€” The state setter. The current updater state is assigned to it.
  • getFrame(...args) β€” The function that returns the current frame.

If updater is a function, it is called as updater(state, ...args).

The result of the getFrame() method or the updater function is strings or a value that can be converted to strings.

state can be one of the following string values:

  • the empty string ('') β€” no updates are started.
  • 'active' β€” updates are started.
  • 'paused' β€” updates are paused.
  • 'finished' β€” updates are finished.

The updater can incorporate this information into its frames.

Usually for non-TTY streams the only state used is 'final'. No periodic updates are done.

constructor()'s options can have the following properties:

  • prologue β€” the text to output before the first frame. Typically it is sequence of CSI commands to prepare the terminal for updates. Defaults to RESET_ALL. Examples: hide the cursor, clear the screen.
  • epilogue β€” the text to output after the last frame. Typically it is sequence of CSI commands. Defaults to RESET_ALL. Examples: show the cursor, clear the screen.
  • beforeFrame β€” the text to output before each frame. Defaults to ''. Examples: clear the screen from the cursor before drawing a new frame.
  • afterFrame β€” the text to output after each frame. Defaults to ''. Examples: clear the screen from the cursor after drawing a new frame.
  • beforeLine β€” the text to output before each line. Defaults to ''. Examples: reset or set styles.
  • afterLine β€” the text to output after each line. Defaults to ''. Examples: clear the line from the cursor after drawing a new line.
  • noLastNewLine β€” if true, the last line of a frame is not ended with a new line character. Defaults to false.

isRefreshing, startRefreshing() and stopRefreshing() are rarely used in non-TTY streams. Internally they are based on the setInterval function. Note: the first frame will be requested in ms milliseconds. If you want to update immediately call update() before starting refreshing.

If isDone is true, update(), done(), final() and stopRefreshing() are no-ops.

If writer.isTTY is false, update() and startRefreshing() are no-ops.

Typical usage of the class:

import {Updater} from 'console-toolkit/output/updater.js';

const frameSource = state => 'state: ' + state;

const updater = new Updater(frameSource);

if (updater.writer.isTTY) {
  updater.update(); // draw the initial frame now
  updater.startRefreshing();
} else {
  updater.final(); // just draw the last frame
}

If you want to track some asynchronous operations, e.g., a downloading of a file, you can call update() on progress events (for TTY steams) and final() on completion. Both methods support variadic ...args, which are passed through to the frame source.

For more elaborate example see scripts/memory.js. An example of its output to a file:

Memory usage by this process (Press Ctrl+C to exit)
Legend: RSS - resident set size, green - goes down, red - goes up
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”°β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Memory usage  ┃      Bytes β”‚  Abbr β”‚
┝━━━━━━━━━━━━━━━╋━━━━━━━━━━━━┿━━━━━━━β”₯
β”‚ RSS           ┃ 48,758,784 β”‚ 48.8M β”‚
β”‚ Heap total    ┃  7,524,352 β”‚  7.5M β”‚
β”‚ Heap used     ┃  5,105,440 β”‚  5.1M β”‚
β”‚ External      ┃  1,627,818 β”‚  1.6M β”‚
β”‚ Array buffers ┃     10,515 β”‚ 10.5k β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Έβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”˜
 Heap - 5.1M of 7.5M:
 β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡

Exports

The Updater class is exported by name and as the default export.