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.
- package/CHANGELOG.md +13 -0
- package/README.md +205 -82
- package/dist/MemorizeStore.d.ts +31 -8
- package/dist/MemorizeStore.d.ts.map +1 -1
- package/dist/MemorizeStore.js +98 -14
- package/dist/MemorizeStore.js.map +1 -1
- package/dist/adapters/express.d.ts +25 -0
- package/dist/adapters/express.d.ts.map +1 -0
- package/dist/adapters/express.js +62 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/fetch.d.ts +45 -0
- package/dist/adapters/fetch.d.ts.map +1 -0
- package/dist/adapters/fetch.js +72 -0
- package/dist/adapters/fetch.js.map +1 -0
- package/dist/adapters/hono.d.ts +34 -0
- package/dist/adapters/hono.d.ts.map +1 -0
- package/dist/adapters/hono.js +63 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/nestjs.d.ts +84 -0
- package/dist/adapters/nestjs.d.ts.map +1 -0
- package/dist/adapters/nestjs.js +194 -0
- package/dist/adapters/nestjs.js.map +1 -0
- package/dist/domain/CacheEntry.d.ts +3 -1
- package/dist/domain/CacheEntry.d.ts.map +1 -1
- package/dist/domain/CacheInfo.d.ts +1 -1
- package/dist/domain/CacheInfo.d.ts.map +1 -1
- package/dist/domain/Memorize.d.ts +99 -4
- package/dist/domain/Memorize.d.ts.map +1 -1
- package/dist/domain/MemorizeCallOptions.d.ts +2 -1
- package/dist/domain/MemorizeCallOptions.d.ts.map +1 -1
- package/dist/domain/MemorizeEvent.d.ts +2 -1
- package/dist/domain/MemorizeEvent.d.ts.map +1 -1
- package/dist/domain/MemorizeEventType.d.ts +3 -1
- package/dist/domain/MemorizeEventType.d.ts.map +1 -1
- package/dist/domain/MemorizeEventType.js +2 -0
- package/dist/domain/MemorizeEventType.js.map +1 -1
- package/dist/domain/MemorizeEvictEvent.d.ts +18 -0
- package/dist/domain/MemorizeEvictEvent.d.ts.map +1 -0
- package/dist/domain/MemorizeEvictEvent.js +3 -0
- package/dist/domain/MemorizeEvictEvent.js.map +1 -0
- package/dist/domain/MemorizeOptions.d.ts +14 -1
- package/dist/domain/MemorizeOptions.d.ts.map +1 -1
- package/dist/domain/MemorizeSetEvent.d.ts +3 -1
- package/dist/domain/MemorizeSetEvent.d.ts.map +1 -1
- package/dist/domain/MemorizeStats.d.ts +12 -0
- package/dist/domain/MemorizeStats.d.ts.map +1 -0
- package/dist/domain/MemorizeStats.js +3 -0
- package/dist/domain/MemorizeStats.js.map +1 -0
- package/dist/domain/index.d.ts +2 -0
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/memorize.d.ts +19 -16
- package/dist/memorize.d.ts.map +1 -1
- package/dist/memorize.js +51 -50
- package/dist/memorize.js.map +1 -1
- package/package.json +50 -12
package/dist/MemorizeStore.js
CHANGED
|
@@ -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.
|
|
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`
|
|
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
|
|
44
|
-
|
|
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.
|
|
47
|
-
|
|
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
|
-
},
|
|
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()
|
|
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()
|
|
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()
|
|
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":";;;AAAA,qDAAkD;
|
|
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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"}
|