express-memorize 2.3.0 → 2.4.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/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ # [2.4.0](https://github.com/ElJijuna/express-memorize/compare/v2.3.1...v2.4.0) (2026-05-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * guard async cache writes and coalesce remember calls ([24bf853](https://github.com/ElJijuna/express-memorize/commit/24bf853eb26ff55652e0bbf5a55b130d448ed2d7))
7
+
8
+
9
+ ### Features
10
+
11
+ * add async direct cache APIs with cooperative yielding ([0f8e99d](https://github.com/ElJijuna/express-memorize/commit/0f8e99d1f20d933196ccdd2726c8e607b606e40e))
12
+ * add batched cache operations and byte-size limits ([8ec1000](https://github.com/ElJijuna/express-memorize/commit/8ec1000ccb409cfc71c5857d541ebda829af8449))
13
+ * add worker-backed async serialization ([1dd1883](https://github.com/ElJijuna/express-memorize/commit/1dd18838c9643989d99c753a07b1d77ae8b25f68))
14
+
15
+
16
+ ### Performance Improvements
17
+
18
+ * batch lazy ttl expiry cleanup ([92e6d68](https://github.com/ElJijuna/express-memorize/commit/92e6d682352693fd14c703cd9a878cb74bb3ea06))
19
+ * optimize ttl scheduler reprogramming ([c51aadc](https://github.com/ElJijuna/express-memorize/commit/c51aadc0c39afda7fe1cfe69fd4794e31b0d91fc))
20
+ * replace per-entry ttl timers with shared scheduler ([df9f9d4](https://github.com/ElJijuna/express-memorize/commit/df9f9d4baf937270d855f0ba1fc71367bdd5c5cc))
21
+
1
22
  # [2.3.0](https://github.com/ElJijuna/express-memorize/compare/v2.2.0...v2.3.0) (2026-05-18)
2
23
 
3
24
 
package/README.md CHANGED
@@ -181,11 +181,55 @@ const cache = memorize({ ttl: 60_000 });
181
181
  // Compute-and-cache pattern
182
182
  const users = await cache.remember('users:list', () => usersService.findAll());
183
183
 
184
+ // Per-call TTL
185
+ const user = await cache.remember(
186
+ `users:${id}`,
187
+ () => usersService.findById(id),
188
+ 10_000
189
+ );
190
+
191
+ // Concurrent calls for the same key share one in-flight factory
192
+ const [featuredA, featuredB] = await Promise.all([
193
+ cache.remember('users:featured', () => usersService.findFeatured()),
194
+ cache.remember('users:featured', () => usersService.findFeatured()),
195
+ ]);
196
+
197
+ // Async direct-cache variant: yields around serialization/deserialization
198
+ const stats = await cache.rememberAsync(
199
+ 'reports:daily-stats',
200
+ () => reportsService.dailyStats(),
201
+ 30_000
202
+ );
203
+
184
204
  // Explicit set/get
185
205
  cache.set('config', appConfig);
186
206
  const config = cache.getValue<AppConfig>('config');
187
207
  ```
188
208
 
209
+ Inside an Express route:
210
+
211
+ ```typescript
212
+ import express from 'express';
213
+ import { memorize } from 'express-memorize';
214
+
215
+ const app = express();
216
+ const cache = memorize({ ttl: 60_000 });
217
+
218
+ app.get('/users/:id', async (req, res, next) => {
219
+ try {
220
+ const user = await cache.remember(
221
+ `users:${req.params.id}`,
222
+ () => usersService.findById(req.params.id),
223
+ 10_000
224
+ );
225
+
226
+ res.json(user);
227
+ } catch (err) {
228
+ next(err);
229
+ }
230
+ });
231
+ ```
232
+
189
233
  ### Serializer
190
234
 
191
235
  The `serializer` option controls how values passed to `set()` / `getValue()` / `remember()` are stored internally. It does **not** affect HTTP middleware caching — adapters store response bodies as-is.
@@ -373,6 +417,14 @@ app.put('/users/:id', (req, res) => {
373
417
  });
374
418
  ```
375
419
 
420
+ For large caches, use the async variants to process removals in batches and
421
+ yield back to the event loop between batches:
422
+
423
+ ```typescript
424
+ await cache.deleteMatchingAsync(`**/users/${req.params.id}*`, { batchSize: 500 });
425
+ await cache.clearAsync({ batchSize: 500 });
426
+ ```
427
+
376
428
  **Glob rules:**
377
429
 
378
430
  | Pattern | Behaviour |
@@ -381,12 +433,20 @@ app.put('/users/:id', (req, res) => {
381
433
  | `**` | Matches any sequence across path segments (crosses `/`) |
382
434
  | `?` | Matches any single character except `/` |
383
435
 
384
- ### Bounding memory with `maxEntries`
436
+ ### Bounding memory
385
437
 
386
- Prevent unbounded growth by setting a maximum number of entries. When the limit is reached, the **least-recently-used (LRU)** entry is evicted before the new one is stored.
438
+ Prevent unbounded growth by setting a maximum number of entries or bytes. When
439
+ `maxEntries` or `maxTotalBytes` is reached, the **least-recently-used (LRU)**
440
+ entry is evicted before the new one is stored. Entries larger than
441
+ `maxValueBytes` are skipped by default.
387
442
 
388
443
  ```typescript
389
- const cache = memorize({ ttl: 30_000, maxEntries: 1_000 });
444
+ const cache = memorize({
445
+ ttl: 30_000,
446
+ maxEntries: 1_000,
447
+ maxValueBytes: 256_000,
448
+ maxTotalBytes: 50_000_000,
449
+ });
390
450
  ```
391
451
 
392
452
  ### Size metrics
@@ -394,7 +454,7 @@ const cache = memorize({ ttl: 30_000, maxEntries: 1_000 });
394
454
  ```typescript
395
455
  cache.size(); // number of active entries
396
456
  cache.byteSize(); // approximate total body size in bytes
397
- cache.getStats(); // { entries, maxEntries, byteSize }
457
+ cache.getStats(); // { entries, maxEntries, maxValueBytes, maxTotalBytes, byteSize }
398
458
  ```
399
459
 
400
460
  > `byteSize()` is an estimate based on UTF-8 encoding for strings and `byteLength` for buffers. It may not reflect actual VM memory usage.
@@ -404,6 +464,7 @@ cache.getStats(); // { entries, maxEntries, byteSize }
404
464
  ```typescript
405
465
  cache.get('/users'); // CacheInfo | null
406
466
  cache.getAll(); // Record<string, CacheInfo>
467
+ cache.getAllAsync(); // Promise<Record<string, CacheInfo>>
407
468
  ```
408
469
 
409
470
  `CacheInfo` shape:
@@ -447,6 +508,10 @@ Creates a cache instance. Returns a `Memorize` object.
447
508
  |--------|------|---------|-------------|
448
509
  | `ttl` | `number` | `60_000` | Time-to-live in milliseconds. Pass `Infinity` for no expiry. |
449
510
  | `maxEntries` | `number` | `undefined` | Maximum number of entries. LRU eviction when reached. |
511
+ | `maxValueBytes` | `number` | `undefined` | Maximum serialized byte size for one entry. Oversized entries are skipped by default. |
512
+ | `maxTotalBytes` | `number` | `undefined` | Maximum approximate byte size for the whole cache. LRU eviction when reached. |
513
+ | `sizeLimitAction` | `'skip' \| 'throw'` | `'skip'` | Behavior when one entry exceeds a byte limit. |
514
+ | `asyncSerializer` | `'yield' \| 'worker'` | `'yield'` | Backend for `setAsync` / `getValueAsync` / `rememberAsync`. `'worker'` offloads built-in serializers to `worker_threads`. |
450
515
  | `serializer` | `'auto' \| 'json' \| 'v8' \| Serializer` | `'auto'` | Serializer for `set()` / `getValue()`. `'auto'` uses `node:v8` when available, falls back to JSON. Does not affect HTTP middleware caching. |
451
516
 
452
517
  ### `cache(options?)` / `cache.express(options?)`
@@ -463,8 +528,20 @@ Returns an Express `RequestHandler`. `cache()` is a backwards-compatible alias f
463
528
  | Method | Signature | Description |
464
529
  |--------|-----------|-------------|
465
530
  | `remember` | `(key, factory, ttl?) => Promise<T>` | Return cached value or call factory and cache the result. |
531
+ | `rememberAsync` | `(key, factory, ttl?) => Promise<T>` | Async variant using cooperative yielding around direct-cache serialization. |
466
532
  | `set` | `(key, value, ttl?) => void` | Store an arbitrary value. |
533
+ | `setAsync` | `(key, value, ttl?) => Promise<void>` | Async variant that yields before serializing and storing. |
467
534
  | `getValue` | `(key) => T \| undefined` | Retrieve a value stored via `set` or `remember`. |
535
+ | `getValueAsync` | `(key) => Promise<T \| undefined>` | Async variant that yields before deserializing. |
536
+
537
+ Concurrent `remember()` / `rememberAsync()` calls for the same key are
538
+ coalesced: while one factory is in flight, later calls wait for the same
539
+ promise instead of running the factory again.
540
+
541
+ `setAsync()` guards against stale async writes. If another write or broad
542
+ invalidation (`clear`, `clearAsync`, `deleteMatching`, `deleteMatchingAsync`)
543
+ touches the cache before serialization finishes, the older async write is
544
+ discarded instead of overwriting newer state.
468
545
 
469
546
  ### Cache management
470
547
 
@@ -472,12 +549,15 @@ Returns an Express `RequestHandler`. `cache()` is a backwards-compatible alias f
472
549
  |--------|-----------|-------------|
473
550
  | `get` | `(key) => CacheInfo \| null` | Returns info for a cached key. |
474
551
  | `getAll` | `() => Record<string, CacheInfo>` | Returns all active entries. |
552
+ | `getAllAsync` | `({ batchSize }?) => Promise<Record<string, CacheInfo>>` | Async batched variant of `getAll`. |
475
553
  | `delete` | `(key) => boolean` | Removes a single entry. |
476
554
  | `deleteMatching` | `(pattern) => number` | Removes entries matching a glob pattern. |
555
+ | `deleteMatchingAsync` | `(pattern, { batchSize }?) => Promise<number>` | Async batched variant of `deleteMatching`. |
477
556
  | `clear` | `() => void` | Removes all entries. |
557
+ | `clearAsync` | `({ batchSize }?) => Promise<number>` | Async batched variant of `clear`. |
478
558
  | `size` | `() => number` | Number of active entries. |
479
559
  | `byteSize` | `() => number` | Approximate total body size in bytes. |
480
- | `getStats` | `() => MemorizeStats` | Aggregate stats: `{ entries, maxEntries, byteSize }`. |
560
+ | `getStats` | `() => MemorizeStats` | Aggregate stats: `{ entries, maxEntries, maxValueBytes, maxTotalBytes, byteSize }`. |
481
561
 
482
562
  ### Adapters
483
563
 
@@ -498,7 +578,7 @@ Returns an Express `RequestHandler`. `cache()` is a backwards-compatible alias f
498
578
  | `set` | `{ type, key, body, statusCode, contentType, expiresAt, size }` | A response is stored |
499
579
  | `delete` | `{ type, key }` | Manual removal via `delete`, `deleteMatching`, or `clear` |
500
580
  | `expire` | `{ type, key }` | TTL timer fires or lazy expiry is detected |
501
- | `evict` | `{ type, key }` | LRU eviction due to `maxEntries` limit |
581
+ | `evict` | `{ type, key }` | LRU eviction due to `maxEntries` or `maxTotalBytes` limit |
502
582
  | `empty` | `{ type }` | Last entry removed, cache is now empty |
503
583
 
504
584
  ## Response Headers
@@ -516,6 +596,7 @@ Returns an Express `RequestHandler`. `cache()` is a backwards-compatible alias f
516
596
  - All middleware and adapter instances created from the same `memorize()` call **share the same store**.
517
597
  - Two separate `memorize()` calls produce **independent stores**.
518
598
  - Byte size is an approximation — strings use UTF-8 encoding, objects use `JSON.stringify` length.
599
+ - Async batched inspection/invalidation methods are eventually consistent, not transactional snapshots; other cache operations may interleave between batches.
519
600
 
520
601
  ## License
521
602
 
@@ -8,8 +8,18 @@ import { MemorizeDeleteEvent } from './domain/MemorizeDeleteEvent';
8
8
  import { MemorizeExpireEvent } from './domain/MemorizeExpireEvent';
9
9
  import { MemorizeEmptyEvent } from './domain/MemorizeEmptyEvent';
10
10
  import { MemorizeEvictEvent } from './domain/MemorizeEvictEvent';
11
+ import { MemorizeBatchOptions } from './domain/MemorizeBatchOptions';
11
12
  export type { CacheEntry, CacheInfo, MemorizeStats, MemorizeEvent, MemorizeSetEvent, MemorizeDeleteEvent, MemorizeExpireEvent, MemorizeEmptyEvent, MemorizeEvictEvent, };
12
13
  export { MemorizeEventType };
14
+ interface MemorizeStoreOptions {
15
+ maxEntries?: number;
16
+ maxValueBytes?: number;
17
+ maxTotalBytes?: number;
18
+ sizeLimitAction?: 'skip' | 'throw';
19
+ }
20
+ type StoreEntryInput = Omit<CacheEntry, 'expiresAt' | 'hits' | 'size'> & {
21
+ size?: number;
22
+ };
13
23
  /**
14
24
  * Low-level in-memory key-value store with optional TTL, LRU eviction, and event emission.
15
25
  *
@@ -17,12 +27,17 @@ export { MemorizeEventType };
17
27
  * instead, which wraps this store in an Express middleware.
18
28
  */
19
29
  export declare class MemorizeStore {
20
- private readonly _maxEntries?;
21
30
  private _store;
22
- private _timers;
31
+ private _expiryTimer;
32
+ private _nextExpiryAt;
33
+ private _nextExpiryKey;
23
34
  private _totalByteSize;
24
35
  private _listeners;
25
- constructor(_maxEntries?: number | undefined);
36
+ private readonly _maxEntries?;
37
+ private readonly _maxValueBytes?;
38
+ private readonly _maxTotalBytes?;
39
+ private readonly _sizeLimitAction;
40
+ constructor(maxEntriesOrOptions?: number | MemorizeStoreOptions);
26
41
  /**
27
42
  * Registers an event listener.
28
43
  *
@@ -52,7 +67,7 @@ export declare class MemorizeStore {
52
67
  * @param ttl - Time-to-live in milliseconds. Omit or pass `null` to use the default TTL.
53
68
  * Pass `Infinity` for no expiry.
54
69
  */
55
- set(key: string, entry: Omit<CacheEntry, 'expiresAt' | 'hits' | 'size'>, ttl?: number | null): void;
70
+ set(key: string, entry: StoreEntryInput, ttl?: number | null): void;
56
71
  /**
57
72
  * Returns the formatted {@link CacheInfo} for the given key, or `null` if the
58
73
  * key does not exist or its TTL has elapsed.
@@ -65,6 +80,14 @@ export declare class MemorizeStore {
65
80
  * Expired entries are lazily evicted during this call.
66
81
  */
67
82
  getAll(): Record<string, CacheInfo>;
83
+ /**
84
+ * Async variant of {@link getAll} that yields between batches to reduce
85
+ * event-loop blocking on large stores.
86
+ *
87
+ * @param options - Batch options.
88
+ * @returns All active cache entries keyed by cache key.
89
+ */
90
+ getAllAsync(options?: MemorizeBatchOptions): Promise<Record<string, CacheInfo>>;
68
91
  /**
69
92
  * Removes a single entry from the cache. Emits a {@link MemorizeEventType.Delete} event.
70
93
  *
@@ -85,11 +108,28 @@ export declare class MemorizeStore {
85
108
  * @returns The number of entries removed.
86
109
  */
87
110
  deleteMatching(pattern: string): number;
111
+ /**
112
+ * Async variant of {@link deleteMatching} that yields between batches to
113
+ * reduce event-loop blocking on large stores.
114
+ *
115
+ * @param pattern - Glob pattern to match against cache keys.
116
+ * @param options - Batch options.
117
+ * @returns The number of entries removed.
118
+ */
119
+ deleteMatchingAsync(pattern: string, options?: MemorizeBatchOptions): Promise<number>;
88
120
  /**
89
121
  * Removes all entries from the cache. Emits a {@link MemorizeEventType.Delete} event
90
122
  * for each entry.
91
123
  */
92
124
  clear(): void;
125
+ /**
126
+ * Async variant of {@link clear} that yields between batches to reduce
127
+ * event-loop blocking on large stores.
128
+ *
129
+ * @param options - Batch options.
130
+ * @returns The number of entries removed.
131
+ */
132
+ clearAsync(options?: MemorizeBatchOptions): Promise<number>;
93
133
  /**
94
134
  * Returns the number of active cache entries.
95
135
  */
@@ -114,7 +154,17 @@ export declare class MemorizeStore {
114
154
  */
115
155
  getRaw(key: string): CacheEntry | null;
116
156
  private _evictLRU;
157
+ private _canStoreSize;
158
+ private _removeStoredEntry;
117
159
  private _evict;
160
+ private _scheduleAfterRemoval;
161
+ private _scheduleNextExpiry;
162
+ private _scheduleExpiryFor;
163
+ private _scheduleExpiryAt;
164
+ private _clearExpiryTimer;
165
+ private _findNextExpiry;
166
+ private _evictExpiredEntries;
167
+ private _evictExpiredEntry;
118
168
  private _emit;
119
169
  private _format;
120
170
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MemorizeStore.d.ts","sourceRoot":"","sources":["../src/MemorizeStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MemorizeStore.d.ts","sourceRoot":"","sources":["../src/MemorizeStore.ts"],"names":[],"mappings":"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"}