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/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
- * @Description:
17
- * @Usage:
18
- * @Author: richen
19
- * @Date: 2024-11-07 16:00:02
20
- * @LastEditTime: 2024-11-07 16:00:05
21
- * @License: BSD (3-Clause)
22
- * @Copyright (c): <richenlin(at)gmail.com>
23
- */
24
- // storeCache
25
- const storeCache = {
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
- // Promise to track initialization in progress
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
- // Return existing store if available
39
- if (storeCache.store && storeCache.store.getConnection) {
40
- return storeCache.store;
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
- * Close cache store connection for cleanup (mainly for testing)
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
- // Clear the CacheStore singleton instance
32
+ return storeCache.store || null;
33
+ }
34
+ initPromise = (async () => {
90
35
  try {
91
- await koatty_store.CacheStore.clearAllInstances();
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
- catch {
94
- // Ignore cleanup errors
95
- }
96
- // Always clear the cache
97
- storeCache.store = null;
98
- initPromise = null;
45
+ })();
46
+ return initPromise;
99
47
  }
100
-
101
- /* eslint-disable @typescript-eslint/no-unused-vars */
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
- // Match function parameters in parentheses
120
- const args = func.toString().match(/.*?\(([^)]*)\)/);
121
- if (args && args.length > 1) {
122
- // Split parameters into array and clean them
123
- return args[1].split(",").map(function (a) {
124
- // Remove multi-line comments /* ... */ and single-line comments //
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
- return [];
59
+ }
60
+ } catch {
135
61
  }
136
- catch (error) {
137
- // Return empty array if parsing fails
138
- return [];
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
- return params.map(param => funcParams.indexOf(param));
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
- let key = cacheName;
160
- for (let i = 0; i < paramIndexes.length; i++) {
161
- const paramIndex = paramIndexes[i];
162
- if (paramIndex >= 0 && props[paramIndex] !== undefined) {
163
- key += `:${paramNames[i]}:${koatty_lib.Helper.toString(props[paramIndex])}`;
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
- return key.length > longKey ? koatty_lib.Helper.murmurHash(key) : key;
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
- return new Promise(resolve => setTimeout(resolve, ms));
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
- await delay(ms);
184
- return fn();
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
- params: [],
214
- timeout: 300,
117
+ params: [],
118
+ timeout: 300
215
119
  }) {
216
- return (target, methodName, descriptor) => {
217
- const componentType = koatty_container.IOCContainer.getType(target);
218
- if (!["SERVICE", "COMPONENT"].includes(componentType)) {
219
- throw Error("This decorator only used in the service、component class.");
220
- }
221
- const { value, configurable, enumerable } = descriptor;
222
- const mergedOpt = { ...{ params: [], timeout: 300 }, ...opt };
223
- // Get the parameter list of the method
224
- const funcParams = getArgs(target[methodName]);
225
- // Get the defined parameter location
226
- const paramIndexes = getParamIndex(funcParams, mergedOpt.params || []);
227
- // Validate parameters
228
- const invalidParams = [];
229
- (mergedOpt.params || []).forEach((param, index) => {
230
- if (paramIndexes[index] === -1) {
231
- invalidParams.push(param);
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 (invalidParams.length > 0) {
235
- koatty_logger.DefaultLogger.Warn(`CacheAble: Parameter(s) [${invalidParams.join(", ")}] not found in method ${String(methodName)}. These parameters will be ignored.`);
236
- }
237
- descriptor = {
238
- configurable,
239
- enumerable,
240
- writable: true,
241
- async value(...props) {
242
- const store = await GetCacheStore().catch((e) => {
243
- koatty_logger.DefaultLogger.error("Get cache store instance failed." + e.message);
244
- return null;
245
- });
246
- if (store) {
247
- const key = generateCacheKey(cacheName, paramIndexes, mergedOpt.params, props);
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
- return descriptor;
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
- delayedDoubleDeletion: true,
187
+ delayedDoubleDeletion: true
298
188
  }) {
299
- return (target, methodName, descriptor) => {
300
- const componentType = koatty_container.IOCContainer.getType(target);
301
- if (!["SERVICE", "COMPONENT"].includes(componentType)) {
302
- throw Error("This decorator only used in the service、component class.");
303
- }
304
- const { value, configurable, enumerable } = descriptor;
305
- opt = { ...{ delayedDoubleDeletion: true, }, ...opt };
306
- // Get the parameter list of the method
307
- const funcParams = getArgs(target[methodName]);
308
- // Get the defined parameter location
309
- const paramIndexes = getParamIndex(funcParams, opt.params || []);
310
- // Validate parameters
311
- const invalidParams = [];
312
- (opt.params || []).forEach((param, index) => {
313
- if (paramIndexes[index] === -1) {
314
- invalidParams.push(param);
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 (invalidParams.length > 0) {
318
- koatty_logger.DefaultLogger.Warn(`CacheEvict: Parameter(s) [${invalidParams.join(", ")}] not found in method ${String(methodName)}. These parameters will be ignored.`);
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
- descriptor = {
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
- * defaultOptions
357
- */
358
- const defaultOptions = {
359
- type: "memory",
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
- options = { ...defaultOptions, ...options };
369
- app.once("appReady", async function () {
370
- // 初始化缓存存储
371
- await GetCacheStore(options);
372
- });
373
- app.on("appStop", async function () {
374
- // 关闭缓存存储
375
- await CloseCacheStore();
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":"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","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}"]}