@jintianxiayu/cache-decorator 0.1.2

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.
Files changed (55) hide show
  1. package/README.md +133 -0
  2. package/dist/core/cache-provider-registry.d.ts +30 -0
  3. package/dist/core/cache-provider-registry.d.ts.map +1 -0
  4. package/dist/core/cache-provider-registry.js +52 -0
  5. package/dist/core/cache-provider-registry.js.map +1 -0
  6. package/dist/core/cache-provider.d.ts +34 -0
  7. package/dist/core/cache-provider.d.ts.map +1 -0
  8. package/dist/core/cache-provider.js +3 -0
  9. package/dist/core/cache-provider.js.map +1 -0
  10. package/dist/core/key-builder.d.ts +14 -0
  11. package/dist/core/key-builder.d.ts.map +1 -0
  12. package/dist/core/key-builder.js +38 -0
  13. package/dist/core/key-builder.js.map +1 -0
  14. package/dist/core/native-cache.d.ts +18 -0
  15. package/dist/core/native-cache.d.ts.map +1 -0
  16. package/dist/core/native-cache.js +46 -0
  17. package/dist/core/native-cache.js.map +1 -0
  18. package/dist/core/pending-cache.d.ts +12 -0
  19. package/dist/core/pending-cache.d.ts.map +1 -0
  20. package/dist/core/pending-cache.js +29 -0
  21. package/dist/core/pending-cache.js.map +1 -0
  22. package/dist/core/redis-cache.d.ts +20 -0
  23. package/dist/core/redis-cache.d.ts.map +1 -0
  24. package/dist/core/redis-cache.js +58 -0
  25. package/dist/core/redis-cache.js.map +1 -0
  26. package/dist/decorators/cache-evict.d.ts +23 -0
  27. package/dist/decorators/cache-evict.d.ts.map +1 -0
  28. package/dist/decorators/cache-evict.js +54 -0
  29. package/dist/decorators/cache-evict.js.map +1 -0
  30. package/dist/decorators/cache.d.ts +37 -0
  31. package/dist/decorators/cache.d.ts.map +1 -0
  32. package/dist/decorators/cache.js +74 -0
  33. package/dist/decorators/cache.js.map +1 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +25 -0
  37. package/dist/index.js.map +1 -0
  38. package/jest.config.js +14 -0
  39. package/package.json +30 -0
  40. package/src/core/cache-provider-registry.ts +53 -0
  41. package/src/core/cache-provider.ts +37 -0
  42. package/src/core/key-builder.ts +31 -0
  43. package/src/core/native-cache.ts +53 -0
  44. package/src/core/pending-cache.ts +26 -0
  45. package/src/core/redis-cache.ts +62 -0
  46. package/src/decorators/cache-evict.ts +73 -0
  47. package/src/decorators/cache.ts +129 -0
  48. package/src/index.ts +9 -0
  49. package/test/cache-evict.test.ts +178 -0
  50. package/test/cache-provider-registry.test.ts +36 -0
  51. package/test/cache.test.ts +256 -0
  52. package/test/key-builder.test.ts +37 -0
  53. package/test/native-cache.test.ts +71 -0
  54. package/test/pending-cache.test.ts +56 -0
  55. package/tsconfig.json +8 -0
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+
2
+ export * from './core/cache-provider';
3
+ export * from './core/cache-provider-registry';
4
+ export * from './core/key-builder';
5
+ export * from './core/native-cache';
6
+ export * from './core/pending-cache';
7
+ export * from './core/redis-cache';
8
+ export * from './decorators/cache';
9
+ export * from './decorators/cache-evict';
@@ -0,0 +1,178 @@
1
+ import { Cache } from '../src/decorators/cache';
2
+ import { CacheEvict } from '../src/decorators/cache-evict';
3
+ import { CacheProviderRegistry } from '../src/core/cache-provider-registry';
4
+ import { MemoryCacheProvider } from '../src/core/native-cache';
5
+
6
+ describe('@CacheEvict 装饰器', () => {
7
+ let memoryProvider: MemoryCacheProvider;
8
+
9
+ beforeAll(() => {
10
+ memoryProvider = new MemoryCacheProvider();
11
+ CacheProviderRegistry.register('memory', memoryProvider);
12
+ CacheProviderRegistry.setDefault('memory');
13
+ });
14
+
15
+ afterEach(() => {
16
+ memoryProvider.clear();
17
+ });
18
+
19
+ describe('按入参清除', () => {
20
+ it('应清除对应缓存条目', async () => {
21
+ let getUserCallCount = 0;
22
+ let updateUserCallCount = 0;
23
+
24
+ class UserService {
25
+ @Cache('user-cache')
26
+ async getUser(id: number) {
27
+ getUserCallCount++;
28
+ return { id };
29
+ }
30
+
31
+ @CacheEvict('user-cache')
32
+ async updateUser(id: number) {
33
+ updateUserCallCount++;
34
+ return { id, updated: true };
35
+ }
36
+ }
37
+
38
+ const service = new UserService();
39
+ await service.getUser(1);
40
+ await service.getUser(1);
41
+ expect(getUserCallCount).toBe(1);
42
+
43
+ await service.updateUser(1);
44
+ await service.getUser(1);
45
+ expect(getUserCallCount).toBe(2);
46
+ expect(updateUserCallCount).toBe(1);
47
+ });
48
+ });
49
+
50
+ describe('清除所有条目', () => {
51
+ it('应清除该缓存名称下所有条目', async () => {
52
+ let getUserCallCount = 0;
53
+ let getOrderCallCount = 0;
54
+ let clearCallCount = 0;
55
+
56
+ class Service {
57
+ @Cache('user-cache')
58
+ async getUser(id: number) {
59
+ getUserCallCount++;
60
+ return { id };
61
+ }
62
+
63
+ @Cache('order-cache')
64
+ async getOrder(id: number) {
65
+ getOrderCallCount++;
66
+ return { id };
67
+ }
68
+
69
+ @CacheEvict('user-cache', { allEntries: true })
70
+ async clearAllUsers() {
71
+ clearCallCount++;
72
+ return true;
73
+ }
74
+ }
75
+
76
+ const service = new Service();
77
+ await service.getUser(1);
78
+ await service.getUser(2);
79
+ await service.getOrder(1);
80
+ expect(getUserCallCount).toBe(2);
81
+ expect(getOrderCallCount).toBe(1);
82
+
83
+ await service.clearAllUsers();
84
+ expect(clearCallCount).toBe(1);
85
+
86
+ await service.getUser(1);
87
+ await service.getUser(2);
88
+ await service.getOrder(1);
89
+ expect(getUserCallCount).toBe(4);
90
+ expect(getOrderCallCount).toBe(1);
91
+ });
92
+ });
93
+
94
+ describe('key 选项', () => {
95
+ it('key 为字符串时应删除对应缓存条目', async () => {
96
+ let getUserCallCount = 0;
97
+
98
+ class UserService {
99
+ @Cache('user-cache', { key: 'all-users' })
100
+ async getUsers() {
101
+ getUserCallCount++;
102
+ return [{ id: 1 }, { id: 2 }];
103
+ }
104
+
105
+ @CacheEvict('user-cache', { key: 'all-users' })
106
+ async clearUsers() {
107
+ return true;
108
+ }
109
+ }
110
+
111
+ const service = new UserService();
112
+ await service.getUsers();
113
+ await service.getUsers();
114
+ expect(getUserCallCount).toBe(1);
115
+
116
+ await service.clearUsers();
117
+ await service.getUsers();
118
+ expect(getUserCallCount).toBe(2);
119
+ });
120
+
121
+ it('key 为函数时应使用函数返回值删除缓存条目', async () => {
122
+ let getUserCallCount = 0;
123
+
124
+ class UserService {
125
+ @Cache('user-cache', { key: (...args: unknown[]) => String(args[0]) })
126
+ async getUser(id: number) {
127
+ getUserCallCount++;
128
+ return { id };
129
+ }
130
+
131
+ @CacheEvict('user-cache', { key: (...args: unknown[]) => String(args[0]) })
132
+ async deleteUser(id: number) {
133
+ return { id, deleted: true };
134
+ }
135
+ }
136
+
137
+ const service = new UserService();
138
+ await service.getUser(1);
139
+ await service.getUser(2);
140
+ expect(getUserCallCount).toBe(2);
141
+
142
+ await service.deleteUser(1);
143
+ await service.getUser(1);
144
+ await service.getUser(2);
145
+ expect(getUserCallCount).toBe(3);
146
+ });
147
+
148
+ it('allEntries 为 true 时忽略 key 选项', async () => {
149
+ let getUserCallCount = 0;
150
+ let clearCallCount = 0;
151
+
152
+ class UserService {
153
+ @Cache('user-cache', { key: 'specific-key' })
154
+ async getUsers() {
155
+ getUserCallCount++;
156
+ return [];
157
+ }
158
+
159
+ @CacheEvict('user-cache', { allEntries: true, key: 'ignored-key' })
160
+ async clearAllUsers() {
161
+ clearCallCount++;
162
+ return true;
163
+ }
164
+ }
165
+
166
+ const service = new UserService();
167
+ await service.getUsers();
168
+ await service.getUsers();
169
+ expect(getUserCallCount).toBe(1);
170
+
171
+ await service.clearAllUsers();
172
+ expect(clearCallCount).toBe(1);
173
+
174
+ await service.getUsers();
175
+ expect(getUserCallCount).toBe(2);
176
+ });
177
+ });
178
+ });
@@ -0,0 +1,36 @@
1
+ import { CacheProviderRegistry } from '../src/core/cache-provider-registry';
2
+ import { MemoryCacheProvider } from '../src/core/native-cache';
3
+
4
+ describe('CacheProviderRegistry', () => {
5
+ let memoryProvider: MemoryCacheProvider;
6
+
7
+ beforeEach(() => {
8
+ memoryProvider = new MemoryCacheProvider();
9
+ CacheProviderRegistry.register('memory', memoryProvider);
10
+ });
11
+
12
+ afterEach(() => {
13
+ CacheProviderRegistry.clear();
14
+ });
15
+
16
+ describe('register & get', () => {
17
+ it('应注册并获取 Provider', () => {
18
+ expect(CacheProviderRegistry.get('memory')).toBe(memoryProvider);
19
+ });
20
+
21
+ it('应在 Provider 不存在时抛出错误', () => {
22
+ expect(() => CacheProviderRegistry.get('nonexistent')).toThrow();
23
+ });
24
+ });
25
+
26
+ describe('setDefault & get', () => {
27
+ it('应设置并获取默认 Provider', () => {
28
+ CacheProviderRegistry.setDefault('memory');
29
+ expect(CacheProviderRegistry.get()).toBe(memoryProvider);
30
+ });
31
+
32
+ it('应在未设置默认且未指定时抛出错误', () => {
33
+ expect(() => CacheProviderRegistry.get()).toThrow();
34
+ });
35
+ });
36
+ });
@@ -0,0 +1,256 @@
1
+ import { Cache } from '../src/decorators/cache';
2
+ import { CacheProviderRegistry } from '../src/core/cache-provider-registry';
3
+ import { MemoryCacheProvider } from '../src/core/native-cache';
4
+
5
+ describe('@Cache 装饰器', () => {
6
+ beforeAll(() => {
7
+ CacheProviderRegistry.register('memory', new MemoryCacheProvider());
8
+ CacheProviderRegistry.setDefault('memory');
9
+ });
10
+
11
+ beforeEach(() => {
12
+ const provider = CacheProviderRegistry.get();
13
+ provider.clear();
14
+ });
15
+
16
+ describe('基础缓存', () => {
17
+ it('应缓存方法结果', async () => {
18
+ class UserService {
19
+ callCount = 0;
20
+
21
+ @Cache('user-cache')
22
+ async getUser(id: number) {
23
+ this.callCount++;
24
+ return { id, name: 'test' };
25
+ }
26
+ }
27
+
28
+ const service = new UserService();
29
+ const result1 = await service.getUser(1);
30
+ const result2 = await service.getUser(1);
31
+
32
+ expect(result1).toEqual({ id: 1, name: 'test' });
33
+ expect(result2).toEqual({ id: 1, name: 'test' });
34
+ expect(service.callCount).toBe(1);
35
+ });
36
+
37
+ it('不同参数应分别缓存', async () => {
38
+ class UserService {
39
+ callCount = 0;
40
+
41
+ @Cache('user-cache')
42
+ async getUser(id: number) {
43
+ this.callCount++;
44
+ return { id };
45
+ }
46
+ }
47
+
48
+ const service = new UserService();
49
+ await service.getUser(1);
50
+ await service.getUser(2);
51
+
52
+ expect(service.callCount).toBe(2);
53
+ });
54
+ });
55
+
56
+ describe('TTL 过期', () => {
57
+ it('应在 TTL 后失效', async () => {
58
+ jest.useFakeTimers();
59
+
60
+ class UserService {
61
+ @Cache('user-cache', { ttl: 60 })
62
+ async getUser(id: number) {
63
+ return { id };
64
+ }
65
+ }
66
+
67
+ const service = new UserService();
68
+ const result1 = await service.getUser(1);
69
+ expect(result1).toEqual({ id: 1 });
70
+
71
+ jest.advanceTimersByTime(60001);
72
+
73
+ const result2 = await service.getUser(1);
74
+ expect(result2).toEqual({ id: 1 });
75
+
76
+ jest.useRealTimers();
77
+ });
78
+ });
79
+
80
+ describe('缓存命中', () => {
81
+ it('应直接返回缓存值', async () => {
82
+ class UserService {
83
+ callCount = 0;
84
+
85
+ @Cache('user-cache')
86
+ async getUser(id: number) {
87
+ this.callCount++;
88
+ return { id, timestamp: Date.now() };
89
+ }
90
+ }
91
+
92
+ const service = new UserService();
93
+ const result1 = await service.getUser(1);
94
+ const result2 = await service.getUser(1);
95
+
96
+ expect(result1.id).toBe(1);
97
+ expect(result2.id).toBe(1);
98
+ expect(result1.timestamp).toBe(result2.timestamp);
99
+ expect(service.callCount).toBe(1);
100
+ });
101
+ });
102
+
103
+ describe('错误结果缓存', () => {
104
+ it.skip('应缓存错误结果', async () => {
105
+ class UserService {
106
+ callCount = 0;
107
+
108
+ @Cache('user-cache')
109
+ async getUser(_id: number) {
110
+ this.callCount++;
111
+ throw new Error('user not found');
112
+ }
113
+ }
114
+
115
+ const service = new UserService();
116
+
117
+ try {
118
+ await service.getUser(1);
119
+ } catch (e) {
120
+ // expected
121
+ }
122
+ try {
123
+ await service.getUser(1);
124
+ } catch (e) {
125
+ // expected
126
+ }
127
+ expect(service.callCount).toBe(1);
128
+ });
129
+ });
130
+
131
+ describe('请求合并', () => {
132
+ it.skip('并发请求应返回同一 Promise', async () => {
133
+ let resolvePromise: ((value: number) => void) | undefined;
134
+ let callCount = 0;
135
+
136
+ class UserService {
137
+ @Cache('user-cache')
138
+ async getUser(_id: number): Promise<number> {
139
+ callCount++;
140
+ return new Promise(resolve => {
141
+ resolvePromise = resolve;
142
+ });
143
+ }
144
+ }
145
+
146
+ const service = new UserService();
147
+ const promise1 = service.getUser(1);
148
+ const promise2 = service.getUser(1);
149
+
150
+ await new Promise(resolve => setTimeout(resolve, 10));
151
+
152
+ expect(callCount).toBe(1);
153
+ expect(promise1).toBe(promise2);
154
+
155
+ resolvePromise!(42);
156
+
157
+ const [result1, result2] = await Promise.all([promise1, promise2]);
158
+ expect(result1).toBe(42);
159
+ expect(result2).toBe(42);
160
+ expect(callCount).toBe(1);
161
+ });
162
+ });
163
+
164
+ describe('key 选项', () => {
165
+ it('key 为 undefined 时使用自动生成逻辑', async () => {
166
+ class UserService {
167
+ callCount = 0;
168
+
169
+ @Cache('user-cache', { key: undefined })
170
+ async getUser(id: number) {
171
+ this.callCount++;
172
+ return { id };
173
+ }
174
+ }
175
+
176
+ const service = new UserService();
177
+ await service.getUser(1);
178
+ await service.getUser(1);
179
+ expect(service.callCount).toBe(1);
180
+ });
181
+
182
+ it('key 为 null 时使用自动生成逻辑', async () => {
183
+ class UserService {
184
+ callCount = 0;
185
+
186
+ @Cache('user-cache', { key: null })
187
+ async getUser(id: number) {
188
+ this.callCount++;
189
+ return { id };
190
+ }
191
+ }
192
+
193
+ const service = new UserService();
194
+ await service.getUser(1);
195
+ await service.getUser(1);
196
+ expect(service.callCount).toBe(1);
197
+ });
198
+
199
+ it('key 为字符串时使用字符串值', async () => {
200
+ class UserService {
201
+ callCount = 0;
202
+
203
+ @Cache('user-cache', { key: 'specific-key' })
204
+ async getUser(id: number) {
205
+ this.callCount++;
206
+ return { id };
207
+ }
208
+ }
209
+
210
+ const service = new UserService();
211
+ await service.getUser(1);
212
+ await service.getUser(2);
213
+ expect(service.callCount).toBe(1);
214
+ });
215
+
216
+ it('key 为函数时使用函数返回值', async () => {
217
+ class UserService {
218
+ callCount = 0;
219
+
220
+ @Cache('user-cache', { key: (...args: unknown[]) => String(args[0]) })
221
+ async getUser(id: number) {
222
+ this.callCount++;
223
+ return { id };
224
+ }
225
+ }
226
+
227
+ const service = new UserService();
228
+ await service.getUser(1);
229
+ await service.getUser(1);
230
+ expect(service.callCount).toBe(1);
231
+ await service.getUser(2);
232
+ expect(service.callCount).toBe(2);
233
+ });
234
+
235
+ it('key 函数抛出异常时降级到自动生成', async () => {
236
+ class UserService {
237
+ callCount = 0;
238
+
239
+ @Cache('user-cache', {
240
+ key: () => {
241
+ throw new Error('bad key');
242
+ },
243
+ })
244
+ async getUser(id: number) {
245
+ this.callCount++;
246
+ return { id };
247
+ }
248
+ }
249
+
250
+ const service = new UserService();
251
+ await service.getUser(1);
252
+ await service.getUser(1);
253
+ expect(service.callCount).toBe(1);
254
+ });
255
+ });
256
+ });
@@ -0,0 +1,37 @@
1
+ import { KeyBuilder } from '../src/core/key-builder';
2
+
3
+ describe('KeyBuilder', () => {
4
+ describe('build', () => {
5
+ it('应生成包含缓存名的 key', () => {
6
+ const key = KeyBuilder.build('user-cache', []);
7
+ expect(key).toBe('user-cache');
8
+ });
9
+
10
+ it('应生成包含参数值的 key', () => {
11
+ const key = KeyBuilder.build('user-cache', [1]);
12
+ expect(key).toBe('user-cache:1');
13
+ });
14
+
15
+ it('应处理多个参数', () => {
16
+ const key = KeyBuilder.build('user-cache', [1, 'test']);
17
+ expect(key).toBe('user-cache:1&test');
18
+ });
19
+
20
+ it('应处理对象参数', () => {
21
+ const key = KeyBuilder.build('user-cache', [{ id: 1, name: 'test' }]);
22
+ expect(key).toBe('user-cache:{"id":1,"name":"test"}');
23
+ });
24
+
25
+ it('应处理 null 和 undefined', () => {
26
+ const key1 = KeyBuilder.build('user-cache', [null]);
27
+ const key2 = KeyBuilder.build('user-cache', [undefined]);
28
+ expect(key1).toBe('user-cache:null');
29
+ expect(key2).toBe('user-cache:null');
30
+ });
31
+
32
+ it('应处理数字和布尔值', () => {
33
+ const key = KeyBuilder.build('user-cache', [123, true, false]);
34
+ expect(key).toBe('user-cache:123&true&false');
35
+ });
36
+ });
37
+ });
@@ -0,0 +1,71 @@
1
+ import { MemoryCacheProvider } from '../src/core/native-cache';
2
+
3
+ describe('MemoryCacheProvider', () => {
4
+ let provider: MemoryCacheProvider;
5
+
6
+ beforeEach(() => {
7
+ provider = new MemoryCacheProvider();
8
+ });
9
+
10
+ describe('get & set', () => {
11
+ it('应返回已缓存的值', () => {
12
+ provider.set('key1', 'value1');
13
+ expect(provider.get('key1')).toBe('value1');
14
+ });
15
+
16
+ it('应返回 undefined 对不存在的键', () => {
17
+ expect(provider.get('nonexistent')).toBeUndefined();
18
+ });
19
+ });
20
+
21
+ describe('TTL', () => {
22
+ it('应在 TTL 后失效', () => {
23
+ jest.useFakeTimers();
24
+
25
+ provider.set('key1', 'value1', 5);
26
+ expect(provider.get('key1')).toBe('value1');
27
+
28
+ jest.advanceTimersByTime(5001);
29
+ expect(provider.get('key1')).toBeUndefined();
30
+
31
+ jest.useRealTimers();
32
+ });
33
+
34
+ it('无 TTL 时不应失效', () => {
35
+ provider.set('key1', 'value1');
36
+ expect(provider.get('key1')).toBe('value1');
37
+ });
38
+ });
39
+
40
+ describe('delete', () => {
41
+ it('应删除指定键', () => {
42
+ provider.set('key1', 'value1');
43
+ provider.delete('key1');
44
+ expect(provider.get('key1')).toBeUndefined();
45
+ });
46
+ });
47
+
48
+ describe('clear', () => {
49
+ it('应清除所有缓存', () => {
50
+ provider.set('key1', 'value1');
51
+ provider.set('key2', 'value2');
52
+ provider.clear();
53
+ expect(provider.get('key1')).toBeUndefined();
54
+ expect(provider.get('key2')).toBeUndefined();
55
+ });
56
+ });
57
+
58
+ describe('deleteByPattern', () => {
59
+ it('应删除匹配模式的键', () => {
60
+ provider.set('user:1', 'user1');
61
+ provider.set('user:2', 'user2');
62
+ provider.set('order:1', 'order1');
63
+
64
+ provider.deleteByPattern('user:*');
65
+
66
+ expect(provider.get('user:1')).toBeUndefined();
67
+ expect(provider.get('user:2')).toBeUndefined();
68
+ expect(provider.get('order:1')).toBe('order1');
69
+ });
70
+ });
71
+ });
@@ -0,0 +1,56 @@
1
+ import { PendingCache } from '../src/core/pending-cache';
2
+
3
+ describe('PendingCache', () => {
4
+ let pendingCache: PendingCache;
5
+
6
+ beforeEach(() => {
7
+ pendingCache = new PendingCache();
8
+ });
9
+
10
+ describe('get & set', () => {
11
+ it('应返回已存储的 Promise', async () => {
12
+ const promise = Promise.resolve('value');
13
+ pendingCache.set('key1', promise);
14
+ expect(await pendingCache.get('key1')).toBe('value');
15
+ });
16
+
17
+ it('应返回 undefined 对不存在的键', () => {
18
+ expect(pendingCache.get('nonexistent')).toBeUndefined();
19
+ });
20
+ });
21
+
22
+ describe('请求合并', () => {
23
+ it('应在 Promise 完成时自动删除', async () => {
24
+ let resolve: (value: string) => void;
25
+ const promise = new Promise<string>(r => { resolve = r; });
26
+
27
+ pendingCache.set('key1', promise);
28
+ expect(pendingCache.get('key1')).toBeDefined();
29
+
30
+ resolve!('value');
31
+ await promise;
32
+ await new Promise(resolve => setTimeout(resolve, 0));
33
+
34
+ expect(pendingCache.get('key1')).toBeUndefined();
35
+ });
36
+ });
37
+
38
+ describe('delete', () => {
39
+ it('应删除指定键', async () => {
40
+ const promise = Promise.resolve('value');
41
+ pendingCache.set('key1', promise);
42
+ pendingCache.delete('key1');
43
+ expect(pendingCache.get('key1')).toBeUndefined();
44
+ });
45
+ });
46
+
47
+ describe('clear', () => {
48
+ it('应清除所有 pending 请求', async () => {
49
+ pendingCache.set('key1', Promise.resolve('v1'));
50
+ pendingCache.set('key2', Promise.resolve('v2'));
51
+ pendingCache.clear();
52
+ expect(pendingCache.get('key1')).toBeUndefined();
53
+ expect(pendingCache.get('key2')).toBeUndefined();
54
+ });
55
+ });
56
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src/**/*"]
8
+ }