Skip to content

Commit

Permalink
chore: add debug helper
Browse files Browse the repository at this point in the history
  • Loading branch information
wellwelwel committed Sep 20, 2024
1 parent 1d8d76e commit 5f8731c
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 23 deletions.
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![GitHub Workflow Status (Bun)](https://img.shields.io/github/actions/workflow/status/wellwelwel/lru.min/ci_bun.yml?event=push&label=&branch=main&logo=bun&logoColor=ffffff&color=f368e0)](https://github.com/wellwelwel/lru.min/actions/workflows/ci_bun.yml?query=branch%3Amain)
[![GitHub Workflow Status (Deno)](https://img.shields.io/github/actions/workflow/status/wellwelwel/lru.min/ci_deno.yml?event=push&label=&branch=main&logo=deno&logoColor=ffffff&color=079992)](https://github.com/wellwelwel/lru.min/actions/workflows/ci_deno.yml?query=branch%3Amain)

🔥 An extremely fast and efficient <strong><a href="https://en.m.wikipedia.org/wiki/Cache_replacement_policies#Least_Recently_Used_.28LRU.29">LRU</a> Cache</strong> for <strong>JavaScript</strong> (<strong>Browser</strong> compatible) — **6.8KB**.
🔥 An extremely fast and efficient <strong><a href="https://en.m.wikipedia.org/wiki/Cache_replacement_policies#Least_Recently_Used_.28LRU.29">LRU</a> Cache</strong> for <strong>JavaScript</strong> (<strong>Browser</strong> compatible) — **8.8KB**.

</div>

Expand Down Expand Up @@ -45,13 +45,15 @@ deno add npm:lru.min
import { createLRU } from 'lru.min';

const max = 2;
const maxAge = 300000; // 5m
const onEviction = (key, value) => {
console.log(`Key "${key}" with value "${value}" has been evicted.`);
};

const LRU = createLRU({
max,
onEviction,
maxAge,
});

LRU.set('A', 'My Value');
Expand All @@ -72,7 +74,9 @@ LRU.clear(); // LRU.evict(max)

// => Key "C" with value "Another Value" has been evicted.

LRU.set('D', "You're amazing 💛");
LRU.set('D', "You're amazing 💛", {
maxAge: Number.POSITIVE_INFINITY,
});

LRU.size; // 1
LRU.max; // 2
Expand All @@ -83,6 +87,30 @@ LRU.resize(10);
LRU.size; // 1
LRU.max; // 10
LRU.available; // 9

LRU.set('E', 'Yet Another Value');

[...LRU.debug()];
/**
* [
* {
* key: 'E',
* value: 'Yet Another Value',
* maxAge: 300000,
* expiresAt: 299999.90000000596,
* isExpired: false,
* position: 0
* },
* {
* key: 'D',
* value: "You're amazing 💛",
* maxAge: Infinity,
* expiresAt: Infinity,
* isExpired: false,
* position: 1
* },
* ]
*/
```

> For _up-to-date_ documentation, always follow the [**README.md**](https://github.com/wellwelwel/lru.min?tab=readme-ov-file#readme) in the **GitHub** repository.
Expand Down
2 changes: 1 addition & 1 deletion benchmark/worker.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const measurePerformance = (fn) => {
};
};

const times = 100;
const times = 10;
const max = 100000;
const brute = 1000000;

Expand Down
2 changes: 1 addition & 1 deletion benchmark/worker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const measurePerformance = (fn) => {
};
};

const times = 100;
const times = 10;
const max = 100000;
const brute = 1000000;

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lru.min",
"version": "1.1.1",
"description": "🔥 An extremely fast and efficient LRU cache for JavaScript with high compatibility (including Browsers) — 6.8KB.",
"description": "🔥 An extremely fast and efficient LRU cache for JavaScript with high compatibility (including Browsers) — 8.8KB.",
"main": "./lib/index.js",
"module": "./lib/index.mjs",
"types": "./lib/index.d.ts",
Expand Down Expand Up @@ -34,6 +34,7 @@
"build:browser": "tsx tools/browserfy.ts",
"build:esm": "esbuild src/index.ts --outfile=lib/index.mjs --platform=node --target=node12 --format=esm",
"build": "tsc && npm run build:esm && npm run build:browser",
"postbuild": "tsx tools/strip-comments.ts",
"test:node": "poku --node -p",
"test:bun": "poku --bun -p",
"test:deno": "poku --deno -p",
Expand Down
73 changes: 70 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { performance } from 'node:perf_hooks';

export type CacheOptions<Key = unknown, Value = unknown> = {
/** Maximum number of items the cache can hold. */
max: number;
/** Maximum age (in ms) for items before they are considered stale. */
maxAge?: number;
/** Function called when an item is evicted from the cache. */
onEviction?: (key: Key, value: Value) => unknown;
Expand All @@ -17,7 +16,13 @@ export const createLRU = <Key, Value>(options: CacheOptions<Key, Value>) => {
if (typeof maxAge === 'number' && maxAge <= 0)
throw new TypeError('`maxAge` must be a positive number');

Check warning on line 17 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L17

Added line #L17 was not covered by tests

const Age = typeof performance?.now === 'object' ? performance : Date;
const Age = (() => {
try {
return typeof performance.now === 'function' ? performance : Date;
} catch {
return Date;
}

Check warning on line 24 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L23-L24

Added lines #L23 - L24 were not covered by tests
})();

let size = 0;
let head = 0;
Expand Down Expand Up @@ -116,6 +121,35 @@ export const createLRU = <Key, Value>(options: CacheOptions<Key, Value>) => {
return true;
};

const _debug = (key: Key) => {
const index = keyMap.get(key);

Check warning on line 125 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L125

Added line #L125 was not covered by tests

if (index === undefined) return;

Check warning on line 127 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L127

Added line #L127 was not covered by tests

const ageItem = ageList[index];
const expiresAt = expList[index];
const now = Age.now();
const timeRemaining = expiresAt !== 0 ? expiresAt - now : 0;
const isExpired = expiresAt !== 0 && now > expiresAt;

Check warning on line 133 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L129-L133

Added lines #L129 - L133 were not covered by tests

let current = tail;
let position = 0;

Check warning on line 136 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L135-L136

Added lines #L135 - L136 were not covered by tests

while (current !== index && current !== 0) {
current = prev[current];
position++;
}

Check warning on line 141 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L138-L141

Added lines #L138 - L141 were not covered by tests

return {
key,
value: valList[index],
maxAge: ageItem,
expiresAt: timeRemaining > 0 ? timeRemaining : 0,
isExpired,
position,
};
};

Check warning on line 151 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L143-L151

Added lines #L143 - L151 were not covered by tests

return {
/** Adds a key-value pair to the cache. Updates the value if the key already exists. */
set(key: Key, value: Value, options?: { maxAge?: number }): undefined {
Expand Down Expand Up @@ -344,6 +378,39 @@ export const createLRU = <Key, Value>(options: CacheOptions<Key, Value>) => {
max = newMax;
},

*debug(key?: Key): Generator<
| {

Check warning on line 382 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L381-L382

Added lines #L381 - L382 were not covered by tests
/** Item key. */
key: Key;

Check warning on line 384 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L384

Added line #L384 was not covered by tests
/** Item value. */
value: Value | undefined;

Check warning on line 386 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L386

Added line #L386 was not covered by tests
/** Time in milliseconds. */
maxAge: number;

Check warning on line 388 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L388

Added line #L388 was not covered by tests
/** Time in milliseconds. */
expiresAt: number;

Check warning on line 390 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L390

Added line #L390 was not covered by tests
/** When it's `true`, the next interaction with the key will evict it. */
isExpired: boolean;

Check warning on line 392 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L392

Added line #L392 was not covered by tests
/** From the most recent (`0`) to the oldest (`max`). */
position: number;
}
| undefined
> {
if (key !== undefined) {
const result = _debug(key);

Check warning on line 399 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L394-L399

Added lines #L394 - L399 were not covered by tests

if (result) yield result;

Check warning on line 401 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L401

Added line #L401 was not covered by tests

return;
}

Check warning on line 404 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L403-L404

Added lines #L403 - L404 were not covered by tests

let current = tail;

Check warning on line 406 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L406

Added line #L406 was not covered by tests

for (let i = 0; i < size; i++) {
yield _debug(keyList[current]!);
current = prev[current];
}

Check warning on line 411 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L408-L411

Added lines #L408 - L411 were not covered by tests
},

/** Returns the maximum number of items that can be stored in the cache. */
get max() {
return max;
Expand Down
12 changes: 0 additions & 12 deletions t.ts

This file was deleted.

7 changes: 4 additions & 3 deletions tools/browserfy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { transformAsync } from '@babel/core';
import { minify } from 'terser';

(async () => {
const contents = (await readFile('src/index.ts', 'utf8'))
.replace(/export const/gim, 'window.')
.replace(/import { performance } from 'node:perf_hooks';/gim, '');
const contents = (await readFile('src/index.ts', 'utf8')).replace(
/export const/gim,
'window.'
);

const result = await esbuild.build({
stdin: {
Expand Down
19 changes: 19 additions & 0 deletions tools/strip-comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { promises as fs } from 'node:fs';
import { listFiles } from 'poku';

const ensureNodeCompatibility = async (path: string) => {
const files = await listFiles(path, {
filter: /\.(|m)?(j)?s$/,
});

console.log('Ensuring no unnecessary comments for:', files);

for (const file of files) {
const raw = await fs.readFile(file, 'utf8');
const content = raw.replace(/(\/\*)((?:|[^1])+?)\//gim, '');

await fs.writeFile(file, content, { encoding: 'utf8' });
}
};

ensureNodeCompatibility('./lib');

0 comments on commit 5f8731c

Please sign in to comment.