koatty_cacheable 1.3.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/index.d.ts +36 -6
- package/dist/index.js +109 -51
- package/dist/index.mjs +110 -33
- package/dist/package.json +89 -87
- package/package.json +89 -87
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.4.0](https://github.com/thinkkoa/koatty_cacheable/compare/v1.3.8...v1.4.0) (2023-02-18)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* cache subkey ([408e3c7](https://github.com/thinkkoa/koatty_cacheable/commit/408e3c709a4dfff6e7d224a22d26e58854a805ac))
|
|
11
|
+
* 启动时链接 ([e7ec709](https://github.com/thinkkoa/koatty_cacheable/commit/e7ec7094be106e4e48783c9b214b8369e8a18297))
|
|
12
|
+
* 支持引入变量做缓存key ([4ce81aa](https://github.com/thinkkoa/koatty_cacheable/commit/4ce81aaaf9610f4a62ddf43e3c4389dd003c2db8))
|
|
13
|
+
* 获取单例 ([0759972](https://github.com/thinkkoa/koatty_cacheable/commit/0759972adf7e86312f60f0bf77604bddf06ce0de))
|
|
14
|
+
|
|
5
15
|
### [1.3.8](https://github.com/thinkkoa/koatty_cacheable/compare/v1.3.6...v1.3.8) (2023-01-13)
|
|
6
16
|
|
|
7
17
|
### [1.3.7](https://github.com/thinkkoa/koatty_cacheable/compare/v1.3.6...v1.3.7) (2022-05-27)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @Author: richen
|
|
3
|
-
* @Date: 2023-
|
|
3
|
+
* @Date: 2023-02-19 01:22:50
|
|
4
4
|
* @License: BSD (3-Clause)
|
|
5
5
|
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
6
6
|
* @HomePage: https://koatty.org/
|
|
@@ -15,20 +15,50 @@ import { CacheStore } from 'koatty_store';
|
|
|
15
15
|
*
|
|
16
16
|
* @export
|
|
17
17
|
* @param {string} cacheName cache name
|
|
18
|
-
* @param {
|
|
18
|
+
* @param {CacheAbleOpt} [opt] cache options
|
|
19
|
+
* e.g:
|
|
20
|
+
* {
|
|
21
|
+
* params: ["id"],
|
|
22
|
+
* timeout: 30
|
|
23
|
+
* }
|
|
24
|
+
* Use the 'id' parameters of the method as cache subkeys, the cache expiration time 30s
|
|
19
25
|
* @returns {MethodDecorator}
|
|
20
26
|
*/
|
|
21
|
-
export declare function CacheAble(cacheName: string,
|
|
27
|
+
export declare function CacheAble(cacheName: string, opt?: CacheAbleOpt): MethodDecorator;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @description:
|
|
31
|
+
* @return {*}
|
|
32
|
+
*/
|
|
33
|
+
export declare interface CacheAbleOpt {
|
|
34
|
+
params?: string[];
|
|
35
|
+
timeout?: number;
|
|
36
|
+
}
|
|
22
37
|
|
|
23
38
|
/**
|
|
24
39
|
* Decorating the execution of this method will trigger a cache clear operation. Redis server config from db.ts.
|
|
25
40
|
*
|
|
26
41
|
* @export
|
|
27
42
|
* @param {string} cacheName cacheName cache name
|
|
28
|
-
* @param {
|
|
43
|
+
* @param {CacheEvictOpt} [opt] cache options
|
|
44
|
+
* e.g:
|
|
45
|
+
* {
|
|
46
|
+
* params: ["id"],
|
|
47
|
+
* eventTime: "Before"
|
|
48
|
+
* }
|
|
49
|
+
* Use the 'id' parameters of the method as cache subkeys, and clear the cache before the method executed
|
|
29
50
|
* @returns
|
|
30
51
|
*/
|
|
31
|
-
export declare function CacheEvict(cacheName: string,
|
|
52
|
+
export declare function CacheEvict(cacheName: string, opt?: CacheEvictOpt): (target: any, methodName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @description:
|
|
56
|
+
* @return {*}
|
|
57
|
+
*/
|
|
58
|
+
export declare interface CacheEvictOpt {
|
|
59
|
+
params?: string[];
|
|
60
|
+
eventTime?: "Before";
|
|
61
|
+
}
|
|
32
62
|
|
|
33
63
|
/**
|
|
34
64
|
*
|
|
@@ -36,7 +66,7 @@ export declare function CacheEvict(cacheName: string, eventTime?: eventTimes): (
|
|
|
36
66
|
export declare type eventTimes = "Before" | "After";
|
|
37
67
|
|
|
38
68
|
/**
|
|
39
|
-
* get instances of
|
|
69
|
+
* get instances of storeCache
|
|
40
70
|
*
|
|
41
71
|
* @export
|
|
42
72
|
* @param {Application} app
|
package/dist/index.js
CHANGED
|
@@ -1,49 +1,31 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @Author: richen
|
|
3
|
-
* @Date: 2023-
|
|
3
|
+
* @Date: 2023-02-19 01:22:36
|
|
4
4
|
* @License: BSD (3-Clause)
|
|
5
5
|
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
6
6
|
* @HomePage: https://koatty.org/
|
|
7
7
|
*/
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var koatty_lib = require('koatty_lib');
|
|
11
11
|
var koatty_logger = require('koatty_logger');
|
|
12
12
|
var koatty_store = require('koatty_store');
|
|
13
13
|
var koatty_container = require('koatty_container');
|
|
14
14
|
|
|
15
|
-
function _interopNamespaceDefault(e) {
|
|
16
|
-
var n = Object.create(null);
|
|
17
|
-
if (e) {
|
|
18
|
-
Object.keys(e).forEach(function (k) {
|
|
19
|
-
if (k !== 'default') {
|
|
20
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
21
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
22
|
-
enumerable: true,
|
|
23
|
-
get: function () { return e[k]; }
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
n.default = e;
|
|
29
|
-
return Object.freeze(n);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var helper__namespace = /*#__PURE__*/_interopNamespaceDefault(helper);
|
|
33
|
-
|
|
34
15
|
/*
|
|
35
16
|
* @Author: richen
|
|
36
17
|
* @Date: 2020-07-06 19:53:43
|
|
37
|
-
* @LastEditTime: 2023-
|
|
18
|
+
* @LastEditTime: 2023-02-19 01:16:52
|
|
38
19
|
* @Description:
|
|
39
20
|
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
40
21
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
22
|
+
const PreKey = "k";
|
|
23
|
+
// storeCache
|
|
24
|
+
const storeCache = {
|
|
43
25
|
store: null
|
|
44
26
|
};
|
|
45
27
|
/**
|
|
46
|
-
* get instances of
|
|
28
|
+
* get instances of storeCache
|
|
47
29
|
*
|
|
48
30
|
* @export
|
|
49
31
|
* @param {Application} app
|
|
@@ -51,18 +33,19 @@ const cacheStore = {
|
|
|
51
33
|
*/
|
|
52
34
|
async function GetCacheStore(app) {
|
|
53
35
|
var _a;
|
|
54
|
-
if (
|
|
55
|
-
return
|
|
36
|
+
if (storeCache.store && storeCache.store.getConnection) {
|
|
37
|
+
return storeCache.store;
|
|
56
38
|
}
|
|
57
39
|
const opt = (_a = app.config("CacheStore", "db")) !== null && _a !== void 0 ? _a : {};
|
|
58
|
-
if (
|
|
40
|
+
if (koatty_lib.Helper.isEmpty(opt)) {
|
|
59
41
|
koatty_logger.DefaultLogger.Warn(`Missing CacheStore server configuration. Please write a configuration item with the key name 'CacheStore' in the db.ts file.`);
|
|
60
42
|
}
|
|
61
|
-
|
|
62
|
-
if (!
|
|
43
|
+
storeCache.store = koatty_store.CacheStore.getInstance(opt);
|
|
44
|
+
if (!koatty_lib.Helper.isFunction(storeCache.store.getConnection)) {
|
|
63
45
|
throw Error(`CacheStore connection failed. `);
|
|
64
46
|
}
|
|
65
|
-
|
|
47
|
+
await storeCache.store.client.getConnection();
|
|
48
|
+
return storeCache.store;
|
|
66
49
|
}
|
|
67
50
|
/**
|
|
68
51
|
* initiation CacheStore connection and client.
|
|
@@ -81,18 +64,27 @@ async function InitCacheStore() {
|
|
|
81
64
|
*
|
|
82
65
|
* @export
|
|
83
66
|
* @param {string} cacheName cache name
|
|
84
|
-
* @param {
|
|
67
|
+
* @param {CacheAbleOpt} [opt] cache options
|
|
68
|
+
* e.g:
|
|
69
|
+
* {
|
|
70
|
+
* params: ["id"],
|
|
71
|
+
* timeout: 30
|
|
72
|
+
* }
|
|
73
|
+
* Use the 'id' parameters of the method as cache subkeys, the cache expiration time 30s
|
|
85
74
|
* @returns {MethodDecorator}
|
|
86
75
|
*/
|
|
87
|
-
function CacheAble(cacheName,
|
|
76
|
+
function CacheAble(cacheName, opt = {
|
|
77
|
+
params: [],
|
|
78
|
+
timeout: 3600,
|
|
79
|
+
}) {
|
|
88
80
|
return (target, methodName, descriptor) => {
|
|
89
81
|
const componentType = koatty_container.IOCContainer.getType(target);
|
|
90
82
|
if (componentType !== "SERVICE" && componentType !== "COMPONENT") {
|
|
91
83
|
throw Error("This decorator only used in the service、component class.");
|
|
92
84
|
}
|
|
93
|
-
let identifier = koatty_container.IOCContainer.getIdentifier(target);
|
|
94
|
-
identifier = identifier || (target.constructor ? (target.constructor.name || "") : "");
|
|
95
85
|
const { value, configurable, enumerable } = descriptor;
|
|
86
|
+
// 获取定义的参数位置
|
|
87
|
+
const paramIndexes = getParamIndex(opt.params, getArgs(value));
|
|
96
88
|
descriptor = {
|
|
97
89
|
configurable,
|
|
98
90
|
enumerable,
|
|
@@ -106,26 +98,35 @@ function CacheAble(cacheName, timeout = 3600) {
|
|
|
106
98
|
});
|
|
107
99
|
if (cacheFlag) {
|
|
108
100
|
// tslint:disable-next-line: one-variable-per-declaration
|
|
109
|
-
let key =
|
|
101
|
+
let key = PreKey;
|
|
110
102
|
if (props && props.length > 0) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
103
|
+
for (const item of paramIndexes) {
|
|
104
|
+
if (props[item] !== undefined) {
|
|
105
|
+
const value = koatty_lib.Helper.toString(props[item]);
|
|
106
|
+
key += `:${value}`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// 防止key超长
|
|
110
|
+
if (key.length > 32) {
|
|
111
|
+
key = koatty_lib.Helper.murmurHash(key);
|
|
112
|
+
}
|
|
115
113
|
}
|
|
116
|
-
res = await store.
|
|
117
|
-
if (!
|
|
114
|
+
let res = await store.get(`${cacheName}:${key}`).catch(() => null);
|
|
115
|
+
if (!koatty_lib.Helper.isEmpty(res)) {
|
|
118
116
|
return JSON.parse(res);
|
|
119
117
|
}
|
|
120
118
|
// tslint:disable-next-line: no-invalid-this
|
|
121
119
|
res = await value.apply(this, props);
|
|
122
120
|
// prevent cache penetration
|
|
123
|
-
if (
|
|
121
|
+
if (koatty_lib.Helper.isEmpty(res)) {
|
|
124
122
|
res = "";
|
|
125
|
-
timeout =
|
|
123
|
+
opt.timeout = 5;
|
|
124
|
+
}
|
|
125
|
+
if (!opt.timeout) {
|
|
126
|
+
opt.timeout = 3600;
|
|
126
127
|
}
|
|
127
128
|
// async set store
|
|
128
|
-
store.
|
|
129
|
+
store.set(`${cacheName}:${key}`, JSON.stringify(res), opt.timeout).catch(() => null);
|
|
129
130
|
return res;
|
|
130
131
|
}
|
|
131
132
|
else {
|
|
@@ -144,17 +145,26 @@ function CacheAble(cacheName, timeout = 3600) {
|
|
|
144
145
|
*
|
|
145
146
|
* @export
|
|
146
147
|
* @param {string} cacheName cacheName cache name
|
|
147
|
-
* @param {
|
|
148
|
+
* @param {CacheEvictOpt} [opt] cache options
|
|
149
|
+
* e.g:
|
|
150
|
+
* {
|
|
151
|
+
* params: ["id"],
|
|
152
|
+
* eventTime: "Before"
|
|
153
|
+
* }
|
|
154
|
+
* Use the 'id' parameters of the method as cache subkeys, and clear the cache before the method executed
|
|
148
155
|
* @returns
|
|
149
156
|
*/
|
|
150
|
-
function CacheEvict(cacheName,
|
|
157
|
+
function CacheEvict(cacheName, opt = {
|
|
158
|
+
eventTime: "Before",
|
|
159
|
+
}) {
|
|
151
160
|
return (target, methodName, descriptor) => {
|
|
152
161
|
const componentType = koatty_container.IOCContainer.getType(target);
|
|
153
162
|
if (componentType !== "SERVICE" && componentType !== "COMPONENT") {
|
|
154
163
|
throw Error("This decorator only used in the service、component class.");
|
|
155
164
|
}
|
|
156
|
-
koatty_container.IOCContainer.getIdentifier(target);
|
|
157
165
|
const { value, configurable, enumerable } = descriptor;
|
|
166
|
+
// 获取定义的参数位置
|
|
167
|
+
const paramIndexes = getParamIndex(opt.params, getArgs(value));
|
|
158
168
|
descriptor = {
|
|
159
169
|
configurable,
|
|
160
170
|
enumerable,
|
|
@@ -167,15 +177,28 @@ function CacheEvict(cacheName, eventTime = "Before") {
|
|
|
167
177
|
return null;
|
|
168
178
|
});
|
|
169
179
|
if (cacheFlag) {
|
|
170
|
-
|
|
171
|
-
|
|
180
|
+
let key = PreKey;
|
|
181
|
+
if (props && props.length > 0) {
|
|
182
|
+
for (const item of paramIndexes) {
|
|
183
|
+
if (props[item] !== undefined) {
|
|
184
|
+
const value = koatty_lib.Helper.toString(props[item]);
|
|
185
|
+
key += `:${value}`;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// 防止key超长
|
|
189
|
+
if (key.length > 32) {
|
|
190
|
+
key = koatty_lib.Helper.murmurHash(key);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (opt.eventTime === "Before") {
|
|
194
|
+
await store.del(`${cacheName}:${key}`).catch(() => null);
|
|
172
195
|
// tslint:disable-next-line: no-invalid-this
|
|
173
196
|
return value.apply(this, props);
|
|
174
197
|
}
|
|
175
198
|
else {
|
|
176
199
|
// tslint:disable-next-line: no-invalid-this
|
|
177
200
|
const res = await value.apply(this, props);
|
|
178
|
-
store.del(cacheName).catch(() => null);
|
|
201
|
+
store.del(`${cacheName}:${key}`).catch(() => null);
|
|
179
202
|
return res;
|
|
180
203
|
}
|
|
181
204
|
}
|
|
@@ -189,6 +212,41 @@ function CacheEvict(cacheName, eventTime = "Before") {
|
|
|
189
212
|
InitCacheStore();
|
|
190
213
|
return descriptor;
|
|
191
214
|
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* @description:
|
|
218
|
+
* @param {*} func
|
|
219
|
+
* @return {*}
|
|
220
|
+
*/
|
|
221
|
+
function getArgs(func) {
|
|
222
|
+
// 首先匹配函数括弧里的参数
|
|
223
|
+
const args = func.toString().match(/.*?\(([^)]*)\)/);
|
|
224
|
+
if (args.length > 1) {
|
|
225
|
+
// 分解参数成数组
|
|
226
|
+
return args[1].split(",").map(function (a) {
|
|
227
|
+
// 去空格和内联注释
|
|
228
|
+
return a.replace(/\/\*.*\*\//, "").trim();
|
|
229
|
+
}).filter(function (ae) {
|
|
230
|
+
// 确保没有undefineds
|
|
231
|
+
return ae;
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* @description:
|
|
238
|
+
* @param {string} params
|
|
239
|
+
* @param {string} args
|
|
240
|
+
* @return {*}
|
|
241
|
+
*/
|
|
242
|
+
function getParamIndex(params, args) {
|
|
243
|
+
const res = [];
|
|
244
|
+
for (let i = 0; i < params.length; i++) {
|
|
245
|
+
if (params.includes(params[i])) {
|
|
246
|
+
res.push(i);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return res;
|
|
192
250
|
}
|
|
193
251
|
|
|
194
252
|
exports.CacheAble = CacheAble;
|
package/dist/index.mjs
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @Author: richen
|
|
3
|
-
* @Date: 2023-
|
|
3
|
+
* @Date: 2023-02-19 01:22:36
|
|
4
4
|
* @License: BSD (3-Clause)
|
|
5
5
|
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
6
6
|
* @HomePage: https://koatty.org/
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
8
|
+
import { Helper } from 'koatty_lib';
|
|
9
9
|
import { DefaultLogger } from 'koatty_logger';
|
|
10
|
-
import {
|
|
10
|
+
import { CacheStore } from 'koatty_store';
|
|
11
11
|
import { IOCContainer } from 'koatty_container';
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
14
|
* @Author: richen
|
|
15
15
|
* @Date: 2020-07-06 19:53:43
|
|
16
|
-
* @LastEditTime: 2023-
|
|
16
|
+
* @LastEditTime: 2023-02-19 01:16:52
|
|
17
17
|
* @Description:
|
|
18
18
|
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const PreKey = "k";
|
|
21
|
+
// storeCache
|
|
22
|
+
const storeCache = {
|
|
22
23
|
store: null
|
|
23
24
|
};
|
|
24
25
|
/**
|
|
25
|
-
* get instances of
|
|
26
|
+
* get instances of storeCache
|
|
26
27
|
*
|
|
27
28
|
* @export
|
|
28
29
|
* @param {Application} app
|
|
@@ -30,18 +31,19 @@ const cacheStore = {
|
|
|
30
31
|
*/
|
|
31
32
|
async function GetCacheStore(app) {
|
|
32
33
|
var _a;
|
|
33
|
-
if (
|
|
34
|
-
return
|
|
34
|
+
if (storeCache.store && storeCache.store.getConnection) {
|
|
35
|
+
return storeCache.store;
|
|
35
36
|
}
|
|
36
37
|
const opt = (_a = app.config("CacheStore", "db")) !== null && _a !== void 0 ? _a : {};
|
|
37
|
-
if (
|
|
38
|
+
if (Helper.isEmpty(opt)) {
|
|
38
39
|
DefaultLogger.Warn(`Missing CacheStore server configuration. Please write a configuration item with the key name 'CacheStore' in the db.ts file.`);
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
if (!
|
|
41
|
+
storeCache.store = CacheStore.getInstance(opt);
|
|
42
|
+
if (!Helper.isFunction(storeCache.store.getConnection)) {
|
|
42
43
|
throw Error(`CacheStore connection failed. `);
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
await storeCache.store.client.getConnection();
|
|
46
|
+
return storeCache.store;
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
47
49
|
* initiation CacheStore connection and client.
|
|
@@ -60,18 +62,27 @@ async function InitCacheStore() {
|
|
|
60
62
|
*
|
|
61
63
|
* @export
|
|
62
64
|
* @param {string} cacheName cache name
|
|
63
|
-
* @param {
|
|
65
|
+
* @param {CacheAbleOpt} [opt] cache options
|
|
66
|
+
* e.g:
|
|
67
|
+
* {
|
|
68
|
+
* params: ["id"],
|
|
69
|
+
* timeout: 30
|
|
70
|
+
* }
|
|
71
|
+
* Use the 'id' parameters of the method as cache subkeys, the cache expiration time 30s
|
|
64
72
|
* @returns {MethodDecorator}
|
|
65
73
|
*/
|
|
66
|
-
function CacheAble(cacheName,
|
|
74
|
+
function CacheAble(cacheName, opt = {
|
|
75
|
+
params: [],
|
|
76
|
+
timeout: 3600,
|
|
77
|
+
}) {
|
|
67
78
|
return (target, methodName, descriptor) => {
|
|
68
79
|
const componentType = IOCContainer.getType(target);
|
|
69
80
|
if (componentType !== "SERVICE" && componentType !== "COMPONENT") {
|
|
70
81
|
throw Error("This decorator only used in the service、component class.");
|
|
71
82
|
}
|
|
72
|
-
let identifier = IOCContainer.getIdentifier(target);
|
|
73
|
-
identifier = identifier || (target.constructor ? (target.constructor.name || "") : "");
|
|
74
83
|
const { value, configurable, enumerable } = descriptor;
|
|
84
|
+
// 获取定义的参数位置
|
|
85
|
+
const paramIndexes = getParamIndex(opt.params, getArgs(value));
|
|
75
86
|
descriptor = {
|
|
76
87
|
configurable,
|
|
77
88
|
enumerable,
|
|
@@ -85,26 +96,35 @@ function CacheAble(cacheName, timeout = 3600) {
|
|
|
85
96
|
});
|
|
86
97
|
if (cacheFlag) {
|
|
87
98
|
// tslint:disable-next-line: one-variable-per-declaration
|
|
88
|
-
let key =
|
|
99
|
+
let key = PreKey;
|
|
89
100
|
if (props && props.length > 0) {
|
|
90
|
-
|
|
101
|
+
for (const item of paramIndexes) {
|
|
102
|
+
if (props[item] !== undefined) {
|
|
103
|
+
const value = Helper.toString(props[item]);
|
|
104
|
+
key += `:${value}`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// 防止key超长
|
|
108
|
+
if (key.length > 32) {
|
|
109
|
+
key = Helper.murmurHash(key);
|
|
110
|
+
}
|
|
91
111
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
res = await store.hget(cacheName, key).catch(() => null);
|
|
96
|
-
if (!helper.isEmpty(res)) {
|
|
112
|
+
let res = await store.get(`${cacheName}:${key}`).catch(() => null);
|
|
113
|
+
if (!Helper.isEmpty(res)) {
|
|
97
114
|
return JSON.parse(res);
|
|
98
115
|
}
|
|
99
116
|
// tslint:disable-next-line: no-invalid-this
|
|
100
117
|
res = await value.apply(this, props);
|
|
101
118
|
// prevent cache penetration
|
|
102
|
-
if (
|
|
119
|
+
if (Helper.isEmpty(res)) {
|
|
103
120
|
res = "";
|
|
104
|
-
timeout =
|
|
121
|
+
opt.timeout = 5;
|
|
122
|
+
}
|
|
123
|
+
if (!opt.timeout) {
|
|
124
|
+
opt.timeout = 3600;
|
|
105
125
|
}
|
|
106
126
|
// async set store
|
|
107
|
-
store.
|
|
127
|
+
store.set(`${cacheName}:${key}`, JSON.stringify(res), opt.timeout).catch(() => null);
|
|
108
128
|
return res;
|
|
109
129
|
}
|
|
110
130
|
else {
|
|
@@ -123,17 +143,26 @@ function CacheAble(cacheName, timeout = 3600) {
|
|
|
123
143
|
*
|
|
124
144
|
* @export
|
|
125
145
|
* @param {string} cacheName cacheName cache name
|
|
126
|
-
* @param {
|
|
146
|
+
* @param {CacheEvictOpt} [opt] cache options
|
|
147
|
+
* e.g:
|
|
148
|
+
* {
|
|
149
|
+
* params: ["id"],
|
|
150
|
+
* eventTime: "Before"
|
|
151
|
+
* }
|
|
152
|
+
* Use the 'id' parameters of the method as cache subkeys, and clear the cache before the method executed
|
|
127
153
|
* @returns
|
|
128
154
|
*/
|
|
129
|
-
function CacheEvict(cacheName,
|
|
155
|
+
function CacheEvict(cacheName, opt = {
|
|
156
|
+
eventTime: "Before",
|
|
157
|
+
}) {
|
|
130
158
|
return (target, methodName, descriptor) => {
|
|
131
159
|
const componentType = IOCContainer.getType(target);
|
|
132
160
|
if (componentType !== "SERVICE" && componentType !== "COMPONENT") {
|
|
133
161
|
throw Error("This decorator only used in the service、component class.");
|
|
134
162
|
}
|
|
135
|
-
IOCContainer.getIdentifier(target);
|
|
136
163
|
const { value, configurable, enumerable } = descriptor;
|
|
164
|
+
// 获取定义的参数位置
|
|
165
|
+
const paramIndexes = getParamIndex(opt.params, getArgs(value));
|
|
137
166
|
descriptor = {
|
|
138
167
|
configurable,
|
|
139
168
|
enumerable,
|
|
@@ -146,15 +175,28 @@ function CacheEvict(cacheName, eventTime = "Before") {
|
|
|
146
175
|
return null;
|
|
147
176
|
});
|
|
148
177
|
if (cacheFlag) {
|
|
149
|
-
|
|
150
|
-
|
|
178
|
+
let key = PreKey;
|
|
179
|
+
if (props && props.length > 0) {
|
|
180
|
+
for (const item of paramIndexes) {
|
|
181
|
+
if (props[item] !== undefined) {
|
|
182
|
+
const value = Helper.toString(props[item]);
|
|
183
|
+
key += `:${value}`;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// 防止key超长
|
|
187
|
+
if (key.length > 32) {
|
|
188
|
+
key = Helper.murmurHash(key);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (opt.eventTime === "Before") {
|
|
192
|
+
await store.del(`${cacheName}:${key}`).catch(() => null);
|
|
151
193
|
// tslint:disable-next-line: no-invalid-this
|
|
152
194
|
return value.apply(this, props);
|
|
153
195
|
}
|
|
154
196
|
else {
|
|
155
197
|
// tslint:disable-next-line: no-invalid-this
|
|
156
198
|
const res = await value.apply(this, props);
|
|
157
|
-
store.del(cacheName).catch(() => null);
|
|
199
|
+
store.del(`${cacheName}:${key}`).catch(() => null);
|
|
158
200
|
return res;
|
|
159
201
|
}
|
|
160
202
|
}
|
|
@@ -168,6 +210,41 @@ function CacheEvict(cacheName, eventTime = "Before") {
|
|
|
168
210
|
InitCacheStore();
|
|
169
211
|
return descriptor;
|
|
170
212
|
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* @description:
|
|
216
|
+
* @param {*} func
|
|
217
|
+
* @return {*}
|
|
218
|
+
*/
|
|
219
|
+
function getArgs(func) {
|
|
220
|
+
// 首先匹配函数括弧里的参数
|
|
221
|
+
const args = func.toString().match(/.*?\(([^)]*)\)/);
|
|
222
|
+
if (args.length > 1) {
|
|
223
|
+
// 分解参数成数组
|
|
224
|
+
return args[1].split(",").map(function (a) {
|
|
225
|
+
// 去空格和内联注释
|
|
226
|
+
return a.replace(/\/\*.*\*\//, "").trim();
|
|
227
|
+
}).filter(function (ae) {
|
|
228
|
+
// 确保没有undefineds
|
|
229
|
+
return ae;
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* @description:
|
|
236
|
+
* @param {string} params
|
|
237
|
+
* @param {string} args
|
|
238
|
+
* @return {*}
|
|
239
|
+
*/
|
|
240
|
+
function getParamIndex(params, args) {
|
|
241
|
+
const res = [];
|
|
242
|
+
for (let i = 0; i < params.length; i++) {
|
|
243
|
+
if (params.includes(params[i])) {
|
|
244
|
+
res.push(i);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return res;
|
|
171
248
|
}
|
|
172
249
|
|
|
173
250
|
export { CacheAble, CacheEvict, GetCacheStore };
|
package/dist/package.json
CHANGED
|
@@ -1,90 +1,92 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"@commitlint/cli": "^17.x.x",
|
|
53
|
-
"@commitlint/config-conventional": "^17.x.x",
|
|
54
|
-
"@microsoft/api-documenter": "^7.x.x",
|
|
55
|
-
"@microsoft/api-extractor": "^7.x.x",
|
|
56
|
-
"@rollup/plugin-json": "^6.x.x",
|
|
57
|
-
"@types/jest": "^29.x.x",
|
|
58
|
-
"@types/koa": "^2.x.x",
|
|
59
|
-
"@types/node": "^18.x.x",
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^5.x.x",
|
|
61
|
-
"@typescript-eslint/parser": "^5.x.x",
|
|
62
|
-
"conventional-changelog-cli": "^2.x.x",
|
|
63
|
-
"copyfiles": "^2.x.x",
|
|
64
|
-
"del-cli": "^4.x.x",
|
|
65
|
-
"eslint": "^8.x.x",
|
|
66
|
-
"eslint-plugin-jest": "^27.x.x",
|
|
67
|
-
"husky": "^4.x.x",
|
|
68
|
-
"jest": "^29.x.x",
|
|
69
|
-
"jest-html-reporters": "^3.x.x",
|
|
70
|
-
"rollup": "^3.x.x",
|
|
71
|
-
"rollup-plugin-typescript2": "^0.x.x",
|
|
72
|
-
"standard-version": "^9.x.x",
|
|
73
|
-
"ts-jest": "^29.x.x",
|
|
74
|
-
"ts-node": "^10.x.x",
|
|
75
|
-
"typescript": "^4.x.x"
|
|
76
|
-
},
|
|
77
|
-
"dependencies": {
|
|
78
|
-
"koatty_container": "^1.x.x",
|
|
79
|
-
"koatty_lib": "^1.x.x",
|
|
80
|
-
"koatty_logger": "^2.x.x",
|
|
81
|
-
"koatty_store": "^1.x.x",
|
|
82
|
-
"tslib": "^2.4.1"
|
|
83
|
-
},
|
|
84
|
-
"peerDependencies": {
|
|
85
|
-
"koatty_container": "^1.x.x",
|
|
86
|
-
"koatty_lib": "^1.x.x",
|
|
87
|
-
"koatty_logger": "^2.x.x",
|
|
88
|
-
"koatty_store": "^1.x.x"
|
|
2
|
+
"name": "koatty_cacheable",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "Cacheable for koatty.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
|
7
|
+
"build:cp": "node scripts/postBuild && copyfiles package.json LICENSE README.md dist/",
|
|
8
|
+
"build:js": "del-cli --force dist && npx rollup --bundleConfigAsCjs -c .rollup.config.js",
|
|
9
|
+
"build:doc": "del-cli --force docs/api && npx api-documenter markdown --input temp --output docs/api",
|
|
10
|
+
"build:dts": "del-cli --force temp && npx tsc && npx api-extractor run --local --verbose",
|
|
11
|
+
"eslint": "eslint --ext .ts,.js ./",
|
|
12
|
+
"prepublishOnly": "npm test && npm run build",
|
|
13
|
+
"prerelease": "npm test && npm run build",
|
|
14
|
+
"pub": "git push --follow-tags origin && npm publish",
|
|
15
|
+
"release": "standard-version",
|
|
16
|
+
"release:pre": "npm run release -- --prerelease",
|
|
17
|
+
"release:major": "npm run release -- --release-as major",
|
|
18
|
+
"release:minor": "npm run release -- --release-as minor",
|
|
19
|
+
"test": "npm run eslint && jest --passWithNoTests"
|
|
20
|
+
},
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"exports": {
|
|
23
|
+
"require": "./dist/index.js",
|
|
24
|
+
"import": "./dist/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/thinkkoa/koatty_cacheable.git"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"cache",
|
|
32
|
+
"store",
|
|
33
|
+
"koatty",
|
|
34
|
+
"thinkkoa"
|
|
35
|
+
],
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">10.0.0"
|
|
38
|
+
},
|
|
39
|
+
"author": {
|
|
40
|
+
"name": "richenlin",
|
|
41
|
+
"email": "richenlin@gmail.com"
|
|
42
|
+
},
|
|
43
|
+
"license": "BSD-3-Clause",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/thinkkoa/koatty_cacheable/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/thinkkoa/koatty_cacheable",
|
|
48
|
+
"maintainers": [
|
|
49
|
+
{
|
|
50
|
+
"name": "richenlin",
|
|
51
|
+
"email": "richenlin@gmail.com"
|
|
89
52
|
}
|
|
53
|
+
],
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@commitlint/cli": "^17.x.x",
|
|
56
|
+
"@commitlint/config-conventional": "^17.x.x",
|
|
57
|
+
"@microsoft/api-documenter": "^7.x.x",
|
|
58
|
+
"@microsoft/api-extractor": "^7.x.x",
|
|
59
|
+
"@rollup/plugin-json": "^6.x.x",
|
|
60
|
+
"@types/jest": "^29.x.x",
|
|
61
|
+
"@types/koa": "^2.x.x",
|
|
62
|
+
"@types/node": "^18.x.x",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^5.x.x",
|
|
64
|
+
"@typescript-eslint/parser": "^5.x.x",
|
|
65
|
+
"conventional-changelog-cli": "^2.x.x",
|
|
66
|
+
"copyfiles": "^2.x.x",
|
|
67
|
+
"del-cli": "^4.x.x",
|
|
68
|
+
"eslint": "^8.x.x",
|
|
69
|
+
"eslint-plugin-jest": "^27.x.x",
|
|
70
|
+
"husky": "^4.x.x",
|
|
71
|
+
"jest": "^29.x.x",
|
|
72
|
+
"jest-html-reporters": "^3.x.x",
|
|
73
|
+
"rollup": "^3.x.x",
|
|
74
|
+
"rollup-plugin-typescript2": "^0.x.x",
|
|
75
|
+
"standard-version": "^9.x.x",
|
|
76
|
+
"ts-jest": "^29.x.x",
|
|
77
|
+
"ts-node": "^10.x.x",
|
|
78
|
+
"typescript": "^4.x.x"
|
|
79
|
+
},
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"koatty_container": "^1.x.x",
|
|
82
|
+
"koatty_lib": "^1.x.x",
|
|
83
|
+
"koatty_logger": "^2.x.x",
|
|
84
|
+
"koatty_store": "^1.x.x"
|
|
85
|
+
},
|
|
86
|
+
"peerDependencies": {
|
|
87
|
+
"koatty_container": "^1.x.x",
|
|
88
|
+
"koatty_lib": "^1.x.x",
|
|
89
|
+
"koatty_logger": "^2.x.x",
|
|
90
|
+
"koatty_store": "^1.x.x"
|
|
91
|
+
}
|
|
90
92
|
}
|
package/package.json
CHANGED
|
@@ -1,90 +1,92 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"@commitlint/cli": "^17.x.x",
|
|
53
|
-
"@commitlint/config-conventional": "^17.x.x",
|
|
54
|
-
"@microsoft/api-documenter": "^7.x.x",
|
|
55
|
-
"@microsoft/api-extractor": "^7.x.x",
|
|
56
|
-
"@rollup/plugin-json": "^6.x.x",
|
|
57
|
-
"@types/jest": "^29.x.x",
|
|
58
|
-
"@types/koa": "^2.x.x",
|
|
59
|
-
"@types/node": "^18.x.x",
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^5.x.x",
|
|
61
|
-
"@typescript-eslint/parser": "^5.x.x",
|
|
62
|
-
"conventional-changelog-cli": "^2.x.x",
|
|
63
|
-
"copyfiles": "^2.x.x",
|
|
64
|
-
"del-cli": "^4.x.x",
|
|
65
|
-
"eslint": "^8.x.x",
|
|
66
|
-
"eslint-plugin-jest": "^27.x.x",
|
|
67
|
-
"husky": "^4.x.x",
|
|
68
|
-
"jest": "^29.x.x",
|
|
69
|
-
"jest-html-reporters": "^3.x.x",
|
|
70
|
-
"rollup": "^3.x.x",
|
|
71
|
-
"rollup-plugin-typescript2": "^0.x.x",
|
|
72
|
-
"standard-version": "^9.x.x",
|
|
73
|
-
"ts-jest": "^29.x.x",
|
|
74
|
-
"ts-node": "^10.x.x",
|
|
75
|
-
"typescript": "^4.x.x"
|
|
76
|
-
},
|
|
77
|
-
"dependencies": {
|
|
78
|
-
"koatty_container": "^1.x.x",
|
|
79
|
-
"koatty_lib": "^1.x.x",
|
|
80
|
-
"koatty_logger": "^2.x.x",
|
|
81
|
-
"koatty_store": "^1.x.x",
|
|
82
|
-
"tslib": "^2.4.1"
|
|
83
|
-
},
|
|
84
|
-
"peerDependencies": {
|
|
85
|
-
"koatty_container": "^1.x.x",
|
|
86
|
-
"koatty_lib": "^1.x.x",
|
|
87
|
-
"koatty_logger": "^2.x.x",
|
|
88
|
-
"koatty_store": "^1.x.x"
|
|
2
|
+
"name": "koatty_cacheable",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "Cacheable for koatty.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
|
7
|
+
"build:cp": "node scripts/postBuild && copyfiles package.json LICENSE README.md dist/",
|
|
8
|
+
"build:js": "del-cli --force dist && npx rollup --bundleConfigAsCjs -c .rollup.config.js",
|
|
9
|
+
"build:doc": "del-cli --force docs/api && npx api-documenter markdown --input temp --output docs/api",
|
|
10
|
+
"build:dts": "del-cli --force temp && npx tsc && npx api-extractor run --local --verbose",
|
|
11
|
+
"eslint": "eslint --ext .ts,.js ./",
|
|
12
|
+
"prepublishOnly": "npm test && npm run build",
|
|
13
|
+
"prerelease": "npm test && npm run build",
|
|
14
|
+
"pub": "git push --follow-tags origin && npm publish",
|
|
15
|
+
"release": "standard-version",
|
|
16
|
+
"release:pre": "npm run release -- --prerelease",
|
|
17
|
+
"release:major": "npm run release -- --release-as major",
|
|
18
|
+
"release:minor": "npm run release -- --release-as minor",
|
|
19
|
+
"test": "npm run eslint && jest --passWithNoTests"
|
|
20
|
+
},
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"exports": {
|
|
23
|
+
"require": "./dist/index.js",
|
|
24
|
+
"import": "./dist/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/thinkkoa/koatty_cacheable.git"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"cache",
|
|
32
|
+
"store",
|
|
33
|
+
"koatty",
|
|
34
|
+
"thinkkoa"
|
|
35
|
+
],
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">10.0.0"
|
|
38
|
+
},
|
|
39
|
+
"author": {
|
|
40
|
+
"name": "richenlin",
|
|
41
|
+
"email": "richenlin@gmail.com"
|
|
42
|
+
},
|
|
43
|
+
"license": "BSD-3-Clause",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/thinkkoa/koatty_cacheable/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/thinkkoa/koatty_cacheable",
|
|
48
|
+
"maintainers": [
|
|
49
|
+
{
|
|
50
|
+
"name": "richenlin",
|
|
51
|
+
"email": "richenlin@gmail.com"
|
|
89
52
|
}
|
|
53
|
+
],
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@commitlint/cli": "^17.x.x",
|
|
56
|
+
"@commitlint/config-conventional": "^17.x.x",
|
|
57
|
+
"@microsoft/api-documenter": "^7.x.x",
|
|
58
|
+
"@microsoft/api-extractor": "^7.x.x",
|
|
59
|
+
"@rollup/plugin-json": "^6.x.x",
|
|
60
|
+
"@types/jest": "^29.x.x",
|
|
61
|
+
"@types/koa": "^2.x.x",
|
|
62
|
+
"@types/node": "^18.x.x",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^5.x.x",
|
|
64
|
+
"@typescript-eslint/parser": "^5.x.x",
|
|
65
|
+
"conventional-changelog-cli": "^2.x.x",
|
|
66
|
+
"copyfiles": "^2.x.x",
|
|
67
|
+
"del-cli": "^4.x.x",
|
|
68
|
+
"eslint": "^8.x.x",
|
|
69
|
+
"eslint-plugin-jest": "^27.x.x",
|
|
70
|
+
"husky": "^4.x.x",
|
|
71
|
+
"jest": "^29.x.x",
|
|
72
|
+
"jest-html-reporters": "^3.x.x",
|
|
73
|
+
"rollup": "^3.x.x",
|
|
74
|
+
"rollup-plugin-typescript2": "^0.x.x",
|
|
75
|
+
"standard-version": "^9.x.x",
|
|
76
|
+
"ts-jest": "^29.x.x",
|
|
77
|
+
"ts-node": "^10.x.x",
|
|
78
|
+
"typescript": "^4.x.x"
|
|
79
|
+
},
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"koatty_container": "^1.x.x",
|
|
82
|
+
"koatty_lib": "^1.x.x",
|
|
83
|
+
"koatty_logger": "^2.x.x",
|
|
84
|
+
"koatty_store": "^1.x.x"
|
|
85
|
+
},
|
|
86
|
+
"peerDependencies": {
|
|
87
|
+
"koatty_container": "^1.x.x",
|
|
88
|
+
"koatty_lib": "^1.x.x",
|
|
89
|
+
"koatty_logger": "^2.x.x",
|
|
90
|
+
"koatty_store": "^1.x.x"
|
|
91
|
+
}
|
|
90
92
|
}
|