diff --git a/CHANGELOG.md b/CHANGELOG.md index 4167138..8f98fdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.8.1 (2025-01-10) + +- refactor: optimize package size + ## 3.8.0 (2025-01-09) - feat: enforce a specific color support by a `FORCE_COLOR` value: diff --git a/README.md b/README.md index 7b79aec..c586f00 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,11 @@ Ansis is as [small](#compare-size) as **Picocolors** but has the [functionality] ## ๐Ÿ› ๏ธ Usage ```js -import ansis, { red, green, cyan, black, ansi256, hex } from 'ansis'; +import ansis, { red, cyan, ansi256, hex } from 'ansis'; ansis.blueBright('file.txt') -green`Succeful!` red`Error: ${cyan(file)} not found!` -black.bgYellow`Warning!` +red.bgWhite`ERROR` ansi256(214)`Orange` hex('#E0115F').bold.underline('Truecolor!') ``` @@ -112,7 +111,7 @@ Both are [recommended](https://github.com/es-tooling/module-replacements/blob/ma The package size in `node_modules` directory: - `picocolors`: [6.4 kB][npm-picocolors] - A micro library with only basic features. -- `ะฐnsis`: [7.0 kB][npm-ansis] - A powerful library containing all the features you need. +- `ะฐnsis`: [6.7 kB][npm-ansis] - A powerful library containing all the features you need. - `chalk`: [44.2 kB][npm-chalk] - Provides similar functionality to Ansis. ### โšก Performance @@ -946,7 +945,7 @@ npm run compare | Npm package | Download tarball size | Unpacked Size | Code size | |:-----------------------------|-----------------------------------------------------------------------:|-------------------------------:|----------:| | [`picocolors`][picocolors] | [2.6 kB](https://arve0.github.io/npm-download-size/#picocolors) | [6.4 kB][npm-picocolors] | 2.6 kB -| [`ansis`][ansis] | [3.8 kB](https://arve0.github.io/npm-download-size/#ansis) | [7.0 kB][npm-ansis] | 3.4 kB +| [`ansis`][ansis] | [3.8 kB](https://arve0.github.io/npm-download-size/#ansis) | [6.7 kB][npm-ansis] | 3.4 kB | [`colorette`][colorette] | [4.9 kB](https://arve0.github.io/npm-download-size/#colorette) | [17.0 kB][npm-colorette] | 3.4 kB | [`kleur`][kleur] | [6.0 kB](https://arve0.github.io/npm-download-size/#kleur) | [20.3 kB][npm-kleur] | 2.7 kB | [`ansi-colors`][ansi-colors] | [8.5 kB](https://arve0.github.io/npm-download-size/#ansi-colors) | [26.1 kB][npm-ansi-colors] | 5.8 kB diff --git a/README.npm-src.md b/README.npm-src.md index f4b318e..c58f8b8 100644 --- a/README.npm-src.md +++ b/README.npm-src.md @@ -1,36 +1,26 @@ +# Ansis + +Enable ANSI colors in terminal output. [Docs on GitHub](https://github.com/webdiscus/ansis). + +# +

-
- ANSI Styling +

---- -[![codecov](https://codecov.io/gh/webdiscus/ansis/branch/master/graph/badge.svg?token=H7SFJONX1X)](https://codecov.io/gh/webdiscus/ansis) -[![node](https://img.shields.io/npm/dm/ansis)](https://www.npmjs.com/package/ansis) -[![size](https://img.shields.io/bundlephobia/minzip/ansis)](https://bundlephobia.com/package/ansis) - -Colorize terminal with ANSI colors & styles, smaller and faster alternative to Chalk. - -๐Ÿš€ [Install and Quick Start](https://github.com/webdiscus/ansis#install) - -โœ… [Compare features](https://github.com/webdiscus/ansis#compare) with similar packages - -๐Ÿ“Š [Benchmarks](https://github.com/webdiscus/ansis#benchmark) - -๐Ÿ“– [Read full docs on GitHub](https://github.com/webdiscus/ansis) ## Usage ```js -import ansis, { red, green, black, ansi256, hex } from 'ansis'; +import ansis, { red, cyan, ansi256, hex } from 'ansis'; -ansis.cyan('file') -green('Ok') -red`Error` -black.bgYellow`Warning` +ansis.blueBright('file.txt') +red`Error: ${cyan(file)} not found!` +red.bgWhite`ERROR` ansi256(214)`Orange` -hex('#E0115F').bold('TrueColor') +hex('#E0115F').bold.underline('Truecolor!') ``` ## Highlights diff --git a/README.npm.md b/README.npm.md index ccb423b..dfe4ff6 100644 --- a/README.npm.md +++ b/README.npm.md @@ -1,7 +1,7 @@ -

+# Ansis -Colorize terminal with ANSI colors & styles. +Enable ANSI colors in terminal output. [Docs on GitHub](https://github.com/webdiscus/ansis). -## ๐Ÿ“– [Docs on GitHub](https://github.com/webdiscus/ansis) +# -![](docs/img/npm.png) +![](docs/npm.png) diff --git a/bench/index.js b/bench/index.js index 8b87f3c..84e94d2 100644 --- a/bench/index.js +++ b/bench/index.js @@ -70,6 +70,8 @@ const bench = new Bench({ log(hex('#F88').inverse.bold` -= Benchmark =- `); +bench('Simple, ansis').add(packages['ansis'], () => ansis.red('foo')).run(); + // Simple bench bench('Simple, using 1 style'). add(packages['chalk'], () => chalk.red('foo')). diff --git a/docs/img/npm.png b/docs/img/npm.png deleted file mode 100644 index 6a1e387..0000000 Binary files a/docs/img/npm.png and /dev/null differ diff --git a/docs/npm.png b/docs/npm.png new file mode 100644 index 0000000..8e08454 Binary files /dev/null and b/docs/npm.png differ diff --git a/package.json b/package.json index 3a609ec..49850a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ansis", - "version": "3.8.0", + "version": "3.8.1", "description": "A small and fast Node.js library for applying ANSI colors and styles in terminal output", "keywords": [ "ansi", @@ -8,28 +8,15 @@ "color", "colors", "styles", + "console", "terminal", "xterm", - "console", "cli", "log", - "logging", - "truecolor", "rgb", - "red", - "green", - "yellow", - "blue", - "magenta", - "cyan", + "truecolor", "FORCE_COLOR", - "NO_COLOR", - "ansi-colors", - "chalk", - "colorette", - "colors.js", - "kleur", - "picocolors" + "NO_COLOR" ], "license": "ISC", "author": "webdiscus (https://github.com/webdiscus)", diff --git a/package.npm.json b/package.npm.json index 746f591..9072ac1 100644 --- a/package.npm.json +++ b/package.npm.json @@ -1,31 +1,21 @@ { - "name": "ansis", - "version": "3.8.0", - "description": "ANSI colors and styles in terminal output", - "keywords": [ - "ansi", - "color", - "console", - "terminal", - "cli" - ], - "license": "ISC", - "author": "webdiscus", - "repository": "webdiscus/ansis", - "main": "./index.js", - "types": "./index.d.ts", - "exports": { - ".": { - "types": "./index.d.ts", - "require": "./index.js", - "import": "./index.mjs" - } - }, - "sideEffects": false, - "engines": { - "node": ">=16" - }, - "files": [ - "index.*" - ] +"name":"ansis", +"version":"3.8.1", +"description":"ANSI colors in terminal output", +"keywords":["ansi","color","style","terminal","cli"], +"license":"ISC", +"author":"webdiscus", +"repository":"webdiscus/ansis", +"main":"./index.js", +"types":"./index.d.ts", +"exports":{ + ".":{ + "types":"./index.d.ts", + "require":"./index.js", + "import":"./index.mjs" + } +}, +"sideEffects":false, +"engines":{"node":">=16"}, +"files":["index.*"] } diff --git a/src/index.js b/src/index.js index aa5ba25..f78714e 100644 --- a/src/index.js +++ b/src/index.js @@ -26,45 +26,43 @@ let stylePrototype; let createStyle = ({ _p: props }, { open, close }) => { /** * Decorate the string with ANSI codes. - * @param {string} strings The normal or template string. + * @param {string} input The input value, can be any or a template string. * @param {array} values The values of the template string. * @return {string} */ - let styleFn = (strings, ...values) => { + let styleFn = (input, ...values) => { // if the argument is an empty string, an empty string w/o escape codes should be returned - if (strings === '') return strings; + if (input === '') return input; let props = styleFn._p; let { _a: openStack, _b: closeStack } = props; // resolve the input string - let str = strings?.raw + let output = input?.raw // render template string - ? String.raw(strings, ...values) + ? String.raw(input, ...values) // convert to string - : '' + strings; + : '' + input; // -> detect nested styles - // on node.js, the performance of `includes()` and `~indexOf()` is the same, no difference - if (str.includes('')) { + if (~output.indexOf('')) { while (props) { // this implementation is over 30% faster than native String.replaceAll() - //str = str.replaceAll(props.close, props.open); - // -- begin replaceAll, inline the function here to optimize the bundle size + //output = output.replaceAll(props.close, props.open); + // -- begin replaceAll, inline the function here to reduce the bundle size let search = props.close; let replacement = props.open; let searchLength = search.length; let result = ''; - let lastPos; + let lastPos = 0; let pos; - // the `visible` style has empty open/close props + // the `visible` style has empty open/close properties if (searchLength) { - for (lastPos = 0; ~(pos = str.indexOf(search, lastPos)); lastPos = pos + searchLength) { - result += str.slice(lastPos, pos) + replacement; + for (; ~(pos = output.indexOf(search, lastPos)); lastPos = pos + searchLength) { + result += output.slice(lastPos, pos) + replacement; } - - if (lastPos) str = result + str.slice(lastPos); + output = result + output.slice(lastPos); } // -- end replaceAll @@ -73,13 +71,11 @@ let createStyle = ({ _p: props }, { open, close }) => { } // -> detect new line - //if (str.includes('\n')) { - // size optimisation: using ~indexOf instead of includes, the compiled bundle is smaller by 1 byte - if (~str.indexOf('\n')) { - str = str.replace(/(\r?\n)/g, closeStack + '$1' + openStack); + if (~output.indexOf('\n')) { + output = output.replace(/(\r?\n)/g, closeStack + '$1' + openStack); } - return openStack + str + closeStack; + return openStack + output + closeStack; }; let openStack = open; diff --git a/test/functional.test.js b/test/functional.test.js index 9319e58..38c5ae8 100644 --- a/test/functional.test.js +++ b/test/functional.test.js @@ -209,8 +209,8 @@ describe('style tests', () => { }); test(`visible with template literal`, () => { - const received = ansis.visible`foo ${green`bar`}`; - const expected = 'foo \x1b[32mbar\x1b[39m'; + const received = ansis.visible`foo ${green`bar ${red`baz`} bar`} foo`; + const expected = 'foo \x1b[32mbar \x1b[31mbaz\x1b[32m bar\x1b[39m foo'; expect(esc(received)).toEqual(esc(expected)); });