@jintianxiayu/cache-decorator 1.0.0 → 1.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +20 -14
  2. package/README.md +358 -270
  3. package/dist/core/cache-error.d.ts +75 -0
  4. package/dist/core/cache-error.d.ts.map +1 -0
  5. package/dist/core/cache-error.js +168 -0
  6. package/dist/core/cache-error.js.map +1 -0
  7. package/dist/core/cache-logger.d.ts +3 -2
  8. package/dist/core/cache-logger.d.ts.map +1 -1
  9. package/dist/core/cache-logger.js +2 -0
  10. package/dist/core/cache-logger.js.map +1 -1
  11. package/dist/decorators/cache.d.ts +6 -0
  12. package/dist/decorators/cache.d.ts.map +1 -1
  13. package/dist/decorators/cache.js +106 -23
  14. package/dist/decorators/cache.js.map +1 -1
  15. package/jest.config.js +11 -11
  16. package/package.json +1 -1
  17. package/src/adapters/ioredis-cache-client.ts +89 -89
  18. package/src/adapters/node-redis-cache-client.ts +95 -95
  19. package/src/adapters/redis-key-prefix.ts +38 -38
  20. package/src/core/cache-error.ts +233 -0
  21. package/src/core/cache-logger.ts +116 -105
  22. package/src/core/key-builder.ts +33 -33
  23. package/src/core/native-cache.ts +55 -55
  24. package/src/core/pending-cache.ts +29 -29
  25. package/src/core/redis-cache-client.ts +160 -160
  26. package/src/core/redis-cache.ts +104 -104
  27. package/src/decorators/cache-evict.ts +129 -129
  28. package/src/decorators/cache.ts +319 -203
  29. package/src/index.ts +11 -11
  30. package/test/cache-evict-logging.test.ts +362 -362
  31. package/test/cache-logger.integration.test.ts +129 -129
  32. package/test/cache-logger.test.ts +156 -153
  33. package/test/cache-logging.test.ts +852 -544
  34. package/test/cache.test.ts +939 -255
  35. package/test/helpers/legacy-redis-cache.ts +41 -22
  36. package/test/helpers/package-consumer.ts +231 -231
  37. package/test/helpers/redis-fixture.ts +142 -142
  38. package/test/ioredis-cache-client.test.ts +143 -143
  39. package/test/legacy-redis-cache.test.ts +51 -0
  40. package/test/native-cache.test.ts +77 -77
  41. package/test/node-redis-cache-client.test.ts +149 -149
  42. package/test/pending-cache.test.ts +69 -69
  43. package/test/redis-cache-client-lifecycle.test.ts +112 -112
  44. package/test/redis-cache-client-types.test.ts +184 -184
  45. package/test/redis-cache-client.integration.test.ts +355 -327
  46. package/test/redis-cache-decorator.test.ts +540 -201
  47. package/test/redis-cache-provider.test.ts +269 -269
  48. package/test/type-contract/contract.ts +119 -64
  49. package/test/type-contract/tsconfig.json +12 -12
  50. package/tsconfig.json +8 -8
@@ -1,64 +1,119 @@
1
- import {
2
- Cache,
3
- CacheEvict,
4
- type CacheEvictOptions,
5
- type CacheKeyResolver,
6
- type CacheOptions,
7
- type CacheProvider,
8
- } from '@jintianxiayu/cache-decorator';
9
-
10
- type Equal<Left, Right> =
11
- (<Value>() => Value extends Left ? 1 : 2) extends <Value>() => Value extends Right ? 1 : 2 ? true : false;
12
- type Assert<Condition extends true> = Condition;
13
- type LegacyMethodDecorator = (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => void;
14
-
15
- export type CacheOptionKeysMatch = Assert<Equal<keyof CacheOptions, 'ttl' | 'providerName' | 'key'>>;
16
- export type CacheEvictOptionKeysMatch = Assert<Equal<keyof CacheEvictOptions, 'key' | 'allEntries' | 'providerName'>>;
17
- export type CacheKeyResolverMatch = Assert<Equal<CacheKeyResolver, null | string | ((...args: unknown[]) => string)>>;
18
-
19
- const provider: CacheProvider = {
20
- get: <Value>(_key: string): Value | undefined => undefined,
21
- set: <Value>(_key: string, _value: Value, _ttl?: number): void => {
22
- return;
23
- },
24
- delete: (_key: string): void => {
25
- return;
26
- },
27
- clear: (): void => {
28
- return;
29
- },
30
- deleteByPattern: (_pattern: string): void => {
31
- return;
32
- },
33
- };
34
-
35
- const cacheDecorator: LegacyMethodDecorator = Cache('contract-cache', {
36
- ttl: 60,
37
- providerName: 'memory',
38
- key: (...args: unknown[]) => String(args[0]),
39
- });
40
- const evictDecorator: LegacyMethodDecorator = CacheEvict('contract-cache', {
41
- providerName: 'memory',
42
- key: null,
43
- allEntries: false,
44
- });
45
-
46
- const invalidLoggingOption: CacheOptions = {
47
- // @ts-expect-error CacheOptions 不提供第二套日志开关。
48
- logging: true,
49
- };
50
- const invalidDebugOption: CacheOptions = {
51
- // @ts-expect-error CacheOptions 不提供 debug 开关。
52
- debug: true,
53
- };
54
- const invalidLoggerOption: CacheEvictOptions = {
55
- // @ts-expect-error CacheEvictOptions 不接受 Logger 实例或回调。
56
- logger: undefined,
57
- };
58
-
59
- void provider;
60
- void cacheDecorator;
61
- void evictDecorator;
62
- void invalidLoggingOption;
63
- void invalidDebugOption;
64
- void invalidLoggerOption;
1
+ import {
2
+ Cache,
3
+ CacheEvict,
4
+ type CacheErrorCodec,
5
+ type CacheErrorPolicy,
6
+ type CacheEvictOptions,
7
+ type CacheKeyResolver,
8
+ type CacheOptions,
9
+ type CacheProvider,
10
+ } from '@jintianxiayu/cache-decorator';
11
+
12
+ type Equal<Left, Right> =
13
+ (<Value>() => Value extends Left ? 1 : 2) extends <Value>() => Value extends Right ? 1 : 2 ? true : false;
14
+ type Assert<Condition extends true> = Condition;
15
+ type LegacyMethodDecorator = (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => void;
16
+
17
+ export type CacheOptionKeysMatch = Assert<Equal<keyof CacheOptions, 'ttl' | 'providerName' | 'key' | 'errorCache'>>;
18
+ export type CacheErrorPolicyKeysMatch = Assert<Equal<keyof CacheErrorPolicy, 'ttl' | 'shouldCache' | 'codec'>>;
19
+ export type CacheErrorCodecKeysMatch = Assert<Equal<keyof CacheErrorCodec, 'encode' | 'decode'>>;
20
+ export type CacheEvictOptionKeysMatch = Assert<Equal<keyof CacheEvictOptions, 'key' | 'allEntries' | 'providerName'>>;
21
+ export type CacheKeyResolverMatch = Assert<Equal<CacheKeyResolver, null | string | ((...args: unknown[]) => string)>>;
22
+
23
+ const provider: CacheProvider = {
24
+ get: <Value>(_key: string): Value | undefined => undefined,
25
+ set: <Value>(_key: string, _value: Value, _ttl?: number): void => {
26
+ return;
27
+ },
28
+ delete: (_key: string): void => {
29
+ return;
30
+ },
31
+ clear: (): void => {
32
+ return;
33
+ },
34
+ deleteByPattern: (_pattern: string): void => {
35
+ return;
36
+ },
37
+ };
38
+
39
+ const cacheDecorator: LegacyMethodDecorator = Cache('contract-cache', {
40
+ ttl: 60,
41
+ providerName: 'memory',
42
+ key: (...args: unknown[]) => String(args[0]),
43
+ });
44
+ const cacheWithoutErrorPolicy: LegacyMethodDecorator = Cache('contract-cache');
45
+ const cacheWithErrorTtl: LegacyMethodDecorator = Cache('contract-cache', { errorCache: { ttl: 10 } });
46
+ const codec: CacheErrorCodec = {
47
+ encode: (error: unknown): unknown => ({ message: error instanceof Error ? error.message : String(error) }),
48
+ decode: (payload: unknown): unknown => payload,
49
+ };
50
+ const cacheWithCompleteErrorPolicy: LegacyMethodDecorator = Cache('contract-cache', {
51
+ errorCache: {
52
+ ttl: 5,
53
+ shouldCache: (error: unknown): boolean => error instanceof Error,
54
+ codec,
55
+ },
56
+ });
57
+ const evictDecorator: LegacyMethodDecorator = CacheEvict('contract-cache', {
58
+ providerName: 'memory',
59
+ key: null,
60
+ allEntries: false,
61
+ });
62
+
63
+ const invalidLoggingOption: CacheOptions = {
64
+ // @ts-expect-error CacheOptions 不提供第二套日志开关。
65
+ logging: true,
66
+ };
67
+ const invalidDebugOption: CacheOptions = {
68
+ // @ts-expect-error CacheOptions 不提供 debug 开关。
69
+ debug: true,
70
+ };
71
+ const invalidLoggerOption: CacheEvictOptions = {
72
+ // @ts-expect-error CacheEvictOptions 不接受 Logger 实例或回调。
73
+ logger: undefined,
74
+ };
75
+ const invalidMissingErrorTtl: CacheOptions = {
76
+ // @ts-expect-error 启用异常缓存时 ttl 必填。
77
+ errorCache: {},
78
+ };
79
+ const invalidEncodeOnlyCodec: CacheOptions = {
80
+ errorCache: {
81
+ ttl: 5,
82
+ // @ts-expect-error codec 必须同时提供 encode 和 decode。
83
+ codec: { encode: (error: unknown): unknown => error },
84
+ },
85
+ };
86
+ const invalidDecodeOnlyCodec: CacheOptions = {
87
+ errorCache: {
88
+ ttl: 5,
89
+ // @ts-expect-error codec 必须同时提供 encode 和 decode。
90
+ codec: { decode: (payload: unknown): unknown => payload },
91
+ },
92
+ };
93
+ const invalidPredicateSignature: CacheOptions = {
94
+ errorCache: {
95
+ ttl: 5,
96
+ // @ts-expect-error 筛选器必须接受 unknown 并同步返回 boolean。
97
+ shouldCache: (_error: string): boolean => true,
98
+ },
99
+ };
100
+ const invalidEvictErrorPolicy: CacheEvictOptions = {
101
+ // @ts-expect-error CacheEvictOptions 不接受异常缓存策略。
102
+ errorCache: { ttl: 5 },
103
+ };
104
+
105
+ void provider;
106
+ void cacheDecorator;
107
+ void cacheWithoutErrorPolicy;
108
+ void cacheWithErrorTtl;
109
+ void cacheWithCompleteErrorPolicy;
110
+ void codec;
111
+ void evictDecorator;
112
+ void invalidLoggingOption;
113
+ void invalidDebugOption;
114
+ void invalidLoggerOption;
115
+ void invalidMissingErrorTtl;
116
+ void invalidEncodeOnlyCodec;
117
+ void invalidDecodeOnlyCodec;
118
+ void invalidPredicateSignature;
119
+ void invalidEvictErrorPolicy;
@@ -1,12 +1,12 @@
1
- {
2
- "extends": "../../../../tsconfig.json",
3
- "compilerOptions": {
4
- "noEmit": true,
5
- "skipLibCheck": false,
6
- "paths": {
7
- "@jintianxiayu/cache-decorator": ["../../dist/index.d.ts"]
8
- },
9
- "types": ["node"]
10
- },
11
- "include": ["contract.ts"]
12
- }
1
+ {
2
+ "extends": "../../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "skipLibCheck": false,
6
+ "paths": {
7
+ "@jintianxiayu/cache-decorator": ["../../dist/index.d.ts"]
8
+ },
9
+ "types": ["node"]
10
+ },
11
+ "include": ["contract.ts"]
12
+ }
package/tsconfig.json CHANGED
@@ -1,8 +1,8 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./src"
6
- },
7
- "include": ["src/**/*"]
8
- }
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src/**/*"]
8
+ }