📜 Create mutable log lines into the terminal, and give life to your logs!

Overview

DraftLog

Build Status Dependency Status

Because Logging can be pretty and fun

DraftLog GIF

Installation

$ npm install draftlog

What it does

It allows you to re-write a line of your log after being written. Just like post 'updating'. This is the building block for any dynamic element such as progress bars, loading status, animations, checkboxes and so on.

It does that by keeping track of the current lines of code written through the stream, and moving the cursor up to the line of the LogDraft you created previously, and updating its content.

Look in the examples folders to see how easy it is, to create anything. No strict and fixed widgets are given to you. Instead, use your creativity with this tool to create anything you want! Share the results later with an example ;)

Looking for CUTE Unicode chars? Check out Unicute.

How the HECK is that even possible?

Usage

// Setup
const DraftLog = require('draftlog')
DraftLog(console)

// Or, in a single line:
require('draftlog').into(console)

// Account for manual line breaks with:
require('draftlog').into(console).addLineListener(process.stdin)

To create a updatable log, use the draft method injected into the provided console:

// Create a Draft log
var update = console.draft('Hi, my name is')

// You can call logs after it
console.log('Something else')

// Use the received callback to update it as many times as you want
update('Hi, my name is Ivan!')

Here are some interesting examples:

// Prints a clock incrementing one every second in the same line
var draft = console.draft()
var elapsed = 1
setInterval( () => {
  draft('Elapsed', elapsed++, 'seconds')
}, 1000)

console.log('It doesn`t matter')
console.log('How \n many \n lines \n it uses')

Or maybe, to show an flow process?

function someAsyncFunction(){ 
  var TAG = '[someAsyncFunction]'
  var log = console.draft(TAG, 'init')

  function a() {
    setTimeout(() => {
      log(TAG, 'calling b')
      b()
    }, 500)
  }

  function b() {
    setTimeout(() => {
      log(TAG, 'finished')
    })
  }
}

You can create your own progress bar, just like "that":

require('draftlog').into(console)

// Input progess 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...')
downloadFile(function (progress) {
  barLine(ProgressBar(progress))
})

// Will show something like: (being updated in realtime)
// [============================                      ] 56%

Learn from examples!

We have a few of them ready for you to use! Take a look at the examples folder. Remember to replace require('../') with require('draftlog').

Also, install chalk to get colors on your terminal ;)

Important things to know

Because of the way Terminals are built, it is not possible to update a text outside the viewing area of the terminal.

That said, DraftLogs are setup to automagically be rewritten on a new line if they reach the end of the viewport. Note that, you can disable that behavior, by setting DraftLog.defaults.canReWrite = false

Also, if the NodeJS environment cannot detect the number of rows of your terminal automatically, it will use the default height on DraftLog.defaults.maximumLinesUp. Modify that if needed.

When using into(console).addLineListener(process.stdin), your code will no longer exit automatically, because the stream is being "read". To stop your own code, you can call process.exit(0) or pause the stream when you want with: process.stdin.pause().

Discouragements

This library is awesome for development, cli tools and what ever you want to created, that is NOT an optimized "slave" server. Please, disable it passing true as a second parameter to the DraftLog initialization:

// Disable Initialization (true = production; false = development)
DraftLog(console, true)
// Or, with one line require-init:
require('draftlog').into(console, true)

Creator

Ivan Seidel

Comments
  • Expose DraftLog instance's line on stdout stream

    Expose DraftLog instance's line on stdout stream

    It may be useful to expose the line number whenever you update a draft console via console.draft()() so if we want to clear that line, we can use the line number without adding complex code to calculate it ourselves, as I see DraftLog._line contains the line, however it cannot be accessed via console.draft()()._line as console.draft() returns an new DraftLog(...).update.

    Maybe you could add this simple thing by returning this._line in the update method. Sorry about the big sentence above, I didn't know how to explain myself.

    Or maybe a feature to clean the line completely could be added, as

    DraftLog.update(); // or DraftLog.update('');
    

    still leaves an empty line.

    Thank you for your time, and sorry if this isn't something you want DraftLog to do. Thanks for making such a great module. ✌️

    opened by datitisev 13
  • Question: Fix line at the bottom

    Question: Fix line at the bottom

    First of all: Nice lib!

    Now my question: Is it possible to fix a log at the bottom while I keep sending more console.logs?

    I want to keep a status bar counting the number of downloads and failed downloads, while I keep submitting lines with the individual downloads

    opened by sirgallifrey 2
  • Output seems to have a bug where some previous chars aren't deleted on update

    Output seems to have a bug where some previous chars aren't deleted on update

    When I run my timer for long enough, it seems to fail to re-render the line resulting in bizzare spelling issues that gradually become gibberish for each update. When the minute count no longer is necessary, the seconds from that format stick around as seen below.

    image

    opened by paulosllvn 0
  • Typescript compatibility

    Typescript compatibility

    Because this module extends functionality of Console, the following is required to avoid typescript complaining about missing "draft" function:

    interface Console {
            draft: (a) => (b) => {}
    }
    

    I think to support this from the module level, we can use the global declaration feature

    declare global {
        interface Console {
            draft: (a) => (b) => {}
        }
    }
    
    opened by ilyasfoo 6
  • can't generate multiple lines

    can't generate multiple lines

    Let's say I have codes like this below:

    let a = console.draft(' ')
    let b = console.draft('')
    
    setInterval(() => {
      a('something')
      b('something')
    }, 1000)
    

    It only shows a string.

    opened by imkimchi 1
  • Compatibility with Node repl module?

    Compatibility with Node repl module?

    Here's a naive attempt at writing a Node REPL which shows the output of each command on the same line every time:

    const repl = require('repl')
    require('draftlog').into(console)
    const update = console.draft('Starting REPL...')
    repl.start({prompt:update})
    

    And the output looks like this: https://asciinema.org/a/U0y4BMlqxMlhQLE2QE1szHiFi

    opened by IamCarbonMan 0
  • Proposals for new version

    Proposals for new version

    DraftLog works. The API is simple. I want to keep it that way, but it might be improved with a few ideas.

    Please, contribute by giving your insights, ideas and so on.

    [1] Avoid overriding console._stdout

    Can we find a way to NOT put something in the middle of the Stream? Is it possible to 'listen' to data on a Writable stream? If so, that's all we need (we don't ever modify contents anyway)

    [2] Should we 'hook' draft method into console?

    Hooking into console is really cool, but... To specific.

    What if the person doesn't uses console to do logging, but writing to stdout directly? In that case, it would cause two problems:

    1. Draft method would be available only through custom instantiated Console. That's a bad requirement to ask developers... (Console is cool, but not a requirement for logging stuff)
    2. If any data get's logged directly into stdout, then it would not capture that data. [1] would fix that, if just in listening mode.

    [3] Ideas for a new (and simpler) API

    const DraftLog = require('draftlog')
    console.draft = DraftLog(process.stdout[, process.stdin])
    // Or save to a custom function maybe
    const draft = DraftLog(process.stdout[, process.stdin])
    
    // Would make things easier in case of disabling:
    if (PRODUCTION) 
      const draft = DraftLog();
    
    opened by ivanseidel 1
Owner
Ivan Seidel
Just a "Problem Solver"
Ivan Seidel
Terminal ui for discord with interactive terminal

dickord why No fucking clue i was bored or something. why does it look dogshit Try and find a node module that supports terminal functions like trauma

Hima 3 Nov 7, 2022
Terminal recorder: Record your termial session into HTML

terminal-recorder Terminal recorder allows you to record your bash session, and export it to html so then you can share it with your friends. GitHub P

Cristian Cortez 104 Mar 3, 2022
Create clickable links in the terminal

terminal-link Create clickable links in the terminal Install $ npm install terminal-link Usage import terminalLink from 'terminal-link'; const link

Sindre Sorhus 539 Dec 31, 2022
Add a hungry turtle to your terminal and feed it every time you mistype 'npm' as 'nom'

Nom Does this ever happen to you? You happily code away on a project, navigating the command line like a pro, testing, error logging, installing packa

Meike Hankewicz 5 Apr 26, 2022
Translations with speech synthesis in your terminal as a node package

Normit Normit is an easy way to translate stuff in your terminal. You can check out its Ruby gem version termit. Installation npm install normit -g Us

Paweł Urbanek 234 Jan 1, 2023
DataENV is a cli tool that allows you to save data temporarily using your terminal.

DataEnv CLI Instllation npm install -g dataenv Usage Table of Contents LocalStorage npx dataenv save Parameters npx dataenv show Parameters npx dataen

PGamerX 2 Feb 5, 2022
Pipeable javascript. Quickly filter, map, and reduce from the terminal

Pipeable JavaScript - another utility like sed/awk/wc... but with JS! Quickly filter, map and reduce from the command line. Features a streaming API.

Daniel St. Jules 410 Dec 10, 2022
Sublime-like terminal-based text editor

slap ?? slap is a Sublime-like terminal-based text editor that strives to make editing from the terminal easier. It has: first-class mouse support (ev

slap 6.1k Jan 1, 2023
A terminal-to-gif recorder minus the headaches.

ttystudio A terminal-to-gif recorder minus the headaches. Record your terminal and compile it to a GIF or APNG without any external dependencies, bash

Christopher Jeffrey (JJ) 3.2k Dec 23, 2022
rtail(1) - Terminal output to the browser in seconds, using UNIX pipes.

rtail(1) Terminal output to the browser in seconds, using UNIX pipes. rtail is a command line utility that grabs every line in stdin and broadcasts it

Kilian Ciuffolo 1.6k Jan 6, 2023
Terminal task list

listr Terminal task list Install $ npm install --save listr Usage const execa = require('execa'); const Listr = require('listr'); const tasks = new

Sam Verschueren 3.1k Jan 3, 2023
Display images in the terminal

terminal-image Display images in the terminal Works in any terminal that supports colors. In iTerm, the image will be displayed in full resolution, si

Sindre Sorhus 905 Dec 25, 2022
:rainbow: Beautiful color gradients in terminal output

gradient-string Beautiful color gradients in terminal output Install $ npm i gradient-string Usage const gradient = require('gradient-string'); cons

Boris K 864 Jan 3, 2023
Reliably get the terminal window size

term-size Reliably get the terminal window size Because process.stdout.columns doesn't exist when run non-interactively, for example, in a child proce

Sindre Sorhus 132 Oct 11, 2022
Truncate a string to a specific width in the terminal

cli-truncate Truncate a string to a specific width in the terminal Gracefully handles ANSI escapes. Like a string styled with chalk. It also supports

Sindre Sorhus 78 Oct 10, 2022
Execute shell commands in terminal

Execute shell commands in terminal

skanehira 9 Dec 11, 2021
Just a minimal library to do some terminal stuff.

Termctl A simple library to do some basic terminal stuff. Usage const termctl = require("termctl"); Note: We have tested this on Linux Mint and Window

Biraj 4 Sep 28, 2021
A terminal for a more modern age

Downloads: Latest release Repositories: Debian/Ubuntu-based, RPM-based Latest nightly build This README is also available in: Korean 简体中文 Tabby (forme

null 41.8k Dec 30, 2022