@nest-omni/core 3.1.1-11 → 3.1.1-13
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/cache/cache-metrics.service.d.ts +83 -0
- package/cache/cache-metrics.service.js +298 -0
- package/cache/cache-serialization.service.d.ts +29 -0
- package/cache/cache-serialization.service.js +217 -0
- package/cache/cache.health.d.ts +35 -0
- package/cache/cache.health.js +193 -0
- package/cache/cache.module.d.ts +24 -0
- package/cache/cache.module.js +105 -0
- package/cache/cache.service.d.ts +35 -0
- package/cache/cache.service.js +280 -0
- package/cache/cache.warmup.service.d.ts +34 -0
- package/cache/cache.warmup.service.js +199 -0
- package/cache/decorators/cache-evict.decorator.d.ts +2 -0
- package/cache/decorators/cache-evict.decorator.js +72 -0
- package/cache/decorators/cache-put.decorator.d.ts +2 -0
- package/cache/decorators/cache-put.decorator.js +48 -0
- package/cache/decorators/cacheable.decorator.d.ts +4 -0
- package/cache/decorators/cacheable.decorator.js +68 -0
- package/cache/decorators/index.d.ts +3 -0
- package/cache/decorators/index.js +11 -0
- package/cache/dependencies/callback.dependency.d.ts +11 -0
- package/cache/dependencies/callback.dependency.js +92 -0
- package/cache/dependencies/chain.dependency.d.ts +20 -0
- package/cache/dependencies/chain.dependency.js +113 -0
- package/cache/dependencies/db.dependency.d.ts +15 -0
- package/cache/dependencies/db.dependency.js +71 -0
- package/cache/dependencies/file.dependency.d.ts +17 -0
- package/cache/dependencies/file.dependency.js +63 -0
- package/cache/dependencies/index.d.ts +6 -0
- package/cache/dependencies/index.js +22 -0
- package/cache/dependencies/tag.dependency.d.ts +16 -0
- package/cache/dependencies/tag.dependency.js +75 -0
- package/cache/dependencies/time.dependency.d.ts +19 -0
- package/cache/dependencies/time.dependency.js +71 -0
- package/cache/examples/quick-start.d.ts +5 -0
- package/cache/examples/quick-start.js +341 -0
- package/cache/index.d.ts +14 -0
- package/cache/index.js +41 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +11 -0
- package/cache/interfaces/cache-dependency.interface.js +2 -0
- package/cache/interfaces/cache-options.interface.d.ts +32 -0
- package/cache/interfaces/cache-options.interface.js +9 -0
- package/cache/interfaces/cache-provider.interface.d.ts +28 -0
- package/cache/interfaces/cache-provider.interface.js +2 -0
- package/cache/interfaces/index.d.ts +3 -0
- package/cache/interfaces/index.js +19 -0
- package/cache/providers/base-cache.provider.d.ts +16 -0
- package/cache/providers/base-cache.provider.js +32 -0
- package/cache/providers/cls-cache.provider.d.ts +16 -0
- package/cache/providers/cls-cache.provider.js +140 -0
- package/cache/providers/index.d.ts +4 -0
- package/cache/providers/index.js +23 -0
- package/cache/providers/memory-cache.provider.d.ts +23 -0
- package/cache/providers/memory-cache.provider.js +130 -0
- package/cache/providers/redis-cache.provider.d.ts +23 -0
- package/cache/providers/redis-cache.provider.js +215 -0
- package/cache/utils/dependency-manager.util.d.ts +15 -0
- package/cache/utils/dependency-manager.util.js +141 -0
- package/cache/utils/index.d.ts +2 -0
- package/cache/utils/index.js +18 -0
- package/cache/utils/key-generator.util.d.ts +13 -0
- package/cache/utils/key-generator.util.js +74 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +4 -17
- package/redis-lock/index.d.ts +4 -0
- package/redis-lock/index.js +13 -0
- package/{setup → redis-lock}/redis-lock.decorator.d.ts +3 -0
- package/{setup → redis-lock}/redis-lock.decorator.js +25 -14
- package/redis-lock/redis-lock.examples.d.ts +13 -0
- package/redis-lock/redis-lock.examples.js +159 -0
- package/redis-lock/redis-lock.module.d.ts +23 -0
- package/redis-lock/redis-lock.module.js +117 -0
- package/{setup → redis-lock}/redis-lock.service.d.ts +9 -21
- package/{setup → redis-lock}/redis-lock.service.js +29 -103
- package/setup/index.d.ts +1 -2
- package/setup/index.js +1 -2
- package/setup/schedule.decorator.js +4 -4
- package/shared/serviceRegistryModule.js +63 -4
- package/shared/services/api-config.service.d.ts +0 -5
- package/shared/services/api-config.service.js +3 -27
|
@@ -0,0 +1,199 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var CacheWarmupService_1;
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.CacheWarmupService = void 0;
|
|
23
|
+
const common_1 = require("@nestjs/common");
|
|
24
|
+
const cache_service_1 = require("./cache.service");
|
|
25
|
+
let CacheWarmupService = CacheWarmupService_1 = class CacheWarmupService {
|
|
26
|
+
constructor(cacheService) {
|
|
27
|
+
this.cacheService = cacheService;
|
|
28
|
+
this.logger = new common_1.Logger(CacheWarmupService_1.name);
|
|
29
|
+
this.warmupConfigs = new Map();
|
|
30
|
+
}
|
|
31
|
+
registerWarmup(groupName, configs) {
|
|
32
|
+
this.warmupConfigs.set(groupName, configs);
|
|
33
|
+
this.logger.debug(`Registered ${configs.length} warmup tasks for group: ${groupName}`);
|
|
34
|
+
}
|
|
35
|
+
warmupGroup(groupName) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const configs = this.warmupConfigs.get(groupName);
|
|
38
|
+
if (!configs || configs.length === 0) {
|
|
39
|
+
this.logger.warn(`No warmup configurations found for group: ${groupName}`);
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
this.logger.log(`Starting cache warmup for group: ${groupName}`);
|
|
43
|
+
const startTime = Date.now();
|
|
44
|
+
const results = [];
|
|
45
|
+
for (const config of configs) {
|
|
46
|
+
const result = yield this.executeWarmupTask(config);
|
|
47
|
+
results.push(result);
|
|
48
|
+
if (config.critical && !result.success) {
|
|
49
|
+
this.logger.error(`Critical warmup task failed: ${config.name}`);
|
|
50
|
+
throw new Error(`Critical warmup task failed: ${config.name}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const duration = Date.now() - startTime;
|
|
54
|
+
const successCount = results.filter((r) => r.success).length;
|
|
55
|
+
this.logger.log(`Warmup completed for group: ${groupName}. ` +
|
|
56
|
+
`Success: ${successCount}/${results.length}, Duration: ${duration}ms`);
|
|
57
|
+
return results;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
warmupAll() {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
const results = new Map();
|
|
63
|
+
for (const groupName of this.warmupConfigs.keys()) {
|
|
64
|
+
try {
|
|
65
|
+
const groupResults = yield this.warmupGroup(groupName);
|
|
66
|
+
results.set(groupName, groupResults);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
this.logger.error(`Failed to warm up group ${groupName}:`, error);
|
|
70
|
+
results.set(groupName, [
|
|
71
|
+
{
|
|
72
|
+
name: groupName,
|
|
73
|
+
success: false,
|
|
74
|
+
itemCount: 0,
|
|
75
|
+
duration: 0,
|
|
76
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
77
|
+
},
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return results;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
getWarmupStats() {
|
|
85
|
+
const totalGroups = this.warmupConfigs.size;
|
|
86
|
+
let totalTasks = 0;
|
|
87
|
+
const taskDetails = [];
|
|
88
|
+
for (const [groupName, configs] of this.warmupConfigs) {
|
|
89
|
+
for (const config of configs) {
|
|
90
|
+
totalTasks++;
|
|
91
|
+
taskDetails.push({
|
|
92
|
+
group: groupName,
|
|
93
|
+
name: config.name,
|
|
94
|
+
critical: config.critical || false,
|
|
95
|
+
batchSize: config.batchSize,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { totalGroups, totalTasks, taskDetails };
|
|
100
|
+
}
|
|
101
|
+
removeWarmupGroup(groupName) {
|
|
102
|
+
return this.warmupConfigs.delete(groupName);
|
|
103
|
+
}
|
|
104
|
+
clearWarmupConfigs() {
|
|
105
|
+
this.warmupConfigs.clear();
|
|
106
|
+
this.logger.debug('All warmup configurations cleared');
|
|
107
|
+
}
|
|
108
|
+
executeWarmupTask(config) {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
const startTime = Date.now();
|
|
111
|
+
const errors = [];
|
|
112
|
+
let itemCount = 0;
|
|
113
|
+
let success = true;
|
|
114
|
+
try {
|
|
115
|
+
this.logger.debug(`Executing warmup task: ${config.name}`);
|
|
116
|
+
const data = yield Promise.resolve(config.dataProvider());
|
|
117
|
+
if (Array.isArray(data)) {
|
|
118
|
+
const batchSize = config.batchSize || 100;
|
|
119
|
+
itemCount = data.length;
|
|
120
|
+
for (let i = 0; i < data.length; i += batchSize) {
|
|
121
|
+
const batch = data.slice(i, i + batchSize);
|
|
122
|
+
yield Promise.all(batch.map((item) => __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
try {
|
|
124
|
+
const key = typeof config.key === 'function'
|
|
125
|
+
? config.key(item)
|
|
126
|
+
: config.key;
|
|
127
|
+
yield this.cacheService.set(key, item, {
|
|
128
|
+
ttl: config.ttl,
|
|
129
|
+
layers: config.layers,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
errors.push(`Failed to cache item: ${error instanceof Error ? error.message : String(error)}`);
|
|
134
|
+
}
|
|
135
|
+
})));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (data && typeof data === 'object') {
|
|
139
|
+
if (data instanceof Map) {
|
|
140
|
+
itemCount = data.size;
|
|
141
|
+
for (const [key, value] of data) {
|
|
142
|
+
try {
|
|
143
|
+
yield this.cacheService.set(key, value, {
|
|
144
|
+
ttl: config.ttl,
|
|
145
|
+
layers: config.layers,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
errors.push(`Failed to cache key ${key}: ${error instanceof Error ? error.message : String(error)}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
itemCount = 1;
|
|
155
|
+
const key = typeof config.key === 'function' ? config.key(data) : config.key;
|
|
156
|
+
yield this.cacheService.set(key, data, {
|
|
157
|
+
ttl: config.ttl,
|
|
158
|
+
layers: config.layers,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (data !== null && data !== undefined) {
|
|
163
|
+
itemCount = 1;
|
|
164
|
+
const key = typeof config.key === 'function' ? config.key(data) : config.key;
|
|
165
|
+
yield this.cacheService.set(key, data, {
|
|
166
|
+
ttl: config.ttl,
|
|
167
|
+
layers: config.layers,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
errors.push('Data provider returned null or undefined');
|
|
172
|
+
success = false;
|
|
173
|
+
}
|
|
174
|
+
if (errors.length > 0) {
|
|
175
|
+
success = false;
|
|
176
|
+
this.logger.warn(`Warmup task ${config.name} completed with ${errors.length} errors`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
success = false;
|
|
181
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
182
|
+
this.logger.error(`Warmup task ${config.name} failed:`, error);
|
|
183
|
+
}
|
|
184
|
+
const duration = Date.now() - startTime;
|
|
185
|
+
return {
|
|
186
|
+
name: config.name,
|
|
187
|
+
success,
|
|
188
|
+
itemCount,
|
|
189
|
+
duration,
|
|
190
|
+
errors,
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
exports.CacheWarmupService = CacheWarmupService;
|
|
196
|
+
exports.CacheWarmupService = CacheWarmupService = CacheWarmupService_1 = __decorate([
|
|
197
|
+
(0, common_1.Injectable)(),
|
|
198
|
+
__metadata("design:paramtypes", [cache_service_1.CacheService])
|
|
199
|
+
], CacheWarmupService);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CacheEvict = CacheEvict;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const cacheable_decorator_1 = require("./cacheable.decorator");
|
|
15
|
+
function CacheEvict(options = {}) {
|
|
16
|
+
const logger = new common_1.Logger('CacheEvictDecorator');
|
|
17
|
+
return function (target, propertyKey, descriptor) {
|
|
18
|
+
const originalMethod = descriptor.value;
|
|
19
|
+
const methodName = String(propertyKey);
|
|
20
|
+
descriptor.value = function (...args) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const cacheService = (0, cacheable_decorator_1.getCacheService)();
|
|
23
|
+
if (!cacheService) {
|
|
24
|
+
logger.warn(`CacheService not initialized. Skipping cache eviction for ${target.constructor.name}.${methodName}`);
|
|
25
|
+
return originalMethod.apply(this, args);
|
|
26
|
+
}
|
|
27
|
+
const evictCache = (result) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
try {
|
|
29
|
+
if (options.condition) {
|
|
30
|
+
const shouldEvict = yield Promise.resolve(options.condition(...args, result));
|
|
31
|
+
if (!shouldEvict) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (options.keys && options.keys.length > 0) {
|
|
36
|
+
const resolvedKeys = options.keys.map((keyOrFn) => typeof keyOrFn === 'function' ? keyOrFn(...args) : keyOrFn);
|
|
37
|
+
yield cacheService.delete(resolvedKeys, options.layers);
|
|
38
|
+
}
|
|
39
|
+
if (options.patterns && options.patterns.length > 0) {
|
|
40
|
+
for (const pattern of options.patterns) {
|
|
41
|
+
yield cacheService.deletePattern(pattern, options.layers);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (options.tags && options.tags.length > 0) {
|
|
45
|
+
yield cacheService.invalidateTags(options.tags);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
logger.error(`Cache eviction error in ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
if (options.timing === 'before') {
|
|
54
|
+
yield evictCache();
|
|
55
|
+
}
|
|
56
|
+
const result = yield originalMethod.apply(this, args);
|
|
57
|
+
if (options.timing !== 'before') {
|
|
58
|
+
yield evictCache(result);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (options.timing === 'before') {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
return descriptor;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CachePut = CachePut;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const utils_1 = require("../utils");
|
|
15
|
+
const cacheable_decorator_1 = require("./cacheable.decorator");
|
|
16
|
+
function CachePut(options = {}) {
|
|
17
|
+
const logger = new common_1.Logger('CachePutDecorator');
|
|
18
|
+
return function (target, propertyKey, descriptor) {
|
|
19
|
+
const originalMethod = descriptor.value;
|
|
20
|
+
const methodName = String(propertyKey);
|
|
21
|
+
descriptor.value = function (...args) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const cacheService = (0, cacheable_decorator_1.getCacheService)();
|
|
24
|
+
if (!cacheService) {
|
|
25
|
+
logger.warn(`CacheService not initialized. Skipping cache put for ${target.constructor.name}.${methodName}`);
|
|
26
|
+
return originalMethod.apply(this, args);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const result = yield originalMethod.apply(this, args);
|
|
30
|
+
if (options.condition) {
|
|
31
|
+
const shouldCache = yield Promise.resolve(options.condition(...args));
|
|
32
|
+
if (!shouldCache) {
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const key = utils_1.KeyGenerator.generate(options, args);
|
|
37
|
+
yield cacheService.set(key, result, options);
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger.error(`Cache put error in ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
return descriptor;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.setCacheService = setCacheService;
|
|
13
|
+
exports.getCacheService = getCacheService;
|
|
14
|
+
exports.Cacheable = Cacheable;
|
|
15
|
+
const common_1 = require("@nestjs/common");
|
|
16
|
+
const utils_1 = require("../utils");
|
|
17
|
+
let globalCacheService = null;
|
|
18
|
+
function setCacheService(cacheService) {
|
|
19
|
+
globalCacheService = cacheService;
|
|
20
|
+
}
|
|
21
|
+
function getCacheService() {
|
|
22
|
+
return globalCacheService;
|
|
23
|
+
}
|
|
24
|
+
function Cacheable(options = {}) {
|
|
25
|
+
const logger = new common_1.Logger('CacheableDecorator');
|
|
26
|
+
return function (target, propertyKey, descriptor) {
|
|
27
|
+
const originalMethod = descriptor.value;
|
|
28
|
+
const methodName = String(propertyKey);
|
|
29
|
+
descriptor.value = function (...args) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const cacheService = getCacheService();
|
|
32
|
+
if (!cacheService) {
|
|
33
|
+
logger.warn(`CacheService not initialized. Skipping cache for ${target.constructor.name}.${methodName}`);
|
|
34
|
+
return originalMethod.apply(this, args);
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const key = utils_1.KeyGenerator.generate(options, args);
|
|
38
|
+
if (options.condition) {
|
|
39
|
+
const shouldCache = yield Promise.resolve(options.condition(...args));
|
|
40
|
+
if (!shouldCache) {
|
|
41
|
+
return originalMethod.apply(this, args);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const dependencies = options.dependencies
|
|
45
|
+
? yield resolveDependenciesWithContext(options.dependencies, args)
|
|
46
|
+
: undefined;
|
|
47
|
+
return yield cacheService.getOrSet(key, () => originalMethod.apply(this, args), Object.assign(Object.assign({}, options), { dependencies }));
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
logger.error(`Cache error in ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
51
|
+
return originalMethod.apply(this, args);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
return descriptor;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function resolveDependenciesWithContext(dependencies, args) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
return dependencies.map((dep) => {
|
|
61
|
+
if (dep.paramsFactory && typeof dep.paramsFactory === 'function') {
|
|
62
|
+
const params = dep.paramsFactory(...args);
|
|
63
|
+
return new dep.constructor(dep.sql, () => params, dep.name);
|
|
64
|
+
}
|
|
65
|
+
return dep;
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CachePut = exports.CacheEvict = exports.setCacheService = exports.getCacheService = exports.Cacheable = void 0;
|
|
4
|
+
var cacheable_decorator_1 = require("./cacheable.decorator");
|
|
5
|
+
Object.defineProperty(exports, "Cacheable", { enumerable: true, get: function () { return cacheable_decorator_1.Cacheable; } });
|
|
6
|
+
Object.defineProperty(exports, "getCacheService", { enumerable: true, get: function () { return cacheable_decorator_1.getCacheService; } });
|
|
7
|
+
Object.defineProperty(exports, "setCacheService", { enumerable: true, get: function () { return cacheable_decorator_1.setCacheService; } });
|
|
8
|
+
var cache_evict_decorator_1 = require("./cache-evict.decorator");
|
|
9
|
+
Object.defineProperty(exports, "CacheEvict", { enumerable: true, get: function () { return cache_evict_decorator_1.CacheEvict; } });
|
|
10
|
+
var cache_put_decorator_1 = require("./cache-put.decorator");
|
|
11
|
+
Object.defineProperty(exports, "CachePut", { enumerable: true, get: function () { return cache_put_decorator_1.CachePut; } });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
2
|
+
export declare class CallbackDependency implements CacheDependency {
|
|
3
|
+
private readonly callback;
|
|
4
|
+
private readonly name?;
|
|
5
|
+
constructor(callback: () => Promise<any> | any, name?: string);
|
|
6
|
+
getKey(): string;
|
|
7
|
+
getData(): Promise<any>;
|
|
8
|
+
isChanged(oldData: any): Promise<boolean>;
|
|
9
|
+
private isEqual;
|
|
10
|
+
private hashCode;
|
|
11
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CallbackDependency = void 0;
|
|
13
|
+
class CallbackDependency {
|
|
14
|
+
constructor(callback, name) {
|
|
15
|
+
this.callback = callback;
|
|
16
|
+
this.name = name;
|
|
17
|
+
if (typeof callback !== 'function') {
|
|
18
|
+
throw new Error('CallbackDependency requires a valid callback function');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
getKey() {
|
|
22
|
+
const callbackName = this.name || this.callback.name || 'anonymous';
|
|
23
|
+
return `callback:${callbackName}:${this.hashCode(this.callback.toString())}`;
|
|
24
|
+
}
|
|
25
|
+
getData() {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
try {
|
|
28
|
+
return yield Promise.resolve(this.callback());
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`CallbackDependency getData failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
isChanged(oldData) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
try {
|
|
38
|
+
const currentData = yield this.getData();
|
|
39
|
+
return !this.isEqual(oldData, currentData);
|
|
40
|
+
}
|
|
41
|
+
catch (_a) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
isEqual(a, b) {
|
|
47
|
+
if (a === b) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if (a == null || b == null) {
|
|
51
|
+
return a === b;
|
|
52
|
+
}
|
|
53
|
+
if (typeof a !== typeof b) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (typeof a !== 'object') {
|
|
57
|
+
return a === b;
|
|
58
|
+
}
|
|
59
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
60
|
+
if (a.length !== b.length) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
for (let i = 0; i < a.length; i++) {
|
|
64
|
+
if (!this.isEqual(a[i], b[i])) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
const keysA = Object.keys(a);
|
|
71
|
+
const keysB = Object.keys(b);
|
|
72
|
+
if (keysA.length !== keysB.length) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
for (const key of keysA) {
|
|
76
|
+
if (!keysB.includes(key) || !this.isEqual(a[key], b[key])) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
hashCode(str) {
|
|
83
|
+
let hash = 0;
|
|
84
|
+
for (let i = 0; i < str.length; i++) {
|
|
85
|
+
const char = str.charCodeAt(i);
|
|
86
|
+
hash = (hash << 5) - hash + char;
|
|
87
|
+
hash = hash & hash;
|
|
88
|
+
}
|
|
89
|
+
return Math.abs(hash).toString(36);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.CallbackDependency = CallbackDependency;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
2
|
+
export declare class ChainDependency implements CacheDependency {
|
|
3
|
+
private readonly dependencies;
|
|
4
|
+
constructor(dependencies: CacheDependency[]);
|
|
5
|
+
getKey(): string;
|
|
6
|
+
getData(): Promise<Array<{
|
|
7
|
+
key: string;
|
|
8
|
+
data: any;
|
|
9
|
+
}>>;
|
|
10
|
+
isChanged(oldData: Array<{
|
|
11
|
+
key: string;
|
|
12
|
+
data: any;
|
|
13
|
+
}>): Promise<boolean>;
|
|
14
|
+
reset(): Promise<void>;
|
|
15
|
+
getDependencies(): CacheDependency[];
|
|
16
|
+
getChangedDependencies(oldData: Array<{
|
|
17
|
+
key: string;
|
|
18
|
+
data: any;
|
|
19
|
+
}>): Promise<CacheDependency[]>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ChainDependency = void 0;
|
|
13
|
+
class ChainDependency {
|
|
14
|
+
constructor(dependencies) {
|
|
15
|
+
this.dependencies = dependencies;
|
|
16
|
+
if (!Array.isArray(dependencies) || dependencies.length === 0) {
|
|
17
|
+
throw new Error('ChainDependency requires at least one dependency');
|
|
18
|
+
}
|
|
19
|
+
for (const dep of dependencies) {
|
|
20
|
+
if (!dep.getKey || !dep.getData || !dep.isChanged) {
|
|
21
|
+
throw new Error('All dependencies must implement CacheDependency interface');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
getKey() {
|
|
26
|
+
const keys = this.dependencies.map((dep) => dep.getKey());
|
|
27
|
+
return `chain:${keys.join('+')}`;
|
|
28
|
+
}
|
|
29
|
+
getData() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const results = [];
|
|
32
|
+
for (const dep of this.dependencies) {
|
|
33
|
+
try {
|
|
34
|
+
const data = yield dep.getData();
|
|
35
|
+
results.push({
|
|
36
|
+
key: dep.getKey(),
|
|
37
|
+
data,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
results.push({
|
|
42
|
+
key: dep.getKey(),
|
|
43
|
+
data: {
|
|
44
|
+
error: error instanceof Error ? error.message : String(error),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return results;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
isChanged(oldData) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
if (!Array.isArray(oldData) ||
|
|
55
|
+
oldData.length !== this.dependencies.length) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
for (let i = 0; i < this.dependencies.length; i++) {
|
|
59
|
+
const dep = this.dependencies[i];
|
|
60
|
+
const oldDepData = oldData[i];
|
|
61
|
+
if (oldDepData.key !== dep.getKey()) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const changed = yield dep.isChanged(oldDepData.data);
|
|
66
|
+
if (changed) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (_a) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
reset() {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
for (const dep of this.dependencies) {
|
|
80
|
+
if (dep.reset) {
|
|
81
|
+
yield dep.reset();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
getDependencies() {
|
|
87
|
+
return [...this.dependencies];
|
|
88
|
+
}
|
|
89
|
+
getChangedDependencies(oldData) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
if (!Array.isArray(oldData) ||
|
|
92
|
+
oldData.length !== this.dependencies.length) {
|
|
93
|
+
return this.dependencies;
|
|
94
|
+
}
|
|
95
|
+
const changed = [];
|
|
96
|
+
for (let i = 0; i < this.dependencies.length; i++) {
|
|
97
|
+
const dep = this.dependencies[i];
|
|
98
|
+
const oldDepData = oldData[i];
|
|
99
|
+
try {
|
|
100
|
+
if (oldDepData.key !== dep.getKey() ||
|
|
101
|
+
(yield dep.isChanged(oldDepData.data))) {
|
|
102
|
+
changed.push(dep);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (_a) {
|
|
106
|
+
changed.push(dep);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return changed;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.ChainDependency = ChainDependency;
|