express-memorize 1.0.0 → 1.3.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 (68) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/LICENSE +21 -0
  3. package/README.md +230 -0
  4. package/dist/MemorizeStore.d.ts +83 -31
  5. package/dist/MemorizeStore.d.ts.map +1 -1
  6. package/dist/MemorizeStore.js +87 -10
  7. package/dist/MemorizeStore.js.map +1 -1
  8. package/dist/domain/CacheEntry.d.ts +14 -0
  9. package/dist/domain/CacheEntry.d.ts.map +1 -0
  10. package/dist/domain/CacheEntry.js +3 -0
  11. package/dist/domain/CacheEntry.js.map +1 -0
  12. package/dist/domain/CacheInfo.d.ts +12 -0
  13. package/dist/domain/CacheInfo.d.ts.map +1 -0
  14. package/dist/domain/CacheInfo.js +3 -0
  15. package/dist/domain/CacheInfo.js.map +1 -0
  16. package/dist/domain/Memorize.d.ts +148 -0
  17. package/dist/domain/Memorize.d.ts.map +1 -0
  18. package/dist/domain/Memorize.js +3 -0
  19. package/dist/domain/Memorize.js.map +1 -0
  20. package/dist/domain/MemorizeCallOptions.d.ts +24 -0
  21. package/dist/domain/MemorizeCallOptions.d.ts.map +1 -0
  22. package/dist/domain/MemorizeCallOptions.js +3 -0
  23. package/dist/domain/MemorizeCallOptions.js.map +1 -0
  24. package/dist/domain/MemorizeDeleteEvent.d.ts +18 -0
  25. package/dist/domain/MemorizeDeleteEvent.d.ts.map +1 -0
  26. package/dist/domain/MemorizeDeleteEvent.js +3 -0
  27. package/dist/domain/MemorizeDeleteEvent.js.map +1 -0
  28. package/dist/domain/MemorizeEmptyEvent.d.ts +16 -0
  29. package/dist/domain/MemorizeEmptyEvent.d.ts.map +1 -0
  30. package/dist/domain/MemorizeEmptyEvent.js +3 -0
  31. package/dist/domain/MemorizeEmptyEvent.js.map +1 -0
  32. package/dist/domain/MemorizeEvent.d.ts +7 -0
  33. package/dist/domain/MemorizeEvent.d.ts.map +1 -0
  34. package/dist/domain/MemorizeEvent.js +3 -0
  35. package/dist/domain/MemorizeEvent.js.map +1 -0
  36. package/dist/domain/MemorizeEventType.d.ts +22 -0
  37. package/dist/domain/MemorizeEventType.d.ts.map +1 -0
  38. package/dist/domain/MemorizeEventType.js +26 -0
  39. package/dist/domain/MemorizeEventType.js.map +1 -0
  40. package/dist/domain/MemorizeExpireEvent.d.ts +17 -0
  41. package/dist/domain/MemorizeExpireEvent.d.ts.map +1 -0
  42. package/dist/domain/MemorizeExpireEvent.js +3 -0
  43. package/dist/domain/MemorizeExpireEvent.js.map +1 -0
  44. package/dist/domain/MemorizeOptions.d.ts +16 -0
  45. package/dist/domain/MemorizeOptions.d.ts.map +1 -0
  46. package/dist/domain/MemorizeOptions.js +3 -0
  47. package/dist/domain/MemorizeOptions.js.map +1 -0
  48. package/dist/domain/MemorizeSetEvent.d.ts +25 -0
  49. package/dist/domain/MemorizeSetEvent.d.ts.map +1 -0
  50. package/dist/domain/MemorizeSetEvent.js +3 -0
  51. package/dist/domain/MemorizeSetEvent.js.map +1 -0
  52. package/dist/domain/index.d.ts +12 -0
  53. package/dist/domain/index.d.ts.map +1 -0
  54. package/dist/domain/index.js +6 -0
  55. package/dist/domain/index.js.map +1 -0
  56. package/dist/index.d.ts +3 -2
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +3 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/memorize.d.ts +51 -18
  61. package/dist/memorize.d.ts.map +1 -1
  62. package/dist/memorize.js +52 -0
  63. package/dist/memorize.js.map +1 -1
  64. package/dist/utils/globToRegex.d.ts +12 -0
  65. package/dist/utils/globToRegex.d.ts.map +1 -0
  66. package/dist/utils/globToRegex.js +41 -0
  67. package/dist/utils/globToRegex.js.map +1 -0
  68. package/package.json +30 -6
@@ -0,0 +1,12 @@
1
+ import { CacheEntry } from './CacheEntry';
2
+ /**
3
+ * A cache entry enriched with lookup metadata, returned by {@link Memorize.get} and
4
+ * {@link Memorize.getAll}.
5
+ */
6
+ export interface CacheInfo extends CacheEntry {
7
+ /** The cache key — the full request path including query string (e.g. `/users?page=1`). */
8
+ key: string;
9
+ /** Milliseconds remaining until the entry expires. `null` if the entry has no TTL. */
10
+ remainingTtl: number | null;
11
+ }
12
+ //# sourceMappingURL=CacheInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheInfo.d.ts","sourceRoot":"","sources":["../../src/domain/CacheInfo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;GAGG;AACH,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,2FAA2F;IAC3F,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=CacheInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheInfo.js","sourceRoot":"","sources":["../../src/domain/CacheInfo.ts"],"names":[],"mappings":""}
@@ -0,0 +1,148 @@
1
+ import { RequestHandler } from 'express';
2
+ import { CacheInfo } from './CacheInfo';
3
+ import { MemorizeCallOptions } from './MemorizeCallOptions';
4
+ import { MemorizeEventType } from './MemorizeEventType';
5
+ import { MemorizeSetEvent } from './MemorizeSetEvent';
6
+ import { MemorizeDeleteEvent } from './MemorizeDeleteEvent';
7
+ import { MemorizeExpireEvent } from './MemorizeExpireEvent';
8
+ import { MemorizeEmptyEvent } from './MemorizeEmptyEvent';
9
+ /**
10
+ * The cache instance returned by {@link memorize}.
11
+ *
12
+ * It is both a callable that produces Express middleware **and** a namespace for
13
+ * cache management methods and event hooks. All middleware created from the same
14
+ * `Memorize` instance share a single underlying store.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const cache = memorize({ ttl: 30_000 });
19
+ *
20
+ * // Per-route middleware
21
+ * app.get('/users', cache(), handler);
22
+ *
23
+ * // Global middleware — caches every GET route automatically
24
+ * app.use(cache());
25
+ *
26
+ * // Cache management
27
+ * cache.delete('/users');
28
+ * cache.clear();
29
+ * ```
30
+ */
31
+ export interface Memorize {
32
+ /**
33
+ * Returns an Express `RequestHandler` that caches `GET` responses with a `2xx`
34
+ * status code.
35
+ *
36
+ * - On a **cache miss** the request proceeds normally. The response is intercepted
37
+ * and stored after being sent. Sets `X-Cache: MISS`.
38
+ * - On a **cache hit** the stored response is returned immediately without calling
39
+ * downstream handlers. Sets `X-Cache: HIT`.
40
+ * - Non-`GET` requests are forwarded to `next()` unchanged.
41
+ *
42
+ * @param options - Optional per-route options (e.g. TTL override).
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * app.get('/users', cache(), handler); // global TTL
47
+ * app.get('/products', cache({ ttl: 5_000 }), handler); // 5-second override
48
+ * app.use(cache()); // global middleware
49
+ * ```
50
+ */
51
+ (options?: MemorizeCallOptions): RequestHandler;
52
+ /**
53
+ * Returns the {@link CacheInfo} for a specific cache key, or `null` if the key
54
+ * does not exist or has expired.
55
+ *
56
+ * @param key - The full request URL used as the cache key (e.g. `/users?page=1`).
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * const info = cache.get('/users');
61
+ * if (info) console.log(`expires in ${info.remainingTtl}ms`);
62
+ * ```
63
+ */
64
+ get(key: string): CacheInfo | null;
65
+ /**
66
+ * Returns all active (non-expired) cache entries as a plain object keyed by URL.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * console.log(Object.keys(cache.getAll())); // ['/users', '/products']
71
+ * ```
72
+ */
73
+ getAll(): Record<string, CacheInfo>;
74
+ /**
75
+ * Removes a single entry from the cache and emits a {@link MemorizeEventType.Delete} event.
76
+ *
77
+ * @param key - The full request URL to invalidate.
78
+ * @returns `true` if the entry existed and was removed, `false` otherwise.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * app.post('/users', (req, res) => {
83
+ * users.push(req.body);
84
+ * cache.delete('/users');
85
+ * res.status(201).json(req.body);
86
+ * });
87
+ * ```
88
+ */
89
+ delete(key: string): boolean;
90
+ /**
91
+ * Removes all cache entries whose keys match the given glob pattern.
92
+ * Emits a {@link MemorizeEventType.Delete} event for each removed entry.
93
+ *
94
+ * Glob rules:
95
+ * - `**` — matches any character sequence **across** path segments (crosses `/`).
96
+ * - `*` — matches any character sequence **within** a single path segment (does not cross `/`).
97
+ * - `?` — matches any single character except `/`.
98
+ *
99
+ * @param pattern - Glob pattern to match against cache keys.
100
+ * @returns The number of entries removed.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * // Invalidate all cached variants of a user regardless of query params.
105
+ * // Build the pattern with join to avoid the closing-comment sequence in source.
106
+ * app.put('/users/:id', (req, res) => {
107
+ * users.update(req.params.id, req.body);
108
+ * const pattern = ['**', 'users', req.params.id + '*'].join('/');
109
+ * cache.deleteMatching(pattern); // e.g. ** /users/abc123* (no space)
110
+ * res.json({ ok: true });
111
+ * });
112
+ * ```
113
+ */
114
+ deleteMatching(pattern: string): number;
115
+ /**
116
+ * Removes **all** entries from the cache and emits a {@link MemorizeEventType.Delete}
117
+ * event for each.
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * cache.clear();
122
+ * ```
123
+ */
124
+ clear(): void;
125
+ /**
126
+ * Registers a listener for cache events.
127
+ *
128
+ * | Event | When |
129
+ * |-------|------|
130
+ * | `MemorizeEventType.Set` | A response is stored |
131
+ * | `MemorizeEventType.Delete` | An entry is removed via `delete()` or `clear()` |
132
+ * | `MemorizeEventType.Expire` | An entry's TTL elapses |
133
+ * | `MemorizeEventType.Empty` | The last entry is removed, cache is now empty |
134
+ *
135
+ * @example
136
+ * ```ts
137
+ * cache.on(MemorizeEventType.Set, (e) => console.log('stored', e.key));
138
+ * cache.on(MemorizeEventType.Delete, (e) => console.log('deleted', e.key));
139
+ * cache.on(MemorizeEventType.Expire, (e) => console.log('expired', e.key));
140
+ * cache.on(MemorizeEventType.Empty, () => console.log('cache is empty'));
141
+ * ```
142
+ */
143
+ on(event: MemorizeEventType.Set, handler: (e: MemorizeSetEvent) => void): void;
144
+ on(event: MemorizeEventType.Delete, handler: (e: MemorizeDeleteEvent) => void): void;
145
+ on(event: MemorizeEventType.Expire, handler: (e: MemorizeExpireEvent) => void): void;
146
+ on(event: MemorizeEventType.Empty, handler: (e: MemorizeEmptyEvent) => void): void;
147
+ }
148
+ //# sourceMappingURL=Memorize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Memorize.d.ts","sourceRoot":"","sources":["../../src/domain/Memorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;;;;;;;;;;;;;OAkBG;IACH,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,cAAc,CAAC;IAEhD;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAEnC;;;;;;;OAOG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAEpC;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAE7B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAExC;;;;;;;;OAQG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;;;;;;;;;;;;;;;;OAiBG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,GAAG,EAAK,OAAO,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAC;IAClF,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAAC;IACrF,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAAC;IACrF,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,EAAG,OAAO,EAAE,CAAC,CAAC,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI,CAAC;CACrF"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=Memorize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Memorize.js","sourceRoot":"","sources":["../../src/domain/Memorize.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Options passed when invoking `cache()` to create a route-level middleware.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * // This route uses a 10-second TTL instead of the global 60-second TTL.
7
+ * app.get('/products', cache({ ttl: 10_000 }), handler);
8
+ * ```
9
+ */
10
+ export interface MemorizeCallOptions {
11
+ /**
12
+ * Time-to-live override for this specific route, in milliseconds.
13
+ * Takes precedence over the global `ttl` set in {@link MemorizeOptions}.
14
+ * Pass `0` or omit to fall back to the global TTL.
15
+ */
16
+ ttl?: number;
17
+ /**
18
+ * When `true`, the middleware skips both reading from and writing to the cache
19
+ * for this route. Useful when a global `app.use(cache())` is in place but a
20
+ * specific route should never be cached.
21
+ */
22
+ noCache?: boolean;
23
+ }
24
+ //# sourceMappingURL=MemorizeCallOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeCallOptions.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeCallOptions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MemorizeCallOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeCallOptions.js","sourceRoot":"","sources":["../../src/domain/MemorizeCallOptions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import { MemorizeEventType } from './MemorizeEventType';
2
+ /**
3
+ * Emitted when a cache entry is manually removed via {@link Memorize.delete} or
4
+ * {@link Memorize.clear}.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * cache.on(MemorizeEventType.Delete, (e) => {
9
+ * console.log(`deleted ${e.key}`);
10
+ * });
11
+ * ```
12
+ */
13
+ export interface MemorizeDeleteEvent {
14
+ type: MemorizeEventType.Delete;
15
+ /** The cache key that was removed. */
16
+ key: string;
17
+ }
18
+ //# sourceMappingURL=MemorizeDeleteEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeDeleteEvent.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeDeleteEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC;IAC/B,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;CACb"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MemorizeDeleteEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeDeleteEvent.js","sourceRoot":"","sources":["../../src/domain/MemorizeDeleteEvent.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import { MemorizeEventType } from './MemorizeEventType';
2
+ /**
3
+ * Emitted when the last entry is removed from the cache, leaving it empty.
4
+ * Triggered after a `delete` or `expire` eviction.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * cache.on(MemorizeEventType.Empty, () => {
9
+ * console.log('cache is now empty');
10
+ * });
11
+ * ```
12
+ */
13
+ export interface MemorizeEmptyEvent {
14
+ type: MemorizeEventType.Empty;
15
+ }
16
+ //# sourceMappingURL=MemorizeEmptyEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeEmptyEvent.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeEmptyEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC;CAC/B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MemorizeEmptyEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeEmptyEvent.js","sourceRoot":"","sources":["../../src/domain/MemorizeEmptyEvent.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import { MemorizeSetEvent } from './MemorizeSetEvent';
2
+ import { MemorizeDeleteEvent } from './MemorizeDeleteEvent';
3
+ import { MemorizeExpireEvent } from './MemorizeExpireEvent';
4
+ import { MemorizeEmptyEvent } from './MemorizeEmptyEvent';
5
+ /** Union of all possible cache events. */
6
+ export type MemorizeEvent = MemorizeSetEvent | MemorizeDeleteEvent | MemorizeExpireEvent | MemorizeEmptyEvent;
7
+ //# sourceMappingURL=MemorizeEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeEvent.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,0CAA0C;AAC1C,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,mBAAmB,GACnB,mBAAmB,GACnB,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MemorizeEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeEvent.js","sourceRoot":"","sources":["../../src/domain/MemorizeEvent.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Enum of all supported cache event types.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * cache.on(MemorizeEventType.Set, (e) => console.log('stored', e.key));
7
+ * cache.on(MemorizeEventType.Delete, (e) => console.log('deleted', e.key));
8
+ * cache.on(MemorizeEventType.Expire, (e) => console.log('expired', e.key));
9
+ * cache.on(MemorizeEventType.Empty, () => console.log('cache is empty'));
10
+ * ```
11
+ */
12
+ export declare enum MemorizeEventType {
13
+ /** Fired when a response is stored in the cache. */
14
+ Set = "set",
15
+ /** Fired when an entry is manually removed via `delete()` or `clear()`. */
16
+ Delete = "delete",
17
+ /** Fired when an entry is automatically removed after its TTL elapses. */
18
+ Expire = "expire",
19
+ /** Fired when the last entry is removed, leaving the cache empty. */
20
+ Empty = "empty"
21
+ }
22
+ //# sourceMappingURL=MemorizeEventType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeEventType.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeEventType.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,oBAAY,iBAAiB;IAC3B,oDAAoD;IACpD,GAAG,QAAQ;IACX,2EAA2E;IAC3E,MAAM,WAAW;IACjB,0EAA0E;IAC1E,MAAM,WAAW;IACjB,qEAAqE;IACrE,KAAK,UAAU;CAChB"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemorizeEventType = void 0;
4
+ /**
5
+ * Enum of all supported cache event types.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * cache.on(MemorizeEventType.Set, (e) => console.log('stored', e.key));
10
+ * cache.on(MemorizeEventType.Delete, (e) => console.log('deleted', e.key));
11
+ * cache.on(MemorizeEventType.Expire, (e) => console.log('expired', e.key));
12
+ * cache.on(MemorizeEventType.Empty, () => console.log('cache is empty'));
13
+ * ```
14
+ */
15
+ var MemorizeEventType;
16
+ (function (MemorizeEventType) {
17
+ /** Fired when a response is stored in the cache. */
18
+ MemorizeEventType["Set"] = "set";
19
+ /** Fired when an entry is manually removed via `delete()` or `clear()`. */
20
+ MemorizeEventType["Delete"] = "delete";
21
+ /** Fired when an entry is automatically removed after its TTL elapses. */
22
+ MemorizeEventType["Expire"] = "expire";
23
+ /** Fired when the last entry is removed, leaving the cache empty. */
24
+ MemorizeEventType["Empty"] = "empty";
25
+ })(MemorizeEventType || (exports.MemorizeEventType = MemorizeEventType = {}));
26
+ //# sourceMappingURL=MemorizeEventType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeEventType.js","sourceRoot":"","sources":["../../src/domain/MemorizeEventType.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;GAUG;AACH,IAAY,iBASX;AATD,WAAY,iBAAiB;IAC3B,oDAAoD;IACpD,gCAAW,CAAA;IACX,2EAA2E;IAC3E,sCAAiB,CAAA;IACjB,0EAA0E;IAC1E,sCAAiB,CAAA;IACjB,qEAAqE;IACrE,oCAAe,CAAA;AACjB,CAAC,EATW,iBAAiB,iCAAjB,iBAAiB,QAS5B"}
@@ -0,0 +1,17 @@
1
+ import { MemorizeEventType } from './MemorizeEventType';
2
+ /**
3
+ * Emitted when a cache entry is automatically removed after its TTL elapses.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * cache.on(MemorizeEventType.Expire, (e) => {
8
+ * console.log(`expired ${e.key}`);
9
+ * });
10
+ * ```
11
+ */
12
+ export interface MemorizeExpireEvent {
13
+ type: MemorizeEventType.Expire;
14
+ /** The cache key that expired. */
15
+ key: string;
16
+ }
17
+ //# sourceMappingURL=MemorizeExpireEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeExpireEvent.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeExpireEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC;IAC/B,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACb"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MemorizeExpireEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeExpireEvent.js","sourceRoot":"","sources":["../../src/domain/MemorizeExpireEvent.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Options passed to the {@link memorize} factory.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * const cache = memorize({ ttl: 60_000 }); // cache entries live for 60 seconds
7
+ * ```
8
+ */
9
+ export interface MemorizeOptions {
10
+ /**
11
+ * Default time-to-live for every cached entry, in milliseconds.
12
+ * Omit to cache indefinitely. Can be overridden per-route via {@link MemorizeCallOptions}.
13
+ */
14
+ ttl?: number;
15
+ }
16
+ //# sourceMappingURL=MemorizeOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeOptions.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeOptions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MemorizeOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeOptions.js","sourceRoot":"","sources":["../../src/domain/MemorizeOptions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import { MemorizeEventType } from './MemorizeEventType';
2
+ /**
3
+ * Emitted when a new response is stored in the cache.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * cache.on(MemorizeEventType.Set, (e) => {
8
+ * console.log(`stored ${e.key} — status ${e.statusCode}`);
9
+ * });
10
+ * ```
11
+ */
12
+ export interface MemorizeSetEvent {
13
+ type: MemorizeEventType.Set;
14
+ /** The cache key (full request URL). */
15
+ key: string;
16
+ /** The stored response body. */
17
+ body: unknown;
18
+ /** HTTP status code of the stored response. */
19
+ statusCode: number;
20
+ /** `Content-Type` header value of the stored response. */
21
+ contentType: string;
22
+ /** Expiry timestamp in ms, or `null` if no TTL was set. */
23
+ expiresAt: number | null;
24
+ }
25
+ //# sourceMappingURL=MemorizeSetEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeSetEvent.d.ts","sourceRoot":"","sources":["../../src/domain/MemorizeSetEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,iBAAiB,CAAC,GAAG,CAAC;IAC5B,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=MemorizeSetEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorizeSetEvent.js","sourceRoot":"","sources":["../../src/domain/MemorizeSetEvent.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ export type { CacheEntry } from './CacheEntry';
2
+ export type { CacheInfo } from './CacheInfo';
3
+ export { MemorizeEventType } from './MemorizeEventType';
4
+ export type { MemorizeEvent } from './MemorizeEvent';
5
+ export type { MemorizeSetEvent } from './MemorizeSetEvent';
6
+ export type { MemorizeDeleteEvent } from './MemorizeDeleteEvent';
7
+ export type { MemorizeExpireEvent } from './MemorizeExpireEvent';
8
+ export type { MemorizeEmptyEvent } from './MemorizeEmptyEvent';
9
+ export type { MemorizeOptions } from './MemorizeOptions';
10
+ export type { MemorizeCallOptions } from './MemorizeCallOptions';
11
+ export type { Memorize } from './Memorize';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemorizeEventType = void 0;
4
+ var MemorizeEventType_1 = require("./MemorizeEventType");
5
+ Object.defineProperty(exports, "MemorizeEventType", { enumerable: true, get: function () { return MemorizeEventType_1.MemorizeEventType; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":";;;AAEA,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { memorize } from './memorize';
2
- export type { MemorizeOptions, MemorizeCallOptions, Memorize } from './memorize';
3
- export type { CacheEntry, CacheInfo, MemorizeEvent, MemorizeEventType, MemorizeSetEvent, MemorizeDeleteEvent, MemorizeExpireEvent, } from './MemorizeStore';
2
+ export type { Memorize, MemorizeOptions, MemorizeCallOptions } from './memorize';
3
+ export { MemorizeEventType } from './domain/MemorizeEventType';
4
+ export type { CacheEntry, CacheInfo, MemorizeEvent, MemorizeSetEvent, MemorizeDeleteEvent, MemorizeExpireEvent, MemorizeEmptyEvent, } from './domain/index';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACjF,YAAY,EACV,UAAU,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EACV,UAAU,EACV,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.memorize = void 0;
3
+ exports.MemorizeEventType = exports.memorize = void 0;
4
4
  var memorize_1 = require("./memorize");
5
5
  Object.defineProperty(exports, "memorize", { enumerable: true, get: function () { return memorize_1.memorize; } });
6
+ var MemorizeEventType_1 = require("./domain/MemorizeEventType");
7
+ Object.defineProperty(exports, "MemorizeEventType", { enumerable: true, get: function () { return MemorizeEventType_1.MemorizeEventType; } });
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AAEjB,gEAA+D;AAAtD,sHAAA,iBAAiB,OAAA"}
@@ -1,20 +1,53 @@
1
- import { RequestHandler } from 'express';
2
- import { CacheInfo, MemorizeSetEvent, MemorizeDeleteEvent, MemorizeExpireEvent } from './MemorizeStore';
3
- export interface MemorizeOptions {
4
- ttl?: number;
5
- }
6
- export interface MemorizeCallOptions {
7
- ttl?: number;
8
- }
9
- export interface Memorize {
10
- (options?: MemorizeCallOptions): RequestHandler;
11
- get(key: string): CacheInfo | null;
12
- getAll(): Record<string, CacheInfo>;
13
- delete(key: string): boolean;
14
- clear(): void;
15
- on(event: 'set', handler: (e: MemorizeSetEvent) => void): void;
16
- on(event: 'delete', handler: (e: MemorizeDeleteEvent) => void): void;
17
- on(event: 'expire', handler: (e: MemorizeExpireEvent) => void): void;
18
- }
1
+ import { Memorize } from './domain/Memorize';
2
+ import { MemorizeOptions } from './domain/MemorizeOptions';
3
+ import { MemorizeCallOptions } from './domain/MemorizeCallOptions';
4
+ export type { Memorize, MemorizeOptions, MemorizeCallOptions };
5
+ /**
6
+ * Creates an in-memory cache for an Express application.
7
+ *
8
+ * Returns a {@link Memorize} instance that can be used as per-route middleware,
9
+ * a global `app.use()` middleware, or a cache management API — all sharing the
10
+ * same underlying store.
11
+ *
12
+ * **Only `GET` requests are cached.** Responses are cached only when the HTTP
13
+ * status code is in the `2xx` range. The cache key is `req.originalUrl`, which
14
+ * includes the query string.
15
+ *
16
+ * @param options - Global configuration for the cache instance.
17
+ *
18
+ * @example Per-route middleware
19
+ * ```ts
20
+ * const cache = memorize({ ttl: 30_000 });
21
+ *
22
+ * app.get('/users', cache(), (req, res) => {
23
+ * res.json({ data: users });
24
+ * });
25
+ * ```
26
+ *
27
+ * @example Global middleware
28
+ * ```ts
29
+ * const cache = memorize({ ttl: 60_000 });
30
+ * app.use(cache()); // caches all GET routes
31
+ * ```
32
+ *
33
+ * @example Cache invalidation
34
+ * ```ts
35
+ * const cache = memorize({ ttl: 30_000 });
36
+ *
37
+ * app.post('/users', (req, res) => {
38
+ * users.push(req.body);
39
+ * cache.delete('/users');
40
+ * res.status(201).json(req.body);
41
+ * });
42
+ * ```
43
+ *
44
+ * @example Event hooks
45
+ * ```ts
46
+ * cache.on(MemorizeEventType.Set, (e) => console.log('stored', e.key));
47
+ * cache.on(MemorizeEventType.Delete, (e) => console.log('deleted', e.key));
48
+ * cache.on(MemorizeEventType.Expire, (e) => console.log('expired', e.key));
49
+ * cache.on(MemorizeEventType.Empty, () => console.log('cache is empty'));
50
+ * ```
51
+ */
19
52
  export declare function memorize(options?: MemorizeOptions): Memorize;
20
53
  //# sourceMappingURL=memorize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memorize.d.ts","sourceRoot":"","sources":["../src/memorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAEL,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,cAAc,CAAC;IAChD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACnC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,KAAK,IAAI,IAAI,CAAC;IACd,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/D,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAAC;IACrE,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAAC;CACtE;AAED,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAwChE"}
1
+ {"version":3,"file":"memorize.d.ts","sourceRoot":"","sources":["../src/memorize.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CA8ChE"}