Skip to content

Commit

Permalink
Cache resolved colors (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
asamuzaK authored Nov 17, 2024
1 parent 7a1e8a0 commit e5db357
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 1 deletion.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
"require": "./dist/cjs/css-color.min.cjs"
},
"types": "types/index.d.ts",
"dependencies": {
"lru-cache": "^11.0.2"
},
"devDependencies": {
"c8": "^10.1.2",
"esbuild": "^0.24.0",
Expand Down
11 changes: 11 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}
*/

import { LRUCache } from 'lru-cache';
import {
convertHexToRgb, convertRgbToHex, convertXyzD50ToLab, convertXyzD50ToLch,
convertXyzToHex, convertXyzToHsl, convertXyzToHwb, convertXyzToOklab,
Expand All @@ -14,6 +15,11 @@ import {
} from './js/color.js';
import { getType, isString } from './js/common.js';

/* cache resolved colors */
const resolvedColors = new LRUCache({
max: 4096
});

/**
* resolve CSS color
* @param {string} color - color value
Expand All @@ -40,6 +46,10 @@ export const resolve = (color, opt = {}) => {
} else {
throw new TypeError(`Expected String but got ${getType(color)}.`);
}
const cacheKey = `{color:${color.toLowerCase()},opt:${JSON.stringify(opt)}}`;
if (resolvedColors.has(cacheKey)) {
return resolvedColors.get(cacheKey);
}
const { currentColor, format, key } = opt;
let r, g, b, a;
if (/^currentcolor$/i.test(color)) {
Expand Down Expand Up @@ -130,6 +140,7 @@ export const resolve = (color, opt = {}) => {
}
}
}
resolvedColors.set(cacheKey, res);
return res;
};

Expand Down
92 changes: 91 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,68 +20,98 @@ describe('resolve CSS color', () => {
it('should get empty string', () => {
const res = func('foo');
assert.strictEqual(res, '', 'result');
const res2 = func('foo');
assert.strictEqual(res2, '', 'result');
});

it('should get value', () => {
const res = func('currentColor', {
currentColor: 'color-mix(in srgb, blue, red)'
});
assert.strictEqual(res, 'rgb(128, 0, 128)', 'result');
const res2 = func('currentColor', {
currentColor: 'color-mix(in srgb, blue, red)'
});
assert.strictEqual(res2, 'rgb(128, 0, 128)', 'result');
});

it('should get value', () => {
const res = func('currentColor', {
currentColor: 'color(srgb 0 0.5 0 / 0.5)'
});
assert.strictEqual(res, 'rgba(0, 128, 0, 0.5)', 'result');
const res2 = func('currentColor', {
currentColor: 'color(srgb 0 0.5 0 / 0.5)'
});
assert.strictEqual(res2, 'rgba(0, 128, 0, 0.5)', 'result');
});

it('should get value', () => {
const res = func('currentColor', {
currentColor: 'green'
});
assert.strictEqual(res, 'rgb(0, 128, 0)', 'result');
const res2 = func('currentColor', {
currentColor: 'green'
});
assert.strictEqual(res2, 'rgb(0, 128, 0)', 'result');
});

it('should get value', () => {
const res = func('currentColor');
assert.strictEqual(res, 'rgba(0, 0, 0, 0)', 'result');
const res2 = func('currentColor');
assert.strictEqual(res2, 'rgba(0, 0, 0, 0)', 'result');
});

it('should get value', () => {
const res = func('transparent');
assert.strictEqual(res, 'rgba(0, 0, 0, 0)', 'result');
const res2 = func('transparent');
assert.strictEqual(res2, 'rgba(0, 0, 0, 0)', 'result');
});

it('should get value', () => {
const res = func('color-mix(in srgb, blue, red)');
assert.strictEqual(res, 'rgb(128, 0, 128)', 'result');
const res2 = func('color-mix(in srgb, blue, red)');
assert.strictEqual(res2, 'rgb(128, 0, 128)', 'result');
});

it('should get value', () => {
const res = func('color(srgb 0 0.5 0)');
assert.strictEqual(res, 'rgb(0, 128, 0)', 'result');
const res2 = func('color(srgb 0 0.5 0)');
assert.strictEqual(res2, 'rgb(0, 128, 0)', 'result');
});

it('should get value', () => {
const res = func('green');
assert.strictEqual(res, 'rgb(0, 128, 0)', 'result');
const res2 = func('green');
assert.strictEqual(res2, 'rgb(0, 128, 0)', 'result');
});

it('should get value', () => {
const res = func(' GREEN ');
assert.strictEqual(res, 'rgb(0, 128, 0)', 'result');
const res2 = func(' GREEN ');
assert.strictEqual(res2, 'rgb(0, 128, 0)', 'result');
});

it('should get value', () => {
const res = func('color-mix(in srgb, blue, red)', {
key: 'foo'
});
assert.deepEqual(res, ['foo', 'rgb(128, 0, 128)'], 'result');
const res2 = func('color-mix(in srgb, blue, red)', {
key: 'foo'
});
assert.deepEqual(res2, ['foo', 'rgb(128, 0, 128)'], 'result');
});

it('should get value', () => {
const res = func('foo)', {
const res = func('foo', {
format: 'array'
});
assert.deepEqual(res, [
Expand All @@ -90,13 +120,26 @@ describe('resolve CSS color', () => {
undefined,
undefined
], 'result');
const res2 = func('foo', {
format: 'array'
});
assert.deepEqual(res2, [
undefined,
undefined,
undefined,
undefined
], 'result');
});

it('should get value', () => {
const res = func('color-mix(in srgb, blue, red)', {
format: 'array'
});
assert.deepEqual(res, [127.5, 0, 127.5, 1], 'result');
const res2 = func('color-mix(in srgb, blue, red)', {
format: 'array'
});
assert.deepEqual(res2, [127.5, 0, 127.5, 1], 'result');
});

it('should get value', () => {
Expand All @@ -105,34 +148,55 @@ describe('resolve CSS color', () => {
key: 'foo'
});
assert.deepEqual(res, ['foo', [127.5, 0, 127.5, 1]], 'result');
const res2 = func('color-mix(in srgb, blue, red)', {
format: 'array',
key: 'foo'
});
assert.deepEqual(res2, ['foo', [127.5, 0, 127.5, 1]], 'result');
});

it('should get null', () => {
const res = func('transparent', {
format: 'hex'
});
assert.deepEqual(res, null, 'result');
const res2 = func('transparent', {
format: 'hex'
});
assert.deepEqual(res2, null, 'result');
});

it('should get null', () => {
const res = func('foo', {
format: 'hex'
});
assert.deepEqual(res, null, 'result');
const res2 = func('foo', {
format: 'hex'
});
assert.deepEqual(res2, null, 'result');
});

it('should get value', () => {
const res = func('rgba(0% 50% 0% / 0.5)', {
format: 'hex'
});
assert.strictEqual(res, '#008000', 'result');
const res2 = func('rgba(0% 50% 0% / 0.5)', {
format: 'hex'
});
assert.strictEqual(res2, '#008000', 'result');
});

it('should get value', () => {
const res = func('currentColor', {
format: 'hex'
});
assert.strictEqual(res, '#000000', 'result');
const res2 = func('currentColor', {
format: 'hex'
});
assert.strictEqual(res2, '#000000', 'result');
});

it('should get value', () => {
Expand All @@ -141,34 +205,55 @@ describe('resolve CSS color', () => {
key: 'foo'
});
assert.deepEqual(res, ['foo', '#008000'], 'result');
const res2 = func('rgba(0% 50% 0%)', {
format: 'hex',
key: 'foo'
});
assert.deepEqual(res2, ['foo', '#008000'], 'result');
});

it('should get value', () => {
const res = func('transparent', {
format: 'hexAlpha'
});
assert.strictEqual(res, '#00000000', 'result');
const res2 = func('transparent', {
format: 'hexAlpha'
});
assert.strictEqual(res2, '#00000000', 'result');
});

it('should get null', () => {
const res = func('foo', {
format: 'hexAlpha'
});
assert.deepEqual(res, null, 'result');
const res2 = func('foo', {
format: 'hexAlpha'
});
assert.deepEqual(res2, null, 'result');
});

it('should get value', () => {
const res = func('rgba(0% 50% 0% / 0.5)', {
format: 'hexAlpha'
});
assert.strictEqual(res, '#00800080', 'result');
const res2 = func('rgba(0% 50% 0% / 0.5)', {
format: 'hexAlpha'
});
assert.strictEqual(res2, '#00800080', 'result');
});

it('should get value', () => {
const res = func('currentColor', {
format: 'hexAlpha'
});
assert.strictEqual(res, '#00000000', 'result');
const res2 = func('currentColor', {
format: 'hexAlpha'
});
assert.strictEqual(res2, '#00000000', 'result');
});

it('should get value', () => {
Expand All @@ -177,6 +262,11 @@ describe('resolve CSS color', () => {
key: 'foo'
});
assert.deepEqual(res, ['foo', '#00800080'], 'result');
const res2 = func('rgba(0% 50% 0% / 0.5)', {
format: 'hexAlpha',
key: 'foo'
});
assert.deepEqual(res2, ['foo', '#00800080'], 'result');
});
});

Expand Down

0 comments on commit e5db357

Please sign in to comment.