@hazeljs/cache 0.2.0-beta.1
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/README.md +523 -0
- package/dist/cache.module.d.ts +81 -0
- package/dist/cache.module.d.ts.map +1 -0
- package/dist/cache.module.js +111 -0
- package/dist/cache.service.d.ts +109 -0
- package/dist/cache.service.d.ts.map +1 -0
- package/dist/cache.service.js +263 -0
- package/dist/cache.types.d.ts +180 -0
- package/dist/cache.types.d.ts.map +1 -0
- package/dist/cache.types.js +2 -0
- package/dist/decorators/cache.decorator.d.ts +93 -0
- package/dist/decorators/cache.decorator.d.ts.map +1 -0
- package/dist/decorators/cache.decorator.js +155 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/src/cache.module.d.ts +81 -0
- package/dist/src/cache.module.d.ts.map +1 -0
- package/dist/src/cache.module.js +111 -0
- package/dist/src/cache.service.d.ts +109 -0
- package/dist/src/cache.service.d.ts.map +1 -0
- package/dist/src/cache.service.js +263 -0
- package/dist/src/cache.types.d.ts +180 -0
- package/dist/src/cache.types.d.ts.map +1 -0
- package/dist/src/cache.types.js +2 -0
- package/dist/src/decorators/cache.decorator.d.ts +93 -0
- package/dist/src/decorators/cache.decorator.d.ts.map +1 -0
- package/dist/src/decorators/cache.decorator.js +155 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/strategies/memory.strategy.d.ts +73 -0
- package/dist/src/strategies/memory.strategy.d.ts.map +1 -0
- package/dist/src/strategies/memory.strategy.js +236 -0
- package/dist/src/strategies/multi-tier.strategy.d.ts +69 -0
- package/dist/src/strategies/multi-tier.strategy.d.ts.map +1 -0
- package/dist/src/strategies/multi-tier.strategy.js +154 -0
- package/dist/src/strategies/redis.strategy.d.ts +61 -0
- package/dist/src/strategies/redis.strategy.d.ts.map +1 -0
- package/dist/src/strategies/redis.strategy.js +185 -0
- package/dist/strategies/memory.strategy.d.ts +73 -0
- package/dist/strategies/memory.strategy.d.ts.map +1 -0
- package/dist/strategies/memory.strategy.js +236 -0
- package/dist/strategies/multi-tier.strategy.d.ts +69 -0
- package/dist/strategies/multi-tier.strategy.d.ts.map +1 -0
- package/dist/strategies/multi-tier.strategy.js +154 -0
- package/dist/strategies/redis.strategy.d.ts +61 -0
- package/dist/strategies/redis.strategy.d.ts.map +1 -0
- package/dist/strategies/redis.strategy.js +185 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ICacheStore, CacheStats, CacheWarmingOptions, CacheStrategy } from './cache.types';
|
|
2
|
+
/**
|
|
3
|
+
* Cache service for managing cache operations
|
|
4
|
+
*/
|
|
5
|
+
export declare class CacheService {
|
|
6
|
+
private store;
|
|
7
|
+
private strategy;
|
|
8
|
+
constructor(strategy?: CacheStrategy, options?: unknown);
|
|
9
|
+
/**
|
|
10
|
+
* Create cache store based on strategy
|
|
11
|
+
*/
|
|
12
|
+
private createStore;
|
|
13
|
+
/**
|
|
14
|
+
* Get a value from cache
|
|
15
|
+
*/
|
|
16
|
+
get<T>(key: string): Promise<T | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Set a value in cache
|
|
19
|
+
*/
|
|
20
|
+
set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Set a value with tags
|
|
23
|
+
*/
|
|
24
|
+
setWithTags<T>(key: string, value: T, ttl: number, tags?: string[]): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Delete a value from cache
|
|
27
|
+
*/
|
|
28
|
+
delete(key: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Delete entries by tag
|
|
31
|
+
*/
|
|
32
|
+
deleteByTag(tag: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Invalidate cache by tags
|
|
35
|
+
*/
|
|
36
|
+
invalidateTags(tags: string[]): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if key exists in cache
|
|
39
|
+
*/
|
|
40
|
+
has(key: string): Promise<boolean>;
|
|
41
|
+
/**
|
|
42
|
+
* Clear all cache entries
|
|
43
|
+
*/
|
|
44
|
+
clear(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Get all keys matching a pattern
|
|
47
|
+
*/
|
|
48
|
+
keys(pattern?: string): Promise<string[]>;
|
|
49
|
+
/**
|
|
50
|
+
* Get cache statistics
|
|
51
|
+
*/
|
|
52
|
+
getStats(): Promise<CacheStats>;
|
|
53
|
+
/**
|
|
54
|
+
* Warm up cache with predefined data
|
|
55
|
+
*/
|
|
56
|
+
warmUp(options: CacheWarmingOptions): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Get or set a value (cache-aside pattern)
|
|
59
|
+
*/
|
|
60
|
+
getOrSet<T>(key: string, fetcher: () => Promise<T>, ttl?: number, tags?: string[]): Promise<T>;
|
|
61
|
+
/**
|
|
62
|
+
* Wrap a function with caching
|
|
63
|
+
*/
|
|
64
|
+
wrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T>;
|
|
65
|
+
/**
|
|
66
|
+
* Get the underlying cache store
|
|
67
|
+
*/
|
|
68
|
+
getStore(): ICacheStore;
|
|
69
|
+
/**
|
|
70
|
+
* Get cache strategy
|
|
71
|
+
*/
|
|
72
|
+
getStrategy(): CacheStrategy;
|
|
73
|
+
/**
|
|
74
|
+
* Reset cache statistics
|
|
75
|
+
*/
|
|
76
|
+
resetStats(): void;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Cache manager for managing multiple cache instances
|
|
80
|
+
*/
|
|
81
|
+
export declare class CacheManager {
|
|
82
|
+
private caches;
|
|
83
|
+
private defaultCache?;
|
|
84
|
+
/**
|
|
85
|
+
* Register a cache instance
|
|
86
|
+
*/
|
|
87
|
+
register(name: string, cache: CacheService, isDefault?: boolean): void;
|
|
88
|
+
/**
|
|
89
|
+
* Get a cache instance by name
|
|
90
|
+
*/
|
|
91
|
+
get(name?: string): CacheService;
|
|
92
|
+
/**
|
|
93
|
+
* Get all cache instances
|
|
94
|
+
*/
|
|
95
|
+
getAll(): Map<string, CacheService>;
|
|
96
|
+
/**
|
|
97
|
+
* Clear all caches
|
|
98
|
+
*/
|
|
99
|
+
clearAll(): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Get statistics for all caches
|
|
102
|
+
*/
|
|
103
|
+
getAllStats(): Promise<Map<string, CacheStats>>;
|
|
104
|
+
/**
|
|
105
|
+
* Invalidate tags across all caches
|
|
106
|
+
*/
|
|
107
|
+
invalidateTagsGlobal(tags: string[]): Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=cache.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.service.d.ts","sourceRoot":"","sources":["../src/cache.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CacheManager = exports.CacheService = void 0;
|
|
16
|
+
const core_1 = require("@hazeljs/core");
|
|
17
|
+
const memory_strategy_1 = require("./strategies/memory.strategy");
|
|
18
|
+
const redis_strategy_1 = require("./strategies/redis.strategy");
|
|
19
|
+
const multi_tier_strategy_1 = require("./strategies/multi-tier.strategy");
|
|
20
|
+
const core_2 = __importDefault(require("@hazeljs/core"));
|
|
21
|
+
/**
|
|
22
|
+
* Cache service for managing cache operations
|
|
23
|
+
*/
|
|
24
|
+
let CacheService = class CacheService {
|
|
25
|
+
constructor(strategy = 'memory', options) {
|
|
26
|
+
this.strategy = strategy;
|
|
27
|
+
this.store = this.createStore(strategy, options);
|
|
28
|
+
core_2.default.info(`Cache service initialized with strategy: ${strategy}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create cache store based on strategy
|
|
32
|
+
*/
|
|
33
|
+
createStore(strategy, options) {
|
|
34
|
+
const opts = options;
|
|
35
|
+
switch (strategy) {
|
|
36
|
+
case 'redis':
|
|
37
|
+
return new redis_strategy_1.RedisCacheStore(opts?.redis);
|
|
38
|
+
case 'multi-tier':
|
|
39
|
+
return new multi_tier_strategy_1.MultiTierCacheStore(opts);
|
|
40
|
+
case 'memory':
|
|
41
|
+
default:
|
|
42
|
+
return new memory_strategy_1.MemoryCacheStore(opts?.cleanupInterval);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a value from cache
|
|
47
|
+
*/
|
|
48
|
+
async get(key) {
|
|
49
|
+
return await this.store.get(key);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set a value in cache
|
|
53
|
+
*/
|
|
54
|
+
async set(key, value, ttl) {
|
|
55
|
+
await this.store.set(key, value, ttl);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set a value with tags
|
|
59
|
+
*/
|
|
60
|
+
async setWithTags(key, value, ttl, tags) {
|
|
61
|
+
if ('setWithTags' in this.store &&
|
|
62
|
+
typeof this.store.setWithTags === 'function') {
|
|
63
|
+
await this.store.setWithTags(key, value, ttl, tags);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
await this.store.set(key, value, ttl);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Delete a value from cache
|
|
71
|
+
*/
|
|
72
|
+
async delete(key) {
|
|
73
|
+
await this.store.delete(key);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Delete entries by tag
|
|
77
|
+
*/
|
|
78
|
+
async deleteByTag(tag) {
|
|
79
|
+
if ('deleteByTag' in this.store &&
|
|
80
|
+
typeof this.store.deleteByTag === 'function') {
|
|
81
|
+
await this.store.deleteByTag(tag);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
core_2.default.warn(`deleteByTag not supported for ${this.strategy} strategy`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Invalidate cache by tags
|
|
89
|
+
*/
|
|
90
|
+
async invalidateTags(tags) {
|
|
91
|
+
for (const tag of tags) {
|
|
92
|
+
await this.deleteByTag(tag);
|
|
93
|
+
}
|
|
94
|
+
core_2.default.info(`Invalidated cache for tags: ${tags.join(', ')}`);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if key exists in cache
|
|
98
|
+
*/
|
|
99
|
+
async has(key) {
|
|
100
|
+
return await this.store.has(key);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Clear all cache entries
|
|
104
|
+
*/
|
|
105
|
+
async clear() {
|
|
106
|
+
await this.store.clear();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get all keys matching a pattern
|
|
110
|
+
*/
|
|
111
|
+
async keys(pattern) {
|
|
112
|
+
return await this.store.keys(pattern);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get cache statistics
|
|
116
|
+
*/
|
|
117
|
+
async getStats() {
|
|
118
|
+
return await this.store.getStats();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Warm up cache with predefined data
|
|
122
|
+
*/
|
|
123
|
+
async warmUp(options) {
|
|
124
|
+
const { keys, fetcher, ttl = 3600, parallel = true } = options;
|
|
125
|
+
core_2.default.info(`Warming up cache for ${keys.length} keys...`);
|
|
126
|
+
const warmUpKey = async (key) => {
|
|
127
|
+
try {
|
|
128
|
+
const data = await fetcher(key);
|
|
129
|
+
await this.set(key, data, ttl);
|
|
130
|
+
core_2.default.debug(`Warmed up cache key: ${key}`);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
core_2.default.error(`Failed to warm up cache key ${key}:`, error);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
if (parallel) {
|
|
137
|
+
await Promise.all(keys.map(warmUpKey));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
for (const key of keys) {
|
|
141
|
+
await warmUpKey(key);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
core_2.default.info(`Cache warming completed for ${keys.length} keys`);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get or set a value (cache-aside pattern)
|
|
148
|
+
*/
|
|
149
|
+
async getOrSet(key, fetcher, ttl, tags) {
|
|
150
|
+
// Try to get from cache
|
|
151
|
+
const cached = await this.get(key);
|
|
152
|
+
if (cached !== null) {
|
|
153
|
+
return cached;
|
|
154
|
+
}
|
|
155
|
+
// Fetch data
|
|
156
|
+
const data = await fetcher();
|
|
157
|
+
// Store in cache
|
|
158
|
+
if (tags) {
|
|
159
|
+
await this.setWithTags(key, data, ttl || 3600, tags);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
await this.set(key, data, ttl);
|
|
163
|
+
}
|
|
164
|
+
return data;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Wrap a function with caching
|
|
168
|
+
*/
|
|
169
|
+
wrap(key, fn, ttl) {
|
|
170
|
+
return this.getOrSet(key, fn, ttl);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get the underlying cache store
|
|
174
|
+
*/
|
|
175
|
+
getStore() {
|
|
176
|
+
return this.store;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get cache strategy
|
|
180
|
+
*/
|
|
181
|
+
getStrategy() {
|
|
182
|
+
return this.strategy;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Reset cache statistics
|
|
186
|
+
*/
|
|
187
|
+
resetStats() {
|
|
188
|
+
if ('resetStats' in this.store &&
|
|
189
|
+
typeof this.store.resetStats === 'function') {
|
|
190
|
+
this.store.resetStats();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
exports.CacheService = CacheService;
|
|
195
|
+
exports.CacheService = CacheService = __decorate([
|
|
196
|
+
(0, core_1.Injectable)(),
|
|
197
|
+
__metadata("design:paramtypes", [String, Object])
|
|
198
|
+
], CacheService);
|
|
199
|
+
/**
|
|
200
|
+
* Cache manager for managing multiple cache instances
|
|
201
|
+
*/
|
|
202
|
+
class CacheManager {
|
|
203
|
+
constructor() {
|
|
204
|
+
this.caches = new Map();
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Register a cache instance
|
|
208
|
+
*/
|
|
209
|
+
register(name, cache, isDefault = false) {
|
|
210
|
+
this.caches.set(name, cache);
|
|
211
|
+
if (isDefault || !this.defaultCache) {
|
|
212
|
+
this.defaultCache = cache;
|
|
213
|
+
}
|
|
214
|
+
core_2.default.info(`Cache registered: ${name}${isDefault ? ' (default)' : ''}`);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Get a cache instance by name
|
|
218
|
+
*/
|
|
219
|
+
get(name) {
|
|
220
|
+
if (!name) {
|
|
221
|
+
if (!this.defaultCache) {
|
|
222
|
+
throw new Error('No default cache configured');
|
|
223
|
+
}
|
|
224
|
+
return this.defaultCache;
|
|
225
|
+
}
|
|
226
|
+
const cache = this.caches.get(name);
|
|
227
|
+
if (!cache) {
|
|
228
|
+
throw new Error(`Cache not found: ${name}`);
|
|
229
|
+
}
|
|
230
|
+
return cache;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get all cache instances
|
|
234
|
+
*/
|
|
235
|
+
getAll() {
|
|
236
|
+
return this.caches;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Clear all caches
|
|
240
|
+
*/
|
|
241
|
+
async clearAll() {
|
|
242
|
+
await Promise.all(Array.from(this.caches.values()).map((cache) => cache.clear()));
|
|
243
|
+
core_2.default.info('All caches cleared');
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get statistics for all caches
|
|
247
|
+
*/
|
|
248
|
+
async getAllStats() {
|
|
249
|
+
const stats = new Map();
|
|
250
|
+
for (const [name, cache] of this.caches.entries()) {
|
|
251
|
+
stats.set(name, await cache.getStats());
|
|
252
|
+
}
|
|
253
|
+
return stats;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Invalidate tags across all caches
|
|
257
|
+
*/
|
|
258
|
+
async invalidateTagsGlobal(tags) {
|
|
259
|
+
await Promise.all(Array.from(this.caches.values()).map((cache) => cache.invalidateTags(tags)));
|
|
260
|
+
core_2.default.info(`Invalidated tags globally: ${tags.join(', ')}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
exports.CacheManager = CacheManager;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache strategy types
|
|
3
|
+
*/
|
|
4
|
+
export type CacheStrategy = 'memory' | 'redis' | 'multi-tier';
|
|
5
|
+
/**
|
|
6
|
+
* TTL strategy types
|
|
7
|
+
*/
|
|
8
|
+
export type TTLStrategy = 'absolute' | 'sliding';
|
|
9
|
+
/**
|
|
10
|
+
* Cache options
|
|
11
|
+
*/
|
|
12
|
+
export interface CacheOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Cache strategy to use
|
|
15
|
+
* @default 'memory'
|
|
16
|
+
*/
|
|
17
|
+
strategy?: CacheStrategy;
|
|
18
|
+
/**
|
|
19
|
+
* Time to live in seconds
|
|
20
|
+
* @default 3600
|
|
21
|
+
*/
|
|
22
|
+
ttl?: number;
|
|
23
|
+
/**
|
|
24
|
+
* TTL strategy
|
|
25
|
+
* @default 'absolute'
|
|
26
|
+
*/
|
|
27
|
+
ttlStrategy?: TTLStrategy;
|
|
28
|
+
/**
|
|
29
|
+
* Cache key pattern (supports placeholders like {id}, {userId})
|
|
30
|
+
*/
|
|
31
|
+
key?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Tags for group invalidation
|
|
34
|
+
*/
|
|
35
|
+
tags?: string[];
|
|
36
|
+
/**
|
|
37
|
+
* Events that should invalidate this cache
|
|
38
|
+
*/
|
|
39
|
+
invalidateOn?: string[];
|
|
40
|
+
/**
|
|
41
|
+
* Whether to cache null/undefined values
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
cacheNull?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Custom condition function to determine if value should be cached
|
|
47
|
+
*/
|
|
48
|
+
condition?: (value: unknown) => boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Cache entry metadata
|
|
52
|
+
*/
|
|
53
|
+
export interface CacheEntry<T = unknown> {
|
|
54
|
+
/**
|
|
55
|
+
* Cached value
|
|
56
|
+
*/
|
|
57
|
+
value: T;
|
|
58
|
+
/**
|
|
59
|
+
* Timestamp when cached
|
|
60
|
+
*/
|
|
61
|
+
cachedAt: number;
|
|
62
|
+
/**
|
|
63
|
+
* Expiration timestamp
|
|
64
|
+
*/
|
|
65
|
+
expiresAt: number;
|
|
66
|
+
/**
|
|
67
|
+
* Last accessed timestamp (for sliding TTL)
|
|
68
|
+
*/
|
|
69
|
+
lastAccessedAt?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Cache tags
|
|
72
|
+
*/
|
|
73
|
+
tags?: string[];
|
|
74
|
+
/**
|
|
75
|
+
* Cache key
|
|
76
|
+
*/
|
|
77
|
+
key: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Cache statistics
|
|
81
|
+
*/
|
|
82
|
+
export interface CacheStats {
|
|
83
|
+
/**
|
|
84
|
+
* Total number of cache hits
|
|
85
|
+
*/
|
|
86
|
+
hits: number;
|
|
87
|
+
/**
|
|
88
|
+
* Total number of cache misses
|
|
89
|
+
*/
|
|
90
|
+
misses: number;
|
|
91
|
+
/**
|
|
92
|
+
* Hit rate percentage
|
|
93
|
+
*/
|
|
94
|
+
hitRate: number;
|
|
95
|
+
/**
|
|
96
|
+
* Total number of cached entries
|
|
97
|
+
*/
|
|
98
|
+
size: number;
|
|
99
|
+
/**
|
|
100
|
+
* Total memory used (in bytes, if applicable)
|
|
101
|
+
*/
|
|
102
|
+
memoryUsage?: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Cache store interface
|
|
106
|
+
*/
|
|
107
|
+
export interface ICacheStore {
|
|
108
|
+
/**
|
|
109
|
+
* Get a value from cache
|
|
110
|
+
*/
|
|
111
|
+
get<T>(key: string): Promise<T | null>;
|
|
112
|
+
/**
|
|
113
|
+
* Set a value in cache
|
|
114
|
+
*/
|
|
115
|
+
set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Delete a value from cache
|
|
118
|
+
*/
|
|
119
|
+
delete(key: string): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Check if key exists in cache
|
|
122
|
+
*/
|
|
123
|
+
has(key: string): Promise<boolean>;
|
|
124
|
+
/**
|
|
125
|
+
* Clear all cache entries
|
|
126
|
+
*/
|
|
127
|
+
clear(): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Get all keys matching a pattern
|
|
130
|
+
*/
|
|
131
|
+
keys(pattern?: string): Promise<string[]>;
|
|
132
|
+
/**
|
|
133
|
+
* Get cache statistics
|
|
134
|
+
*/
|
|
135
|
+
getStats(): Promise<CacheStats>;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Cache warming options
|
|
139
|
+
*/
|
|
140
|
+
export interface CacheWarmingOptions {
|
|
141
|
+
/**
|
|
142
|
+
* Keys to warm up
|
|
143
|
+
*/
|
|
144
|
+
keys: string[];
|
|
145
|
+
/**
|
|
146
|
+
* Function to fetch data for warming
|
|
147
|
+
*/
|
|
148
|
+
fetcher: (key: string) => Promise<unknown>;
|
|
149
|
+
/**
|
|
150
|
+
* TTL for warmed entries
|
|
151
|
+
*/
|
|
152
|
+
ttl?: number;
|
|
153
|
+
/**
|
|
154
|
+
* Whether to warm in parallel
|
|
155
|
+
* @default true
|
|
156
|
+
*/
|
|
157
|
+
parallel?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Cache invalidation event
|
|
161
|
+
*/
|
|
162
|
+
export interface CacheInvalidationEvent {
|
|
163
|
+
/**
|
|
164
|
+
* Event name
|
|
165
|
+
*/
|
|
166
|
+
event: string;
|
|
167
|
+
/**
|
|
168
|
+
* Keys to invalidate
|
|
169
|
+
*/
|
|
170
|
+
keys?: string[];
|
|
171
|
+
/**
|
|
172
|
+
* Tags to invalidate
|
|
173
|
+
*/
|
|
174
|
+
tags?: string[];
|
|
175
|
+
/**
|
|
176
|
+
* Timestamp
|
|
177
|
+
*/
|
|
178
|
+
timestamp: number;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=cache.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.types.d.ts","sourceRoot":"","sources":["../src/cache.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { CacheOptions } from '../cache.types';
|
|
3
|
+
/**
|
|
4
|
+
* Cache decorator for methods
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* @Cache({
|
|
9
|
+
* strategy: 'memory',
|
|
10
|
+
* ttl: 3600,
|
|
11
|
+
* key: 'user-{id}',
|
|
12
|
+
* tags: ['users']
|
|
13
|
+
* })
|
|
14
|
+
* @Get('/users/:id')
|
|
15
|
+
* async getUser(@Param('id') id: string) {
|
|
16
|
+
* return this.userService.findById(id);
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function Cache(options?: CacheOptions): MethodDecorator;
|
|
21
|
+
/**
|
|
22
|
+
* Get cache metadata from a method
|
|
23
|
+
*/
|
|
24
|
+
export declare function getCacheMetadata(target: object, propertyKey: string | symbol): CacheOptions | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a method has cache metadata
|
|
27
|
+
*/
|
|
28
|
+
export declare function hasCacheMetadata(target: object, propertyKey: string | symbol): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* CacheKey decorator to specify custom cache key generation
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* @CacheKey('user-{id}-{role}')
|
|
35
|
+
* @Get('/users/:id')
|
|
36
|
+
* async getUser(@Param('id') id: string, @Query('role') role: string) {
|
|
37
|
+
* return this.userService.findById(id);
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function CacheKey(keyPattern: string): MethodDecorator;
|
|
42
|
+
/**
|
|
43
|
+
* CacheTTL decorator to specify cache TTL
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* @CacheTTL(7200) // 2 hours
|
|
48
|
+
* @Get('/users')
|
|
49
|
+
* async getUsers() {
|
|
50
|
+
* return this.userService.findAll();
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function CacheTTL(ttl: number): MethodDecorator;
|
|
55
|
+
/**
|
|
56
|
+
* CacheTags decorator to specify cache tags
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* @CacheTags(['users', 'profiles'])
|
|
61
|
+
* @Get('/users/:id/profile')
|
|
62
|
+
* async getUserProfile(@Param('id') id: string) {
|
|
63
|
+
* return this.userService.getProfile(id);
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function CacheTags(tags: string[]): MethodDecorator;
|
|
68
|
+
/**
|
|
69
|
+
* CacheEvict decorator to evict cache entries
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* @CacheEvict({ tags: ['users'] })
|
|
74
|
+
* @Post('/users')
|
|
75
|
+
* async createUser(@Body() user: CreateUserDto) {
|
|
76
|
+
* return this.userService.create(user);
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function CacheEvict(options: {
|
|
81
|
+
keys?: string[];
|
|
82
|
+
tags?: string[];
|
|
83
|
+
all?: boolean;
|
|
84
|
+
}): MethodDecorator;
|
|
85
|
+
/**
|
|
86
|
+
* Get cache evict metadata
|
|
87
|
+
*/
|
|
88
|
+
export declare function getCacheEvictMetadata(target: object, propertyKey: string | symbol): {
|
|
89
|
+
keys?: string[];
|
|
90
|
+
tags?: string[];
|
|
91
|
+
all?: boolean;
|
|
92
|
+
} | undefined;
|
|
93
|
+
//# sourceMappingURL=cache.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/cache.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,eAAe,CAoBjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,YAAY,GAAG,SAAS,CAE1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAEtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAY5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAYrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAYzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,GAAG,eAAe,CAMlB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B;IAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAEjE"}
|