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

stoyle

v1.0.0

Published

Stoyle for NodeJS

Downloads

5

Readme

Stoyle

ANSI styling for Deno/NodeJS

Usage

import {
  Style,
  BackgroundSimpleCode, ForegroundSimpleCode, DecorationCode,
  stoyle, stoyleGlobal,
} from '../mod.ts';

const boldCyanOnRed: Style = {
  color: ForegroundSimpleCode.FG_Cyan,
  backgroundColor: BackgroundSimpleCode.BG_Red,
  decoration: DecorationCode.Bold,
};

const bold: Style = { decoration: DecorationCode.Bold };
const italic: Style = { decoration: DecorationCode.Italic };

// Styling parameters of a string
const parameter = 'this';
console.log(stoyle`I'm styling ${parameter}, but not ${parameter} or ${parameter}.`(
  {
    nodes: [ // The nodes are the template string's dynamic parts
      boldCyanOnRed,
      undefined, /* Undefined style => no style */
      {}, /* Empty styles work the same as no style */
    ],
  },
));

// Styling a whole string
const otherParameter = 'EVERYTHING';
console.log(
  stoyleGlobal`I'm styling ${otherParameter}`(boldCyanOnRed), // The style is for the whole string with stoyleGlobal
);

// Full example
console.log(stoyle`I'm styling ${parameter}, but not ${parameter} or ${parameter}.`(
  {
    global: italic, // The global style is for the whole string, it's overwritten by edges/nodes styles
    edges: [ // The edges are the template string's static parts
      undefined, bold, undefined, undefined,
    ],
    nodes: [ // The nodes are the template string's dynamic parts
      boldCyanOnRed,
      undefined, // Undefined style means no style, which means global style is applied
      {}, // Empty styles reset all styles, the global style is not applied
    ],
  },
));

Why

I was tired of reading the common pattern that has the following drawbacks:

  • mixes style and content
  • usually does not support batch mode (no-color/style)
  • dilutes the CLI tool's color scheme everywhere in the code
import { red, bold, blue } from 'anyLib';

console.log(`${red(commit.sha)} ${bold(blue(`<${commit.owner}>`))}`);

Compare to the following:

import { stoyle } from 'stoyle'; // dummy location, of course
import { theme } from './theme.ts';

const { commit: { shaStyle, authorStyle } } = theme;
const styleMode = computeStyleModeFromCliArgOrWhatever(); // Allows no-color mode

console.log(
  stoyle`${commit.sha} ${`<${commit.author}>`}`(
    { nodes: [ shaStyle, authorStyle ] },
    styleMode,
  )
);

More verbose, but much cleaner too!

For what usage

I wrote this lib to help me write CLI tools with a theme that would be:

  • centralized
  • consistent
  • swap-able
  • de-activated easily (batch/CI mode)

Modules

  • mod.ts apply styles on a template literal
  • validateTheme.ts validate a theme against a reference theme. This allows you to create a default theme for your CLI tool and let anyone change it by loading another theme instead, with guarantees that there won't be missing styles

The only module that is required is mod.ts.

Philosophy

The goal is to follow the philosophy below:

  • IDE-integrated: uses real template literals!

  • simple: straight-forward API, I don't handle the parsing!

  • maintainable: the whole algorithm is under a 100 lines long, and annotated

  • efficient: the algorithm uses the smallest possible amount of ANSI codes

  • fail fast and hard: the lib throws ASAP if it finds an error

  • small:

    Although deno bundle currently inflates the bundle quite much

    | Module | Raw size | Gzipped size | Bundled size | | ---------------- | --------------------------------------------- | -------------------------------------------------- | ------------------------------------------------- | | mod.ts | 8.5 Kb | 2.4 Kb | 11.8 Kb | | validateTheme.ts | 2.8 Kb | 820.0 b | 8.2 Kb |

My regrets:

  • the template string mechanism can't statically check for errors, but I find that the price to pay is pretty small compared to the gains
  • the validation of the theme is a bit clumsy at the moment, I'd like to try using runtypes to check that the template conforms to the provided interface but no library of this type has been ported to Deno to my knowledge (although for runtypes it seems to be happening)