@neezco/cache 0.4.1 → 0.6.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.
@@ -89,6 +89,9 @@ interface EntryMetadata<T = unknown> {
89
89
  // The cached value.
90
90
  data: T;
91
91
 
92
+ // Absolute timestamp when the entry was created (in milliseconds).
93
+ createdAt: number;
94
+
92
95
  // Absolute timestamp when this entry becomes fully expired (in milliseconds).
93
96
  expirationTime: number;
94
97
 
@@ -123,6 +126,7 @@ const user = cache.get("user:123");
123
126
  const entry = cache.get("user:123", { includeMetadata: true });
124
127
  if (entry) {
125
128
  console.log(entry.data);
129
+ console.log(entry.createdAt);
126
130
  console.log(entry.status);
127
131
  console.log(entry.expirationTime);
128
132
  console.log(entry.staleWindowExpiration);
package/package.json CHANGED
@@ -67,10 +67,6 @@
67
67
  "@commitlint/cli": "20.3.0",
68
68
  "@commitlint/config-conventional": "20.3.0",
69
69
  "@eslint/js": "9.39.2",
70
- "@semantic-release/changelog": "6.0.3",
71
- "@semantic-release/git": "10.0.1",
72
- "@semantic-release/github": "12.0.6",
73
- "@semantic-release/npm": "13.1.4",
74
70
  "@types/bun": "latest",
75
71
  "@types/node": "25.0.6",
76
72
  "@vitest/coverage-v8": "4.0.17",
@@ -97,10 +93,20 @@
97
93
  },
98
94
  "pnpm": {
99
95
  "overrides": {
100
- "minimatch": "^10.2.1",
96
+ "handlebars": "^4.7.9",
97
+ "lodash-es": "^4.18.0",
98
+ "minimatch": "^10.2.3",
99
+ "rollup": "^4.59.0",
100
+ "vite": "^7.3.2",
101
+ "flatted": "^3.4.2",
102
+ "defu": "^6.1.5",
103
+ "picomatch@<2.3.2": "2.3.2",
104
+ "picomatch@>=4.0.0 <4.0.4": "4.0.4",
105
+ "undici@<6.24.0": "6.24.0",
106
+ "undici@>=7.0.0 <7.24.0": "7.24.0",
101
107
  "ajv@<6.14.0": "6.14.0",
102
108
  "ajv@>=7.0.0 <8.18.0": "8.18.0"
103
109
  }
104
110
  },
105
- "version": "0.4.1"
111
+ "version": "0.6.0"
106
112
  }
package/CHANGELOG.md DELETED
@@ -1,56 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- ## [0.4.1](https://github.com/neezco/cache/compare/v0.4.0...v0.4.1) (2026-02-21)
6
-
7
-
8
- ### Bug Fixes
9
-
10
- * adjust semantic-release title and section configuration for proper changelog grouping ([919729a](https://github.com/neezco/cache/commit/919729a9d4d826e5ea78e7147914fc52f8d12149))
11
-
12
- ## 0.4.0 (2026-02-14)
13
-
14
- * chore: implement startSweep function to manage cache sweep process ([78ded7a](https://github.com/neezco/cache/commit/78ded7a))
15
- * chore: install semantic-release plugins and add unified release script ([5b7a8b3](https://github.com/neezco/cache/commit/5b7a8b3))
16
- * test: add comprehensive tests for LocalTtlCache purge strategies and basic operations ([a410f2d](https://github.com/neezco/cache/commit/a410f2d))
17
- * test: ensure tag invalidation does not affect entries created after the tag ([9282397](https://github.com/neezco/cache/commit/9282397))
18
- * fix: enforce stale window upper bound when applying tag-based stale invalidation ([593c1d4](https://github.com/neezco/cache/commit/593c1d4)), closes [#19](https://github.com/neezco/cache/issues/19)
19
- * feat: enhance cache purging strategy with configurable thresholds ([ee762c1](https://github.com/neezco/cache/commit/ee762c1))
20
- * feat: refactor purge configuration logic and enhance validation for thresholds ([350b9de](https://github.com/neezco/cache/commit/350b9de)), closes [#18](https://github.com/neezco/cache/issues/18)
21
- * style: add conventional-changelog-conventionalcommits package for improved changelog generation ([5435048](https://github.com/neezco/cache/commit/5435048))
22
- * style: simplify commit-analyzer plugin configuration ([ecff6a0](https://github.com/neezco/cache/commit/ecff6a0))
23
- * style: update release notes generator configuration for improved changelog formatting ([1ac4776](https://github.com/neezco/cache/commit/1ac4776))
24
-
25
- # [0.3.0](https://github.com/neezco/cache/compare/v0.2.1...v0.3.0) (2026-02-11)
26
-
27
-
28
- ### Features
29
-
30
- * enhance cache retrieval with metadata support in `get()` method ([eb198d6](https://github.com/neezco/cache/commit/eb198d66c9e1abda86c448fb81a35f14e376a79c)), closes [#17](https://github.com/neezco/cache/issues/17)
31
-
32
- ## [0.2.1](https://github.com/neezco/cache/compare/v0.2.0...v0.2.1) (2026-02-11)
33
-
34
-
35
- ### Performance Improvements
36
-
37
- * optimize cache entry validation by introducing pre-computed status handling ([bafb6a0](https://github.com/neezco/cache/commit/bafb6a024b0082a1b81f2d0e959c883df4136976))
38
-
39
- # [0.2.0](https://github.com/neezco/cache/compare/v0.1.1...v0.2.0) (2026-02-09)
40
-
41
-
42
- ### Bug Fixes
43
-
44
- * add regex for todo-tree to enhance tag recognition ([e0c3292](https://github.com/neezco/cache/commit/e0c3292cd83f5e6d1c5cd9b9c2e199b4a7c9eda0))
45
-
46
-
47
- ### Features
48
-
49
- * add maxMemorySize configuration and update cache behavior for size limits ([fb3f173](https://github.com/neezco/cache/commit/fb3f173b891fc4f345596904ad82b606e5cbc00c))
50
-
51
- ## [0.1.1](https://github.com/neezco/cache/compare/v0.1.0...v0.1.1) (2026-02-09)
52
-
53
-
54
- ### Bug Fixes
55
-
56
- * update `invalidateTag` method to use `InvalidateTagOptions` for extensibility ([8184098](https://github.com/neezco/cache/commit/8184098a3b7eed24dc8ebf211b4929f4b383b4a9))
@@ -1,338 +0,0 @@
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 an entry expires naturally (not manually deleted).
15
- * @param key - The expired key.
16
- * @param value - The value associated with the expired key.
17
- * @param reason - The reason for expiration: 'expired' (fully expired) or 'stale' (stale window expired).
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 without explicit `staleWindow`.
34
- *
35
- * Defines how long an entry can be served as stale after expiration.
36
- * The window is relative to each entry's expiration moment, whether from
37
- * explicit `ttl` or the cache's `defaultTtl`.
38
- *
39
- * @default 0 (no stale window)
40
- */
41
- defaultStaleWindow: number;
42
- /**
43
- * Maximum number of entries the cache can hold.
44
- * Beyond this limit, new entries are ignored.
45
- * @default Infinite (unlimited)
46
- */
47
- maxSize: number;
48
- /**
49
- * Maximum memory size in MB the cache can use.
50
- * Beyond this limit, new entries are ignored.
51
- * @default Infinite (unlimited)
52
- */
53
- maxMemorySize: number;
54
- /**
55
- * Controls stale entry purging behavior on `get()` operations.
56
- *
57
- * Possible values:
58
- * - `true` → purge stale entries immediately after read.
59
- * - `false` → retain stale entries after read.
60
- * - `number (0-1)` → purge when `resourceUsage ≥ threshold` (uses `purgeResourceMetric`).
61
- *
62
- * Numeric threshold validation:
63
- * - Must be 0 < value ≤ 1 (boolean fallback if invalid range)
64
- * - Requires purgeResourceMetric to support thresholds (not 'fixed')
65
- * - Requires matching configuration limits for the metric:
66
- * * 'size' metric requires maxSize
67
- * * 'memory' metric requires maxMemorySize
68
- * * 'higher' metric requires both maxSize and maxMemorySize
69
- * - Invalid numeric values fallback to default: 0.80 (with limits) or false (without)
70
- *
71
- * Environment notes:
72
- * - Backend: `"memory"` and `"higher"` metrics available; frontend: only `"size"`.
73
- * - Can be overridden per-read via `get(key, { purgeStale })`.
74
- *
75
- * Defaults:
76
- * - With matching limits → `0.80` (80% resource usage).
77
- * - Without matching limits → `false`.
78
- */
79
- purgeStaleOnGet: PurgeMode;
80
- /**
81
- * Controls stale entry purging behavior during sweep operations.
82
- *
83
- * Possible values:
84
- * - `true` → purge stale entries during sweeps.
85
- * - `false` → retain stale entries during sweeps.
86
- * - `number (0-1)` → purge when `resourceUsage ≥ threshold` (uses `purgeResourceMetric`).
87
- *
88
- * Numeric threshold validation:
89
- * - Must be 0 < value ≤ 1 (boolean fallback if invalid range)
90
- * - Requires purgeResourceMetric to support thresholds (not 'fixed')
91
- * - Requires matching configuration limits for the metric:
92
- * * 'size' metric requires maxSize
93
- * * 'memory' metric requires maxMemorySize
94
- * * 'higher' metric requires both maxSize and maxMemorySize
95
- * - Invalid numeric values fallback to default: 0.5 (with limits) or true (without)
96
- *
97
- * Prevents stale entry accumulation when enabled. Without limits, defaults to `true`
98
- * to prevent unbounded growth.
99
- *
100
- * Environment notes:
101
- * - Backend: `"memory"` and `"higher"` metrics available; frontend: only `"size"`.
102
- *
103
- * Defaults:
104
- * - With matching limits → `0.5` (50% resource usage).
105
- * - Without matching limits → `true` (prevent unbounded accumulation).
106
- */
107
- purgeStaleOnSweep: PurgeMode;
108
- /**
109
- * Metric used to evaluate resource usage for threshold-based stale purging.
110
- *
111
- * Applies when `purgeStaleOnGet` or `purgeStaleOnSweep` are numeric (0-1).
112
- *
113
- * Metric options:
114
- * - `"size"` → normalized entry count (`current / maxSize`).
115
- * - `"memory"` → normalized RAM (`currentMB / maxMemorySize`).
116
- * - `"higher"` → max of both metrics (recommended for dual limits).
117
- * - `"fixed"` → disable threshold purging; only bool values apply.
118
- *
119
- * Environment support:
120
- * - Backend: all metrics available.
121
- * - Frontend: only `"size"`; numeric thresholds fallback to `"fixed"`.
122
- *
123
- * Auto-selection (if not specified):
124
- * - Backend: `"higher"` (both limits) → `"memory"` → `"size"` → `"fixed"`.
125
- * - Frontend: `"size"` (if valid) → `"fixed"`.
126
- *
127
- * @default Depends on environment and valid limits.
128
- */
129
- purgeResourceMetric?: "memory" | "size" | "higher" | "fixed";
130
- /**
131
- * Auto-start sweep process on cache initialization.
132
- *
133
- * @internal
134
- * @default true
135
- */
136
- _autoStartSweep: boolean;
137
- /**
138
- * @internal Maximum allowed ratio of expired entries before aggressive sweep.
139
- */
140
- _maxAllowExpiredRatio: number;
141
- }
142
- /**
143
- * Purge mode: boolean for immediate/skip, or 0-1 for threshold-based purging.
144
- */
145
- type PurgeMode = boolean | number;
146
- /**
147
- * Public cache configuration (all fields optional).
148
- */
149
- type CacheOptions = Partial<CacheConfigBase>;
150
- /**
151
- * Options for tag invalidation. Extensible for forward-compatibility.
152
- */
153
- interface InvalidateTagOptions {
154
- /**
155
- * If true, mark entries as stale instead of fully expired.
156
- * They remain accessible via stale window if configured.
157
- */
158
- asStale?: boolean;
159
- [key: string]: unknown;
160
- }
161
- /**
162
- * Entry status: fresh, stale, or expired.
163
- */
164
- declare enum ENTRY_STATUS {
165
- /** Valid and within TTL. */
166
- FRESH = "fresh",
167
- /** Expired but within stale window; still served. */
168
- STALE = "stale",
169
- /** Beyond stale window; not served. */
170
- EXPIRED = "expired",
171
- }
172
- /**
173
- * Metadata returned from `get()` with `includeMetadata: true`.
174
- * Provides complete entry state including timing, status, and tags.
175
- */
176
- interface EntryMetadata<T = unknown> {
177
- /** The cached value. */
178
- data: T;
179
- /** Absolute timestamp (ms) when entry expires. */
180
- expirationTime: number;
181
- /** Absolute timestamp (ms) when stale window ends. */
182
- staleWindowExpiration: number;
183
- /** Current entry status. */
184
- status: ENTRY_STATUS;
185
- /** Associated tags for group invalidation, or null. */
186
- tags: string[] | null;
187
- }
188
- /**
189
- * Options for `get()` without metadata (default).
190
- * Returns only the cached value.
191
- */
192
- interface GetOptionsWithoutMetadata {
193
- /**
194
- * If false (or omitted), returns value only without metadata.
195
- * @default false
196
- */
197
- includeMetadata?: false;
198
- /**
199
- * Controls stale entry purging on this read.
200
- *
201
- * - `true` → purge immediately after return.
202
- * - `false` → keep stale entries.
203
- * - `number (0-1)` → purge at resource usage threshold.
204
- *
205
- * Overrides global `purgeStaleOnGet` setting.
206
- */
207
- purgeStale?: PurgeMode;
208
- }
209
- /**
210
- * Options for `get()` with metadata.
211
- * Returns value and complete entry state.
212
- */
213
- interface GetOptionsWithMetadata {
214
- /**
215
- * If true, returns `EntryMetadata<T>` object with value, timing, and tags.
216
- */
217
- includeMetadata: true;
218
- /**
219
- * Controls stale entry purging on this read.
220
- *
221
- * - `true` → purge immediately after return.
222
- * - `false` → keep stale entries.
223
- * - `number (0-1)` → purge at resource usage threshold.
224
- *
225
- * Overrides global `purgeStaleOnGet` setting.
226
- */
227
- purgeStale?: PurgeMode;
228
- }
229
- /**
230
- * Options for `set()` method.
231
- * Controls TTL, stale window, and tagging per entry.
232
- */
233
- interface SetOptions {
234
- /**
235
- * Time-To-Live in milliseconds.
236
- * Determines fresh period before expiration.
237
- *
238
- * Special values:
239
- * - `0` | `Infinity` → entry never expires
240
- *
241
- * Falls back to cache's `defaultTtl` if omitted.
242
- */
243
- ttl?: number;
244
- /**
245
- * Stale window duration in milliseconds.
246
- *
247
- * Determines how long entry serves stale after expiration.
248
- * Falls back to cache's `defaultStaleWindow` if omitted.
249
- */
250
- staleWindow?: number;
251
- /**
252
- * One or more tags for group-based invalidation.
253
- *
254
- * Tags enable batch invalidation via `invalidateTag()`.
255
- * Invalidating ANY tag on an entry invalidates the whole entry.
256
- *
257
- * Falls back to cache's default if omitted.
258
- */
259
- tags?: string | string[];
260
- }
261
- /**
262
- * TTL cache public interface.
263
- * Implemented by `LocalTtlCache` class.
264
- */
265
- interface LocalTtlCacheInterface {
266
- /**
267
- * Current number of entries (may include expired entries pending cleanup).
268
- */
269
- readonly size: number;
270
- /**
271
- * Retrieves value from cache.
272
- * Returns fresh, stale, or undefined (expired or not found).
273
- *
274
- * @overload `get<T>(key)` → `T | undefined` (no metadata)
275
- * @overload `get<T>(key, { includeMetadata: true })` → `EntryMetadata<T> | undefined` (with metadata)
276
- */
277
- get<T = unknown>(key: string): T | undefined;
278
- get<T = unknown>(key: string, options: GetOptionsWithMetadata): EntryMetadata<T> | undefined;
279
- get<T = unknown>(key: string, options: GetOptionsWithoutMetadata): T | undefined;
280
- /**
281
- * Sets or replaces a cache entry.
282
- * @returns true if set/updated, false if rejected (limits/invalid).
283
- */
284
- set(key: string, value: unknown, options?: SetOptions): boolean;
285
- /**
286
- * Deletes a specific key from cache.
287
- * @returns true if deleted, false if not found.
288
- */
289
- delete(key: string): boolean;
290
- /**
291
- * Checks if key exists (fresh or stale).
292
- * @returns true if valid, false if not found or fully expired.
293
- */
294
- has(key: string): boolean;
295
- /**
296
- * Removes all entries from cache.
297
- * Does NOT trigger `onDelete` callbacks (optimization).
298
- */
299
- clear(): void;
300
- /**
301
- * Marks entries with given tags as expired (or stale).
302
- * Invalidating ANY tag on an entry invalidates it.
303
- */
304
- invalidateTag(tags: string | string[], options?: InvalidateTagOptions): void;
305
- }
306
- //#endregion
307
- //#region src/index.d.ts
308
- /**
309
- * A TTL (Time-To-Live) cache implementation with support for expiration,
310
- * stale windows, tag-based invalidation, and smart automatic sweeping.
311
- *
312
- * Provides O(1) constant-time operations for all core methods with support for:
313
- * - Expiration and stale windows
314
- * - Tag-based invalidation
315
- * - Automatic sweeping
316
- */
317
- declare class LocalTtlCache implements LocalTtlCacheInterface {
318
- private state;
319
- /**
320
- * Creates a new cache instance.
321
- *
322
- * @param options - Configuration options for the cache (defaultTtl, defaultStaleWindow, maxSize, etc.)
323
- *
324
- */
325
- constructor(options?: CacheOptions);
326
- get size(): number;
327
- get<T = unknown>(key: string): T | undefined;
328
- get<T = unknown>(key: string, options: GetOptionsWithMetadata): EntryMetadata<T>;
329
- get<T = unknown>(key: string, options: GetOptionsWithoutMetadata): T | undefined;
330
- set(key: string, value: unknown, options?: SetOptions): boolean;
331
- delete(key: string): boolean;
332
- has(key: string): boolean;
333
- clear(): void;
334
- invalidateTag(tags: string | string[], options?: InvalidateTagOptions): void;
335
- }
336
- //#endregion
337
- export { type CacheOptions, ENTRY_STATUS, type EntryMetadata, type GetOptionsWithMetadata, type GetOptionsWithoutMetadata, type InvalidateTagOptions, LocalTtlCache, type LocalTtlCacheInterface, type PurgeMode, type SetOptions };
338
- //# sourceMappingURL=index.d.ts.map