@philiprehberger/cache-kit 0.1.0 → 0.2.0

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.
Files changed (2) hide show
  1. package/README.md +127 -0
  2. package/package.json +32 -9
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @philiprehberger/cache-kit
2
+
3
+ In-memory LRU cache with TTL, stale-while-revalidate, and tag invalidation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @philiprehberger/cache-kit
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic
14
+
15
+ ```ts
16
+ import { createCache } from '@philiprehberger/cache-kit';
17
+
18
+ const cache = createCache({ maxItems: 1000, defaultTTL: '5m' });
19
+
20
+ cache.set('user:123', userData);
21
+ cache.set('user:456', otherUser, { ttl: '10m' });
22
+
23
+ const user = cache.get('user:123'); // T | undefined
24
+ cache.has('user:123'); // boolean
25
+ cache.delete('user:123'); // boolean
26
+ cache.clear();
27
+ ```
28
+
29
+ ### TTL Durations
30
+
31
+ Supports string durations or milliseconds:
32
+
33
+ ```ts
34
+ cache.set('key', value, { ttl: '30s' }); // 30 seconds
35
+ cache.set('key', value, { ttl: '5m' }); // 5 minutes
36
+ cache.set('key', value, { ttl: '1h' }); // 1 hour
37
+ cache.set('key', value, { ttl: '1d' }); // 1 day
38
+ cache.set('key', value, { ttl: 60000 }); // 60000ms
39
+ ```
40
+
41
+ ### Tag-Based Invalidation
42
+
43
+ ```ts
44
+ cache.set('user:1', user1, { tags: ['users'] });
45
+ cache.set('user:2', user2, { tags: ['users'] });
46
+ cache.set('post:1', post1, { tags: ['posts'] });
47
+
48
+ cache.invalidateTag('users'); // removes user:1 and user:2
49
+ ```
50
+
51
+ ### Wrap (Memoize)
52
+
53
+ ```ts
54
+ const getUser = cache.wrap(
55
+ 'user',
56
+ (id: string) => db.users.findById(id),
57
+ { ttl: '5m' },
58
+ );
59
+
60
+ const user = await getUser('123'); // fetches from DB
61
+ const same = await getUser('123'); // served from cache
62
+ ```
63
+
64
+ ### Stale-While-Revalidate
65
+
66
+ ```ts
67
+ const getUser = cache.wrap(
68
+ 'user',
69
+ (id: string) => db.users.findById(id),
70
+ { ttl: '5m', staleWhileRevalidate: '1m' },
71
+ );
72
+ // Serves stale data immediately while refreshing in the background
73
+ ```
74
+
75
+ ### Stats
76
+
77
+ ```ts
78
+ cache.stats();
79
+ // { hits: 150, misses: 23, hitRate: 0.867, size: 42 }
80
+ ```
81
+
82
+ ### Persistence
83
+
84
+ ```ts
85
+ const data = cache.dump(); // serialize to JSON
86
+ cache.load(data); // restore from JSON
87
+ ```
88
+
89
+ ## API Reference
90
+
91
+ ### `createCache<V>(options?: CacheOptions): Cache<V>`
92
+
93
+ | Method | Signature | Description |
94
+ |--------|-----------|-------------|
95
+ | `set` | `(key: string, value: V, opts?: SetOptions) => void` | Store a value. |
96
+ | `get` | `(key: string) => V \| undefined` | Retrieve a value. Returns `undefined` if missing or expired. |
97
+ | `has` | `(key: string) => boolean` | Check if a key exists and is not expired. |
98
+ | `delete` | `(key: string) => boolean` | Remove a key. Returns `true` if it existed. |
99
+ | `clear` | `() => void` | Remove all entries and reset stats. |
100
+ | `invalidateTag` | `(tag: string) => number` | Remove all entries with the given tag. Returns count removed. |
101
+ | `wrap` | `(keyPrefix, fn, opts?) => (...args) => Promise` | Memoize an async function with cache. |
102
+ | `stats` | `() => CacheStats` | Get hit/miss/size statistics. |
103
+ | `dump` | `() => SerializedCache` | Serialize cache contents for persistence. |
104
+ | `load` | `(data: SerializedCache) => void` | Restore cache from serialized data. |
105
+
106
+ ### `CacheOptions`
107
+
108
+ | Property | Type | Default | Description |
109
+ |----------|------|---------|-------------|
110
+ | `maxItems` | `number` | `Infinity` | Max entries before LRU eviction. |
111
+ | `defaultTTL` | `string \| number` | None | Default TTL for all entries. |
112
+
113
+ ### `SetOptions`
114
+
115
+ | Property | Type | Description |
116
+ |----------|------|-------------|
117
+ | `ttl` | `string \| number` | Time-to-live (e.g. `"5m"`, `60000`). |
118
+ | `tags` | `string[]` | Tags for group invalidation. |
119
+ | `staleWhileRevalidate` | `string \| number` | Window before expiry where stale data is served while refreshing. |
120
+
121
+ ### Duration Strings
122
+
123
+ `"100ms"`, `"30s"`, `"5m"`, `"1h"`, `"1d"` — or pass milliseconds as a number.
124
+
125
+ ## License
126
+
127
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@philiprehberger/cache-kit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "In-memory LRU cache with TTL, stale-while-revalidate, and tag invalidation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -8,27 +8,50 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
12
- "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
13
19
  }
14
20
  },
15
- "files": ["dist"],
21
+ "files": [
22
+ "dist"
23
+ ],
16
24
  "scripts": {
17
25
  "build": "tsup",
18
26
  "dev": "tsup --watch",
19
27
  "typecheck": "tsc --noEmit",
20
- "prepublishOnly": "npm run build"
28
+ "prepublishOnly": "npm run build",
29
+ "test": "node --test src/__tests__/index.test.mjs"
21
30
  },
22
31
  "devDependencies": {
23
32
  "tsup": "^8.0.0",
24
33
  "typescript": "^5.0.0"
25
34
  },
26
- "keywords": ["cache", "lru", "ttl", "stale-while-revalidate", "in-memory", "memoize"],
35
+ "keywords": [
36
+ "cache",
37
+ "lru",
38
+ "ttl",
39
+ "stale-while-revalidate",
40
+ "in-memory",
41
+ "memoize"
42
+ ],
27
43
  "license": "MIT",
28
- "repository": { "type": "git", "url": "git+https://github.com/philiprehberger/cache-kit.git" },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/philiprehberger/cache-kit.git"
47
+ },
29
48
  "homepage": "https://github.com/philiprehberger/cache-kit#readme",
30
- "bugs": { "url": "https://github.com/philiprehberger/cache-kit/issues" },
49
+ "bugs": {
50
+ "url": "https://github.com/philiprehberger/cache-kit/issues"
51
+ },
31
52
  "author": "Philip Rehberger",
32
- "engines": { "node": ">=18.0.0" },
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ },
33
56
  "sideEffects": false
34
57
  }