koatty_cacheable 3.0.4 → 3.0.6
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/.turbo/turbo-build.log +37 -19
- package/CHANGELOG.md +20 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +224 -332
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +223 -331
- package/dist/index.mjs.map +1 -0
- package/dist/package.json +32 -46
- package/package.json +30 -43
- package/tsup.config.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* @Author: richen
|
|
3
|
-
* @Date: 2026-02-04 10:58:15
|
|
4
|
-
* @License: BSD (3-Clause)
|
|
5
|
-
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
6
|
-
* @HomePage: https://koatty.org/
|
|
7
|
-
*/
|
|
8
1
|
'use strict';
|
|
9
2
|
|
|
10
3
|
var koatty_lib = require('koatty_lib');
|
|
@@ -12,372 +5,271 @@ var koatty_logger = require('koatty_logger');
|
|
|
12
5
|
var koatty_store = require('koatty_store');
|
|
13
6
|
var koatty_container = require('koatty_container');
|
|
14
7
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
store: null
|
|
8
|
+
/*!
|
|
9
|
+
* @Author: richen
|
|
10
|
+
* @Date: 2026-02-11 03:41:57
|
|
11
|
+
* @License: BSD (3-Clause)
|
|
12
|
+
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
13
|
+
* @HomePage: https://koatty.org/
|
|
14
|
+
*/
|
|
15
|
+
var __defProp = Object.defineProperty;
|
|
16
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
17
|
+
var storeCache = {
|
|
18
|
+
store: null
|
|
27
19
|
};
|
|
28
|
-
|
|
29
|
-
let initPromise = null;
|
|
30
|
-
/**
|
|
31
|
-
* get instances of storeCache
|
|
32
|
-
*
|
|
33
|
-
* @export
|
|
34
|
-
* @param {StoreOptions} options
|
|
35
|
-
* @returns {*} {CacheStore}
|
|
36
|
-
*/
|
|
20
|
+
var initPromise = null;
|
|
37
21
|
async function GetCacheStore(options) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// If initialization is in progress, wait for it
|
|
43
|
-
if (initPromise) {
|
|
44
|
-
return initPromise;
|
|
45
|
-
}
|
|
46
|
-
if (koatty_lib.Helper.isEmpty(options)) {
|
|
47
|
-
if (!storeCache.store) {
|
|
48
|
-
koatty_logger.DefaultLogger.Warn(`CacheStore not initialized. Please call KoattyCached() first with proper options in your application startup.`);
|
|
49
|
-
}
|
|
50
|
-
return storeCache.store || null;
|
|
51
|
-
}
|
|
52
|
-
// Start initialization and track it
|
|
53
|
-
initPromise = (async () => {
|
|
54
|
-
try {
|
|
55
|
-
storeCache.store = koatty_store.CacheStore.getInstance(options);
|
|
56
|
-
if (!koatty_lib.Helper.isFunction(storeCache.store.getConnection)) {
|
|
57
|
-
throw Error(`CacheStore connection failed. `);
|
|
58
|
-
}
|
|
59
|
-
await storeCache.store.client.getConnection();
|
|
60
|
-
return storeCache.store;
|
|
61
|
-
}
|
|
62
|
-
finally {
|
|
63
|
-
// Clear init promise after completion
|
|
64
|
-
initPromise = null;
|
|
65
|
-
}
|
|
66
|
-
})();
|
|
22
|
+
if (storeCache.store && storeCache.store.getConnection) {
|
|
23
|
+
return storeCache.store;
|
|
24
|
+
}
|
|
25
|
+
if (initPromise) {
|
|
67
26
|
return initPromise;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
async function CloseCacheStore() {
|
|
73
|
-
if (storeCache.store) {
|
|
74
|
-
try {
|
|
75
|
-
if (storeCache.store.client) {
|
|
76
|
-
const client = storeCache.store.client;
|
|
77
|
-
if (typeof client.quit === 'function') {
|
|
78
|
-
await client.quit();
|
|
79
|
-
}
|
|
80
|
-
else if (typeof client.close === 'function') {
|
|
81
|
-
await client.close();
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
// Ignore cleanup errors
|
|
87
|
-
}
|
|
27
|
+
}
|
|
28
|
+
if (koatty_lib.Helper.isEmpty(options)) {
|
|
29
|
+
if (!storeCache.store) {
|
|
30
|
+
koatty_logger.DefaultLogger.Warn(`CacheStore not initialized. Please call KoattyCached() first with proper options in your application startup.`);
|
|
88
31
|
}
|
|
89
|
-
|
|
32
|
+
return storeCache.store || null;
|
|
33
|
+
}
|
|
34
|
+
initPromise = (async () => {
|
|
90
35
|
try {
|
|
91
|
-
|
|
36
|
+
storeCache.store = koatty_store.CacheStore.getInstance(options);
|
|
37
|
+
if (!koatty_lib.Helper.isFunction(storeCache.store.getConnection)) {
|
|
38
|
+
throw Error(`CacheStore connection failed. `);
|
|
39
|
+
}
|
|
40
|
+
await storeCache.store.client.getConnection();
|
|
41
|
+
return storeCache.store;
|
|
42
|
+
} finally {
|
|
43
|
+
initPromise = null;
|
|
92
44
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
// Always clear the cache
|
|
97
|
-
storeCache.store = null;
|
|
98
|
-
initPromise = null;
|
|
45
|
+
})();
|
|
46
|
+
return initPromise;
|
|
99
47
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
* @Description:
|
|
104
|
-
* @Usage:
|
|
105
|
-
* @Author: richen
|
|
106
|
-
* @Date: 2024-11-07 13:54:24
|
|
107
|
-
* @LastEditTime: 2024-11-07 15:25:36
|
|
108
|
-
* @License: BSD (3-Clause)
|
|
109
|
-
* @Copyright (c): <richenlin(at)gmail.com>
|
|
110
|
-
*/
|
|
111
|
-
const longKey = 128;
|
|
112
|
-
/**
|
|
113
|
-
* Extract parameter names from function signature
|
|
114
|
-
* @param func The function to extract parameters from
|
|
115
|
-
* @returns Array of parameter names
|
|
116
|
-
*/
|
|
117
|
-
function getArgs(func) {
|
|
48
|
+
__name(GetCacheStore, "GetCacheStore");
|
|
49
|
+
async function CloseCacheStore() {
|
|
50
|
+
if (storeCache.store) {
|
|
118
51
|
try {
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const param = a.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").trim();
|
|
126
|
-
// Extract parameter name (before : or = or end of string)
|
|
127
|
-
const match = param.match(/^(\w+)/);
|
|
128
|
-
return match ? match[1] : "";
|
|
129
|
-
}).filter(function (ae) {
|
|
130
|
-
// Filter out empty strings
|
|
131
|
-
return ae;
|
|
132
|
-
});
|
|
52
|
+
if (storeCache.store.client) {
|
|
53
|
+
const client = storeCache.store.client;
|
|
54
|
+
if (typeof client.quit === "function") {
|
|
55
|
+
await client.quit();
|
|
56
|
+
} else if (typeof client.close === "function") {
|
|
57
|
+
await client.close();
|
|
133
58
|
}
|
|
134
|
-
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
135
61
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
await koatty_store.CacheStore.clearAllInstances();
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
storeCache.store = null;
|
|
68
|
+
initPromise = null;
|
|
69
|
+
}
|
|
70
|
+
__name(CloseCacheStore, "CloseCacheStore");
|
|
71
|
+
var longKey = 128;
|
|
72
|
+
function getArgs(func) {
|
|
73
|
+
try {
|
|
74
|
+
const args = func.toString().match(/.*?\(([^)]*)\)/);
|
|
75
|
+
if (args && args.length > 1) {
|
|
76
|
+
return args[1].split(",").map(function(a) {
|
|
77
|
+
const param = a.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").trim();
|
|
78
|
+
const match = param.match(/^(\w+)/);
|
|
79
|
+
return match ? match[1] : "";
|
|
80
|
+
}).filter(function(ae) {
|
|
81
|
+
return ae;
|
|
82
|
+
});
|
|
139
83
|
}
|
|
84
|
+
return [];
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
140
88
|
}
|
|
141
|
-
|
|
142
|
-
* Get parameter indexes based on parameter names
|
|
143
|
-
* @param funcParams Function parameter names
|
|
144
|
-
* @param params Target parameter names to find indexes for
|
|
145
|
-
* @returns Array of parameter indexes (-1 if not found)
|
|
146
|
-
*/
|
|
89
|
+
__name(getArgs, "getArgs");
|
|
147
90
|
function getParamIndex(funcParams, params) {
|
|
148
|
-
|
|
91
|
+
return params.map((param) => funcParams.indexOf(param));
|
|
149
92
|
}
|
|
150
|
-
|
|
151
|
-
* Generate cache key based on cache name and parameters
|
|
152
|
-
* @param cacheName base cache name
|
|
153
|
-
* @param paramIndexes parameter indexes
|
|
154
|
-
* @param paramNames parameter names
|
|
155
|
-
* @param props method arguments
|
|
156
|
-
* @returns generated cache key
|
|
157
|
-
*/
|
|
93
|
+
__name(getParamIndex, "getParamIndex");
|
|
158
94
|
function generateCacheKey(cacheName, paramIndexes, paramNames, props) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
95
|
+
let key = cacheName;
|
|
96
|
+
for (let i = 0; i < paramIndexes.length; i++) {
|
|
97
|
+
const paramIndex = paramIndexes[i];
|
|
98
|
+
if (paramIndex >= 0 && props[paramIndex] !== void 0) {
|
|
99
|
+
key += `:${paramNames[i]}:${koatty_lib.Helper.toString(props[paramIndex])}`;
|
|
165
100
|
}
|
|
166
|
-
|
|
101
|
+
}
|
|
102
|
+
return key.length > longKey ? koatty_lib.Helper.murmurHash(key) : key;
|
|
167
103
|
}
|
|
168
|
-
|
|
169
|
-
* Create a delay promise
|
|
170
|
-
* @param ms Delay time in milliseconds
|
|
171
|
-
* @returns Promise that resolves after the specified delay
|
|
172
|
-
*/
|
|
104
|
+
__name(generateCacheKey, "generateCacheKey");
|
|
173
105
|
function delay(ms) {
|
|
174
|
-
|
|
106
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
175
107
|
}
|
|
176
|
-
|
|
177
|
-
* Execute a function after a specified delay
|
|
178
|
-
* @param fn Function to execute
|
|
179
|
-
* @param ms Delay time in milliseconds
|
|
180
|
-
* @returns Promise that resolves with the function result
|
|
181
|
-
*/
|
|
108
|
+
__name(delay, "delay");
|
|
182
109
|
async function asyncDelayedExecution(fn, ms) {
|
|
183
|
-
|
|
184
|
-
|
|
110
|
+
await delay(ms);
|
|
111
|
+
return fn();
|
|
185
112
|
}
|
|
113
|
+
__name(asyncDelayedExecution, "asyncDelayedExecution");
|
|
186
114
|
|
|
187
|
-
|
|
188
|
-
* @Author: richen
|
|
189
|
-
* @Date: 2020-07-06 19:53:43
|
|
190
|
-
* @LastEditTime: 2024-11-07 15:53:46
|
|
191
|
-
* @Description:
|
|
192
|
-
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
193
|
-
*/
|
|
194
|
-
/**
|
|
195
|
-
* Decorate this method to support caching.
|
|
196
|
-
* The cache method returns a value to ensure that the next time
|
|
197
|
-
* the method is executed with the same parameters, the results can be obtained
|
|
198
|
-
* directly from the cache without the need to execute the method again.
|
|
199
|
-
* CacheStore server config defined in db.ts.
|
|
200
|
-
*
|
|
201
|
-
* @export
|
|
202
|
-
* @param {string} cacheName cache name
|
|
203
|
-
* @param {CacheAbleOpt} [opt] cache options
|
|
204
|
-
* e.g:
|
|
205
|
-
* {
|
|
206
|
-
* params: ["id"],
|
|
207
|
-
* timeout: 30
|
|
208
|
-
* }
|
|
209
|
-
* Use the 'id' parameters of the method as cache subkeys, the cache expiration time 30s
|
|
210
|
-
* @returns {MethodDecorator}
|
|
211
|
-
*/
|
|
115
|
+
// src/cache.ts
|
|
212
116
|
function CacheAble(cacheName, opt = {
|
|
213
|
-
|
|
214
|
-
|
|
117
|
+
params: [],
|
|
118
|
+
timeout: 300
|
|
215
119
|
}) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
120
|
+
return (target, methodName, descriptor) => {
|
|
121
|
+
const componentType = koatty_container.IOCContainer.getType(target);
|
|
122
|
+
if (![
|
|
123
|
+
"SERVICE",
|
|
124
|
+
"COMPONENT"
|
|
125
|
+
].includes(componentType)) {
|
|
126
|
+
throw Error("This decorator only used in the service\u3001component class.");
|
|
127
|
+
}
|
|
128
|
+
const { value, configurable, enumerable } = descriptor;
|
|
129
|
+
const mergedOpt = {
|
|
130
|
+
...{
|
|
131
|
+
params: [],
|
|
132
|
+
timeout: 300
|
|
133
|
+
},
|
|
134
|
+
...opt
|
|
135
|
+
};
|
|
136
|
+
const funcParams = getArgs(target[methodName]);
|
|
137
|
+
const paramIndexes = getParamIndex(funcParams, mergedOpt.params || []);
|
|
138
|
+
const invalidParams = [];
|
|
139
|
+
(mergedOpt.params || []).forEach((param, index) => {
|
|
140
|
+
if (paramIndexes[index] === -1) {
|
|
141
|
+
invalidParams.push(param);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
if (invalidParams.length > 0) {
|
|
145
|
+
koatty_logger.DefaultLogger.Warn(`CacheAble: Parameter(s) [${invalidParams.join(", ")}] not found in method ${String(methodName)}. These parameters will be ignored.`);
|
|
146
|
+
}
|
|
147
|
+
descriptor = {
|
|
148
|
+
configurable,
|
|
149
|
+
enumerable,
|
|
150
|
+
writable: true,
|
|
151
|
+
async value(...props) {
|
|
152
|
+
const store = await GetCacheStore().catch((e) => {
|
|
153
|
+
koatty_logger.DefaultLogger.error("Get cache store instance failed." + e.message);
|
|
154
|
+
return null;
|
|
233
155
|
});
|
|
234
|
-
if (
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const res = await store.get(key).catch((e) => {
|
|
249
|
-
koatty_logger.DefaultLogger.error("Cache get error:" + e.message);
|
|
250
|
-
});
|
|
251
|
-
if (!koatty_lib.Helper.isEmpty(res)) {
|
|
252
|
-
try {
|
|
253
|
-
return JSON.parse(res);
|
|
254
|
-
}
|
|
255
|
-
catch (e) {
|
|
256
|
-
const error = e;
|
|
257
|
-
koatty_logger.DefaultLogger.error("Cache JSON parse error:" + error.message);
|
|
258
|
-
// 如果解析失败,删除损坏的缓存,重新执行方法
|
|
259
|
-
store.del(key).catch((err) => {
|
|
260
|
-
koatty_logger.DefaultLogger.error("Cache del error after parse failure:" + err.message);
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
const result = await value.apply(this, props);
|
|
265
|
-
// async refresh store
|
|
266
|
-
store.set(key, koatty_lib.Helper.isJSONObj(result) ? JSON.stringify(result) : result, mergedOpt.timeout).catch((e) => {
|
|
267
|
-
koatty_logger.DefaultLogger.error("Cache set error:" + e.message);
|
|
268
|
-
});
|
|
269
|
-
return result;
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
// tslint:disable-next-line: no-invalid-this
|
|
273
|
-
return value.apply(this, props);
|
|
274
|
-
}
|
|
156
|
+
if (store) {
|
|
157
|
+
const key = generateCacheKey(cacheName, paramIndexes, mergedOpt.params, props);
|
|
158
|
+
const res = await store.get(key).catch((e) => {
|
|
159
|
+
koatty_logger.DefaultLogger.error("Cache get error:" + e.message);
|
|
160
|
+
});
|
|
161
|
+
if (!koatty_lib.Helper.isEmpty(res)) {
|
|
162
|
+
try {
|
|
163
|
+
return JSON.parse(res);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
const error = e;
|
|
166
|
+
koatty_logger.DefaultLogger.error("Cache JSON parse error:" + error.message);
|
|
167
|
+
store.del(key).catch((err) => {
|
|
168
|
+
koatty_logger.DefaultLogger.error("Cache del error after parse failure:" + err.message);
|
|
169
|
+
});
|
|
275
170
|
}
|
|
276
|
-
|
|
277
|
-
|
|
171
|
+
}
|
|
172
|
+
const result = await value.apply(this, props);
|
|
173
|
+
store.set(key, koatty_lib.Helper.isJSONObj(result) ? JSON.stringify(result) : result, mergedOpt.timeout).catch((e) => {
|
|
174
|
+
koatty_logger.DefaultLogger.error("Cache set error:" + e.message);
|
|
175
|
+
});
|
|
176
|
+
return result;
|
|
177
|
+
} else {
|
|
178
|
+
return value.apply(this, props);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
278
181
|
};
|
|
182
|
+
return descriptor;
|
|
183
|
+
};
|
|
279
184
|
}
|
|
280
|
-
|
|
281
|
-
* Decorating the execution of this method will trigger a cache clear operation.
|
|
282
|
-
* CacheStore server config defined in db.ts.
|
|
283
|
-
*
|
|
284
|
-
* @export
|
|
285
|
-
* @param {string} cacheName cacheName cache name
|
|
286
|
-
* @param {CacheEvictOpt} [opt] cache options
|
|
287
|
-
* e.g:
|
|
288
|
-
* {
|
|
289
|
-
* params: ["id"],
|
|
290
|
-
* delayedDoubleDeletion: true
|
|
291
|
-
* }
|
|
292
|
-
* Use the 'id' parameters of the method as cache subkeys,
|
|
293
|
-
* and clear the cache after the method executed
|
|
294
|
-
* @returns
|
|
295
|
-
*/
|
|
185
|
+
__name(CacheAble, "CacheAble");
|
|
296
186
|
function CacheEvict(cacheName, opt = {
|
|
297
|
-
|
|
187
|
+
delayedDoubleDeletion: true
|
|
298
188
|
}) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
189
|
+
return (target, methodName, descriptor) => {
|
|
190
|
+
const componentType = koatty_container.IOCContainer.getType(target);
|
|
191
|
+
if (![
|
|
192
|
+
"SERVICE",
|
|
193
|
+
"COMPONENT"
|
|
194
|
+
].includes(componentType)) {
|
|
195
|
+
throw Error("This decorator only used in the service\u3001component class.");
|
|
196
|
+
}
|
|
197
|
+
const { value, configurable, enumerable } = descriptor;
|
|
198
|
+
opt = {
|
|
199
|
+
...{
|
|
200
|
+
delayedDoubleDeletion: true
|
|
201
|
+
},
|
|
202
|
+
...opt
|
|
203
|
+
};
|
|
204
|
+
const funcParams = getArgs(target[methodName]);
|
|
205
|
+
const paramIndexes = getParamIndex(funcParams, opt.params || []);
|
|
206
|
+
const invalidParams = [];
|
|
207
|
+
(opt.params || []).forEach((param, index) => {
|
|
208
|
+
if (paramIndexes[index] === -1) {
|
|
209
|
+
invalidParams.push(param);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
if (invalidParams.length > 0) {
|
|
213
|
+
koatty_logger.DefaultLogger.Warn(`CacheEvict: Parameter(s) [${invalidParams.join(", ")}] not found in method ${String(methodName)}. These parameters will be ignored.`);
|
|
214
|
+
}
|
|
215
|
+
descriptor = {
|
|
216
|
+
configurable,
|
|
217
|
+
enumerable,
|
|
218
|
+
writable: true,
|
|
219
|
+
async value(...props) {
|
|
220
|
+
const store = await GetCacheStore().catch((e) => {
|
|
221
|
+
koatty_logger.DefaultLogger.error("Get cache store instance failed." + e.message);
|
|
222
|
+
return null;
|
|
316
223
|
});
|
|
317
|
-
if (
|
|
318
|
-
|
|
224
|
+
if (store) {
|
|
225
|
+
const key = generateCacheKey(cacheName, paramIndexes, opt.params || [], props);
|
|
226
|
+
const result = await value.apply(this, props);
|
|
227
|
+
store.del(key).catch((e) => {
|
|
228
|
+
koatty_logger.DefaultLogger.error("Cache delete error:" + e.message);
|
|
229
|
+
});
|
|
230
|
+
if (opt.delayedDoubleDeletion) {
|
|
231
|
+
const delayTime = opt.delayTime || 5e3;
|
|
232
|
+
asyncDelayedExecution(() => {
|
|
233
|
+
store.del(key).catch((e) => {
|
|
234
|
+
koatty_logger.DefaultLogger.error("Cache double delete error:" + e.message);
|
|
235
|
+
});
|
|
236
|
+
}, delayTime);
|
|
237
|
+
}
|
|
238
|
+
return result;
|
|
239
|
+
} else {
|
|
240
|
+
return value.apply(this, props);
|
|
319
241
|
}
|
|
320
|
-
|
|
321
|
-
configurable,
|
|
322
|
-
enumerable,
|
|
323
|
-
writable: true,
|
|
324
|
-
async value(...props) {
|
|
325
|
-
const store = await GetCacheStore().catch((e) => {
|
|
326
|
-
koatty_logger.DefaultLogger.error("Get cache store instance failed." + e.message);
|
|
327
|
-
return null;
|
|
328
|
-
});
|
|
329
|
-
if (store) {
|
|
330
|
-
const key = generateCacheKey(cacheName, paramIndexes, opt.params || [], props);
|
|
331
|
-
const result = await value.apply(this, props);
|
|
332
|
-
store.del(key).catch((e) => {
|
|
333
|
-
koatty_logger.DefaultLogger.error("Cache delete error:" + e.message);
|
|
334
|
-
});
|
|
335
|
-
if (opt.delayedDoubleDeletion) {
|
|
336
|
-
const delayTime = opt.delayTime || 5000;
|
|
337
|
-
asyncDelayedExecution(() => {
|
|
338
|
-
store.del(key).catch((e) => {
|
|
339
|
-
koatty_logger.DefaultLogger.error("Cache double delete error:" + e.message);
|
|
340
|
-
});
|
|
341
|
-
}, delayTime);
|
|
342
|
-
}
|
|
343
|
-
return result;
|
|
344
|
-
}
|
|
345
|
-
else {
|
|
346
|
-
// If store is not available, execute method directly
|
|
347
|
-
return value.apply(this, props);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
return descriptor;
|
|
242
|
+
}
|
|
352
243
|
};
|
|
244
|
+
return descriptor;
|
|
245
|
+
};
|
|
353
246
|
}
|
|
247
|
+
__name(CacheEvict, "CacheEvict");
|
|
354
248
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
db: 0,
|
|
361
|
-
timeout: 30
|
|
249
|
+
// src/index.ts
|
|
250
|
+
var defaultOptions = {
|
|
251
|
+
type: "memory",
|
|
252
|
+
db: 0,
|
|
253
|
+
timeout: 30
|
|
362
254
|
};
|
|
363
|
-
/**
|
|
364
|
-
* @param options - The options for the cached options
|
|
365
|
-
* @param app - The Koatty application instance
|
|
366
|
-
*/
|
|
367
255
|
async function KoattyCached(options, app) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
256
|
+
options = {
|
|
257
|
+
...defaultOptions,
|
|
258
|
+
...options
|
|
259
|
+
};
|
|
260
|
+
app.once("appReady", async function() {
|
|
261
|
+
await GetCacheStore(options);
|
|
262
|
+
});
|
|
263
|
+
app.on("appStop", async function() {
|
|
264
|
+
await CloseCacheStore();
|
|
265
|
+
});
|
|
377
266
|
}
|
|
267
|
+
__name(KoattyCached, "KoattyCached");
|
|
378
268
|
|
|
379
269
|
exports.CacheAble = CacheAble;
|
|
380
270
|
exports.CacheEvict = CacheEvict;
|
|
381
271
|
exports.CloseCacheStore = CloseCacheStore;
|
|
382
272
|
exports.GetCacheStore = GetCacheStore;
|
|
383
273
|
exports.KoattyCached = KoattyCached;
|
|
274
|
+
//# sourceMappingURL=index.js.map
|
|
275
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts","../src/utils.ts","../src/cache.ts","../src/index.ts"],"names":["storeCache","store","initPromise","GetCacheStore","options","getConnection","Helper","isEmpty","logger","Warn","CacheStore","getInstance","isFunction","Error","client","CloseCacheStore","quit","close","clearAllInstances","longKey","getArgs","func","args","toString","match","length","split","map","a","param","replace","trim","filter","ae","error","getParamIndex","funcParams","params","indexOf","generateCacheKey","cacheName","paramIndexes","paramNames","props","key","i","paramIndex","undefined","murmurHash","delay","ms","Promise","resolve","setTimeout","asyncDelayedExecution","fn","CacheAble","opt","timeout","target","methodName","descriptor","componentType","IOCContainer","getType","includes","value","configurable","enumerable","mergedOpt","invalidParams","forEach","index","push","join","String","writable","catch","e","message","res","get","JSON","parse","del","err","result","apply","set","isJSONObj","stringify","CacheEvict","delayedDoubleDeletion","delayTime","defaultOptions","type","db","KoattyCached","app","once","on"],"mappings":";;;;;;;;;;;;;;;;AAuBA,IAAMA,UAAAA,GAAkC;EACtCC,KAAAA,EAAO;AACT,CAAA;AAGA,IAAIC,WAAAA,GAA0C,IAAA;AAS9C,eAAsBC,cAAcC,OAAAA,EAAsB;AAExD,EAAA,IAAIJ,UAAAA,CAAWC,KAAAA,IAASD,UAAAA,CAAWC,KAAAA,CAAMI,aAAAA,EAAe;AACtD,IAAA,OAAOL,UAAAA,CAAWC,KAAAA;AACpB,EAAA;AAGA,EAAA,IAAIC,WAAAA,EAAa;AACf,IAAA,OAAOA,WAAAA;AACT,EAAA;AAEA,EAAA,IAAII,iBAAAA,CAAOC,OAAAA,CAAQH,OAAAA,CAAAA,EAAU;AAC3B,IAAA,IAAI,CAACJ,WAAWC,KAAAA,EAAO;AACrBO,MAAAA,2BAAAA,CAAOC,KAAK,CAAA,6GAAA,CAA+G,CAAA;AAC7H,IAAA;AACA,IAAA,OAAOT,WAAWC,KAAAA,IAAS,IAAA;AAC7B,EAAA;AAGAC,EAAAA,WAAAA,GAAAA,CAAe,YAAA;AACb,IAAA,IAAI;AACFF,MAAAA,UAAAA,CAAWC,KAAAA,GAAQS,uBAAAA,CAAWC,WAAAA,CAAYP,OAAAA,CAAAA;AAC1C,MAAA,IAAI,CAACE,iBAAAA,CAAOM,UAAAA,CAAWZ,UAAAA,CAAWC,KAAAA,CAAMI,aAAa,CAAA,EAAG;AACtD,QAAA,MAAMQ,MAAM,CAAA,8BAAA,CAAgC,CAAA;AAC9C,MAAA;AACA,MAAA,MAAMb,UAAAA,CAAWC,KAAAA,CAAMa,MAAAA,CAAOT,aAAAA,EAAa;AAC3C,MAAA,OAAOL,UAAAA,CAAWC,KAAAA;IACpB,CAAA,SAAA;AAEEC,MAAAA,WAAAA,GAAc,IAAA;AAChB,IAAA;EACF,CAAA,GAAA;AAEA,EAAA,OAAOA,WAAAA;AACT;AAlCsBC,MAAAA,CAAAA,aAAAA,EAAAA,eAAAA,CAAAA;AAuCtB,eAAsBY,eAAAA,GAAAA;AACpB,EAAA,IAAIf,WAAWC,KAAAA,EAAO;AACpB,IAAA,IAAI;AACF,MAAA,IAAID,UAAAA,CAAWC,MAAMa,MAAAA,EAAQ;AAC3B,QAAA,MAAMA,MAAAA,GAASd,WAAWC,KAAAA,CAAMa,MAAAA;AAChC,QAAA,IAAI,OAAOA,MAAAA,CAAOE,IAAAA,KAAS,UAAA,EAAY;AACrC,UAAA,MAAMF,OAAOE,IAAAA,EAAI;QACnB,CAAA,MAAA,IAAW,OAAOF,MAAAA,CAAOG,KAAAA,KAAU,UAAA,EAAY;AAC7C,UAAA,MAAMH,OAAOG,KAAAA,EAAK;AACpB,QAAA;AACF,MAAA;IACF,CAAA,CAAA,MAAQ;AAER,IAAA;AACF,EAAA;AAGA,EAAA,IAAI;AACF,IAAA,MAAMP,wBAAWQ,iBAAAA,EAAiB;EACpC,CAAA,CAAA,MAAQ;AAER,EAAA;AAGAlB,EAAAA,UAAAA,CAAWC,KAAAA,GAAQ,IAAA;AACnBC,EAAAA,WAAAA,GAAc,IAAA;AAChB;AA1BsBa,MAAAA,CAAAA,eAAAA,EAAAA,iBAAAA,CAAAA;AC/DtB,IAAMI,OAAAA,GAAU,GAAA;AAOT,SAASC,QAAQC,IAAAA,EAA6B;AACnD,EAAA,IAAI;AAEF,IAAA,MAAMC,IAAAA,GAAOD,IAAAA,CAAKE,QAAAA,EAAQ,CAAGC,MAAM,gBAAA,CAAA;AACnC,IAAA,IAAIF,IAAAA,IAAQA,IAAAA,CAAKG,MAAAA,GAAS,CAAA,EAAG;AAE3B,MAAA,OAAOH,IAAAA,CAAK,CAAA,CAAA,CAAGI,KAAAA,CAAM,GAAA,CAAA,CAAKC,GAAAA,CAAI,SAAUC,CAAAA,EAAC;AAEvC,QAAA,MAAMC,KAAAA,GAAQD,CAAAA,CAAEE,OAAAA,CAAQ,mBAAA,EAAqB,EAAA,EAAIA,OAAAA,CAAQ,WAAA,EAAa,EAAA,CAAA,CAAIC,IAAAA,EAAI;AAE9E,QAAA,MAAMP,KAAAA,GAAQK,KAAAA,CAAML,KAAAA,CAAM,QAAA,CAAA;AAC1B,QAAA,OAAOA,KAAAA,GAAQA,KAAAA,CAAM,CAAA,CAAA,GAAK,EAAA;MAC5B,CAAA,CAAA,CAAGQ,MAAAA,CAAO,SAAUC,EAAAA,EAAE;AAEpB,QAAA,OAAOA,EAAAA;MACT,CAAA,CAAA;AACF,IAAA;AACA,IAAA,OAAO,EAAA;AACT,EAAA,CAAA,CAAA,OAASC,KAAAA,EAAO;AAEd,IAAA,OAAO,EAAA;AACT,EAAA;AACF;AAtBgBd,MAAAA,CAAAA,OAAAA,EAAAA,SAAAA,CAAAA;AA8BT,SAASe,aAAAA,CAAcC,YAAsBC,MAAAA,EAAgB;AAClE,EAAA,OAAOA,OAAOV,GAAAA,CAAIE,CAAAA,UAASO,UAAAA,CAAWE,OAAAA,CAAQT,KAAAA,CAAAA,CAAAA;AAChD;AAFgBM,MAAAA,CAAAA,aAAAA,EAAAA,eAAAA,CAAAA;AAYT,SAASI,gBAAAA,CAAiBC,SAAAA,EAAmBC,YAAAA,EAAwBC,UAAAA,EAAsBC,KAAAA,EAAY;AAC5G,EAAA,IAAIC,GAAAA,GAAMJ,SAAAA;AACV,EAAA,KAAA,IAASK,CAAAA,GAAI,CAAA,EAAGA,CAAAA,GAAIJ,YAAAA,CAAahB,QAAQoB,CAAAA,EAAAA,EAAK;AAC5C,IAAA,MAAMC,UAAAA,GAAaL,aAAaI,CAAAA,CAAAA;AAChC,IAAA,IAAIC,UAAAA,IAAc,CAAA,IAAKH,KAAAA,CAAMG,UAAAA,MAAgBC,MAAAA,EAAW;AACtDH,MAAAA,GAAAA,IAAO,CAAA,CAAA,EAAIF,UAAAA,CAAWG,CAAAA,CAAE,CAAA,CAAA,EAAIvC,kBAAOiB,QAAAA,CAASoB,KAAAA,CAAMG,UAAAA,CAAW,CAAA,CAAA,CAAA;AAC/D,IAAA;AACF,EAAA;AACA,EAAA,OAAOF,IAAInB,MAAAA,GAASN,OAAAA,GAAUb,iBAAAA,CAAO0C,UAAAA,CAAWJ,GAAAA,CAAAA,GAAOA,GAAAA;AACzD;AATgBL,MAAAA,CAAAA,gBAAAA,EAAAA,kBAAAA,CAAAA;AAgBhB,SAASU,MAAMC,EAAAA,EAAU;AACvB,EAAA,OAAO,IAAIC,OAAAA,CAAQC,CAAAA,YAAWC,UAAAA,CAAWD,OAAAA,EAASF,EAAAA,CAAAA,CAAAA;AACpD;AAFSD,MAAAA,CAAAA,KAAAA,EAAAA,OAAAA,CAAAA;AAUT,eAAsBK,qBAAAA,CAAsBC,IAAeL,EAAAA,EAAU;AACnE,EAAA,MAAMD,MAAMC,EAAAA,CAAAA;AACZ,EAAA,OAAOK,EAAAA,EAAAA;AACT;AAHsBD,MAAAA,CAAAA,qBAAAA,EAAAA,uBAAAA,CAAAA;;;AChCf,SAASE,SAAAA,CAAUhB,WAAmBiB,GAAAA,GAAoB;AAC/DpB,EAAAA,MAAAA,EAAQ,EAAA;EACRqB,OAAAA,EAAS;AACX,CAAA,EAAC;AACC,EAAA,OAAO,CAACC,MAAAA,EAAaC,UAAAA,EAAoBC,UAAAA,KAAAA;AACvC,IAAA,MAAMC,aAAAA,GAAgBC,6BAAAA,CAAaC,OAAAA,CAAQL,MAAAA,CAAAA;AAC3C,IAAA,IAAI,CAAC;AAAC,MAAA,SAAA;AAAW,MAAA;AAAaM,KAAAA,CAAAA,QAAAA,CAASH,aAAAA,CAAAA,EAAgB;AACrD,MAAA,MAAMjD,MAAM,+DAAA,CAAA;AACd,IAAA;AAEA,IAAA,MAAM,EAAEqD,KAAAA,EAAOC,YAAAA,EAAcC,UAAAA,EAAU,GAAKP,UAAAA;AAC5C,IAAA,MAAMQ,SAAAA,GAAY;MAAE,GAAG;AAAEhC,QAAAA,MAAAA,EAAQ,EAAA;QAAIqB,OAAAA,EAAS;AAAI,OAAA;MAAG,GAAGD;AAAI,KAAA;AAG5D,IAAA,MAAMrB,UAAAA,GAAahB,OAAAA,CAAcuC,MAAAA,CAAQC,UAAAA,CAAW,CAAA;AAEpD,IAAA,MAAMnB,eAAeN,aAAAA,CAAcC,UAAAA,EAAYiC,SAAAA,CAAUhC,MAAAA,IAAU,EAAE,CAAA;AAGrE,IAAA,MAAMiC,gBAA0B,EAAA;AAC/BD,IAAAA,CAAAA,UAAUhC,MAAAA,IAAU,IAAIkC,OAAAA,CAAQ,CAAC1C,OAAO2C,KAAAA,KAAAA;AACvC,MAAA,IAAI/B,YAAAA,CAAa+B,KAAAA,CAAAA,KAAW,EAAA,EAAI;AAC9BF,QAAAA,aAAAA,CAAcG,KAAK5C,KAAAA,CAAAA;AACrB,MAAA;IACF,CAAA,CAAA;AACA,IAAA,IAAIyC,aAAAA,CAAc7C,SAAS,CAAA,EAAG;AAC5BjB,MAAAA,2BAAAA,CAAOC,IAAAA,CAAK,CAAA,yBAAA,EAA4B6D,aAAAA,CAAcI,IAAAA,CAAK,IAAA,CAAA,CAAA,sBAAA,EAA8BC,MAAAA,CAAOf,UAAAA,CAAAA,CAAAA,mCAAAA,CAAgD,CAAA;AAClJ,IAAA;AAEAC,IAAAA,UAAAA,GAAa;AACXM,MAAAA,YAAAA;AACAC,MAAAA,UAAAA;MACAQ,QAAAA,EAAU,IAAA;AACV,MAAA,MAAMV,SAASvB,KAAAA,EAAY;AACzB,QAAA,MAAM1C,QAAoB,MAAME,aAAAA,EAAAA,CAAgB0E,KAAAA,CAAM,CAACC,CAAAA,KAAAA;AACrDtE,UAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,kCAAA,GAAqC4C,CAAAA,CAAEC,OAAO,CAAA;AAC3D,UAAA,OAAO,IAAA;QACT,CAAA,CAAA;AACA,QAAA,IAAI9E,KAAAA,EAAO;AACT,UAAA,MAAM2C,MAAML,gBAAAA,CAAiBC,SAAAA,EAAWC,YAAAA,EAAc4B,SAAAA,CAAUhC,QAAQM,KAAAA,CAAAA;AACxE,UAAA,MAAMqC,GAAAA,GAAM,MAAM/E,KAAAA,CAAMgF,GAAAA,CAAIrC,GAAAA,CAAAA,CAAKiC,KAAAA,CAAM,CAACC,CAAAA,KAAAA;AACtCtE,YAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,kBAAA,GAAqB4C,CAAAA,CAAEC,OAAO,CAAA;UAC7C,CAAA,CAAA;AACA,UAAA,IAAI,CAACzE,iBAAAA,CAAOC,OAAAA,CAAQyE,GAAAA,CAAAA,EAAM;AACxB,YAAA,IAAI;AACF,cAAA,OAAOE,IAAAA,CAAKC,MAAMH,GAAAA,CAAAA;AACpB,YAAA,CAAA,CAAA,OAASF,CAAAA,EAAG;AACV,cAAA,MAAM5C,KAAAA,GAAQ4C,CAAAA;AACdtE,cAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,yBAAA,GAA4BA,KAAAA,CAAM6C,OAAO,CAAA;AAEtD9E,cAAAA,KAAAA,CAAMmF,GAAAA,CAAIxC,GAAAA,CAAAA,CAAKiC,KAAAA,CAAM,CAACQ,GAAAA,KAAAA;AACpB7E,gBAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,sCAAA,GAAyCmD,GAAAA,CAAIN,OAAO,CAAA;cACnE,CAAA,CAAA;AACF,YAAA;AACF,UAAA;AACA,UAAA,MAAMO,MAAAA,GAAS,MAAMpB,KAAAA,CAAMqB,KAAAA,CAAM,MAAM5C,KAAAA,CAAAA;AAEvC1C,UAAAA,KAAAA,CAAMuF,IAAI5C,GAAAA,EAAKtC,iBAAAA,CAAOmF,SAAAA,CAAUH,MAAAA,IAAUJ,IAAAA,CAAKQ,SAAAA,CAAUJ,MAAAA,CAAAA,GAAUA,QACjEjB,SAAAA,CAAUX,OAAO,CAAA,CAAEmB,KAAAA,CAAM,CAACC,CAAAA,KAAAA;AACxBtE,YAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,kBAAA,GAAqB4C,CAAAA,CAAEC,OAAO,CAAA;UAC7C,CAAA,CAAA;AACF,UAAA,OAAOO,MAAAA;QACT,CAAA,MAAO;AAEL,UAAA,OAAOpB,KAAAA,CAAMqB,KAAAA,CAAM,IAAA,EAAM5C,KAAAA,CAAAA;AAC3B,QAAA;AACF,MAAA;AACF,KAAA;AACA,IAAA,OAAOkB,UAAAA;AACT,EAAA,CAAA;AACF;AAtEgBL,MAAAA,CAAAA,SAAAA,EAAAA,WAAAA,CAAAA;AAwFT,SAASmC,UAAAA,CAAWnD,WAAmBiB,GAAAA,GAAqB;EACjEmC,qBAAAA,EAAuB;AACzB,CAAA,EAAC;AACC,EAAA,OAAO,CAACjC,MAAAA,EAAaC,UAAAA,EAAoBC,UAAAA,KAAAA;AACvC,IAAA,MAAMC,aAAAA,GAAgBC,6BAAAA,CAAaC,OAAAA,CAAQL,MAAAA,CAAAA;AAC3C,IAAA,IAAI,CAAC;AAAC,MAAA,SAAA;AAAW,MAAA;AAAaM,KAAAA,CAAAA,QAAAA,CAASH,aAAAA,CAAAA,EAAgB;AACrD,MAAA,MAAMjD,MAAM,+DAAA,CAAA;AACd,IAAA;AACA,IAAA,MAAM,EAAEqD,KAAAA,EAAOC,YAAAA,EAAcC,UAAAA,EAAU,GAAKP,UAAAA;AAC5CJ,IAAAA,GAAAA,GAAM;MAAE,GAAG;QAAEmC,qBAAAA,EAAuB;AAAM,OAAA;MAAG,GAAGnC;AAAI,KAAA;AAEpD,IAAA,MAAMrB,UAAAA,GAAahB,OAAAA,CAAcuC,MAAAA,CAAQC,UAAAA,CAAW,CAAA;AAEpD,IAAA,MAAMnB,eAAeN,aAAAA,CAAcC,UAAAA,EAAYqB,GAAAA,CAAIpB,MAAAA,IAAU,EAAE,CAAA;AAG/D,IAAA,MAAMiC,gBAA0B,EAAA;AAC/Bb,IAAAA,CAAAA,IAAIpB,MAAAA,IAAU,IAAIkC,OAAAA,CAAQ,CAAC1C,OAAO2C,KAAAA,KAAAA;AACjC,MAAA,IAAI/B,YAAAA,CAAa+B,KAAAA,CAAAA,KAAW,EAAA,EAAI;AAC9BF,QAAAA,aAAAA,CAAcG,KAAK5C,KAAAA,CAAAA;AACrB,MAAA;IACF,CAAA,CAAA;AACA,IAAA,IAAIyC,aAAAA,CAAc7C,SAAS,CAAA,EAAG;AAC5BjB,MAAAA,2BAAAA,CAAOC,IAAAA,CAAK,CAAA,0BAAA,EAA6B6D,aAAAA,CAAcI,IAAAA,CAAK,IAAA,CAAA,CAAA,sBAAA,EAA8BC,MAAAA,CAAOf,UAAAA,CAAAA,CAAAA,mCAAAA,CAAgD,CAAA;AACnJ,IAAA;AAEAC,IAAAA,UAAAA,GAAa;AACXM,MAAAA,YAAAA;AACAC,MAAAA,UAAAA;MACAQ,QAAAA,EAAU,IAAA;AACV,MAAA,MAAMV,SAASvB,KAAAA,EAAY;AACzB,QAAA,MAAM1C,QAAoB,MAAME,aAAAA,EAAAA,CAAgB0E,KAAAA,CAAM,CAACC,CAAAA,KAAAA;AACrDtE,UAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,kCAAA,GAAqC4C,CAAAA,CAAEC,OAAO,CAAA;AAC3D,UAAA,OAAO,IAAA;QACT,CAAA,CAAA;AAEA,QAAA,IAAI9E,KAAAA,EAAO;AACT,UAAA,MAAM2C,GAAAA,GAAML,iBAAiBC,SAAAA,EAAWC,YAAAA,EAAcgB,IAAIpB,MAAAA,IAAU,IAAIM,KAAAA,CAAAA;AAExE,UAAA,MAAM2C,MAAAA,GAAS,MAAMpB,KAAAA,CAAMqB,KAAAA,CAAM,MAAM5C,KAAAA,CAAAA;AACvC1C,UAAAA,KAAAA,CAAMmF,GAAAA,CAAIxC,GAAAA,CAAAA,CAAKiC,KAAAA,CAAM,CAACC,CAAAA,KAAAA;AACpBtE,YAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,qBAAA,GAAwB4C,CAAAA,CAAEC,OAAO,CAAA;UAChD,CAAA,CAAA;AAEA,UAAA,IAAItB,IAAImC,qBAAAA,EAAuB;AAC7B,YAAA,MAAMC,SAAAA,GAAYpC,IAAIoC,SAAAA,IAAa,GAAA;AACnCvC,YAAAA,qBAAAA,CAAsB,MAAA;AACpBrD,cAAAA,KAAAA,CAAMmF,GAAAA,CAAIxC,GAAAA,CAAAA,CAAKiC,KAAAA,CAAM,CAACC,CAAAA,KAAAA;AACpBtE,gBAAAA,2BAAAA,CAAO0B,KAAAA,CAAM,4BAAA,GAA+B4C,CAAAA,CAAEC,OAAO,CAAA;cACvD,CAAA,CAAA;AACF,YAAA,CAAA,EAAGc,SAAAA,CAAAA;AACL,UAAA;AACA,UAAA,OAAOP,MAAAA;QACT,CAAA,MAAO;AAEL,UAAA,OAAOpB,KAAAA,CAAMqB,KAAAA,CAAM,IAAA,EAAM5C,KAAAA,CAAAA;AAC3B,QAAA;AACF,MAAA;AACF,KAAA;AACA,IAAA,OAAOkB,UAAAA;AACT,EAAA,CAAA;AACF;AA7DgB8B,MAAAA,CAAAA,UAAAA,EAAAA,YAAAA,CAAAA;;;AC5HhB,IAAMG,cAAAA,GAA+B;EACnCC,IAAAA,EAAM,QAAA;EACNC,EAAAA,EAAI,CAAA;EACJtC,OAAAA,EAAS;AACX,CAAA;AAMA,eAAsBuC,YAAAA,CAAa7F,SAAuB8F,GAAAA,EAAW;AACnE9F,EAAAA,OAAAA,GAAU;IAAE,GAAG0F,cAAAA;IAAgB,GAAG1F;AAAQ,GAAA;AAE1C8F,EAAAA,GAAAA,CAAIC,IAAAA,CAAK,YAAY,iBAAA;AAEnB,IAAA,MAAMhG,cAAcC,OAAAA,CAAAA;EACtB,CAAA,CAAA;AAEA8F,EAAAA,GAAAA,CAAIE,EAAAA,CAAG,WAAW,iBAAA;AAEhB,IAAA,MAAMrF,eAAAA,EAAAA;EACR,CAAA,CAAA;AACF;AAZsBkF,MAAAA,CAAAA,YAAAA,EAAAA,cAAAA,CAAAA","file":"index.js","sourcesContent":["/*\n * @Description: \n * @Usage: \n * @Author: richen\n * @Date: 2024-11-07 16:00:02\n * @LastEditTime: 2024-11-07 16:00:05\n * @License: BSD (3-Clause)\n * @Copyright (c): <richenlin(at)gmail.com>\n */\nimport { Helper } from \"koatty_lib\";\nimport { DefaultLogger as logger } from \"koatty_logger\";\nimport { CacheStore, StoreOptions } from \"koatty_store\";\n\n/**\n * \n *\n * @interface CacheStoreInterface\n */\ninterface CacheStoreInterface {\n store?: CacheStore;\n}\n\n// storeCache\nconst storeCache: CacheStoreInterface = {\n store: null\n};\n\n// Promise to track initialization in progress\nlet initPromise: Promise<CacheStore> | null = null;\n\n/**\n * get instances of storeCache\n *\n * @export\n * @param {StoreOptions} options\n * @returns {*} {CacheStore}\n */\nexport async function GetCacheStore(options?: StoreOptions): Promise<CacheStore> {\n // Return existing store if available\n if (storeCache.store && storeCache.store.getConnection) {\n return storeCache.store;\n }\n\n // If initialization is in progress, wait for it\n if (initPromise) {\n return initPromise;\n }\n\n if (Helper.isEmpty(options)) {\n if (!storeCache.store) {\n logger.Warn(`CacheStore not initialized. Please call KoattyCached() first with proper options in your application startup.`);\n }\n return storeCache.store || null;\n }\n\n // Start initialization and track it\n initPromise = (async () => {\n try {\n storeCache.store = CacheStore.getInstance(options);\n if (!Helper.isFunction(storeCache.store.getConnection)) {\n throw Error(`CacheStore connection failed. `);\n }\n await storeCache.store.client.getConnection();\n return storeCache.store;\n } finally {\n // Clear init promise after completion\n initPromise = null;\n }\n })();\n\n return initPromise;\n}\n\n/**\n * Close cache store connection for cleanup (mainly for testing)\n */\nexport async function CloseCacheStore(): Promise<void> {\n if (storeCache.store) {\n try {\n if (storeCache.store.client) {\n const client = storeCache.store.client as any;\n if (typeof client.quit === 'function') {\n await client.quit();\n } else if (typeof client.close === 'function') {\n await client.close();\n }\n }\n } catch {\n // Ignore cleanup errors\n }\n }\n \n // Clear the CacheStore singleton instance\n try {\n await CacheStore.clearAllInstances();\n } catch {\n // Ignore cleanup errors\n }\n \n // Always clear the cache\n storeCache.store = null;\n initPromise = null;\n}","/* eslint-disable @typescript-eslint/no-unused-vars */\n/*\n * @Description: \n * @Usage: \n * @Author: richen\n * @Date: 2024-11-07 13:54:24\n * @LastEditTime: 2024-11-07 15:25:36\n * @License: BSD (3-Clause)\n * @Copyright (c): <richenlin(at)gmail.com>\n */\n\nimport { Helper } from \"koatty_lib\";\n\nconst longKey = 128;\n\n/**\n * Extract parameter names from function signature\n * @param func The function to extract parameters from\n * @returns Array of parameter names\n */\nexport function getArgs(func: (...args: any[]) => any): string[] {\n try {\n // Match function parameters in parentheses\n const args = func.toString().match(/.*?\\(([^)]*)\\)/);\n if (args && args.length > 1) {\n // Split parameters into array and clean them\n return args[1].split(\",\").map(function (a) {\n // Remove multi-line comments /* ... */ and single-line comments //\n const param = a.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/\\/\\/.*$/gm, \"\").trim();\n // Extract parameter name (before : or = or end of string)\n const match = param.match(/^(\\w+)/);\n return match ? match[1] : \"\";\n }).filter(function (ae) {\n // Filter out empty strings\n return ae;\n });\n }\n return [];\n } catch (error) {\n // Return empty array if parsing fails\n return [];\n }\n}\n\n/**\n * Get parameter indexes based on parameter names\n * @param funcParams Function parameter names\n * @param params Target parameter names to find indexes for\n * @returns Array of parameter indexes (-1 if not found)\n */\nexport function getParamIndex(funcParams: string[], params: string[]): number[] {\n return params.map(param => funcParams.indexOf(param));\n}\n\n/**\n * Generate cache key based on cache name and parameters\n * @param cacheName base cache name\n * @param paramIndexes parameter indexes\n * @param paramNames parameter names\n * @param props method arguments\n * @returns generated cache key\n */\nexport function generateCacheKey(cacheName: string, paramIndexes: number[], paramNames: string[], props: any[]): string {\n let key = cacheName;\n for (let i = 0; i < paramIndexes.length; i++) {\n const paramIndex = paramIndexes[i];\n if (paramIndex >= 0 && props[paramIndex] !== undefined) {\n key += `:${paramNames[i]}:${Helper.toString(props[paramIndex])}`;\n }\n }\n return key.length > longKey ? Helper.murmurHash(key) : key;\n}\n\n/**\n * Create a delay promise\n * @param ms Delay time in milliseconds\n * @returns Promise that resolves after the specified delay\n */\nfunction delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Execute a function after a specified delay\n * @param fn Function to execute\n * @param ms Delay time in milliseconds\n * @returns Promise that resolves with the function result\n */\nexport async function asyncDelayedExecution(fn: () => any, ms: number): Promise<any> {\n await delay(ms);\n return fn();\n}","/*\n * @Author: richen\n * @Date: 2020-07-06 19:53:43\n * @LastEditTime: 2024-11-07 15:53:46\n * @Description:\n * @Copyright (c) - <richenlin(at)gmail.com>\n */\nimport { IOCContainer } from 'koatty_container';\nimport { Helper } from \"koatty_lib\";\nimport { DefaultLogger as logger } from \"koatty_logger\";\nimport { CacheStore } from \"koatty_store\";\nimport { asyncDelayedExecution, generateCacheKey, getArgs, getParamIndex } from './utils';\nimport { GetCacheStore } from './store';\n\n/**\n * @description: \n * @return {*}\n */\nexport interface CacheAbleOpt {\n // parameter name array\n params?: string[];\n // cache validity period, seconds\n timeout?: number;\n}\n\n/**\n * @description: \n * @return {*}\n */\nexport interface CacheEvictOpt {\n // parameter name array\n params?: string[];\n // enable the delayed double deletion strategy\n delayedDoubleDeletion?: boolean;\n // delay time for double deletion in milliseconds, default 5000\n delayTime?: number;\n}\n\n/**\n * Decorate this method to support caching. \n * The cache method returns a value to ensure that the next time \n * the method is executed with the same parameters, the results can be obtained\n * directly from the cache without the need to execute the method again.\n * CacheStore server config defined in db.ts.\n * \n * @export\n * @param {string} cacheName cache name\n * @param {CacheAbleOpt} [opt] cache options\n * e.g: \n * {\n * params: [\"id\"],\n * timeout: 30\n * }\n * Use the 'id' parameters of the method as cache subkeys, the cache expiration time 30s\n * @returns {MethodDecorator}\n */\nexport function CacheAble(cacheName: string, opt: CacheAbleOpt = {\n params: [],\n timeout: 300,\n}): MethodDecorator {\n return (target: any, methodName: string, descriptor: PropertyDescriptor) => {\n const componentType = IOCContainer.getType(target);\n if (![\"SERVICE\", \"COMPONENT\"].includes(componentType)) {\n throw Error(\"This decorator only used in the service、component class.\");\n }\n\n const { value, configurable, enumerable } = descriptor;\n const mergedOpt = { ...{ params: [], timeout: 300 }, ...opt };\n\n // Get the parameter list of the method\n const funcParams = getArgs((<any>target)[methodName]);\n // Get the defined parameter location\n const paramIndexes = getParamIndex(funcParams, mergedOpt.params || []);\n \n // Validate parameters\n const invalidParams: string[] = [];\n (mergedOpt.params || []).forEach((param, index) => {\n if (paramIndexes[index] === -1) {\n invalidParams.push(param);\n }\n });\n if (invalidParams.length > 0) {\n logger.Warn(`CacheAble: Parameter(s) [${invalidParams.join(\", \")}] not found in method ${String(methodName)}. These parameters will be ignored.`);\n }\n \n descriptor = {\n configurable,\n enumerable,\n writable: true,\n async value(...props: any[]) {\n const store: CacheStore = await GetCacheStore().catch((e: Error): null => {\n logger.error(\"Get cache store instance failed.\" + e.message);\n return null;\n });\n if (store) {\n const key = generateCacheKey(cacheName, paramIndexes, mergedOpt.params, props);\n const res = await store.get(key).catch((e: Error) => {\n logger.error(\"Cache get error:\" + e.message);\n });\n if (!Helper.isEmpty(res)) {\n try {\n return JSON.parse(res as string);\n } catch (e) {\n const error = e as Error;\n logger.error(\"Cache JSON parse error:\" + error.message);\n // 如果解析失败,删除损坏的缓存,重新执行方法\n store.del(key).catch((err: Error) => {\n logger.error(\"Cache del error after parse failure:\" + err.message);\n });\n }\n }\n const result = await value.apply(this, props);\n // async refresh store\n store.set(key, Helper.isJSONObj(result) ? JSON.stringify(result) : result,\n mergedOpt.timeout).catch((e: Error) => {\n logger.error(\"Cache set error:\" + e.message);\n });\n return result;\n } else {\n // tslint:disable-next-line: no-invalid-this\n return value.apply(this, props);\n }\n }\n };\n return descriptor;\n };\n}\n\n/**\n * Decorating the execution of this method will trigger a cache clear operation. \n * CacheStore server config defined in db.ts.\n *\n * @export\n * @param {string} cacheName cacheName cache name\n * @param {CacheEvictOpt} [opt] cache options\n * e.g: \n * {\n * params: [\"id\"],\n * delayedDoubleDeletion: true\n * }\n * Use the 'id' parameters of the method as cache subkeys,\n * and clear the cache after the method executed\n * @returns\n */\nexport function CacheEvict(cacheName: string, opt: CacheEvictOpt = {\n delayedDoubleDeletion: true,\n}) {\n return (target: any, methodName: string, descriptor: PropertyDescriptor) => {\n const componentType = IOCContainer.getType(target);\n if (![\"SERVICE\", \"COMPONENT\"].includes(componentType)) {\n throw Error(\"This decorator only used in the service、component class.\");\n }\n const { value, configurable, enumerable } = descriptor;\n opt = { ...{ delayedDoubleDeletion: true, }, ...opt }\n // Get the parameter list of the method\n const funcParams = getArgs((<any>target)[methodName]);\n // Get the defined parameter location\n const paramIndexes = getParamIndex(funcParams, opt.params || []);\n \n // Validate parameters\n const invalidParams: string[] = [];\n (opt.params || []).forEach((param, index) => {\n if (paramIndexes[index] === -1) {\n invalidParams.push(param);\n }\n });\n if (invalidParams.length > 0) {\n logger.Warn(`CacheEvict: Parameter(s) [${invalidParams.join(\", \")}] not found in method ${String(methodName)}. These parameters will be ignored.`);\n }\n\n descriptor = {\n configurable,\n enumerable,\n writable: true,\n async value(...props: any[]) {\n const store: CacheStore = await GetCacheStore().catch((e: Error): null => {\n logger.error(\"Get cache store instance failed.\" + e.message);\n return null;\n });\n\n if (store) {\n const key = generateCacheKey(cacheName, paramIndexes, opt.params || [], props);\n\n const result = await value.apply(this, props);\n store.del(key).catch((e: Error) => {\n logger.error(\"Cache delete error:\" + e.message);\n });\n\n if (opt.delayedDoubleDeletion) {\n const delayTime = opt.delayTime || 5000;\n asyncDelayedExecution(() => {\n store.del(key).catch((e: Error) => {\n logger.error(\"Cache double delete error:\" + e.message);\n });\n }, delayTime);\n }\n return result;\n } else {\n // If store is not available, execute method directly\n return value.apply(this, props);\n }\n }\n };\n return descriptor;\n }\n}\n","/*\n * @Description: \n * @Usage: \n * @Author: richen\n * @Date: 2024-11-07 16:00:02\n * @LastEditTime: 2024-11-07 16:00:05\n * @License: BSD (3-Clause)\n * @Copyright (c): <richenlin(at)gmail.com>\n */\nimport { Koatty } from \"koatty_core\";\nimport { StoreOptions } from \"koatty_store\";\nimport { CloseCacheStore, GetCacheStore } from \"./store\";\n\nexport * from \"./cache\";\nexport * from \"./store\";\n\n/** \n * defaultOptions\n */\n\nconst defaultOptions: StoreOptions = {\n type: \"memory\",\n db: 0,\n timeout: 30\n}\n\n/**\n * @param options - The options for the cached options\n * @param app - The Koatty application instance\n */\nexport async function KoattyCached(options: StoreOptions, app: Koatty) {\n options = { ...defaultOptions, ...options };\n\n app.once(\"appReady\", async function () {\n // 初始化缓存存储\n await GetCacheStore(options);\n });\n\n app.on(\"appStop\", async function () {\n // 关闭缓存存储\n await CloseCacheStore();\n });\n}"]}
|