@neezco/cache 0.1.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.
- package/LICENSE +7 -0
- package/README.md +55 -0
- package/dist/browser/index.d.ts +276 -0
- package/dist/browser/index.js +782 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/node/index.cjs +1153 -0
- package/dist/node/index.cjs.map +1 -0
- package/dist/node/index.d.cts +276 -0
- package/dist/node/index.d.mts +276 -0
- package/dist/node/index.mjs +1124 -0
- package/dist/node/index.mjs.map +1 -0
- package/docs/.gitkeep +0 -0
- package/docs/api-reference.md +285 -0
- package/docs/configuration.md +175 -0
- package/docs/examples.md +145 -0
- package/docs/getting-started.md +86 -0
- package/package.json +93 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2023 github.com/DanhezCode
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
## đźš§ Project Status
|
|
2
|
+
|
|
3
|
+
> **⚠️ Under active development**
|
|
4
|
+
> This library has not yet reached its first stable release.
|
|
5
|
+
> The API is still evolving, and **breaking changes** may occur at any time.
|
|
6
|
+
> Production use is **not recommended** until a stable version is published.
|
|
7
|
+
|
|
8
|
+
# Short-Live 🚀
|
|
9
|
+
|
|
10
|
+
**A smart, lightweight caching library that helps you store data temporarily with automatic cleanup.**
|
|
11
|
+
|
|
12
|
+
## Why Short-Live?
|
|
13
|
+
|
|
14
|
+
### đź§ą **Automatic Cleanup**
|
|
15
|
+
|
|
16
|
+
Expired data is cleaned up automatically in the background without your intervention.
|
|
17
|
+
|
|
18
|
+
### 📊 **Scales Well**
|
|
19
|
+
|
|
20
|
+
Whether caching 10 items or millions, Short-Live is designed to stay fast and efficient.
|
|
21
|
+
|
|
22
|
+
### 🏷️ **Tag-Based Invalidation**
|
|
23
|
+
|
|
24
|
+
Group related data and clear it all with a single command.
|
|
25
|
+
|
|
26
|
+
### 🎯 **Smart Memory Management**
|
|
27
|
+
|
|
28
|
+
Intelligently prioritizes what to clean up based on usage patterns and memory constraints.
|
|
29
|
+
|
|
30
|
+
### ⚡ **CPU Efficient**
|
|
31
|
+
|
|
32
|
+
All core operations are O(1) with minimal CPU overhead. Background cleanup runs intelligently without blocking your application. Perfect for resource-constrained environments and high-throughput scenarios.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Documentation
|
|
37
|
+
|
|
38
|
+
- **[Getting Started](./docs/getting-started.md)** - Installation and basic usage
|
|
39
|
+
- **[Examples](./docs/examples.md)** - Real-world use cases (API caching, sessions, database queries, etc.)
|
|
40
|
+
- **[API Reference](./docs/api-reference.md)** - Complete API documentation with edge cases
|
|
41
|
+
- **[Configuration](./docs/configuration.md)** - All configuration options explained
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT © [Daniel Hernández Ochoa](https://github.com/DanhezCode)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Contributing
|
|
52
|
+
|
|
53
|
+
We'd love your help! Check out [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
54
|
+
|
|
55
|
+
**Questions? Found a bug?** [Open an issue](https://github.com/neezco/cache/issues) on GitHub.
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
//#region src/cache/delete.d.ts
|
|
2
|
+
declare const enum DELETE_REASON {
|
|
3
|
+
MANUAL = "manual",
|
|
4
|
+
EXPIRED = "expired",
|
|
5
|
+
STALE = "stale",
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/types.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* Base configuration shared between CacheOptions and CacheState.
|
|
11
|
+
*/
|
|
12
|
+
interface CacheConfigBase {
|
|
13
|
+
/**
|
|
14
|
+
* Callback invoked when a key expires naturally.
|
|
15
|
+
* @param key - The expired key.
|
|
16
|
+
* @param value - The value associated with the expired key.
|
|
17
|
+
* @param reason - The reason for deletion ('expired', or 'stale').
|
|
18
|
+
*/
|
|
19
|
+
onExpire?: (key: string, value: unknown, reason: Exclude<DELETE_REASON, DELETE_REASON.MANUAL>) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Callback invoked when a key is deleted, either manually or due to expiration.
|
|
22
|
+
* @param key - The deleted key.
|
|
23
|
+
* @param value - The value of the deleted key.
|
|
24
|
+
* @param reason - The reason for deletion ('manual', 'expired', or 'stale').
|
|
25
|
+
*/
|
|
26
|
+
onDelete?: (key: string, value: unknown, reason: DELETE_REASON) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Default TTL (Time-To-Live) in milliseconds for entries without explicit TTL.
|
|
29
|
+
* @default 1_800_000 (30 minutes)
|
|
30
|
+
*/
|
|
31
|
+
defaultTtl: number;
|
|
32
|
+
/**
|
|
33
|
+
* Default stale window in milliseconds for entries that do not
|
|
34
|
+
* specify their own `staleWindowMs`.
|
|
35
|
+
*
|
|
36
|
+
* This window determines how long an entry may continue to be
|
|
37
|
+
* served as stale after it reaches its expiration time.
|
|
38
|
+
*
|
|
39
|
+
* The window is always relative to the entry’s own expiration
|
|
40
|
+
* moment, regardless of whether that expiration comes from an
|
|
41
|
+
* explicit `ttl` or from the cache’s default TTL.
|
|
42
|
+
* @default null (No stale window)
|
|
43
|
+
*/
|
|
44
|
+
defaultStaleWindow: number;
|
|
45
|
+
/**
|
|
46
|
+
* Maximum number of entries the cache can hold.
|
|
47
|
+
* Beyond this limit, new entries are ignored.
|
|
48
|
+
* @default null (unlimited)
|
|
49
|
+
*/
|
|
50
|
+
maxSize?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Controls how stale entries are handled when read from the cache.
|
|
53
|
+
*
|
|
54
|
+
* - true → stale entries are purged immediately after being returned.
|
|
55
|
+
* - false → stale entries are retained after being returned.
|
|
56
|
+
*
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
purgeStaleOnGet: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Controls how stale entries are handled during sweep operations.
|
|
62
|
+
*
|
|
63
|
+
* - true → stale entries are purged during sweeps.
|
|
64
|
+
* - false → stale entries are retained during sweeps.
|
|
65
|
+
*
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
purgeStaleOnSweep: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Whether to automatically start the sweep process when the cache is created.
|
|
71
|
+
*
|
|
72
|
+
* - true → sweep starts automatically.
|
|
73
|
+
* - false → sweep does not start automatically, allowing manual control.
|
|
74
|
+
*
|
|
75
|
+
* @internal
|
|
76
|
+
* @default true
|
|
77
|
+
*/
|
|
78
|
+
_autoStartSweep: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Allowed expired ratio for the cache instance.
|
|
81
|
+
*/
|
|
82
|
+
_maxAllowExpiredRatio: number;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Public configuration options for the TTL cache.
|
|
86
|
+
*/
|
|
87
|
+
type CacheOptions = Partial<CacheConfigBase>;
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/index.d.ts
|
|
90
|
+
/**
|
|
91
|
+
* A TTL (Time-To-Live) cache implementation with support for expiration,
|
|
92
|
+
* stale windows, tag-based invalidation, and automatic sweeping.
|
|
93
|
+
*
|
|
94
|
+
* Provides O(1) constant-time operations for all core methods.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const cache = new LocalTtlCache();
|
|
99
|
+
* cache.set("user:123", { name: "Alice" }, { ttl: 5 * 60 * 1000 });
|
|
100
|
+
* const user = cache.get("user:123"); // { name: "Alice" }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
declare class LocalTtlCache {
|
|
104
|
+
private state;
|
|
105
|
+
/**
|
|
106
|
+
* Creates a new cache instance.
|
|
107
|
+
*
|
|
108
|
+
* @param options - Configuration options for the cache (defaultTtl, defaultStaleWindow, maxSize, etc.)
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const cache = new LocalTtlCache({
|
|
113
|
+
* defaultTtl: 30 * 60 * 1000, // 30 minutes
|
|
114
|
+
* defaultStaleWindow: 5 * 60 * 1000, // 5 minutes
|
|
115
|
+
* maxSize: 500_000, // Maximum 500_000 entries
|
|
116
|
+
* onExpire: (key, value) => console.log(`Expired: ${key}`),
|
|
117
|
+
* onDelete: (key, value, reason) => console.log(`Deleted: ${key}, reason: ${reason}`),
|
|
118
|
+
* });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
constructor(options?: CacheOptions);
|
|
122
|
+
/**
|
|
123
|
+
* Gets the current number of entries tracked by the cache.
|
|
124
|
+
*
|
|
125
|
+
* This value may include entries that are already expired but have not yet been
|
|
126
|
+
* removed by the lazy cleanup system. Expired keys are cleaned only when it is
|
|
127
|
+
* efficient to do so, so the count can temporarily be higher than the number of
|
|
128
|
+
* actually valid (non‑expired) entries.
|
|
129
|
+
*
|
|
130
|
+
* @returns The number of entries currently stored (including entries pending cleanup)
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* console.log(cache.size); // e.g., 42
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
get size(): number;
|
|
138
|
+
/**
|
|
139
|
+
* Retrieves a value from the cache.
|
|
140
|
+
*
|
|
141
|
+
* Returns the value if it exists and is not fully expired. If an entry is in the
|
|
142
|
+
* stale window (expired but still within staleWindow), the stale value is returned.
|
|
143
|
+
*
|
|
144
|
+
|
|
145
|
+
* @param key - The key to retrieve
|
|
146
|
+
* @returns The cached value if valid, undefined otherwise
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* const user = cache.get<{ name: string }>("user:123");
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* @edge-cases
|
|
154
|
+
* - Returns `undefined` if the key doesn't exist
|
|
155
|
+
* - Returns `undefined` if the key has expired beyond the stale window
|
|
156
|
+
* - Returns the stale value if within the stale window
|
|
157
|
+
* - If `purgeStaleOnGet` is enabled, stale entries are deleted after being returned
|
|
158
|
+
*/
|
|
159
|
+
get<T = unknown>(key: string): T | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Sets or updates a value in the cache.
|
|
162
|
+
*
|
|
163
|
+
* If the key already exists, it will be completely replaced.
|
|
164
|
+
*
|
|
165
|
+
* @param key - The key under which to store the value
|
|
166
|
+
* @param value - The value to cache (any type)
|
|
167
|
+
* @param options - Optional configuration for this specific entry
|
|
168
|
+
* @param options.ttl - Time-To-Live in milliseconds. Defaults to `defaultTtl`
|
|
169
|
+
* @param options.staleWindow - How long to serve stale data after expiration (milliseconds)
|
|
170
|
+
* @param options.tags - One or more tags for group invalidation
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* cache.set("user:123", { name: "Alice" }, {
|
|
175
|
+
* ttl: 5 * 60 * 1000,
|
|
176
|
+
* staleWindow: 1 * 60 * 1000,
|
|
177
|
+
* tags: "user:123",
|
|
178
|
+
* });
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* @edge-cases
|
|
182
|
+
* - Overwriting an existing key replaces it completely
|
|
183
|
+
* - If `ttl` is 0 or Infinite, the entry never expires
|
|
184
|
+
* - If `staleWindow` is larger than `ttl`, the entry can be served as stale longer than it was fresh
|
|
185
|
+
* - Tags are optional; only necessary for group invalidation via `invalidateTag()`
|
|
186
|
+
*/
|
|
187
|
+
set(key: string, value: unknown, options?: {
|
|
188
|
+
ttl?: number;
|
|
189
|
+
staleWindow?: number;
|
|
190
|
+
tags?: string | string[];
|
|
191
|
+
}): void;
|
|
192
|
+
/**
|
|
193
|
+
* Deletes a specific key from the cache.
|
|
194
|
+
*
|
|
195
|
+
* @param key - The key to delete
|
|
196
|
+
* @returns True if the key was deleted, false if it didn't exist
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* const wasDeleted = cache.delete("user:123");
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @edge-cases
|
|
204
|
+
* - Triggers the `onDelete` callback with reason `'manual'`
|
|
205
|
+
* - Does not trigger the `onExpire` callback
|
|
206
|
+
* - Returns `false` if the key was already expired
|
|
207
|
+
* - Deleting a non-existent key returns `false` without error
|
|
208
|
+
*/
|
|
209
|
+
delete(key: string): boolean;
|
|
210
|
+
/**
|
|
211
|
+
* Checks if a key exists in the cache and is not fully expired.
|
|
212
|
+
*
|
|
213
|
+
* Returns true if the key exists and is either fresh or within the stale window.
|
|
214
|
+
* Use this when you only need to check existence without retrieving the value.
|
|
215
|
+
*
|
|
216
|
+
* @param key - The key to check
|
|
217
|
+
* @returns True if the key exists and is valid, false otherwise
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* if (cache.has("user:123")) {
|
|
222
|
+
* // Key exists (either fresh or stale)
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*
|
|
226
|
+
* @edge-cases
|
|
227
|
+
* - Returns `false` if the key doesn't exist
|
|
228
|
+
* - Returns `false` if the key has expired beyond the stale window
|
|
229
|
+
* - Returns `true` if the key is in the stale window (still being served)
|
|
230
|
+
* - Both `has()` and `get()` have O(1) complexity; prefer `get()` if you need the value
|
|
231
|
+
*/
|
|
232
|
+
has(key: string): boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Removes all entries from the cache at once.
|
|
235
|
+
*
|
|
236
|
+
* This is useful for resetting the cache or freeing memory when needed.
|
|
237
|
+
* The `onDelete` callback is NOT invoked during clear (intentional optimization).
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* cache.clear(); // cache.size is now 0
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
* @edge-cases
|
|
245
|
+
* - The `onDelete` callback is NOT triggered during clear
|
|
246
|
+
* - Clears both expired and fresh entries
|
|
247
|
+
* - Resets `cache.size` to 0
|
|
248
|
+
*/
|
|
249
|
+
clear(): void;
|
|
250
|
+
/**
|
|
251
|
+
* Marks all entries with one or more tags as expired (or stale, if requested).
|
|
252
|
+
*
|
|
253
|
+
* If an entry has multiple tags, invalidating ANY of those tags will invalidate the entry.
|
|
254
|
+
*
|
|
255
|
+
* @param tags - A single tag (string) or array of tags to invalidate
|
|
256
|
+
* @param asStale - If true, marks entries as stale instead of fully expired (still served from stale window)
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* // Invalidate a single tag
|
|
261
|
+
* cache.invalidateTag("user:123");
|
|
262
|
+
*
|
|
263
|
+
* // Invalidate multiple tags
|
|
264
|
+
* cache.invalidateTag(["user:123", "posts:456"]);
|
|
265
|
+
* ```
|
|
266
|
+
*
|
|
267
|
+
* @edge-cases
|
|
268
|
+
* - Does not throw errors if a tag has no associated entries
|
|
269
|
+
* - Invalidating a tag doesn't prevent new entries from being tagged with it later
|
|
270
|
+
* - The `onDelete` callback is triggered with reason `'expired'` (even if `asStale` is true)
|
|
271
|
+
*/
|
|
272
|
+
invalidateTag(tags: string | string[], asStale?: boolean): void;
|
|
273
|
+
}
|
|
274
|
+
//#endregion
|
|
275
|
+
export { type CacheOptions, LocalTtlCache };
|
|
276
|
+
//# sourceMappingURL=index.d.ts.map
|