npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

kax

v3.1.1

Published

A simple logger with spinners

Downloads

67

Readme

kax

ci

A simple logger that supports asynchronous task nesting without the need for complex constructs.

Based on log-update.

Sample

The following sample code shows some constructs offered by Kax.

const subtask = async () => {
  await kax.task('Subtask One Running').run(delay(2000));
  await kax.warn('This is a\nmultiline warning');
  await kax
    .task('Subtask Two Running', { successMsg: 'Success!' })
    .run(delay(2000));
};

kax.info('This is an info line');
kax.warn('This is a warn line');
kax.error('This is an error line');

await kax.task('Running a top level task').run(delay(2000));
await kax.task('Running Subtasks').run(subtask());
const task = kax.task('Running a task manually');
await delay(2000);
task.text = 'Text can be changed dynamically';
await delay(2000);
task.succeed('Done!');

It will render as follows

kax example

Renderers

kax comes with two different renderers

  • KaxSimpleRenderer - Does not use spinners, colors, or subtask indentation.
  • KaxAdvancedRenderer - Uses spinners, colors, and subtask indentation.

Initialization

import kax from 'kax';

This default singleton instance comes with a default renderer and configuration attached to it.

If the CI environment variable is set, or TERM=dumb, the default renderer is KaxSimpleRenderer, otherwise it is KaxAdvancedRenderer.

If you need to customize the renderer with your own configuration, or need to switch to a KaxSimpleRenderer instead, you can instantiate a renderer with a custom configuration and attach it to the kax instance.

Here is the default configuration:

{
  "colorScheme": {
    "warning": "yellow",
    "error": "red",
    "info": "cyan",
    "task": "white"
  },
  "symbolScheme": {
    "info": "info",
    "warning": "warning",
    "error": "error",
    "taskRunning": "dots",
    "taskSuccess": "success",
    "taskFailure": "error"
  },
  "symbolizeMultiLine": true,
  "shouldLogTime": false
}
  • The colors in colorScheme can be any of the colors from chalk.
  • The symbols in symbolScheme can be any of the symbols from log-symbols except for the taskRunning symbol, which is a spinner and can be any of the spinners from cli-spinners.
  • symbolizeMultiLine indicates whether to prepend a symbol to each line of a multiline message, or only to the first line.
  • shouldLogTime indicated whether to suffix the tasks lines with a timer to show how long the task has been running for.

If you need to replace the default renderer configuration with your own, import the renderer class you need, and instantiate it with the config, as follows:

import { KaxAdvancedRender } from 'kax';

const myRenderer = new KaxAdvancedRenderer(myConfig);

Then you can simply attach this new renderer to the kax instance

kax.renderer = myRenderer;

Alternatively you can directly construct an instance of kax providing your renderer, if you don't want to use the default singleton instance

import { Kax } from 'kax';

const kax = new Kax(myRenderer);

Api

kax.info(msg /* string */);

Renders a message using the info level.
The color used for the message will be the one set in the colorScheme config (defaults to cyan).
The symbol prepended to the message will be the one set in the symbolScheme config (defaults to info).

kax.warn(msg /* string */);

Renders a message using the warn level.
The color used for the message will be the one set in the colorScheme config (defaults to yellow).
The symbol prepended to the message will be the one set in the symbolScheme config (defaults to warning).

kax.error(msg /* string */);

Renders a message using the error level.
The color used for the message will be the one set in the colorScheme config (defaults to red).
The symbol prepended to the message will be the one set in the symbolScheme config (defaults to error).

kax.task(msg /* string */);

Renders a message using the task level.
The color used for the message will be the one set in the colorScheme config (defaults to white).
The symbol prepended to the message will be a spinner (defaults to dots).

kax.raw(msg /* string */);

Renders a message using the raw level.
No color will be used and no symbol will be prepended to the message.

The spinner attached to the message will start spinning upon invocation of this function, and will continue spinning until task completion.

There are two different ways to run/complete a task. Implicitly, or explicitly.

Implicit task run/completion (handled by kax)

This can be achieved by calling run on the KaxTask instance returned by kax.task.

kax.task(msg /* string */).run(task /* Promise<T> */, {
  successMsg /* string [optional] */,
  errorMsg /* string [optional] */,
});

The task provided to the run function, is a function that returns a Promise.
kax will await for this Promise completion, and upon completion will update the message spinner with either the taskSuccess symbol from config (defaults to success) or the taskFailure symbol from config (defaults to error). In the case of successful completion, kax will return the result of the Promise task, and in the case of failure, it will rethrow the task exception.

successMsg and errorMsg are both optional. If not set, the original msg will be used instead.

Explicit task run/completion (handled manually)

Instead of using the run function, it is also possible to control the task completion manually. In this case, kax is not wrapping/monitoring the task so it has no way of knowing when it completes, and what is the completion status.

You can manually call the following two functions on the KaxTask object to either complete the task successfully or with a failure

kaxTask.succeed(successMsg /* string [optional] */);

Manually completes the task with success. It will update the spinner with the taskSuccess symbol from config (defaults to success) and the mesage with successMsg (if provided, otherwise it will leave original message untouched).

kaxTask.fail(errorMsg /* string [optional] */);

Manually completes the task with failure. It will update the spinner with the taskFailure symbol from config (defaults to error) and the mesage with errorMsg (if provided, otherwise it will leave original message untouched).

Automatic task indentation

When using the default KaxAdvancedRenderer, if a task is started while a previous one is still running, the renderer new task message (and any other messages) will be automatically indented until the parent task completes.