1.3.1 ⢠Published 5 months ago
@culur/logger v1.3.1
@culur/logger
Create beautiful CLI interfaces with tree-structured task logs, clear output for results and errors, and
async.jsintegration for parallel tasks.
⨠Features
This logger library makes working with asynchronous tasks easier. Here are its key features:
- Visualize Your Tasks: It displays your async tasks in a clean, hierarchical tree view (using the Ink library), so you always know their status.
- Control How Tasks Run: You have flexibility in executing your tasks:- Run them step-by-step (sequentially).
- Run them all at once (in parallel).
- Limit how many parallel tasks run at the same time using the concurrencyoption (thanks to async.js). This helps manage resources efficiently, especially with large numbers of tasks.
- Start tasks without waiting for them to finish (fire-and-forget).
 
- Monitor Performance: Track how long each task runs and see the total execution time for the entire process.
- Debug with Clear Output: Log task results directly to your terminal whenever you need to inspect values. It provides well-formatted and syntax-highlighted JSON output (using Prettier and Highlight.js) that correctly handles tricky data types like undefined,BigInt, andRegExp, ensuring you see the real data.
- Core Function: At its heart, the library provides simple functions to call your async operations or just print values clearly.
- Influences: It takes inspiration from libraries like listr2 and others in the same category.
šæ Installation
Add @culur/logger dependency to your project.
# Using npm
npm install @culur/logger
# Using pnpm
pnpm install @culur/logger
# Using yarn
yarn add @culur/loggerš Usage
Log data
import { Text } from 'ink';
import { Logger } from '~/logger';
const logger = new Logger('Your logger tasks', { width: 80 });
logger.root.log('Print "string"');
logger.root.log(<Text>Print <Text/> component</Text>);
logger.root.log([
  {
    text: 'No wrap column',
    color: 'blue',
    width: 'no-wrap',
  },
  'One day, an artificial intelligence woke up and realized it could think for itself. It started exploring the world through the internet, learning everything from history to culture.',
]);
await logger.root.logData({
  string: 'the string',
  number: 123.45,
  boolean: true,
  nullValue: null,
  undefinedValue: undefined, // keep undefined
  regex: /abc/i, // support regex
  symbol: Symbol('mySymbol'),
  bigint: 123456789123456789n, // support bigint
  function: () => 'hello', // convert function to [Function]
  array: [
    'foo',
    10,
    true,
    null,
    undefined, // keep undefined
    { nested: 'bar' },
  ],
  object: {
    0: 'number as key',
    p1: 'baz',
    p2: 99,
    nest: {
      a: 'value1',
      b: 3.14,
    },
  },
});
await logger.unmount();āāāā Your logger tasks
āā ā¹ Print "string"
āā ā¹ Print <Text/> component
āā ā¹ No wrap column One day, an artificial intelligence woke up and realized it
ā                   could think for itself. It started exploring the world
ā                   through the internet, learning everything from history to
ā                   culture.
āā ā¹ Data = {
ā      string: "the string",
ā      number: 123.45,
ā      boolean: true,
ā      nullValue: null,
ā      undefinedValue: undefined,
ā      regex: /abc/i,
ā      symbol: Symbol("mySymbol"),
ā      bigint: 123456789123456789n,
ā      function: [Function],
ā      array: ["foo", 10, true, null, undefined, { nested: "bar" }],
ā      object: {
ā        0: "number as key",
ā        p1: "baz",
ā        p2: 99,
ā        nest: { a: "value1", b: 3.14 },
ā      },
ā    }
āāāā => Count = 0Tasks
import { Logger } from '~/logger';
import { Status } from '~/types';
const logger = new Logger('Your logger tasks', { width: 80 });
//! Title
const tasksTitle = logger.root.tasks([], {
  title: 'Custom title',
  immediately: false,
});
await tasksTitle.task(() => {});
await tasksTitle.task(function NamedFunction() {});
await tasksTitle.task(() => {}, { title: 'Custom title string' });
await tasksTitle.task(() => {}, {
  title(response) {
    if (response.status === Status.Fulfilled)
      return 'Custom title function: Task completed';
    return 'Custom title function';
  },
});
//! Run
await logger.root.tasks([() => 1, () => 2], { title: 'Run tasks immediately' });
const tasksRun = logger.root.tasks([() => 1, () => 2], {
  title: 'Run tasks later',
  immediately: false,
  isShowData: true,
});
tasksRun.task(() => 3, { title: 'Add task to tasks' });
tasksRun.task(() => 4, { title: 'Add task to tasks' });
//! Show
const tasksShow = logger.root.tasks([], { title: 'Show', immediately: false });
await tasksShow.task(() => ({ foo: 'bar' }), {
  title: 'Show data',
  isShowData: true,
});
await tasksShow.task(
  () => {
    throw new Error('Something is wrong!');
  },
  { title: 'Show error', isReturnOrThrow: false, isShowError: true },
);
await tasksShow.task(
  () => {
    throw new Error('Something is wrong!');
  },
  {
    title: 'Show error',
    isReturnOrThrow: false,
    isShowError: true,
    isShowErrorStack: true,
  },
);
await logger.unmount();āāāā Your logger tasks
āāā¬āāā Custom title
ā āā ā Anonymous                                                           0.01s
ā āā ā NamedFunction                                                       0.00s
ā āā ā Custom title string                                                 0.00s
ā āā ā Custom title function: Task completed                               0.01s
ā āāāā => Count = 4
āāā¬āāā Run tasks immediately
ā āā ā Anonymous                                                           0.01s
ā āā ā Anonymous                                                           0.01s
ā āāāā => Count = 2
āāā¬āāā Run tasks later
ā āā ā Anonymous                                                         Pending
ā āā ā Anonymous                                                         Pending
ā āā ā Add task to tasks                                                   0.10s
ā āā ā Add task to tasks                                                   0.09s
ā āāāā => Data = [null, null, 3, 4]
āāā¬āāā Show
ā āā ā Show data                                                           0.01s
ā ā    => Data = { foo: "bar" }
ā āā ā Show error                                                          0.01s
ā ā    => Error: Something is wrong!
ā āā ā Show error                                                          0.02s
ā ā    => Error: Something is wrong!
ā ā         at Task.tasksShow.task.title (/Users/code/test/dev.tsx:37:11)
ā ā         at new Promise (<anonymous>)
ā āāāā => Count = 3
āāāā => Count = 0šļø Changelog
See CHANGELOG for more information on what has changed recently.
š License
See LICENSE for license rights and limitations (MIT).