@jintianxiayu/cache-decorator 0.1.2 → 0.1.3
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/README.md +13 -15
- package/jest.config.js +10 -13
- package/package.json +2 -2
- package/src/core/cache-provider-registry.ts +39 -39
- package/src/core/cache-provider.ts +28 -28
- package/src/core/key-builder.ts +25 -25
- package/src/core/native-cache.ts +33 -33
- package/src/core/pending-cache.ts +17 -17
- package/src/core/redis-cache.ts +40 -46
- package/src/decorators/cache-evict.ts +34 -38
- package/src/decorators/cache.ts +67 -71
- package/src/index.ts +0 -1
- package/test/cache-evict.test.ts +165 -165
- package/test/cache-provider-registry.test.ts +24 -24
- package/test/cache.test.ts +232 -232
- package/test/key-builder.test.ts +28 -28
- package/test/native-cache.test.ts +50 -50
- package/test/pending-cache.test.ts +44 -42
- package/tsconfig.json +7 -7
package/README.md
CHANGED
|
@@ -46,15 +46,15 @@ CacheProviderRegistry.register('memory', new MemoryCacheProvider());
|
|
|
46
46
|
CacheProviderRegistry.setDefault('memory');
|
|
47
47
|
|
|
48
48
|
class UserService {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
@Cache('user-cache', { ttl: 60000 })
|
|
50
|
+
async getUser(id: number) {
|
|
51
|
+
return { id, name: 'test' };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@CacheEvict('user-cache')
|
|
55
|
+
async updateUser(id: number) {
|
|
56
|
+
return { id, updated: true };
|
|
57
|
+
}
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
@@ -84,8 +84,6 @@ class UserService {
|
|
|
84
84
|
}
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
87
|
## API
|
|
90
88
|
|
|
91
89
|
### @Cache(cacheName, options?)
|
|
@@ -96,9 +94,9 @@ class UserService {
|
|
|
96
94
|
- `options.ttl`: 过期时间(秒)
|
|
97
95
|
- `options.providerName`: 指定 CacheProvider
|
|
98
96
|
- `options.key`: 自定义缓存 key,支持以下形式:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
- `undefined/null`: 使用默认逻辑,基于方法参数生成 key
|
|
98
|
+
- `string`: 直接作为 key 值,格式为 `cacheName:keyValue`
|
|
99
|
+
- `function`: 接收方法参数数组,返回自定义字符串
|
|
102
100
|
|
|
103
101
|
### @CacheEvict(cacheName, options?)
|
|
104
102
|
|
|
@@ -130,4 +128,4 @@ Redis 实现,适用于分布式场景。
|
|
|
130
128
|
```typescript
|
|
131
129
|
import Redis from 'ioredis';
|
|
132
130
|
const redisProvider = new RedisCacheProvider(new Redis());
|
|
133
|
-
```
|
|
131
|
+
```
|
package/jest.config.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'^.+\\.ts$': 'ts-jest'
|
|
13
|
-
}
|
|
14
|
-
};
|
|
2
|
+
preset: 'ts-jest',
|
|
3
|
+
testEnvironment: 'node',
|
|
4
|
+
roots: ['<rootDir>'],
|
|
5
|
+
testMatch: ['**/test/**/*.test.ts'],
|
|
6
|
+
moduleFileExtensions: ['ts', 'js', 'json'],
|
|
7
|
+
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts'],
|
|
8
|
+
transform: {
|
|
9
|
+
'^.+\\.ts$': 'ts-jest',
|
|
10
|
+
},
|
|
11
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jintianxiayu/cache-decorator",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Method caching decorators for TypeScript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "0518a4e3649799cc6c176dabfebeb86bd0891085"
|
|
30
30
|
}
|
|
@@ -8,46 +8,46 @@ let defaultName: string | undefined;
|
|
|
8
8
|
* 用于注册和获取不同类型的 CacheProvider
|
|
9
9
|
*/
|
|
10
10
|
export class CacheProviderRegistry {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 获取缓存提供者
|
|
22
|
-
* @param name 提供者名称,不指定则使用默认提供者
|
|
23
|
-
* @returns 缓存提供者实例
|
|
24
|
-
* @throws 未注册且无默认提供者时抛出错误
|
|
25
|
-
*/
|
|
26
|
-
static get(name?: string): CacheProvider {
|
|
27
|
-
const providerName = name || defaultName;
|
|
28
|
-
if (!providerName) {
|
|
29
|
-
throw new Error('No CacheProvider registered and no default set');
|
|
11
|
+
/**
|
|
12
|
+
* 注册缓存提供者
|
|
13
|
+
* @param name 提供者名称
|
|
14
|
+
* @param provider 缓存提供者实例
|
|
15
|
+
*/
|
|
16
|
+
static register(name: string, provider: CacheProvider): void {
|
|
17
|
+
providers.set(name, provider);
|
|
30
18
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 获取缓存提供者
|
|
22
|
+
* @param name 提供者名称,不指定则使用默认提供者
|
|
23
|
+
* @returns 缓存提供者实例
|
|
24
|
+
* @throws 未注册且无默认提供者时抛出错误
|
|
25
|
+
*/
|
|
26
|
+
static get(name?: string): CacheProvider {
|
|
27
|
+
const providerName = name || defaultName;
|
|
28
|
+
if (!providerName) {
|
|
29
|
+
throw new Error('No CacheProvider registered and no default set');
|
|
30
|
+
}
|
|
31
|
+
const provider = providers.get(providerName);
|
|
32
|
+
if (!provider) {
|
|
33
|
+
throw new Error(`CacheProvider "${providerName}" not found`);
|
|
34
|
+
}
|
|
35
|
+
return provider;
|
|
34
36
|
}
|
|
35
|
-
return provider;
|
|
36
|
-
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
/**
|
|
39
|
+
* 设置默认缓存提供者
|
|
40
|
+
* @param name 提供者名称
|
|
41
|
+
*/
|
|
42
|
+
static setDefault(name: string): void {
|
|
43
|
+
defaultName = name;
|
|
44
|
+
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
46
|
+
/**
|
|
47
|
+
* 清空注册表
|
|
48
|
+
*/
|
|
49
|
+
static clear(): void {
|
|
50
|
+
providers.clear();
|
|
51
|
+
defaultName = undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -3,35 +3,35 @@
|
|
|
3
3
|
* 支持可插拔的缓存实现(Memory、Redis、自定义)
|
|
4
4
|
*/
|
|
5
5
|
export interface CacheProvider {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
/**
|
|
7
|
+
* 获取缓存值
|
|
8
|
+
* @param key 缓存键
|
|
9
|
+
* @returns 缓存值,不存在或已过期返回 undefined
|
|
10
|
+
*/
|
|
11
|
+
get<T>(key: string): T | undefined | Promise<T | undefined>;
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
/**
|
|
14
|
+
* 设置缓存值
|
|
15
|
+
* @param key 缓存键
|
|
16
|
+
* @param value 缓存值
|
|
17
|
+
* @param ttl 过期时间(秒),不设置则永不过期
|
|
18
|
+
*/
|
|
19
|
+
set<T>(key: string, value: T, ttl?: number): void | Promise<void>;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
/**
|
|
22
|
+
* 删除指定缓存
|
|
23
|
+
* @param key 缓存键
|
|
24
|
+
*/
|
|
25
|
+
delete(key: string): void | Promise<void>;
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
/**
|
|
28
|
+
* 清除所有缓存
|
|
29
|
+
*/
|
|
30
|
+
clear(): void | Promise<void>;
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
32
|
+
/**
|
|
33
|
+
* 根据模式删除匹配的缓存键
|
|
34
|
+
* @param pattern glob模式字符串(如 user:*),末尾的 * 作为前缀匹配
|
|
35
|
+
*/
|
|
36
|
+
deleteByPattern(pattern: string): void | Promise<void>;
|
|
37
|
+
}
|
package/src/core/key-builder.ts
CHANGED
|
@@ -3,29 +3,29 @@
|
|
|
3
3
|
* 负责将缓存名称和参数转换为统一的 key 字符串
|
|
4
4
|
*/
|
|
5
5
|
export class KeyBuilder {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
const serializedArgs = args
|
|
17
|
-
.map(arg => {
|
|
18
|
-
if (arg === null || arg === undefined) return 'null';
|
|
19
|
-
if (typeof arg === 'object') {
|
|
20
|
-
try {
|
|
21
|
-
return JSON.stringify(arg);
|
|
22
|
-
} catch {
|
|
23
|
-
return String(arg);
|
|
24
|
-
}
|
|
6
|
+
/**
|
|
7
|
+
* 构建缓存 key
|
|
8
|
+
* @param cacheName 缓存名称
|
|
9
|
+
* @param args 方法参数列表
|
|
10
|
+
* @returns 格式为 {cacheName}:{serializedArgs} 的 key 字符串
|
|
11
|
+
*/
|
|
12
|
+
static build(cacheName: string, args: unknown[]): string {
|
|
13
|
+
if (args.length === 0) {
|
|
14
|
+
return cacheName;
|
|
25
15
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
16
|
+
const serializedArgs = args
|
|
17
|
+
.map((arg) => {
|
|
18
|
+
if (arg === null || arg === undefined) return 'null';
|
|
19
|
+
if (typeof arg === 'object') {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.stringify(arg);
|
|
22
|
+
} catch {
|
|
23
|
+
return String(arg);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return String(arg);
|
|
27
|
+
})
|
|
28
|
+
.join('&');
|
|
29
|
+
return `${cacheName}:${serializedArgs}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/core/native-cache.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { CacheProvider } from './cache-provider';
|
|
|
4
4
|
* 缓存条目结构
|
|
5
5
|
*/
|
|
6
6
|
interface CacheEntry<T> {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
value: T;
|
|
8
|
+
expiresAt: number | null;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -13,41 +13,41 @@ interface CacheEntry<T> {
|
|
|
13
13
|
* 适用于单机应用,缓存随进程重启清除
|
|
14
14
|
*/
|
|
15
15
|
export class MemoryCacheProvider implements CacheProvider {
|
|
16
|
-
|
|
16
|
+
private cache = new Map<string, CacheEntry<unknown>>();
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
get<T>(key: string): T | undefined {
|
|
19
|
+
const entry = this.cache.get(key);
|
|
20
|
+
if (!entry) return undefined;
|
|
21
|
+
if (entry.expiresAt !== null && Date.now() > entry.expiresAt) {
|
|
22
|
+
this.cache.delete(key);
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return entry.value as T;
|
|
24
26
|
}
|
|
25
|
-
return entry.value as T;
|
|
26
|
-
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
set<T>(key: string, value: T, ttl?: number): void {
|
|
29
|
+
const expiresAt = ttl ? Date.now() + ttl * 1000 : null;
|
|
30
|
+
this.cache.set(key, { value, expiresAt });
|
|
31
|
+
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
delete(key: string): void {
|
|
34
|
+
this.cache.delete(key);
|
|
35
|
+
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
clear(): void {
|
|
38
|
+
this.cache.clear();
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
/**
|
|
42
|
+
* 根据模式删除匹配的缓存键
|
|
43
|
+
* @param pattern glob模式字符串(如 user:*),末尾的 * 作为前缀匹配
|
|
44
|
+
*/
|
|
45
|
+
deleteByPattern(pattern: string): void {
|
|
46
|
+
const prefix = pattern.replace(/\*$/, '');
|
|
47
|
+
for (const key of this.cache.keys()) {
|
|
48
|
+
if (key.startsWith(prefix)) {
|
|
49
|
+
this.cache.delete(key);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
-
}
|
|
53
|
+
}
|
|
@@ -3,24 +3,24 @@
|
|
|
3
3
|
* 用于在并发场景下返回同一个 Promise,避免重复执行
|
|
4
4
|
*/
|
|
5
5
|
export class PendingCache {
|
|
6
|
-
|
|
6
|
+
private pending = new Map<string, Promise<unknown>>();
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
get<T>(key: string): Promise<T> | undefined {
|
|
9
|
+
return this.pending.get(key) as Promise<T> | undefined;
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
set<T>(key: string, promise: Promise<T>): void {
|
|
13
|
+
this.pending.set(key, promise);
|
|
14
|
+
promise.finally(() => {
|
|
15
|
+
this.pending.delete(key);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
delete(key: string): void {
|
|
20
|
+
this.pending.delete(key);
|
|
21
|
+
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
23
|
+
clear(): void {
|
|
24
|
+
this.pending.clear();
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/core/redis-cache.ts
CHANGED
|
@@ -6,57 +6,51 @@ import Redis from 'ioredis';
|
|
|
6
6
|
* 适用于分布式场景,支持跨进程共享缓存
|
|
7
7
|
*/
|
|
8
8
|
export class RedisCacheProvider implements CacheProvider {
|
|
9
|
-
|
|
9
|
+
private redis: Redis;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
constructor(redis?: Redis) {
|
|
12
|
+
this.redis = redis ?? new Redis();
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
async get<T>(key: string): Promise<T | undefined> {
|
|
16
|
+
const value = await this.redis.get(key);
|
|
17
|
+
if (value === null) return undefined;
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(value) as T;
|
|
20
|
+
} catch {
|
|
21
|
+
return value as unknown as T;
|
|
22
|
+
}
|
|
22
23
|
}
|
|
23
|
-
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
async set<T>(key: string, value: T, ttl?: number): Promise<void> {
|
|
26
|
+
const serialized = typeof value === 'string' ? value : JSON.stringify(value);
|
|
27
|
+
if (ttl) {
|
|
28
|
+
await this.redis.setex(key, ttl, serialized);
|
|
29
|
+
} else {
|
|
30
|
+
await this.redis.set(key, serialized);
|
|
31
|
+
}
|
|
31
32
|
}
|
|
32
|
-
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
async delete(key: string): Promise<void> {
|
|
35
|
+
await this.redis.del(key);
|
|
36
|
+
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
async clear(): Promise<void> {
|
|
39
|
+
await this.redis.flushdb();
|
|
40
|
+
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (keys.length > 0) {
|
|
58
|
-
await this.redis.del(...keys);
|
|
59
|
-
}
|
|
60
|
-
} while (cursor !== '0');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
42
|
+
/**
|
|
43
|
+
* 根据模式删除匹配的缓存键
|
|
44
|
+
* @param pattern glob模式字符串(如 user:*),使用 SCAN 游标迭代避免阻塞 Redis
|
|
45
|
+
*/
|
|
46
|
+
async deleteByPattern(pattern: string): Promise<void> {
|
|
47
|
+
let cursor = '0';
|
|
48
|
+
do {
|
|
49
|
+
const [nextCursor, keys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
|
|
50
|
+
cursor = nextCursor;
|
|
51
|
+
if (keys.length > 0) {
|
|
52
|
+
await this.redis.del(...keys);
|
|
53
|
+
}
|
|
54
|
+
} while (cursor !== '0');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -6,15 +6,15 @@ import { CacheOptions, CacheKeyResolver } from './cache';
|
|
|
6
6
|
* @CacheEvict 装饰器配置项
|
|
7
7
|
*/
|
|
8
8
|
export interface CacheEvictOptions extends Pick<CacheOptions, 'key'> {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/**
|
|
10
|
+
* 是否清除所有条目,默认为 false
|
|
11
|
+
*/
|
|
12
|
+
allEntries?: boolean;
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
/**
|
|
15
|
+
* 指定 CacheProvider 名称
|
|
16
|
+
*/
|
|
17
|
+
providerName?: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -25,17 +25,17 @@ export interface CacheEvictOptions extends Pick<CacheOptions, 'key'> {
|
|
|
25
25
|
* @returns 解析后的缓存 key
|
|
26
26
|
*/
|
|
27
27
|
function resolveCacheKey(cacheName: string, keyResolver: CacheKeyResolver | undefined, args: unknown[]): string {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
if (keyResolver === undefined || keyResolver === null) {
|
|
29
|
+
return KeyBuilder.build(cacheName, args);
|
|
30
|
+
}
|
|
31
|
+
if (typeof keyResolver === 'string') {
|
|
32
|
+
return KeyBuilder.build(cacheName, [keyResolver]);
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return KeyBuilder.build(cacheName, [keyResolver(...args)]);
|
|
36
|
+
} catch {
|
|
37
|
+
return KeyBuilder.build(cacheName, args);
|
|
38
|
+
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -45,29 +45,25 @@ function resolveCacheKey(cacheName: string, keyResolver: CacheKeyResolver | unde
|
|
|
45
45
|
* @param options 配置项
|
|
46
46
|
*/
|
|
47
47
|
export function CacheEvict(cacheName: string, options?: CacheEvictOptions) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
_propertyKey: string,
|
|
51
|
-
descriptor: PropertyDescriptor,
|
|
52
|
-
) {
|
|
53
|
-
const originalMethod = descriptor.value;
|
|
48
|
+
return function (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) {
|
|
49
|
+
const originalMethod = descriptor.value;
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
descriptor.value = async function (...args: unknown[]) {
|
|
52
|
+
const result = await originalMethod.apply(this, args);
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const providerName = options?.providerName;
|
|
55
|
+
const provider = CacheProviderRegistry.get(providerName);
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
if (options?.allEntries) {
|
|
58
|
+
await provider.deleteByPattern(cacheName + '*');
|
|
59
|
+
} else {
|
|
60
|
+
const cacheKey = resolveCacheKey(cacheName, options?.key, args);
|
|
61
|
+
provider.delete(cacheKey);
|
|
62
|
+
}
|
|
67
63
|
|
|
68
|
-
|
|
64
|
+
return result;
|
|
65
|
+
};
|
|
69
66
|
};
|
|
70
|
-
};
|
|
71
67
|
}
|
|
72
68
|
|
|
73
|
-
export { CacheProviderRegistry } from '../core/cache-provider-registry';
|
|
69
|
+
export { CacheProviderRegistry } from '../core/cache-provider-registry';
|