chromonym 3.2.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
[](https://www.npmjs.com/package/chromonym)
|
|
15
15
|
[](https://github.com/simiancraft/chromonym/actions/workflows/ci.yml)
|
|
16
16
|
[](https://codecov.io/github/simiancraft/chromonym)
|
|
17
|
-
[](#what-you-actually-ship)
|
|
18
|
+
[](https://securityscorecards.dev/viewer/?uri=github.com/simiancraft/chromonym)
|
|
18
19
|
|
|
19
20
|
<p align="center">
|
|
20
21
|
<code>identify</code> • <code>resolve</code> • <code>convert</code>
|
|
@@ -451,17 +452,19 @@ const tryConvert = (input: ColorInput, opts = {}) => {
|
|
|
451
452
|
|
|
452
453
|
### What you actually ship
|
|
453
454
|
|
|
454
|
-
|
|
455
|
+
**Install size and bundle size are not the same number.** Install size is what lands in your `node_modules/` after `npm install`; bundle size is what ships to your users after tree-shaking, minification, and gzip. For chromonym the gap is roughly two orders of magnitude.
|
|
456
|
+
|
|
457
|
+
The published tarball is **~2.5 MB unpacked / ~557 kB gzipped** because it carries twelve palettes and ~9000 named-color entries; that's the install-size figure `packagephobia` reports. Your **production bundle** pays only for what you actually import, measured with `esbuild --minify`:
|
|
455
458
|
|
|
456
459
|
| Import | min | gzip |
|
|
457
460
|
|---|---|---|
|
|
458
|
-
| `import { identify, web } from 'chromonym'` | 10.9 kB | **4.7 kB** |
|
|
459
|
-
| `import { identify, pantone } from 'chromonym'` | 27 kB | **11.3 kB** |
|
|
460
|
-
| `import { identify, ntc } from 'chromonym'` (one of the bigger palettes) | 43 kB | **20 kB** |
|
|
461
461
|
| `import { defineColorPalette } from 'chromonym'` (pure BYO; no built-in) | 3.8 kB | **1.5 kB** |
|
|
462
|
+
| `import { identify, web } from 'chromonym'` | 10.9 kB | **4.7 kB** |
|
|
462
463
|
| `import { pantoneToRgba } from 'chromonym'` (single conversion) | 17.5 kB | **6.8 kB** |
|
|
464
|
+
| `import { identify, pantone } from 'chromonym'` | 27 kB | **11.3 kB** |
|
|
465
|
+
| `import { identify, ntc } from 'chromonym'` | 43 kB | **20 kB** |
|
|
463
466
|
|
|
464
|
-
|
|
467
|
+
If you're evaluating chromonym against a size budget, the gzip column above is what actually lands in your production build.
|
|
465
468
|
|
|
466
469
|
## Types
|
|
467
470
|
|
|
@@ -3,7 +3,13 @@ import type { Rgba, RgbaInput, RgbInput, RgbString } from '../types.js';
|
|
|
3
3
|
* Normalize any RGB/RGBA input shape (string, tuple, or object) into
|
|
4
4
|
* the canonical Rgba representation. Alpha defaults to 1 when absent.
|
|
5
5
|
* Rejects non-finite numeric inputs; clamps r/g/b to [0,255] and a to [0,1].
|
|
6
|
-
* Throws on malformed strings.
|
|
6
|
+
* Throws on malformed strings. String parsing is linear-time; no polynomial
|
|
7
|
+
* backtracking on pathological input. Leading-dot alpha (e.g. `.5`) is
|
|
8
|
+
* accepted per the CSS Color spec.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* rgbToRgba('rgba(255, 0, 0, .5)');
|
|
12
|
+
* // => { r: 255, g: 0, b: 0, a: 0.5 }
|
|
7
13
|
*/
|
|
8
14
|
export declare function rgbToRgba(input: RgbInput | RgbaInput): Rgba;
|
|
9
15
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rgb.d.ts","sourceRoot":"","sources":["../../src/conversions/rgb.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAa,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"rgb.d.ts","sourceRoot":"","sources":["../../src/conversions/rgb.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAa,SAAS,EAAE,MAAM,aAAa,CAAC;AAgBnF;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,CA+B3D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAK/C","sourcesContent":["import { clamp, requireFinite } from '../math/clamp.js';\nimport type { Rgba, RgbaInput, RgbInput, RgbObject, RgbString } from '../types.js';\n\n// Alpha group split into two unambiguous alternatives to avoid polynomial\n// backtracking (CodeQL js/polynomial-redos) on malformed inputs like\n// `rgb(9,9,9,99...9`.\nconst RGB_RE =\n /^rgba?\\s*\\(\\s*(-?\\d+(?:\\.\\d+)?)\\s*,\\s*(-?\\d+(?:\\.\\d+)?)\\s*,\\s*(-?\\d+(?:\\.\\d+)?)\\s*(?:,\\s*(\\d+(?:\\.\\d+)?|\\.\\d+)\\s*)?\\)$/i;\n\nfunction sanitizeChannel(n: unknown, label: string): number {\n return clamp(requireFinite(n, label), 0, 255);\n}\n\nfunction sanitizeAlpha(n: unknown): number {\n return clamp(requireFinite(n, 'alpha'), 0, 1);\n}\n\n/**\n * Normalize any RGB/RGBA input shape (string, tuple, or object) into\n * the canonical Rgba representation. Alpha defaults to 1 when absent.\n * Rejects non-finite numeric inputs; clamps r/g/b to [0,255] and a to [0,1].\n * Throws on malformed strings. String parsing is linear-time; no polynomial\n * backtracking on pathological input. Leading-dot alpha (e.g. `.5`) is\n * accepted per the CSS Color spec.\n *\n * @example\n * rgbToRgba('rgba(255, 0, 0, .5)');\n * // => { r: 255, g: 0, b: 0, a: 0.5 }\n */\nexport function rgbToRgba(input: RgbInput | RgbaInput): Rgba {\n if (Array.isArray(input)) {\n const rawA = input.length === 4 ? input[3] : 1;\n return {\n r: sanitizeChannel(input[0], 'r'),\n g: sanitizeChannel(input[1], 'g'),\n b: sanitizeChannel(input[2], 'b'),\n a: sanitizeAlpha(rawA),\n };\n }\n\n if (typeof input === 'string') {\n const match = RGB_RE.exec(input);\n if (!match) throw new Error(`Invalid rgb(a) string: ${input}`);\n return {\n r: sanitizeChannel(Number(match[1]), 'r'),\n g: sanitizeChannel(Number(match[2]), 'g'),\n b: sanitizeChannel(Number(match[3]), 'b'),\n a: sanitizeAlpha(match[4] !== undefined ? Number(match[4]) : 1),\n };\n }\n\n // Object form — TypeScript's Array.isArray narrowing doesn't exclude\n // readonly tuple types from the union, so cast after the guards.\n const obj = input as RgbObject | Rgba;\n return {\n r: sanitizeChannel(obj.r, 'r'),\n g: sanitizeChannel(obj.g, 'g'),\n b: sanitizeChannel(obj.b, 'b'),\n a: sanitizeAlpha('a' in obj ? obj.a : 1),\n };\n}\n\n/**\n * Emit an `rgb(r, g, b)` string. Alpha is dropped; values are\n * already-clamped by rgbToRgba, but we re-clamp defensively for direct\n * Rgba-object callers who bypass the input normalizer.\n */\nexport function rgbaToRgb(rgba: Rgba): RgbString {\n const r = clamp(Math.round(rgba.r), 0, 255);\n const g = clamp(Math.round(rgba.g), 0, 255);\n const b = clamp(Math.round(rgba.b), 0, 255);\n return `rgb(${r}, ${g}, ${b})` as RgbString;\n}\n"]}
|
package/dist/conversions/rgb.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { clamp, requireFinite } from '../math/clamp.js';
|
|
2
|
-
|
|
2
|
+
// Alpha group split into two unambiguous alternatives to avoid polynomial
|
|
3
|
+
// backtracking (CodeQL js/polynomial-redos) on malformed inputs like
|
|
4
|
+
// `rgb(9,9,9,99...9`.
|
|
5
|
+
const RGB_RE = /^rgba?\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*(?:,\s*(\d+(?:\.\d+)?|\.\d+)\s*)?\)$/i;
|
|
3
6
|
function sanitizeChannel(n, label) {
|
|
4
7
|
return clamp(requireFinite(n, label), 0, 255);
|
|
5
8
|
}
|
|
@@ -10,7 +13,13 @@ function sanitizeAlpha(n) {
|
|
|
10
13
|
* Normalize any RGB/RGBA input shape (string, tuple, or object) into
|
|
11
14
|
* the canonical Rgba representation. Alpha defaults to 1 when absent.
|
|
12
15
|
* Rejects non-finite numeric inputs; clamps r/g/b to [0,255] and a to [0,1].
|
|
13
|
-
* Throws on malformed strings.
|
|
16
|
+
* Throws on malformed strings. String parsing is linear-time; no polynomial
|
|
17
|
+
* backtracking on pathological input. Leading-dot alpha (e.g. `.5`) is
|
|
18
|
+
* accepted per the CSS Color spec.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* rgbToRgba('rgba(255, 0, 0, .5)');
|
|
22
|
+
* // => { r: 255, g: 0, b: 0, a: 0.5 }
|
|
14
23
|
*/
|
|
15
24
|
export function rgbToRgba(input) {
|
|
16
25
|
if (Array.isArray(input)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rgb.js","sourceRoot":"","sources":["../../src/conversions/rgb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGxD,MAAM,MAAM,GACV
|
|
1
|
+
{"version":3,"file":"rgb.js","sourceRoot":"","sources":["../../src/conversions/rgb.ts"],"names":[],"mappings":"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","sourcesContent":["import { clamp, requireFinite } from '../math/clamp.js';\nimport type { Rgba, RgbaInput, RgbInput, RgbObject, RgbString } from '../types.js';\n\n// Alpha group split into two unambiguous alternatives to avoid polynomial\n// backtracking (CodeQL js/polynomial-redos) on malformed inputs like\n// `rgb(9,9,9,99...9`.\nconst RGB_RE =\n /^rgba?\\s*\\(\\s*(-?\\d+(?:\\.\\d+)?)\\s*,\\s*(-?\\d+(?:\\.\\d+)?)\\s*,\\s*(-?\\d+(?:\\.\\d+)?)\\s*(?:,\\s*(\\d+(?:\\.\\d+)?|\\.\\d+)\\s*)?\\)$/i;\n\nfunction sanitizeChannel(n: unknown, label: string): number {\n return clamp(requireFinite(n, label), 0, 255);\n}\n\nfunction sanitizeAlpha(n: unknown): number {\n return clamp(requireFinite(n, 'alpha'), 0, 1);\n}\n\n/**\n * Normalize any RGB/RGBA input shape (string, tuple, or object) into\n * the canonical Rgba representation. Alpha defaults to 1 when absent.\n * Rejects non-finite numeric inputs; clamps r/g/b to [0,255] and a to [0,1].\n * Throws on malformed strings. String parsing is linear-time; no polynomial\n * backtracking on pathological input. Leading-dot alpha (e.g. `.5`) is\n * accepted per the CSS Color spec.\n *\n * @example\n * rgbToRgba('rgba(255, 0, 0, .5)');\n * // => { r: 255, g: 0, b: 0, a: 0.5 }\n */\nexport function rgbToRgba(input: RgbInput | RgbaInput): Rgba {\n if (Array.isArray(input)) {\n const rawA = input.length === 4 ? input[3] : 1;\n return {\n r: sanitizeChannel(input[0], 'r'),\n g: sanitizeChannel(input[1], 'g'),\n b: sanitizeChannel(input[2], 'b'),\n a: sanitizeAlpha(rawA),\n };\n }\n\n if (typeof input === 'string') {\n const match = RGB_RE.exec(input);\n if (!match) throw new Error(`Invalid rgb(a) string: ${input}`);\n return {\n r: sanitizeChannel(Number(match[1]), 'r'),\n g: sanitizeChannel(Number(match[2]), 'g'),\n b: sanitizeChannel(Number(match[3]), 'b'),\n a: sanitizeAlpha(match[4] !== undefined ? Number(match[4]) : 1),\n };\n }\n\n // Object form — TypeScript's Array.isArray narrowing doesn't exclude\n // readonly tuple types from the union, so cast after the guards.\n const obj = input as RgbObject | Rgba;\n return {\n r: sanitizeChannel(obj.r, 'r'),\n g: sanitizeChannel(obj.g, 'g'),\n b: sanitizeChannel(obj.b, 'b'),\n a: sanitizeAlpha('a' in obj ? obj.a : 1),\n };\n}\n\n/**\n * Emit an `rgb(r, g, b)` string. Alpha is dropped; values are\n * already-clamped by rgbToRgba, but we re-clamp defensively for direct\n * Rgba-object callers who bypass the input normalizer.\n */\nexport function rgbaToRgb(rgba: Rgba): RgbString {\n const r = clamp(Math.round(rgba.r), 0, 255);\n const g = clamp(Math.round(rgba.g), 0, 255);\n const b = clamp(Math.round(rgba.b), 0, 255);\n return `rgb(${r}, ${g}, ${b})` as RgbString;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chromonym",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "One color-naming API for any palette. Identify, resolve, and convert colors across your own palette or
|
|
3
|
+
"version": "3.3.1",
|
|
4
|
+
"description": "One color-naming API for any palette. Identify, resolve, and convert colors across your own palette or twelve built-in sets (CSS, X11, Pantone, Crayola, NTC, XKCD, Resene, NCS, ISCC-NBS, NBS, FS 595 B/C); fully typed, tree-shakeable, perceptual distance metrics (CIEDE2000 / OKLAB).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"color",
|
|
7
7
|
"color-name",
|