express-memorize 1.4.0 → 1.5.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 (57) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +205 -82
  3. package/dist/MemorizeStore.d.ts +31 -8
  4. package/dist/MemorizeStore.d.ts.map +1 -1
  5. package/dist/MemorizeStore.js +98 -14
  6. package/dist/MemorizeStore.js.map +1 -1
  7. package/dist/adapters/express.d.ts +25 -0
  8. package/dist/adapters/express.d.ts.map +1 -0
  9. package/dist/adapters/express.js +62 -0
  10. package/dist/adapters/express.js.map +1 -0
  11. package/dist/adapters/fetch.d.ts +45 -0
  12. package/dist/adapters/fetch.d.ts.map +1 -0
  13. package/dist/adapters/fetch.js +72 -0
  14. package/dist/adapters/fetch.js.map +1 -0
  15. package/dist/adapters/hono.d.ts +34 -0
  16. package/dist/adapters/hono.d.ts.map +1 -0
  17. package/dist/adapters/hono.js +63 -0
  18. package/dist/adapters/hono.js.map +1 -0
  19. package/dist/adapters/nestjs.d.ts +84 -0
  20. package/dist/adapters/nestjs.d.ts.map +1 -0
  21. package/dist/adapters/nestjs.js +194 -0
  22. package/dist/adapters/nestjs.js.map +1 -0
  23. package/dist/domain/CacheEntry.d.ts +3 -1
  24. package/dist/domain/CacheEntry.d.ts.map +1 -1
  25. package/dist/domain/CacheInfo.d.ts +1 -1
  26. package/dist/domain/CacheInfo.d.ts.map +1 -1
  27. package/dist/domain/Memorize.d.ts +99 -4
  28. package/dist/domain/Memorize.d.ts.map +1 -1
  29. package/dist/domain/MemorizeCallOptions.d.ts +2 -1
  30. package/dist/domain/MemorizeCallOptions.d.ts.map +1 -1
  31. package/dist/domain/MemorizeEvent.d.ts +2 -1
  32. package/dist/domain/MemorizeEvent.d.ts.map +1 -1
  33. package/dist/domain/MemorizeEventType.d.ts +3 -1
  34. package/dist/domain/MemorizeEventType.d.ts.map +1 -1
  35. package/dist/domain/MemorizeEventType.js +2 -0
  36. package/dist/domain/MemorizeEventType.js.map +1 -1
  37. package/dist/domain/MemorizeEvictEvent.d.ts +18 -0
  38. package/dist/domain/MemorizeEvictEvent.d.ts.map +1 -0
  39. package/dist/domain/MemorizeEvictEvent.js +3 -0
  40. package/dist/domain/MemorizeEvictEvent.js.map +1 -0
  41. package/dist/domain/MemorizeOptions.d.ts +14 -1
  42. package/dist/domain/MemorizeOptions.d.ts.map +1 -1
  43. package/dist/domain/MemorizeSetEvent.d.ts +3 -1
  44. package/dist/domain/MemorizeSetEvent.d.ts.map +1 -1
  45. package/dist/domain/MemorizeStats.d.ts +12 -0
  46. package/dist/domain/MemorizeStats.d.ts.map +1 -0
  47. package/dist/domain/MemorizeStats.js +3 -0
  48. package/dist/domain/MemorizeStats.js.map +1 -0
  49. package/dist/domain/index.d.ts +2 -0
  50. package/dist/domain/index.d.ts.map +1 -1
  51. package/dist/index.d.ts +1 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/memorize.d.ts +19 -16
  54. package/dist/memorize.d.ts.map +1 -1
  55. package/dist/memorize.js +51 -50
  56. package/dist/memorize.js.map +1 -1
  57. package/package.json +50 -12
@@ -4,21 +4,55 @@ exports.MemorizeStore = exports.MemorizeEventType = void 0;
4
4
  const globToRegex_1 = require("./utils/globToRegex");
5
5
  const MemorizeEventType_1 = require("./domain/MemorizeEventType");
6
6
  Object.defineProperty(exports, "MemorizeEventType", { enumerable: true, get: function () { return MemorizeEventType_1.MemorizeEventType; } });
7
+ const DEFAULT_TTL = 60000;
8
+ function estimateByteSize(value) {
9
+ var _a;
10
+ if (typeof value === 'string')
11
+ return Buffer.byteLength(value);
12
+ if (Buffer.isBuffer(value))
13
+ return value.byteLength;
14
+ if (value instanceof ArrayBuffer)
15
+ return value.byteLength;
16
+ if (ArrayBuffer.isView(value))
17
+ return value.byteLength;
18
+ try {
19
+ return Buffer.byteLength((_a = JSON.stringify(value)) !== null && _a !== void 0 ? _a : '');
20
+ }
21
+ catch (_b) {
22
+ return 0;
23
+ }
24
+ }
25
+ function normalizeTtl(ttl) {
26
+ if (ttl === Infinity) {
27
+ return { expiresAt: null, timerTtl: null };
28
+ }
29
+ const effectiveTtl = ttl !== null && ttl !== void 0 ? ttl : DEFAULT_TTL;
30
+ if (typeof effectiveTtl !== 'number' || Number.isNaN(effectiveTtl) || !Number.isFinite(effectiveTtl)) {
31
+ throw new TypeError('ttl must be a finite number or Infinity');
32
+ }
33
+ if (effectiveTtl < 0) {
34
+ throw new RangeError('ttl must be greater than or equal to 0');
35
+ }
36
+ return { expiresAt: Date.now() + effectiveTtl, timerTtl: effectiveTtl };
37
+ }
7
38
  /**
8
- * Low-level in-memory key-value store with optional TTL and event emission.
39
+ * Low-level in-memory key-value store with optional TTL, LRU eviction, and event emission.
9
40
  *
10
41
  * You do not usually interact with this class directly — use the {@link memorize} factory
11
42
  * instead, which wraps this store in an Express middleware.
12
43
  */
13
44
  class MemorizeStore {
14
- constructor() {
45
+ constructor(_maxEntries) {
46
+ this._maxEntries = _maxEntries;
15
47
  this._store = new Map();
16
48
  this._timers = new Map();
49
+ this._totalByteSize = 0;
17
50
  this._listeners = {
18
51
  [MemorizeEventType_1.MemorizeEventType.Set]: [],
19
52
  [MemorizeEventType_1.MemorizeEventType.Delete]: [],
20
53
  [MemorizeEventType_1.MemorizeEventType.Expire]: [],
21
54
  [MemorizeEventType_1.MemorizeEventType.Empty]: [],
55
+ [MemorizeEventType_1.MemorizeEventType.Evict]: [],
22
56
  };
23
57
  }
24
58
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -29,25 +63,36 @@ class MemorizeStore {
29
63
  * Stores an entry in the cache.
30
64
  *
31
65
  * If an entry already exists for the given key its TTL timer is reset and the
32
- * value is overwritten. Emits a {@link MemorizeEventType.Set} event.
66
+ * value is overwritten. If `maxEntries` is configured and the store is full,
67
+ * the least-recently-used entry is evicted first. Emits a {@link MemorizeEventType.Set} event.
33
68
  *
34
69
  * @param key - The cache key (typically `req.originalUrl`).
35
70
  * @param entry - The response data to store.
36
- * @param ttl - Time-to-live in milliseconds. Omit or pass `null` for no expiry.
71
+ * @param ttl - Time-to-live in milliseconds. Omit or pass `null` to use the default TTL.
72
+ * Pass `Infinity` for no expiry.
37
73
  */
38
74
  set(key, entry, ttl) {
75
+ if (this._maxEntries && !this._store.has(key) && this._store.size >= this._maxEntries) {
76
+ this._evictLRU();
77
+ }
39
78
  if (this._timers.has(key)) {
40
79
  clearTimeout(this._timers.get(key));
41
80
  this._timers.delete(key);
42
81
  }
43
- const expiresAt = ttl ? Date.now() + ttl : null;
44
- const stored = { ...entry, expiresAt, hits: 1 };
82
+ const existing = this._store.get(key);
83
+ if (existing) {
84
+ this._totalByteSize -= existing.size;
85
+ }
86
+ const { expiresAt, timerTtl } = normalizeTtl(ttl);
87
+ const size = estimateByteSize(entry.body);
88
+ const stored = { ...entry, expiresAt, hits: 1, size };
45
89
  this._store.set(key, stored);
46
- this._emit(MemorizeEventType_1.MemorizeEventType.Set, { type: MemorizeEventType_1.MemorizeEventType.Set, key, ...entry, expiresAt });
47
- if (ttl) {
90
+ this._totalByteSize += size;
91
+ this._emit(MemorizeEventType_1.MemorizeEventType.Set, { type: MemorizeEventType_1.MemorizeEventType.Set, key, ...entry, expiresAt, size });
92
+ if (timerTtl !== null) {
48
93
  const timer = setTimeout(() => {
49
94
  this._evict(key, MemorizeEventType_1.MemorizeEventType.Expire);
50
- }, ttl);
95
+ }, timerTtl);
51
96
  if (typeof timer === 'object' && 'unref' in timer)
52
97
  timer.unref();
53
98
  this._timers.set(key, timer);
@@ -63,7 +108,7 @@ class MemorizeStore {
63
108
  const entry = this._store.get(key);
64
109
  if (!entry)
65
110
  return null;
66
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
111
+ if (entry.expiresAt && Date.now() >= entry.expiresAt) {
67
112
  this._evict(key, MemorizeEventType_1.MemorizeEventType.Expire);
68
113
  return null;
69
114
  }
@@ -76,7 +121,7 @@ class MemorizeStore {
76
121
  getAll() {
77
122
  const result = {};
78
123
  for (const [key, entry] of this._store) {
79
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
124
+ if (entry.expiresAt && Date.now() >= entry.expiresAt) {
80
125
  this._evict(key, MemorizeEventType_1.MemorizeEventType.Expire);
81
126
  continue;
82
127
  }
@@ -124,14 +169,39 @@ class MemorizeStore {
124
169
  * for each entry.
125
170
  */
126
171
  clear() {
127
- for (const key of this._store.keys()) {
172
+ for (const key of [...this._store.keys()]) {
128
173
  this._evict(key, MemorizeEventType_1.MemorizeEventType.Delete);
129
174
  }
130
175
  }
176
+ /**
177
+ * Returns the number of active cache entries.
178
+ */
179
+ size() {
180
+ return this._store.size;
181
+ }
182
+ /**
183
+ * Returns the approximate total byte size of all cached bodies.
184
+ *
185
+ * The value is an estimate and may not reflect actual memory usage.
186
+ */
187
+ byteSize() {
188
+ return this._totalByteSize;
189
+ }
190
+ /**
191
+ * Returns aggregate cache statistics.
192
+ */
193
+ getStats() {
194
+ var _a;
195
+ return {
196
+ entries: this._store.size,
197
+ maxEntries: (_a = this._maxEntries) !== null && _a !== void 0 ? _a : null,
198
+ byteSize: this._totalByteSize,
199
+ };
200
+ }
131
201
  /**
132
202
  * Returns the raw {@link CacheEntry} for the given key without formatting metadata,
133
203
  * or `null` if the entry is missing or expired. Used internally by the middleware
134
- * to serve cached responses.
204
+ * to serve cached responses. Updates LRU order and increments the hit counter.
135
205
  *
136
206
  * @param key - The cache key to look up.
137
207
  * @internal
@@ -140,18 +210,31 @@ class MemorizeStore {
140
210
  const entry = this._store.get(key);
141
211
  if (!entry)
142
212
  return null;
143
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
213
+ if (entry.expiresAt && Date.now() >= entry.expiresAt) {
144
214
  this._evict(key, MemorizeEventType_1.MemorizeEventType.Expire);
145
215
  return null;
146
216
  }
217
+ // Move to most-recently-used position for LRU eviction
218
+ this._store.delete(key);
219
+ this._store.set(key, entry);
147
220
  entry.hits++;
148
221
  return entry;
149
222
  }
223
+ _evictLRU() {
224
+ const firstKey = this._store.keys().next().value;
225
+ if (firstKey !== undefined) {
226
+ this._evict(firstKey, MemorizeEventType_1.MemorizeEventType.Evict);
227
+ }
228
+ }
150
229
  _evict(key, reason) {
151
230
  if (this._timers.has(key)) {
152
231
  clearTimeout(this._timers.get(key));
153
232
  this._timers.delete(key);
154
233
  }
234
+ const entry = this._store.get(key);
235
+ if (entry) {
236
+ this._totalByteSize = Math.max(0, this._totalByteSize - entry.size);
237
+ }
155
238
  this._store.delete(key);
156
239
  this._emit(reason, { type: reason, key });
157
240
  if (this._store.size === 0) {
@@ -171,6 +254,7 @@ class MemorizeStore {
171
254
  contentType: entry.contentType,
172
255
  expiresAt: entry.expiresAt,
173
256
  hits: entry.hits,
257
+ size: entry.size,
174
258
  remainingTtl: entry.expiresAt ? Math.max(0, entry.expiresAt - Date.now()) : null,
175
259
  };
176
260
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MemorizeStore.js","sourceRoot":"","sources":["../src/MemorizeStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MemorizeStore.js","sourceRoot":"","sources":["../src/MemorizeStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { RequestHandler } from 'express';
2
+ import type { Memorize } from '../domain/Memorize';
3
+ import { MemorizeStore } from '../MemorizeStore';
4
+ import { MemorizeCallOptions } from '../domain/MemorizeCallOptions';
5
+ /**
6
+ * Creates an Express `RequestHandler` that caches `GET` responses using the
7
+ * provided {@link Memorize} instance.
8
+ *
9
+ * Import from `express-memorize/express` when you need the adapter directly,
10
+ * without going through the `memorize()` factory.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { memorize } from 'express-memorize';
15
+ * import { createExpressAdapter } from 'express-memorize/express';
16
+ *
17
+ * const cache = memorize({ ttl: 30_000 });
18
+ * app.get('/users', createExpressAdapter(cache), handler);
19
+ * app.get('/products', createExpressAdapter(cache, { ttl: 5_000 }), handler);
20
+ * ```
21
+ */
22
+ export declare function createExpressAdapter(cache: Memorize, options?: MemorizeCallOptions): RequestHandler;
23
+ /** @internal Used by the memorize() factory. */
24
+ export declare function createExpressMiddleware(store: MemorizeStore, globalTtl?: number): (callOptions?: MemorizeCallOptions) => RequestHandler;
25
+ //# sourceMappingURL=express.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,EACf,OAAO,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CAEhB;AAED,gDAAgD;AAChD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,aAAa,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,CAAC,WAAW,CAAC,EAAE,mBAAmB,KAAK,cAAc,CAwCvD"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createExpressAdapter = createExpressAdapter;
4
+ exports.createExpressMiddleware = createExpressMiddleware;
5
+ /**
6
+ * Creates an Express `RequestHandler` that caches `GET` responses using the
7
+ * provided {@link Memorize} instance.
8
+ *
9
+ * Import from `express-memorize/express` when you need the adapter directly,
10
+ * without going through the `memorize()` factory.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { memorize } from 'express-memorize';
15
+ * import { createExpressAdapter } from 'express-memorize/express';
16
+ *
17
+ * const cache = memorize({ ttl: 30_000 });
18
+ * app.get('/users', createExpressAdapter(cache), handler);
19
+ * app.get('/products', createExpressAdapter(cache, { ttl: 5_000 }), handler);
20
+ * ```
21
+ */
22
+ function createExpressAdapter(cache, options) {
23
+ return cache.express(options);
24
+ }
25
+ /** @internal Used by the memorize() factory. */
26
+ function createExpressMiddleware(store, globalTtl) {
27
+ return function (callOptions) {
28
+ var _a;
29
+ const effectiveTtl = (_a = callOptions === null || callOptions === void 0 ? void 0 : callOptions.ttl) !== null && _a !== void 0 ? _a : globalTtl;
30
+ return function (req, res, next) {
31
+ if (req.method !== 'GET') {
32
+ next();
33
+ return;
34
+ }
35
+ if (callOptions === null || callOptions === void 0 ? void 0 : callOptions.noCache) {
36
+ res.setHeader('X-Cache', 'BYPASS');
37
+ next();
38
+ return;
39
+ }
40
+ const key = req.originalUrl;
41
+ const cached = store.getRaw(key);
42
+ if (cached) {
43
+ res.setHeader('X-Cache', 'HIT');
44
+ res.setHeader('Content-Type', cached.contentType);
45
+ res.status(cached.statusCode).send(cached.body);
46
+ return;
47
+ }
48
+ const originalSend = res.send.bind(res);
49
+ res.send = function (body) {
50
+ var _a;
51
+ if (res.statusCode >= 200 && res.statusCode < 300) {
52
+ const contentType = (_a = res.getHeader('Content-Type')) !== null && _a !== void 0 ? _a : 'application/octet-stream';
53
+ store.set(key, { body, statusCode: res.statusCode, contentType }, effectiveTtl);
54
+ }
55
+ res.setHeader('X-Cache', 'MISS');
56
+ return originalSend(body);
57
+ };
58
+ next();
59
+ };
60
+ };
61
+ }
62
+ //# sourceMappingURL=express.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":";;AAsBA,oDAKC;AAGD,0DA2CC;AApED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,oBAAoB,CAClC,KAAe,EACf,OAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,gDAAgD;AAChD,SAAgB,uBAAuB,CACrC,KAAoB,EACpB,SAAkB;IAElB,OAAO,UAAU,WAAiC;;QAChD,MAAM,YAAY,GAAG,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,GAAG,mCAAI,SAAS,CAAC;QAEnD,OAAO,UAAU,GAAY,EAAE,GAAa,EAAE,IAAkB;YAC9D,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBACzB,IAAI,EAAE,CAAC;gBACP,OAAO;YACT,CAAC;YAED,IAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,EAAE,CAAC;gBACzB,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACnC,IAAI,EAAE,CAAC;gBACP,OAAO;YACT,CAAC;YAED,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEjC,IAAI,MAAM,EAAE,CAAC;gBACX,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;gBAChC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;gBAClD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YAED,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAiC,CAAC;YAExE,GAAG,CAAC,IAAI,GAAG,UAAU,IAAc;;gBACjC,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;oBAClD,MAAM,WAAW,GAAG,MAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAY,mCAAI,0BAA0B,CAAC;oBAC5F,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,YAAY,CAAC,CAAC;gBAClF,CAAC;gBACD,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBACjC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC,CAAC;YAEF,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { Memorize } from '../domain/Memorize';
2
+ type FetchHandler = (request: Request) => Promise<Response>;
3
+ export interface FetchAdapterOptions {
4
+ /** Time-to-live in milliseconds. Defaults to the global TTL. */
5
+ ttl?: number;
6
+ /** Skip caching. Sets `X-Cache: BYPASS`. */
7
+ noCache?: boolean;
8
+ /** Custom cache key extractor. Defaults to `pathname + search`. */
9
+ key?: (request: Request) => string;
10
+ }
11
+ /**
12
+ * Wraps a Fetch API handler with in-memory caching for `GET` requests with
13
+ * `2xx` responses.
14
+ *
15
+ * Works in any runtime that supports the Web-standard `Request` and `Response`
16
+ * APIs: Node.js, Bun, Deno, Cloudflare Workers, and similar environments.
17
+ *
18
+ * @param cache - The {@link Memorize} instance to use as the backing store.
19
+ * @param handler - The original fetch handler to wrap.
20
+ * @param options - Optional per-handler options.
21
+ *
22
+ * @example Serverless handler
23
+ * ```ts
24
+ * import { memorize } from 'express-memorize';
25
+ * import { cacheFetchHandler } from 'express-memorize/fetch';
26
+ *
27
+ * const cache = memorize({ ttl: 30_000 });
28
+ *
29
+ * export default cacheFetchHandler(cache, async (request) => {
30
+ * const users = await usersService.findAll();
31
+ * return Response.json(users);
32
+ * });
33
+ * ```
34
+ *
35
+ * @example With options
36
+ * ```ts
37
+ * const handler = cacheFetchHandler(cache, originalHandler, {
38
+ * ttl: 60_000,
39
+ * key: (req) => new URL(req.url).pathname,
40
+ * });
41
+ * ```
42
+ */
43
+ export declare function cacheFetchHandler(cache: Memorize, handler: FetchHandler, options?: FetchAdapterOptions): FetchHandler;
44
+ export {};
45
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/adapters/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,KAAK,YAAY,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE5D,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,YAAY,CAyCd"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cacheFetchHandler = cacheFetchHandler;
4
+ /**
5
+ * Wraps a Fetch API handler with in-memory caching for `GET` requests with
6
+ * `2xx` responses.
7
+ *
8
+ * Works in any runtime that supports the Web-standard `Request` and `Response`
9
+ * APIs: Node.js, Bun, Deno, Cloudflare Workers, and similar environments.
10
+ *
11
+ * @param cache - The {@link Memorize} instance to use as the backing store.
12
+ * @param handler - The original fetch handler to wrap.
13
+ * @param options - Optional per-handler options.
14
+ *
15
+ * @example Serverless handler
16
+ * ```ts
17
+ * import { memorize } from 'express-memorize';
18
+ * import { cacheFetchHandler } from 'express-memorize/fetch';
19
+ *
20
+ * const cache = memorize({ ttl: 30_000 });
21
+ *
22
+ * export default cacheFetchHandler(cache, async (request) => {
23
+ * const users = await usersService.findAll();
24
+ * return Response.json(users);
25
+ * });
26
+ * ```
27
+ *
28
+ * @example With options
29
+ * ```ts
30
+ * const handler = cacheFetchHandler(cache, originalHandler, {
31
+ * ttl: 60_000,
32
+ * key: (req) => new URL(req.url).pathname,
33
+ * });
34
+ * ```
35
+ */
36
+ function cacheFetchHandler(cache, handler, options) {
37
+ return async (request) => {
38
+ var _a;
39
+ if (request.method !== 'GET') {
40
+ return handler(request);
41
+ }
42
+ if (options === null || options === void 0 ? void 0 : options.noCache) {
43
+ const response = await handler(request);
44
+ const headers = new Headers(response.headers);
45
+ headers.set('X-Cache', 'BYPASS');
46
+ return new Response(response.body, { status: response.status, headers });
47
+ }
48
+ const { pathname, search } = new URL(request.url);
49
+ const key = (options === null || options === void 0 ? void 0 : options.key) ? options.key(request) : pathname + search;
50
+ const cached = cache._store.getRaw(key);
51
+ if (cached) {
52
+ return new Response(cached.body, {
53
+ status: cached.statusCode,
54
+ headers: {
55
+ 'Content-Type': cached.contentType,
56
+ 'X-Cache': 'HIT',
57
+ },
58
+ });
59
+ }
60
+ const response = await handler(request);
61
+ if (response.status >= 200 && response.status < 300) {
62
+ const body = await response.clone().text();
63
+ const contentType = (_a = response.headers.get('Content-Type')) !== null && _a !== void 0 ? _a : 'application/octet-stream';
64
+ cache._store.set(key, { body, statusCode: response.status, contentType }, options === null || options === void 0 ? void 0 : options.ttl);
65
+ const headers = new Headers(response.headers);
66
+ headers.set('X-Cache', 'MISS');
67
+ return new Response(body, { status: response.status, headers });
68
+ }
69
+ return response;
70
+ };
71
+ }
72
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/adapters/fetch.ts"],"names":[],"mappings":";;AA6CA,8CA6CC;AA7ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,SAAgB,iBAAiB,CAC/B,KAAe,EACf,OAAqB,EACrB,OAA6B;IAE7B,OAAO,KAAK,EAAE,OAAgB,EAAqB,EAAE;;QACnD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;QAED,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACjC,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,EAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC;QACpE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAExC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAc,EAAE;gBACzC,MAAM,EAAE,MAAM,CAAC,UAAU;gBACzB,OAAO,EAAE;oBACP,cAAc,EAAE,MAAM,CAAC,WAAW;oBAClC,SAAS,EAAE,KAAK;iBACjB;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QAExC,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;YAC3C,MAAM,WAAW,GAAG,MAAA,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,mCAAI,0BAA0B,CAAC;YACvF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,CAAC,CAAC;YAExF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC/B,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAClE,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { Context, MiddlewareHandler } from 'hono';
2
+ import type { Memorize } from '../domain/Memorize';
3
+ export interface HonoCallOptions {
4
+ /** Time-to-live in milliseconds. Defaults to the global TTL. */
5
+ ttl?: number;
6
+ /** Skip caching for this route. Sets `X-Cache: BYPASS`. */
7
+ noCache?: boolean;
8
+ /** Custom cache key extractor. Defaults to `c.req.url`. */
9
+ key?: (c: Context) => string;
10
+ }
11
+ /**
12
+ * Creates a Hono middleware that caches `GET` responses with a `2xx` status code.
13
+ *
14
+ * Requires `hono` to be installed as a peer dependency.
15
+ *
16
+ * @param cache - The {@link Memorize} instance to use as the backing store.
17
+ * @param options - Optional per-route options.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { Hono } from 'hono';
22
+ * import { memorize } from 'express-memorize';
23
+ * import { createHonoMiddleware } from 'express-memorize/hono';
24
+ *
25
+ * const app = new Hono();
26
+ * const cache = memorize({ ttl: 30_000 });
27
+ *
28
+ * app.get('/users', createHonoMiddleware(cache), async (c) => {
29
+ * return c.json(await usersService.findAll());
30
+ * });
31
+ * ```
32
+ */
33
+ export declare function createHonoMiddleware(cache: Memorize, options?: HonoCallOptions): MiddlewareHandler;
34
+ //# sourceMappingURL=hono.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../src/adapters/hono.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAQ,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,iBAAiB,CA0ClG"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHonoMiddleware = createHonoMiddleware;
4
+ /**
5
+ * Creates a Hono middleware that caches `GET` responses with a `2xx` status code.
6
+ *
7
+ * Requires `hono` to be installed as a peer dependency.
8
+ *
9
+ * @param cache - The {@link Memorize} instance to use as the backing store.
10
+ * @param options - Optional per-route options.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { Hono } from 'hono';
15
+ * import { memorize } from 'express-memorize';
16
+ * import { createHonoMiddleware } from 'express-memorize/hono';
17
+ *
18
+ * const app = new Hono();
19
+ * const cache = memorize({ ttl: 30_000 });
20
+ *
21
+ * app.get('/users', createHonoMiddleware(cache), async (c) => {
22
+ * return c.json(await usersService.findAll());
23
+ * });
24
+ * ```
25
+ */
26
+ function createHonoMiddleware(cache, options) {
27
+ return async (c, next) => {
28
+ var _a;
29
+ if (c.req.method !== 'GET') {
30
+ return next();
31
+ }
32
+ if (options === null || options === void 0 ? void 0 : options.noCache) {
33
+ await next();
34
+ const headers = new Headers(c.res.headers);
35
+ headers.set('X-Cache', 'BYPASS');
36
+ c.res = new Response(c.res.body, { status: c.res.status, headers });
37
+ return;
38
+ }
39
+ const { pathname, search } = new URL(c.req.url);
40
+ const key = (options === null || options === void 0 ? void 0 : options.key) ? options.key(c) : pathname + search;
41
+ const cached = cache._store.getRaw(key);
42
+ if (cached) {
43
+ return new Response(cached.body, {
44
+ status: cached.statusCode,
45
+ headers: {
46
+ 'Content-Type': cached.contentType,
47
+ 'X-Cache': 'HIT',
48
+ },
49
+ });
50
+ }
51
+ await next();
52
+ const { status } = c.res;
53
+ if (status >= 200 && status < 300) {
54
+ const body = await c.res.clone().text();
55
+ const contentType = (_a = c.res.headers.get('Content-Type')) !== null && _a !== void 0 ? _a : 'application/octet-stream';
56
+ cache._store.set(key, { body, statusCode: status, contentType }, options === null || options === void 0 ? void 0 : options.ttl);
57
+ const headers = new Headers(c.res.headers);
58
+ headers.set('X-Cache', 'MISS');
59
+ c.res = new Response(body, { status, headers });
60
+ }
61
+ };
62
+ }
63
+ //# sourceMappingURL=hono.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono.js","sourceRoot":"","sources":["../../src/adapters/hono.ts"],"names":[],"mappings":";;AAkCA,oDA0CC;AAhED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,oBAAoB,CAAC,KAAe,EAAE,OAAyB;IAC7E,OAAO,KAAK,EAAE,CAAU,EAAE,IAAU,EAAE,EAAE;;QACtC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACjC,CAAC,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,EAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC;QAC9D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAExC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAc,EAAE;gBACzC,MAAM,EAAE,MAAM,CAAC,UAAU;gBACzB,OAAO,EAAE;oBACP,cAAc,EAAE,MAAM,CAAC,WAAW;oBAClC,SAAS,EAAE,KAAK;iBACjB;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,EAAE,CAAC;QAEb,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC;QAEzB,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,MAAA,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,mCAAI,0BAA0B,CAAC;YACpF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,CAAC,CAAC;YAE/E,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC/B,CAAC,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,84 @@
1
+ import type { Memorize } from '../domain/Memorize';
2
+ import type { MemorizeOptions } from '../domain/MemorizeOptions';
3
+ export declare const MEMORIZE_CACHE: unique symbol;
4
+ export declare const MEMORIZE_MODULE_OPTIONS: unique symbol;
5
+ type MetadataTarget = object;
6
+ export interface MemorizeNestExecutionContext {
7
+ getClass(): MetadataTarget;
8
+ getHandler(): MetadataTarget;
9
+ switchToHttp(): {
10
+ getRequest(): MemorizeNestHttpRequest;
11
+ getResponse(): MemorizeNestHttpResponse;
12
+ };
13
+ }
14
+ export interface MemorizeNestCallHandler<T = unknown> {
15
+ handle(): MemorizeNestObservable<T>;
16
+ }
17
+ export interface MemorizeNestObservable<T = unknown> {
18
+ subscribe(observerOrNext?: Partial<ObserverLike<T>> | ((value: T) => void), error?: (error: unknown) => void, complete?: () => void): unknown;
19
+ }
20
+ interface ObserverLike<T = unknown> {
21
+ next(value: T): void;
22
+ error(error: unknown): void;
23
+ complete(): void;
24
+ }
25
+ export interface MemorizeNestHttpRequest {
26
+ method?: string;
27
+ originalUrl?: string;
28
+ url?: string;
29
+ }
30
+ export interface MemorizeNestHttpResponse {
31
+ statusCode?: number;
32
+ setHeader?: (name: string, value: string) => void;
33
+ header?: (name: string, value: string) => void;
34
+ headersSent?: boolean;
35
+ }
36
+ export interface MemorizeNestKeyContext {
37
+ context: MemorizeNestExecutionContext;
38
+ request: MemorizeNestHttpRequest;
39
+ }
40
+ export interface MemorizeNestOptions extends MemorizeOptions {
41
+ /**
42
+ * Custom request-based cache key generator. Defaults to
43
+ * `request.originalUrl ?? request.url`.
44
+ */
45
+ key?: (ctx: MemorizeNestKeyContext) => string;
46
+ }
47
+ interface DynamicModuleLike {
48
+ module: unknown;
49
+ providers: unknown[];
50
+ exports: unknown[];
51
+ global?: boolean;
52
+ }
53
+ /**
54
+ * Decorates a controller or handler with a fixed cache key.
55
+ */
56
+ export declare function MemorizeCacheKey(key: string): MethodDecorator & ClassDecorator;
57
+ /**
58
+ * Decorates a controller or handler with a TTL override in milliseconds.
59
+ */
60
+ export declare function MemorizeTtl(ttl: number): MethodDecorator & ClassDecorator;
61
+ /**
62
+ * Decorates a controller or handler so the interceptor bypasses cache reads and writes.
63
+ */
64
+ export declare function MemorizeNoCache(): MethodDecorator & ClassDecorator;
65
+ /**
66
+ * NestJS interceptor backed by a shared {@link Memorize} cache instance.
67
+ *
68
+ * Register through {@link MemorizeModule.forRoot} for dependency injection, or
69
+ * instantiate directly in tests and small applications.
70
+ */
71
+ export declare class MemorizeInterceptor {
72
+ private readonly cache;
73
+ private readonly options;
74
+ constructor(cache?: Memorize, options?: MemorizeNestOptions);
75
+ intercept(context: MemorizeNestExecutionContext, next: MemorizeNestCallHandler): MemorizeNestObservable<unknown>;
76
+ }
77
+ /**
78
+ * Dynamic Nest module that provides a shared cache and interceptor.
79
+ */
80
+ export declare class MemorizeModule {
81
+ static forRoot(options?: MemorizeNestOptions): DynamicModuleLike;
82
+ }
83
+ export {};
84
+ //# sourceMappingURL=nestjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestjs.d.ts","sourceRoot":"","sources":["../../src/adapters/nestjs.ts"],"names":[],"mappings":"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"}