koatty_cacheable 1.6.1 → 2.0.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 +8 -0
- package/README.md +76 -29
- package/dist/README.md +76 -29
- package/dist/index.d.ts +30 -24
- package/dist/index.js +297 -149
- package/dist/index.mjs +296 -147
- package/dist/package.json +6 -3
- package/package.json +6 -3
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,142 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @Author: richen
|
|
3
|
-
* @Date: 2025-06-
|
|
3
|
+
* @Date: 2025-06-23 01:59:54
|
|
4
4
|
* @License: BSD (3-Clause)
|
|
5
5
|
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
6
6
|
* @HomePage: https://koatty.org/
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { DefaultLogger, Logger } from 'koatty_logger';
|
|
9
9
|
import { Helper } from 'koatty_lib';
|
|
10
|
-
import { DefaultLogger } from 'koatty_logger';
|
|
11
10
|
import { CacheStore } from 'koatty_store';
|
|
11
|
+
import { IOCContainer } from 'koatty_container';
|
|
12
|
+
|
|
13
|
+
// storeCache
|
|
14
|
+
const storeCache = {
|
|
15
|
+
store: null
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* get instances of storeCache
|
|
19
|
+
*
|
|
20
|
+
* @export
|
|
21
|
+
* @param {Application} app
|
|
22
|
+
* @returns {*} {CacheStore}
|
|
23
|
+
*/
|
|
24
|
+
async function GetCacheStore(app) {
|
|
25
|
+
if (storeCache.store && storeCache.store.getConnection) {
|
|
26
|
+
return storeCache.store;
|
|
27
|
+
}
|
|
28
|
+
let opt = {
|
|
29
|
+
type: "memory",
|
|
30
|
+
db: 0,
|
|
31
|
+
timeout: 30
|
|
32
|
+
};
|
|
33
|
+
if (app && Helper.isFunction(app.config)) {
|
|
34
|
+
opt = app.config("CacheStore") || app.config("CacheStore", "db");
|
|
35
|
+
if (Helper.isEmpty(opt)) {
|
|
36
|
+
DefaultLogger.Warn(`Missing CacheStore server configuration. Please write a configuration item with the key name 'CacheStore' in the db.ts file.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
storeCache.store = CacheStore.getInstance(opt);
|
|
40
|
+
if (!Helper.isFunction(storeCache.store.getConnection)) {
|
|
41
|
+
throw Error(`CacheStore connection failed. `);
|
|
42
|
+
}
|
|
43
|
+
await storeCache.store.client.getConnection();
|
|
44
|
+
return storeCache.store;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* @Author: richen
|
|
49
|
+
* @Date: 2020-07-06 19:53:43
|
|
50
|
+
* @LastEditTime: 2025-06-23 15:53:46
|
|
51
|
+
* @Description:
|
|
52
|
+
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
53
|
+
*/
|
|
54
|
+
class CacheManager {
|
|
55
|
+
static instance;
|
|
56
|
+
cacheStore = null;
|
|
57
|
+
defaultTimeout = 300;
|
|
58
|
+
defaultDelayedDoubleDeletion = true;
|
|
59
|
+
static getInstance() {
|
|
60
|
+
if (!CacheManager.instance) {
|
|
61
|
+
CacheManager.instance = new CacheManager();
|
|
62
|
+
}
|
|
63
|
+
return CacheManager.instance;
|
|
64
|
+
}
|
|
65
|
+
setCacheStore(store) {
|
|
66
|
+
this.cacheStore = store;
|
|
67
|
+
}
|
|
68
|
+
getCacheStore() {
|
|
69
|
+
return this.cacheStore;
|
|
70
|
+
}
|
|
71
|
+
setDefaultConfig(timeout, delayedDoubleDeletion) {
|
|
72
|
+
if (timeout !== undefined)
|
|
73
|
+
this.defaultTimeout = timeout;
|
|
74
|
+
if (delayedDoubleDeletion !== undefined)
|
|
75
|
+
this.defaultDelayedDoubleDeletion = delayedDoubleDeletion;
|
|
76
|
+
}
|
|
77
|
+
getDefaultTimeout() {
|
|
78
|
+
return this.defaultTimeout;
|
|
79
|
+
}
|
|
80
|
+
getDefaultDelayedDoubleDeletion() {
|
|
81
|
+
return this.defaultDelayedDoubleDeletion;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @Description: Cache injector, unified processing of all cache decorators
|
|
87
|
+
* @Usage:
|
|
88
|
+
* @Author: richen
|
|
89
|
+
* @Date: 2025-01-10 14:00:00
|
|
90
|
+
* @LastEditTime: 2025-01-10 14:00:00
|
|
91
|
+
* @License: BSD (3-Clause)
|
|
92
|
+
* @Copyright (c): <richenlin(at)gmail.com>
|
|
93
|
+
*/
|
|
94
|
+
// import { Helper } from 'koatty_lib';
|
|
95
|
+
// Create logger instance
|
|
96
|
+
const logger$1 = new Logger();
|
|
97
|
+
/**
|
|
98
|
+
* Cache injector - initialize global cache manager and store
|
|
99
|
+
* @param options Cache options
|
|
100
|
+
* @param app Koatty application instance
|
|
101
|
+
*/
|
|
102
|
+
async function injectCache(options, app) {
|
|
103
|
+
try {
|
|
104
|
+
logger$1.Debug('Initializing cache system...');
|
|
105
|
+
// Get cache store instance
|
|
106
|
+
const store = await GetCacheStore(app);
|
|
107
|
+
if (!store) {
|
|
108
|
+
logger$1.Warn('Cache store unavailable, cache system disabled');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Initialize global cache manager
|
|
112
|
+
const cacheManager = CacheManager.getInstance();
|
|
113
|
+
cacheManager.setCacheStore(store);
|
|
114
|
+
// Set default configuration
|
|
115
|
+
cacheManager.setDefaultConfig(options.cacheTimeout || 300, options.delayedDoubleDeletion !== undefined ? options.delayedDoubleDeletion : true);
|
|
116
|
+
logger$1.Info(`Cache system initialized successfully with timeout: ${options.cacheTimeout || 300}s`);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
logger$1.Error('Cache system initialization failed:', error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Close cache store connection
|
|
124
|
+
* @param app Koatty application instance
|
|
125
|
+
*/
|
|
126
|
+
async function closeCacheStore(_app) {
|
|
127
|
+
try {
|
|
128
|
+
logger$1.Debug('Closing cache store connection...');
|
|
129
|
+
// Reset global cache manager
|
|
130
|
+
const cacheManager = CacheManager.getInstance();
|
|
131
|
+
const store = cacheManager.getCacheStore();
|
|
132
|
+
await store?.close();
|
|
133
|
+
cacheManager.setCacheStore(null);
|
|
134
|
+
logger$1.Info('Cache store connection closed');
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
logger$1.Error('Error closing cache store connection:', error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
12
140
|
|
|
13
141
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
14
142
|
/*
|
|
@@ -93,84 +221,6 @@ async function asyncDelayedExecution(fn, ms) {
|
|
|
93
221
|
return fn();
|
|
94
222
|
}
|
|
95
223
|
|
|
96
|
-
/*
|
|
97
|
-
* @Description:
|
|
98
|
-
* @Usage:
|
|
99
|
-
* @Author: richen
|
|
100
|
-
* @Date: 2024-11-07 16:00:02
|
|
101
|
-
* @LastEditTime: 2024-11-07 16:00:05
|
|
102
|
-
* @License: BSD (3-Clause)
|
|
103
|
-
* @Copyright (c): <richenlin(at)gmail.com>
|
|
104
|
-
*/
|
|
105
|
-
// storeCache
|
|
106
|
-
const storeCache = {
|
|
107
|
-
store: null
|
|
108
|
-
};
|
|
109
|
-
/**
|
|
110
|
-
* get instances of storeCache
|
|
111
|
-
*
|
|
112
|
-
* @export
|
|
113
|
-
* @param {Application} app
|
|
114
|
-
* @returns {*} {CacheStore}
|
|
115
|
-
*/
|
|
116
|
-
async function GetCacheStore(app) {
|
|
117
|
-
if (storeCache.store && storeCache.store.getConnection) {
|
|
118
|
-
return storeCache.store;
|
|
119
|
-
}
|
|
120
|
-
let opt = {
|
|
121
|
-
type: "memory",
|
|
122
|
-
db: 0,
|
|
123
|
-
timeout: 30
|
|
124
|
-
};
|
|
125
|
-
if (app && Helper.isFunction(app.config)) {
|
|
126
|
-
opt = app.config("CacheStore") || app.config("CacheStore", "db");
|
|
127
|
-
if (Helper.isEmpty(opt)) {
|
|
128
|
-
DefaultLogger.Warn(`Missing CacheStore server configuration. Please write a configuration item with the key name 'CacheStore' in the db.ts file.`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
storeCache.store = CacheStore.getInstance(opt);
|
|
132
|
-
if (!Helper.isFunction(storeCache.store.getConnection)) {
|
|
133
|
-
throw Error(`CacheStore connection failed. `);
|
|
134
|
-
}
|
|
135
|
-
await storeCache.store.client.getConnection();
|
|
136
|
-
return storeCache.store;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* initiation CacheStore connection and client.
|
|
140
|
-
*
|
|
141
|
-
*/
|
|
142
|
-
async function InitCacheStore() {
|
|
143
|
-
if (storeCache.store) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
const app = IOCContainer.getApp();
|
|
147
|
-
app?.once("appReady", async () => {
|
|
148
|
-
await GetCacheStore(app);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Close cache store connection for cleanup (mainly for testing)
|
|
153
|
-
*/
|
|
154
|
-
async function CloseCacheStore() {
|
|
155
|
-
if (storeCache.store && storeCache.store.client) {
|
|
156
|
-
try {
|
|
157
|
-
const client = storeCache.store.client;
|
|
158
|
-
if (typeof client.quit === 'function') {
|
|
159
|
-
await client.quit();
|
|
160
|
-
}
|
|
161
|
-
else if (typeof client.close === 'function') {
|
|
162
|
-
await client.close();
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
// Ignore cleanup errors
|
|
167
|
-
}
|
|
168
|
-
finally {
|
|
169
|
-
storeCache.store = null;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
224
|
/*
|
|
175
225
|
* @Author: richen
|
|
176
226
|
* @Date: 2020-07-06 19:53:43
|
|
@@ -178,6 +228,17 @@ async function CloseCacheStore() {
|
|
|
178
228
|
* @Description:
|
|
179
229
|
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
180
230
|
*/
|
|
231
|
+
// Create logger instance
|
|
232
|
+
const logger = new Logger();
|
|
233
|
+
// Define cache decorator types
|
|
234
|
+
var DecoratorType;
|
|
235
|
+
(function (DecoratorType) {
|
|
236
|
+
DecoratorType["CACHE_EVICT"] = "CACHE_EVICT";
|
|
237
|
+
DecoratorType["CACHE_ABLE"] = "CACHE_ABLE";
|
|
238
|
+
})(DecoratorType || (DecoratorType = {}));
|
|
239
|
+
// IOC container key constant
|
|
240
|
+
const COMPONENT_CACHE = "COMPONENT_CACHE";
|
|
241
|
+
const CACHE_METADATA_KEY = "CACHE_METADATA_KEY";
|
|
181
242
|
/**
|
|
182
243
|
* Decorate this method to support caching.
|
|
183
244
|
* The cache method returns a value to ensure that the next time
|
|
@@ -196,53 +257,80 @@ async function CloseCacheStore() {
|
|
|
196
257
|
* Use the 'id' parameters of the method as cache subkeys, the cache expiration time 30s
|
|
197
258
|
* @returns {MethodDecorator}
|
|
198
259
|
*/
|
|
199
|
-
function CacheAble(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
260
|
+
function CacheAble(cacheNameOrOpt, opt = {}) {
|
|
261
|
+
// Handle overloaded parameters
|
|
262
|
+
let cacheName;
|
|
263
|
+
let options;
|
|
264
|
+
if (typeof cacheNameOrOpt === 'string') {
|
|
265
|
+
cacheName = cacheNameOrOpt;
|
|
266
|
+
options = opt;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
options = cacheNameOrOpt || {};
|
|
270
|
+
cacheName = options.cacheName;
|
|
271
|
+
}
|
|
203
272
|
return (target, methodName, descriptor) => {
|
|
204
273
|
const componentType = IOCContainer.getType(target);
|
|
205
274
|
if (!["SERVICE", "COMPONENT"].includes(componentType)) {
|
|
206
275
|
throw Error("This decorator only used in the service、component class.");
|
|
207
276
|
}
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
// Get
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
277
|
+
// Generate cache name if not provided
|
|
278
|
+
const finalCacheName = cacheName || `${target.constructor.name}:${String(methodName)}`;
|
|
279
|
+
// Get original method
|
|
280
|
+
const originalMethod = descriptor.value;
|
|
281
|
+
if (!Helper.isFunction(originalMethod)) {
|
|
282
|
+
throw new Error(`CacheAble decorator can only be applied to methods`);
|
|
283
|
+
}
|
|
284
|
+
// Create wrapped method
|
|
285
|
+
descriptor.value = function (...args) {
|
|
286
|
+
const cacheManager = CacheManager.getInstance();
|
|
287
|
+
const store = cacheManager.getCacheStore();
|
|
288
|
+
// If cache store is not available, execute original method directly
|
|
289
|
+
if (!store) {
|
|
290
|
+
logger.Debug(`Cache store not available for ${finalCacheName}, executing original method`);
|
|
291
|
+
return originalMethod.apply(this, args);
|
|
292
|
+
}
|
|
293
|
+
// Get method parameter list
|
|
294
|
+
const funcParams = getArgs(originalMethod);
|
|
295
|
+
// Get cache parameter positions
|
|
296
|
+
const paramIndexes = getParamIndex(funcParams, options.params || []);
|
|
297
|
+
return (async () => {
|
|
298
|
+
try {
|
|
299
|
+
// Generate cache key
|
|
300
|
+
const key = generateCacheKey(finalCacheName, paramIndexes, options.params || [], args);
|
|
301
|
+
// Try to get data from cache
|
|
302
|
+
const cached = await store.get(key).catch((e) => {
|
|
303
|
+
logger.Debug("Cache get error:" + e.message);
|
|
304
|
+
return null;
|
|
227
305
|
});
|
|
228
|
-
if (!Helper.isEmpty(
|
|
229
|
-
|
|
306
|
+
if (!Helper.isEmpty(cached)) {
|
|
307
|
+
logger.Debug(`Cache hit for key: ${key}`);
|
|
308
|
+
try {
|
|
309
|
+
return JSON.parse(cached);
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// If parse fails, return as string (for simple values)
|
|
313
|
+
return cached;
|
|
314
|
+
}
|
|
230
315
|
}
|
|
231
|
-
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
|
|
316
|
+
logger.Debug(`Cache miss for key: ${key}`);
|
|
317
|
+
// Execute original method
|
|
318
|
+
const result = await originalMethod.apply(this, args);
|
|
319
|
+
// Use decorator timeout if specified, otherwise use global default
|
|
320
|
+
const timeout = options.timeout || cacheManager.getDefaultTimeout();
|
|
321
|
+
// Asynchronously set cache
|
|
322
|
+
store.set(key, Helper.isJSONObj(result) ? JSON.stringify(result) : result, timeout).catch((e) => {
|
|
323
|
+
logger.Debug("Cache set error:" + e.message);
|
|
235
324
|
});
|
|
236
325
|
return result;
|
|
237
326
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
327
|
+
catch (error) {
|
|
328
|
+
logger.Debug(`CacheAble wrapper error: ${error.message}`);
|
|
329
|
+
// If cache operation fails, execute original method directly
|
|
330
|
+
return originalMethod.apply(this, args);
|
|
241
331
|
}
|
|
242
|
-
}
|
|
332
|
+
})();
|
|
243
333
|
};
|
|
244
|
-
// bind app_ready hook event
|
|
245
|
-
InitCacheStore();
|
|
246
334
|
return descriptor;
|
|
247
335
|
};
|
|
248
336
|
}
|
|
@@ -262,55 +350,116 @@ function CacheAble(cacheName, opt = {
|
|
|
262
350
|
* and clear the cache after the method executed
|
|
263
351
|
* @returns
|
|
264
352
|
*/
|
|
265
|
-
function CacheEvict(
|
|
266
|
-
|
|
267
|
-
|
|
353
|
+
function CacheEvict(cacheNameOrOpt, opt = {}) {
|
|
354
|
+
// Handle overloaded parameters
|
|
355
|
+
let cacheName;
|
|
356
|
+
let options;
|
|
357
|
+
if (typeof cacheNameOrOpt === 'string') {
|
|
358
|
+
cacheName = cacheNameOrOpt;
|
|
359
|
+
options = opt;
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
options = cacheNameOrOpt || {};
|
|
363
|
+
cacheName = options.cacheName;
|
|
364
|
+
}
|
|
268
365
|
return (target, methodName, descriptor) => {
|
|
269
366
|
const componentType = IOCContainer.getType(target);
|
|
270
367
|
if (!["SERVICE", "COMPONENT"].includes(componentType)) {
|
|
271
368
|
throw Error("This decorator only used in the service、component class.");
|
|
272
369
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
//
|
|
276
|
-
const
|
|
277
|
-
// Get
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
370
|
+
// Save class to IOC container for tracking
|
|
371
|
+
IOCContainer.saveClass("COMPONENT", target, COMPONENT_CACHE);
|
|
372
|
+
// Generate cache name if not provided
|
|
373
|
+
const finalCacheName = cacheName || `${target.constructor.name}:${String(methodName)}`;
|
|
374
|
+
// Get original method
|
|
375
|
+
const originalMethod = descriptor.value;
|
|
376
|
+
if (!Helper.isFunction(originalMethod)) {
|
|
377
|
+
throw new Error(`CacheEvict decorator can only be applied to methods`);
|
|
378
|
+
}
|
|
379
|
+
// Create wrapped method
|
|
380
|
+
descriptor.value = function (...args) {
|
|
381
|
+
const cacheManager = CacheManager.getInstance();
|
|
382
|
+
const store = cacheManager.getCacheStore();
|
|
383
|
+
// If cache store is not available, execute original method directly
|
|
384
|
+
if (!store) {
|
|
385
|
+
logger.Debug(`Cache store not available for ${finalCacheName}, executing original method`);
|
|
386
|
+
return originalMethod.apply(this, args);
|
|
387
|
+
}
|
|
388
|
+
// Get method parameter list
|
|
389
|
+
const funcParams = getArgs(originalMethod);
|
|
390
|
+
// Get cache parameter positions
|
|
391
|
+
const paramIndexes = getParamIndex(funcParams, options.params || []);
|
|
392
|
+
return (async () => {
|
|
393
|
+
try {
|
|
394
|
+
// Generate cache key
|
|
395
|
+
const key = generateCacheKey(finalCacheName, paramIndexes, options.params || [], args);
|
|
396
|
+
// Execute original method
|
|
397
|
+
const result = await originalMethod.apply(this, args);
|
|
398
|
+
// Immediately clear cache
|
|
291
399
|
store.del(key).catch((e) => {
|
|
292
|
-
|
|
400
|
+
logger.Debug("Cache delete error:" + e.message);
|
|
293
401
|
});
|
|
294
|
-
if
|
|
402
|
+
// Use decorator setting if specified, otherwise use global default
|
|
403
|
+
const enableDelayedDeletion = options.delayedDoubleDeletion !== undefined
|
|
404
|
+
? options.delayedDoubleDeletion
|
|
405
|
+
: cacheManager.getDefaultDelayedDoubleDeletion();
|
|
406
|
+
// Delayed double deletion strategy
|
|
407
|
+
if (enableDelayedDeletion !== false) {
|
|
295
408
|
const delayTime = 5000;
|
|
296
409
|
asyncDelayedExecution(() => {
|
|
297
410
|
store.del(key).catch((e) => {
|
|
298
|
-
|
|
411
|
+
logger.Debug("Cache double delete error:" + e.message);
|
|
299
412
|
});
|
|
300
413
|
}, delayTime);
|
|
301
414
|
}
|
|
302
415
|
return result;
|
|
303
416
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
417
|
+
catch (error) {
|
|
418
|
+
logger.Debug(`CacheEvict wrapper error: ${error.message}`);
|
|
419
|
+
// If cache operation fails, execute original method directly
|
|
420
|
+
return originalMethod.apply(this, args);
|
|
307
421
|
}
|
|
308
|
-
}
|
|
422
|
+
})();
|
|
309
423
|
};
|
|
310
|
-
// bind app_ready hook event
|
|
311
|
-
InitCacheStore();
|
|
312
424
|
return descriptor;
|
|
313
425
|
};
|
|
314
426
|
}
|
|
315
427
|
|
|
316
|
-
|
|
428
|
+
/*
|
|
429
|
+
* @Description:
|
|
430
|
+
* @Usage:
|
|
431
|
+
* @Author: richen
|
|
432
|
+
* @Date: 2024-11-07 16:00:02
|
|
433
|
+
* @LastEditTime: 2024-11-07 16:00:05
|
|
434
|
+
* @License: BSD (3-Clause)
|
|
435
|
+
* @Copyright (c): <richenlin(at)gmail.com>
|
|
436
|
+
*/
|
|
437
|
+
/**
|
|
438
|
+
* defaultOptions
|
|
439
|
+
*/
|
|
440
|
+
const defaultOptions = {
|
|
441
|
+
cacheTimeout: 300,
|
|
442
|
+
delayedDoubleDeletion: true,
|
|
443
|
+
redisConfig: {
|
|
444
|
+
host: "localhost",
|
|
445
|
+
port: 6379,
|
|
446
|
+
password: "",
|
|
447
|
+
db: 0,
|
|
448
|
+
keyPrefix: "redlock:"
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* @param options - The options for the scheduled job
|
|
453
|
+
* @param app - The Koatty application instance
|
|
454
|
+
*/
|
|
455
|
+
async function KoattyCache(options, app) {
|
|
456
|
+
options = { ...defaultOptions, ...options };
|
|
457
|
+
// inject cache decorator
|
|
458
|
+
await injectCache(options, app);
|
|
459
|
+
// Register cleanup on app stop
|
|
460
|
+
app.on('appStop', async () => {
|
|
461
|
+
await closeCacheStore();
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export { CACHE_METADATA_KEY, CacheAble, CacheEvict, DecoratorType, KoattyCache };
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koatty_cacheable",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Cacheable for koatty.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"release:pre": "npm run release -- --prerelease",
|
|
17
17
|
"release:major": "npm run release -- --release-as major",
|
|
18
18
|
"release:minor": "npm run release -- --release-as minor",
|
|
19
|
-
"test": "npm run eslint && jest --passWithNoTests",
|
|
19
|
+
"test": "NODE_ENV=test npm run eslint && NODE_ENV=test jest --passWithNoTests",
|
|
20
20
|
"test:cov": "jest --collectCoverage --detectOpenHandles",
|
|
21
21
|
"version": "conventional-changelog -p angular -i CHANGELOG.md -s"
|
|
22
22
|
},
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"@types/koa": "^2.x.x",
|
|
68
68
|
"@types/lodash": "^4.x.x",
|
|
69
69
|
"@types/node": "^22.x.x",
|
|
70
|
+
"@types/ws": "^8.18.1",
|
|
70
71
|
"@typescript-eslint/eslint-plugin": "^8.x.x",
|
|
71
72
|
"@typescript-eslint/parser": "^8.x.x",
|
|
72
73
|
"conventional-changelog-cli": "^5.x.x",
|
|
@@ -87,12 +88,14 @@
|
|
|
87
88
|
},
|
|
88
89
|
"dependencies": {
|
|
89
90
|
"koatty_container": "^1.x.x",
|
|
91
|
+
"koatty_core": "^1.x.x",
|
|
90
92
|
"koatty_lib": "^1.x.x",
|
|
91
93
|
"koatty_logger": "^2.x.x",
|
|
92
|
-
"koatty_store": "^1.
|
|
94
|
+
"koatty_store": "^1.x.x"
|
|
93
95
|
},
|
|
94
96
|
"peerDependencies": {
|
|
95
97
|
"koatty_container": "^1.x.x",
|
|
98
|
+
"koatty_core": "^1.x.x",
|
|
96
99
|
"koatty_lib": "^1.x.x",
|
|
97
100
|
"koatty_logger": "^2.x.x"
|
|
98
101
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koatty_cacheable",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Cacheable for koatty.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"release:pre": "npm run release -- --prerelease",
|
|
17
17
|
"release:major": "npm run release -- --release-as major",
|
|
18
18
|
"release:minor": "npm run release -- --release-as minor",
|
|
19
|
-
"test": "npm run eslint && jest --passWithNoTests",
|
|
19
|
+
"test": "NODE_ENV=test npm run eslint && NODE_ENV=test jest --passWithNoTests",
|
|
20
20
|
"test:cov": "jest --collectCoverage --detectOpenHandles",
|
|
21
21
|
"version": "conventional-changelog -p angular -i CHANGELOG.md -s"
|
|
22
22
|
},
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"@types/koa": "^2.x.x",
|
|
68
68
|
"@types/lodash": "^4.x.x",
|
|
69
69
|
"@types/node": "^22.x.x",
|
|
70
|
+
"@types/ws": "^8.18.1",
|
|
70
71
|
"@typescript-eslint/eslint-plugin": "^8.x.x",
|
|
71
72
|
"@typescript-eslint/parser": "^8.x.x",
|
|
72
73
|
"conventional-changelog-cli": "^5.x.x",
|
|
@@ -87,12 +88,14 @@
|
|
|
87
88
|
},
|
|
88
89
|
"dependencies": {
|
|
89
90
|
"koatty_container": "^1.x.x",
|
|
91
|
+
"koatty_core": "^1.x.x",
|
|
90
92
|
"koatty_lib": "^1.x.x",
|
|
91
93
|
"koatty_logger": "^2.x.x",
|
|
92
|
-
"koatty_store": "^1.
|
|
94
|
+
"koatty_store": "^1.x.x"
|
|
93
95
|
},
|
|
94
96
|
"peerDependencies": {
|
|
95
97
|
"koatty_container": "^1.x.x",
|
|
98
|
+
"koatty_core": "^1.x.x",
|
|
96
99
|
"koatty_lib": "^1.x.x",
|
|
97
100
|
"koatty_logger": "^2.x.x"
|
|
98
101
|
}
|