koatty_cacheable 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,141 +1,99 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2025-06-23 01:59:54
3
+ * @Date: 2025-11-02 09:19:59
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
7
7
  */
8
- import { DefaultLogger, Logger } from 'koatty_logger';
9
8
  import { Helper } from 'koatty_lib';
9
+ import { DefaultLogger } from 'koatty_logger';
10
10
  import { CacheStore } from 'koatty_store';
11
11
  import { IOCContainer } from 'koatty_container';
12
12
 
13
+ /*
14
+ * @Description:
15
+ * @Usage:
16
+ * @Author: richen
17
+ * @Date: 2024-11-07 16:00:02
18
+ * @LastEditTime: 2024-11-07 16:00:05
19
+ * @License: BSD (3-Clause)
20
+ * @Copyright (c): <richenlin(at)gmail.com>
21
+ */
13
22
  // storeCache
14
23
  const storeCache = {
15
24
  store: null
16
25
  };
26
+ // Promise to track initialization in progress
27
+ let initPromise = null;
17
28
  /**
18
29
  * get instances of storeCache
19
30
  *
20
31
  * @export
21
- * @param {Application} app
32
+ * @param {StoreOptions} options
22
33
  * @returns {*} {CacheStore}
23
34
  */
24
- async function GetCacheStore(app) {
35
+ async function GetCacheStore(options) {
36
+ // Return existing store if available
25
37
  if (storeCache.store && storeCache.store.getConnection) {
26
38
  return storeCache.store;
27
39
  }
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. `);
40
+ // If initialization is in progress, wait for it
41
+ if (initPromise) {
42
+ return initPromise;
42
43
  }
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();
44
+ if (Helper.isEmpty(options)) {
45
+ if (!storeCache.store) {
46
+ DefaultLogger.Warn(`CacheStore not initialized. Please call KoattyCached() first with proper options in your application startup.`);
62
47
  }
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;
48
+ return storeCache.store || null;
82
49
  }
50
+ // Start initialization and track it
51
+ initPromise = (async () => {
52
+ try {
53
+ storeCache.store = CacheStore.getInstance(options);
54
+ if (!Helper.isFunction(storeCache.store.getConnection)) {
55
+ throw Error(`CacheStore connection failed. `);
56
+ }
57
+ await storeCache.store.client.getConnection();
58
+ return storeCache.store;
59
+ }
60
+ finally {
61
+ // Clear init promise after completion
62
+ initPromise = null;
63
+ }
64
+ })();
65
+ return initPromise;
83
66
  }
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
67
  /**
98
- * Cache injector - initialize global cache manager and store
99
- * @param options Cache options
100
- * @param app Koatty application instance
68
+ * Close cache store connection for cleanup (mainly for testing)
101
69
  */
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;
70
+ async function CloseCacheStore() {
71
+ if (storeCache.store) {
72
+ try {
73
+ if (storeCache.store.client) {
74
+ const client = storeCache.store.client;
75
+ if (typeof client.quit === 'function') {
76
+ await client.quit();
77
+ }
78
+ else if (typeof client.close === 'function') {
79
+ await client.close();
80
+ }
81
+ }
82
+ }
83
+ catch {
84
+ // Ignore cleanup errors
110
85
  }
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
86
  }
121
- }
122
- /**
123
- * Close cache store connection
124
- * @param app Koatty application instance
125
- */
126
- async function closeCacheStore(_app) {
87
+ // Clear the CacheStore singleton instance
127
88
  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');
89
+ await CacheStore.clearAllInstances();
135
90
  }
136
- catch (error) {
137
- logger$1.Error('Error closing cache store connection:', error);
91
+ catch {
92
+ // Ignore cleanup errors
138
93
  }
94
+ // Always clear the cache
95
+ storeCache.store = null;
96
+ initPromise = null;
139
97
  }
140
98
 
141
99
  /* eslint-disable @typescript-eslint/no-unused-vars */
@@ -161,8 +119,11 @@ function getArgs(func) {
161
119
  if (args && args.length > 1) {
162
120
  // Split parameters into array and clean them
163
121
  return args[1].split(",").map(function (a) {
164
- // Remove inline comments and whitespace
165
- return a.replace(/\/\*.*\*\//, "").trim();
122
+ // Remove multi-line comments /* ... */ and single-line comments //
123
+ const param = a.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").trim();
124
+ // Extract parameter name (before : or = or end of string)
125
+ const match = param.match(/^(\w+)/);
126
+ return match ? match[1] : "";
166
127
  }).filter(function (ae) {
167
128
  // Filter out empty strings
168
129
  return ae;
@@ -228,17 +189,6 @@ async function asyncDelayedExecution(fn, ms) {
228
189
  * @Description:
229
190
  * @Copyright (c) - <richenlin(at)gmail.com>
230
191
  */
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";
242
192
  /**
243
193
  * Decorate this method to support caching.
244
194
  * The cache method returns a value to ensure that the next time
@@ -257,79 +207,70 @@ const CACHE_METADATA_KEY = "CACHE_METADATA_KEY";
257
207
  * Use the 'id' parameters of the method as cache subkeys, the cache expiration time 30s
258
208
  * @returns {MethodDecorator}
259
209
  */
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
- }
210
+ function CacheAble(cacheName, opt = {
211
+ params: [],
212
+ timeout: 300,
213
+ }) {
272
214
  return (target, methodName, descriptor) => {
273
215
  const componentType = IOCContainer.getType(target);
274
216
  if (!["SERVICE", "COMPONENT"].includes(componentType)) {
275
217
  throw Error("This decorator only used in the service、component class.");
276
218
  }
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);
219
+ const { value, configurable, enumerable } = descriptor;
220
+ const mergedOpt = { ...{ params: [], timeout: 300 }, ...opt };
221
+ // Get the parameter list of the method
222
+ const funcParams = getArgs(target[methodName]);
223
+ // Get the defined parameter location
224
+ const paramIndexes = getParamIndex(funcParams, mergedOpt.params || []);
225
+ // Validate parameters
226
+ const invalidParams = [];
227
+ (mergedOpt.params || []).forEach((param, index) => {
228
+ if (paramIndexes[index] === -1) {
229
+ invalidParams.push(param);
292
230
  }
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;
231
+ });
232
+ if (invalidParams.length > 0) {
233
+ DefaultLogger.Warn(`CacheAble: Parameter(s) [${invalidParams.join(", ")}] not found in method ${String(methodName)}. These parameters will be ignored.`);
234
+ }
235
+ descriptor = {
236
+ configurable,
237
+ enumerable,
238
+ writable: true,
239
+ async value(...props) {
240
+ const store = await GetCacheStore().catch((e) => {
241
+ DefaultLogger.error("Get cache store instance failed." + e.message);
242
+ return null;
243
+ });
244
+ if (store) {
245
+ const key = generateCacheKey(cacheName, paramIndexes, mergedOpt.params, props);
246
+ const res = await store.get(key).catch((e) => {
247
+ DefaultLogger.error("Cache get error:" + e.message);
305
248
  });
306
- if (!Helper.isEmpty(cached)) {
307
- logger.Debug(`Cache hit for key: ${key}`);
249
+ if (!Helper.isEmpty(res)) {
308
250
  try {
309
- return JSON.parse(cached);
251
+ return JSON.parse(res);
310
252
  }
311
- catch {
312
- // If parse fails, return as string (for simple values)
313
- return cached;
253
+ catch (e) {
254
+ const error = e;
255
+ DefaultLogger.error("Cache JSON parse error:" + error.message);
256
+ // 如果解析失败,删除损坏的缓存,重新执行方法
257
+ store.del(key).catch((err) => {
258
+ DefaultLogger.error("Cache del error after parse failure:" + err.message);
259
+ });
314
260
  }
315
261
  }
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);
262
+ const result = await value.apply(this, props);
263
+ // async refresh store
264
+ store.set(key, Helper.isJSONObj(result) ? JSON.stringify(result) : result, mergedOpt.timeout).catch((e) => {
265
+ DefaultLogger.error("Cache set error:" + e.message);
324
266
  });
325
267
  return result;
326
268
  }
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);
269
+ else {
270
+ // tslint:disable-next-line: no-invalid-this
271
+ return value.apply(this, props);
331
272
  }
332
- })();
273
+ }
333
274
  };
334
275
  return descriptor;
335
276
  };
@@ -350,116 +291,87 @@ function CacheAble(cacheNameOrOpt, opt = {}) {
350
291
  * and clear the cache after the method executed
351
292
  * @returns
352
293
  */
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
- }
294
+ function CacheEvict(cacheName, opt = {
295
+ delayedDoubleDeletion: true,
296
+ }) {
365
297
  return (target, methodName, descriptor) => {
366
298
  const componentType = IOCContainer.getType(target);
367
299
  if (!["SERVICE", "COMPONENT"].includes(componentType)) {
368
300
  throw Error("This decorator only used in the service、component class.");
369
301
  }
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);
302
+ const { value, configurable, enumerable } = descriptor;
303
+ opt = { ...{ delayedDoubleDeletion: true, }, ...opt };
304
+ // Get the parameter list of the method
305
+ const funcParams = getArgs(target[methodName]);
306
+ // Get the defined parameter location
307
+ const paramIndexes = getParamIndex(funcParams, opt.params || []);
308
+ // Validate parameters
309
+ const invalidParams = [];
310
+ (opt.params || []).forEach((param, index) => {
311
+ if (paramIndexes[index] === -1) {
312
+ invalidParams.push(param);
387
313
  }
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
314
+ });
315
+ if (invalidParams.length > 0) {
316
+ DefaultLogger.Warn(`CacheEvict: Parameter(s) [${invalidParams.join(", ")}] not found in method ${String(methodName)}. These parameters will be ignored.`);
317
+ }
318
+ descriptor = {
319
+ configurable,
320
+ enumerable,
321
+ writable: true,
322
+ async value(...props) {
323
+ const store = await GetCacheStore().catch((e) => {
324
+ DefaultLogger.error("Get cache store instance failed." + e.message);
325
+ return null;
326
+ });
327
+ if (store) {
328
+ const key = generateCacheKey(cacheName, paramIndexes, opt.params || [], props);
329
+ const result = await value.apply(this, props);
399
330
  store.del(key).catch((e) => {
400
- logger.Debug("Cache delete error:" + e.message);
331
+ DefaultLogger.error("Cache delete error:" + e.message);
401
332
  });
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) {
408
- const delayTime = 5000;
333
+ if (opt.delayedDoubleDeletion) {
334
+ const delayTime = opt.delayTime || 5000;
409
335
  asyncDelayedExecution(() => {
410
336
  store.del(key).catch((e) => {
411
- logger.Debug("Cache double delete error:" + e.message);
337
+ DefaultLogger.error("Cache double delete error:" + e.message);
412
338
  });
413
339
  }, delayTime);
414
340
  }
415
341
  return result;
416
342
  }
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);
343
+ else {
344
+ // If store is not available, execute method directly
345
+ return value.apply(this, props);
421
346
  }
422
- })();
347
+ }
423
348
  };
424
349
  return descriptor;
425
350
  };
426
351
  }
427
352
 
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
353
  /**
438
354
  * defaultOptions
439
355
  */
440
356
  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
- }
357
+ type: "memory",
358
+ db: 0,
359
+ timeout: 30
450
360
  };
451
361
  /**
452
- * @param options - The options for the scheduled job
362
+ * @param options - The options for the cached options
453
363
  * @param app - The Koatty application instance
454
364
  */
455
- async function KoattyCache(options, app) {
365
+ async function KoattyCached(options, app) {
456
366
  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();
367
+ app.once("appReady", async function () {
368
+ // 初始化缓存存储
369
+ await GetCacheStore(options);
370
+ });
371
+ app.on("appStop", async function () {
372
+ // 关闭缓存存储
373
+ await CloseCacheStore();
462
374
  });
463
375
  }
464
376
 
465
- export { CACHE_METADATA_KEY, CacheAble, CacheEvict, DecoratorType, KoattyCache };
377
+ export { CacheAble, CacheEvict, CloseCacheStore, GetCacheStore, KoattyCached };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koatty_cacheable",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
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": "NODE_ENV=test npm run eslint && NODE_ENV=test jest --passWithNoTests",
19
+ "test": "npm run eslint && jest --passWithNoTests",
20
20
  "test:cov": "jest --collectCoverage --detectOpenHandles",
21
21
  "version": "conventional-changelog -p angular -i CHANGELOG.md -s"
22
22
  },
@@ -67,7 +67,6 @@
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",
71
70
  "@typescript-eslint/eslint-plugin": "^8.x.x",
72
71
  "@typescript-eslint/parser": "^8.x.x",
73
72
  "conventional-changelog-cli": "^5.x.x",
@@ -88,15 +87,16 @@
88
87
  },
89
88
  "dependencies": {
90
89
  "koatty_container": "^1.x.x",
91
- "koatty_core": "^1.x.x",
90
+ "koatty_core": "2.x.x",
92
91
  "koatty_lib": "^1.x.x",
93
92
  "koatty_logger": "^2.x.x",
94
93
  "koatty_store": "^1.x.x"
95
94
  },
96
95
  "peerDependencies": {
97
96
  "koatty_container": "^1.x.x",
98
- "koatty_core": "^1.x.x",
97
+ "koatty_core": "2.x.x",
99
98
  "koatty_lib": "^1.x.x",
100
- "koatty_logger": "^2.x.x"
99
+ "koatty_logger": "^2.x.x",
100
+ "koatty_store": "^1.x.x"
101
101
  }
102
102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koatty_cacheable",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
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": "NODE_ENV=test npm run eslint && NODE_ENV=test jest --passWithNoTests",
19
+ "test": "npm run eslint && jest --passWithNoTests",
20
20
  "test:cov": "jest --collectCoverage --detectOpenHandles",
21
21
  "version": "conventional-changelog -p angular -i CHANGELOG.md -s"
22
22
  },
@@ -67,7 +67,6 @@
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",
71
70
  "@typescript-eslint/eslint-plugin": "^8.x.x",
72
71
  "@typescript-eslint/parser": "^8.x.x",
73
72
  "conventional-changelog-cli": "^5.x.x",
@@ -88,15 +87,16 @@
88
87
  },
89
88
  "dependencies": {
90
89
  "koatty_container": "^1.x.x",
91
- "koatty_core": "^1.x.x",
90
+ "koatty_core": "2.x.x",
92
91
  "koatty_lib": "^1.x.x",
93
92
  "koatty_logger": "^2.x.x",
94
93
  "koatty_store": "^1.x.x"
95
94
  },
96
95
  "peerDependencies": {
97
96
  "koatty_container": "^1.x.x",
98
- "koatty_core": "^1.x.x",
97
+ "koatty_core": "2.x.x",
99
98
  "koatty_lib": "^1.x.x",
100
- "koatty_logger": "^2.x.x"
99
+ "koatty_logger": "^2.x.x",
100
+ "koatty_store": "^1.x.x"
101
101
  }
102
102
  }