draftlog

repository·master·Indexed 22 days ago

https://github.com/ivanseidel/node-draftlog

A Node.js utility for creating dynamic, updatable terminal log lines. It allows developers to rewrite specific lines in the console to implement progress bars, animations, and status updates instead of appending new lines. Features include a .draft() method for console objects, configurable viewport limits via maximumLinesUp, and a production mode to disable tracking overhead.

Tokens
1.9K
Snippets
4
Records
13
Agent score
79%

What's inside draftlog

  1. How draftlog works and terminal limitations

    master

    Draftlog works by tracking the current lines written through the stream and moving the terminal cursor up to the specific line of a previously created LogDraft to update its content.

    Key Concepts & Limitations:

    • Viewport Limits: It is not possible to update text that has scrolled outside the visible area of the terminal.
    • Automatic Rewriting: If a DraftLog reaches the end of the terminal viewport, it is configured to automatically rewrite on a new line. You can disable this by setting DraftLog.defaults.canReWrite = false.
    • Terminal Height: If Node.js cannot detect the terminal rows, it uses DraftLog.defaults.maximumLinesUp. This can be modified if needed.
    • Process Exit: When using .addLineListener(process.stdin), the process will not exit automatically because stdin is being read. You must call process.exit(0) or process.stdin.pause() to stop the process.
  2. Initialize draftlog with a console object

    master

    To use draftlog, you must first initialize it by injecting it into a console-like object (usually console). This provides the draft method to your console instance.

    There are several ways to initialize it:

    1. Standard initialization: DraftLog(console)
    2. Single-line initialization: require('draftlog').into(console)
    3. Handling manual line breaks: If your logs include manual line breaks, attach a listener to process.stdin to ensure the cursor tracking remains accurate: require('draftlog').into(console).addLineListener(process.stdin).

    Note: If you are running in a production environment (e.g., a server where you don't want the overhead of tracking lines), pass true as the second argument to disable initialization.

  3. Example: Create a real-time progress bar

    master

    You can build custom widgets like progress bars by combining console.draft() with string manipulation.

    require('draftlog').into(console)
    
    // Input progress goes from 0 to 100
    function ProgressBar(progress) {
      // Make it 50 characters length
      var units = Math.round(progress / 2)
      return '[' + '='.repeat(units) + ' '.repeat(50 - units) + '] ' + progress + '%'
    }
    
    var barLine = console.draft('Starting download...')
    
    // Simulate a download
    downloadFile(function (progress) {
      barLine(ProgressBar(progress))
    })
  4. Create updatable logs using console.draft()

    master

    Once initialized, you can use the console.draft() method to create a dynamic log entry. This method returns a callback function. Calling this callback with new content will rewrite the previous line instead of printing a new one.

    This is useful for progress bars, timers, or status updates.

    // Create a Draft log
    var update = console.draft('Hi, my name is')
    
    // You can call standard logs after it
    console.log('Something else')
    
    // Use the received callback to update the draft line
    update('Hi, my name is Ivan!')
  5. Configure draftlog default options

    master

    When initializing draftlog, you can configure several default behaviors via an options object. These settings control how the log handles line limits and input sources:

    • maximumLinesUp: The number of lines to keep after a log has been created before it stops updating. If the console does not support row counting, this defaults to 30.
    • canReWrite: A boolean determining if the log should rewrite the line once maximumLinesUp is reached and reset the internal line counter. Defaults to true.
    • stdinAutoBind: A boolean that, if set to true, automatically binds to process.stdin as an input source. Note that setting this to true will prevent the process from exiting automatically. Defaults to false.
    {
      maximumLinesUp: 30,
      canReWrite: true,
      stdinAutoBind: false
    }
  6. Access core components of node-draftlog

    master

    The main module exports several core components that can be used directly for advanced configurations or specific logging tasks:

    • Lib.defaults: The default configuration settings.
    • Lib.CSIHelper: A helper for handling Control Sequence Introducer (ANSI) sequences.
    • Lib.LogDraft: The core class responsible for managing log drafts.
    • Lib.LineCountStream: A stream implementation for counting lines.
  7. Attach DrafLog to a console object using into()

    master

    The into(console, extra) function injects DrafLog capabilities into a provided console object.

    By default, it performs a full installation:

    1. It wraps the console._stdout with a LineCountStream to track line counts.
    2. It adds a .draft() method to the console object. This method creates a new LogDraft instance, logs the initial content, and returns an update function that can be used to append more content to that specific draft.
    3. If defaults.stdinAutoBind is enabled, it automatically binds the line counter to process.stdin.

    If you pass true as the second argument (extra), it enters production mode (Mock installation). In this mode, it only adds a .draft() method to the console that acts as an alias to the standard console.log, without any of the line-counting or draft-tracking overhead.

  8. Create and update dynamic log lines with LogDraft

    master

    The LogDraft class allows you to create a single log line that can be updated dynamically in the terminal. When you create a LogDraft instance, it captures the current line position. You can then call .update() repeatedly to overwrite that specific line with new content, which is useful for progress bars or status updates.

    To use it, instantiate LogDraft by passing a console object and the name of the logging method you wish to use (e.g., 'log', 'info', or 'error').

  9. Check or change the validity of a LogDraft

    master

    The valid property is a boolean that indicates whether the LogDraft instance is still allowed to write to the terminal.

    If the terminal line moves off-screen and the configuration prevents rewriting, valid is set to false. Once valid is false, subsequent calls to .update() or .write() will not perform any terminal output.

  10. Manually set the insertion point with saveLine()

    master

    The .saveLine([relative]) method allows you to manually set the line number that the LogDraft instance is responsible for.

    • If called without arguments, it saves the current terminal line.
    • If passed a relative integer, it saves the line at that offset from the current position.

    This is useful if you want the 'draft' to track a line that is not the immediate current line.