@jintianxiayu/cache-decorator 0.1.2 → 1.0.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +270 -133
  3. package/dist/adapters/ioredis-cache-client.d.ts +9 -0
  4. package/dist/adapters/ioredis-cache-client.d.ts.map +1 -0
  5. package/dist/adapters/ioredis-cache-client.js +73 -0
  6. package/dist/adapters/ioredis-cache-client.js.map +1 -0
  7. package/dist/adapters/node-redis-cache-client.d.ts +10 -0
  8. package/dist/adapters/node-redis-cache-client.d.ts.map +1 -0
  9. package/dist/adapters/node-redis-cache-client.js +81 -0
  10. package/dist/adapters/node-redis-cache-client.js.map +1 -0
  11. package/dist/adapters/redis-key-prefix.d.ts +22 -0
  12. package/dist/adapters/redis-key-prefix.d.ts.map +1 -0
  13. package/dist/adapters/redis-key-prefix.js +41 -0
  14. package/dist/adapters/redis-key-prefix.js.map +1 -0
  15. package/dist/core/cache-logger.d.ts +28 -0
  16. package/dist/core/cache-logger.d.ts.map +1 -0
  17. package/dist/core/cache-logger.js +70 -0
  18. package/dist/core/cache-logger.js.map +1 -0
  19. package/dist/core/cache-provider-registry.d.ts.map +1 -1
  20. package/dist/core/cache-provider-registry.js.map +1 -1
  21. package/dist/core/cache-provider.d.ts.map +1 -1
  22. package/dist/core/key-builder.d.ts.map +1 -1
  23. package/dist/core/key-builder.js +3 -2
  24. package/dist/core/key-builder.js.map +1 -1
  25. package/dist/core/native-cache.d.ts.map +1 -1
  26. package/dist/core/native-cache.js +2 -1
  27. package/dist/core/native-cache.js.map +1 -1
  28. package/dist/core/pending-cache.d.ts.map +1 -1
  29. package/dist/core/pending-cache.js +6 -3
  30. package/dist/core/pending-cache.js.map +1 -1
  31. package/dist/core/redis-cache-client.d.ts +156 -0
  32. package/dist/core/redis-cache-client.d.ts.map +1 -0
  33. package/dist/core/redis-cache-client.js +3 -0
  34. package/dist/core/redis-cache-client.js.map +1 -0
  35. package/dist/core/redis-cache.d.ts +39 -7
  36. package/dist/core/redis-cache.d.ts.map +1 -1
  37. package/dist/core/redis-cache.js +63 -22
  38. package/dist/core/redis-cache.js.map +1 -1
  39. package/dist/decorators/cache-evict.d.ts +1 -1
  40. package/dist/decorators/cache-evict.d.ts.map +1 -1
  41. package/dist/decorators/cache-evict.js +68 -14
  42. package/dist/decorators/cache-evict.js.map +1 -1
  43. package/dist/decorators/cache.d.ts +1 -1
  44. package/dist/decorators/cache.d.ts.map +1 -1
  45. package/dist/decorators/cache.js +85 -23
  46. package/dist/decorators/cache.js.map +1 -1
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +6 -0
  50. package/dist/index.js.map +1 -1
  51. package/jest.config.js +11 -14
  52. package/package.json +26 -29
  53. package/src/adapters/ioredis-cache-client.ts +89 -0
  54. package/src/adapters/node-redis-cache-client.ts +95 -0
  55. package/src/adapters/redis-key-prefix.ts +38 -0
  56. package/src/core/cache-logger.ts +105 -0
  57. package/src/core/cache-provider-registry.ts +39 -39
  58. package/src/core/cache-provider.ts +28 -28
  59. package/src/core/key-builder.ts +33 -31
  60. package/src/core/native-cache.ts +55 -53
  61. package/src/core/pending-cache.ts +29 -26
  62. package/src/core/redis-cache-client.ts +160 -0
  63. package/src/core/redis-cache.ts +104 -62
  64. package/src/decorators/cache-evict.ts +129 -73
  65. package/src/decorators/cache.ts +203 -129
  66. package/src/index.ts +11 -9
  67. package/test/cache-evict-logging.test.ts +362 -0
  68. package/test/cache-evict.test.ts +165 -165
  69. package/test/cache-logger.integration.test.ts +129 -0
  70. package/test/cache-logger.test.ts +153 -0
  71. package/test/cache-logging.test.ts +544 -0
  72. package/test/cache-provider-registry.test.ts +24 -24
  73. package/test/cache.test.ts +255 -256
  74. package/test/fixtures/cache-logger-child.mjs +108 -0
  75. package/test/helpers/legacy-redis-cache.ts +22 -0
  76. package/test/helpers/package-consumer.ts +231 -0
  77. package/test/helpers/redis-fixture.ts +142 -0
  78. package/test/ioredis-cache-client.test.ts +143 -0
  79. package/test/key-builder.test.ts +28 -28
  80. package/test/native-cache.test.ts +77 -71
  81. package/test/node-redis-cache-client.test.ts +149 -0
  82. package/test/pending-cache.test.ts +69 -56
  83. package/test/redis-cache-client-lifecycle.test.ts +112 -0
  84. package/test/redis-cache-client-types.test.ts +184 -0
  85. package/test/redis-cache-client.integration.test.ts +327 -0
  86. package/test/redis-cache-decorator.test.ts +201 -0
  87. package/test/redis-cache-package.integration.test.ts +328 -0
  88. package/test/redis-cache-provider.test.ts +269 -0
  89. package/test/type-contract/contract.ts +64 -0
  90. package/test/type-contract/tsconfig.json +12 -0
  91. package/tsconfig.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"redis-cache.js","sourceRoot":"","sources":["../../src/core/redis-cache.ts"],"names":[],"mappings":";;;;;;AACA,sDAA4B;AAE5B;;;GAGG;AACH,MAAa,kBAAkB;IAG7B,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,iBAAK,EAAE,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,GAAW;QACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAqB,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAE,GAAY;QAC9C,MAAM,UAAU,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7E,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,IAAI,MAAM,GAAG,GAAG,CAAC;QACjB,GAAG,CAAC;YACF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAC9C,MAAM,EACN,OAAO,EACP,OAAO,EACP,OAAO,EACP,GAAG,CACJ,CAAC;YACF,MAAM,GAAG,UAAU,CAAC;YACpB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAChC,CAAC;QACH,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAE;IAC3B,CAAC;CACF;AAtDD,gDAsDC"}
1
+ {"version":3,"file":"redis-cache.js","sourceRoot":"","sources":["../../src/core/redis-cache.ts"],"names":[],"mappings":";;;AAGA;;;GAGG;AACH,MAAa,kBAAkB;IAG3B;;;OAGG;IACH,YAAY,MAAwB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAI,GAAW;QACpB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACL,8BAA8B;YAC9B,OAAO,KAAqB,CAAC;QACjC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAE,GAAY;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7E,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YAClD,OAAO;QACX,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW;QACpB,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK;QACP,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,eAAe,CAAC,OAAe;QACjC,IAAI,MAAM,GAAG,GAAG,CAAC;QACjB,GAAG,CAAC;YACA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACrE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACrB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;QACL,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAE;IAC7B,CAAC;IAEO,YAAY,CAAC,GAAuB;QACxC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,UAAU,CAAC,2DAA2D,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;CACJ;AAhGD,gDAgGC"}
@@ -1,4 +1,4 @@
1
- import { CacheOptions } from './cache';
1
+ import type { CacheOptions } from './cache';
2
2
  /**
3
3
  * @CacheEvict 装饰器配置项
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cache-evict.d.ts","sourceRoot":"","sources":["../../src/decorators/cache-evict.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAoB,MAAM,SAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC;IAClE;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAuBD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,IAErE,SAAS,MAAM,EACf,cAAc,MAAM,EACpB,YAAY,kBAAkB,UAoBjC;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"cache-evict.d.ts","sourceRoot":"","sources":["../../src/decorators/cache-evict.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,SAAS,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC;IAChE;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AA8DD;;;;;GAKG;AACH,wBAAgB,UAAU,CACtB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC5B,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,KAAK,IAAI,CAoCjF;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC"}
@@ -2,28 +2,64 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CacheProviderRegistry = void 0;
4
4
  exports.CacheEvict = CacheEvict;
5
+ const cache_logger_1 = require("../core/cache-logger");
5
6
  const cache_provider_registry_1 = require("../core/cache-provider-registry");
6
7
  const key_builder_1 = require("../core/key-builder");
7
8
  /**
8
9
  * 解析缓存 key
9
- * @param cacheName 缓存名称
10
10
  * @param keyResolver key 解析器
11
11
  * @param args 方法参数数组
12
+ * @param logContext 不包含业务参数和值的日志上下文
12
13
  * @returns 解析后的缓存 key
13
14
  */
14
- function resolveCacheKey(cacheName, keyResolver, args) {
15
+ function resolveCacheKey(keyResolver, args, logContext) {
15
16
  if (keyResolver === undefined || keyResolver === null) {
16
- return key_builder_1.KeyBuilder.build(cacheName, args);
17
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, args);
17
18
  }
18
19
  if (typeof keyResolver === 'string') {
19
- return key_builder_1.KeyBuilder.build(cacheName, [keyResolver]);
20
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, [keyResolver]);
21
+ }
22
+ try {
23
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, [keyResolver(...args)]);
24
+ }
25
+ catch (_error) {
26
+ (0, cache_logger_1.logCacheEvent)('cache.key_fallback', { ...logContext, reason: 'resolver_error' });
27
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, args);
28
+ }
29
+ }
30
+ /**
31
+ * 获取淘汰操作使用的 Provider,并在解析失败时记录原始注册表错误。
32
+ * @param providerName decorator 配置中的 Provider 名称。
33
+ * @param logContext 当前方法的稳定日志上下文。
34
+ * @returns 已注册的缓存 Provider。
35
+ * @throws Provider 注册表抛出的原始错误。
36
+ */
37
+ function resolveCacheProvider(providerName, logContext) {
38
+ try {
39
+ return cache_provider_registry_1.CacheProviderRegistry.get(providerName);
40
+ }
41
+ catch (error) {
42
+ (0, cache_logger_1.logCacheEvent)('cache.operation_failed', { ...logContext, operation: 'provider_resolution', error });
43
+ throw error;
20
44
  }
45
+ }
46
+ /**
47
+ * 保持 fire-and-forget 语义发起单 key 删除,只处理调用当下可观察的同步失败。
48
+ * @param provider 当前淘汰使用的 Provider。
49
+ * @param cacheKey 待删除的完整 key;不会进入日志元数据。
50
+ * @param logContext 当前方法的稳定日志上下文。
51
+ * @returns 无返回值;异步删除 Promise 不会被等待或消费。
52
+ * @throws Provider delete 同步抛出的原始错误。
53
+ */
54
+ function dispatchCacheDelete(provider, cacheKey, logContext) {
21
55
  try {
22
- return key_builder_1.KeyBuilder.build(cacheName, [keyResolver(...args)]);
56
+ provider.delete(cacheKey);
23
57
  }
24
- catch {
25
- return key_builder_1.KeyBuilder.build(cacheName, args);
58
+ catch (error) {
59
+ (0, cache_logger_1.logCacheEvent)('cache.operation_failed', { ...logContext, operation: 'evict', error });
60
+ throw error;
26
61
  }
62
+ (0, cache_logger_1.logCacheEvent)('cache.evict_dispatched', { ...logContext, scope: 'key' });
27
63
  }
28
64
  /**
29
65
  * 缓存清除装饰器
@@ -32,18 +68,36 @@ function resolveCacheKey(cacheName, keyResolver, args) {
32
68
  * @param options 配置项
33
69
  */
34
70
  function CacheEvict(cacheName, options) {
35
- return function (_target, _propertyKey, descriptor) {
71
+ return function (_target, propertyKey, descriptor) {
36
72
  const originalMethod = descriptor.value;
73
+ const logContext = {
74
+ cacheName,
75
+ methodName: propertyKey,
76
+ providerName: (0, cache_logger_1.cacheProviderLabel)(options?.providerName),
77
+ };
37
78
  descriptor.value = async function (...args) {
38
- const result = await originalMethod.apply(this, args);
39
- const providerName = options?.providerName;
40
- const provider = cache_provider_registry_1.CacheProviderRegistry.get(providerName);
79
+ let result;
80
+ try {
81
+ result = await originalMethod.apply(this, args);
82
+ }
83
+ catch (error) {
84
+ (0, cache_logger_1.logCacheEvent)('cache.evict_skipped', { ...logContext, reason: 'business_error' });
85
+ throw error;
86
+ }
87
+ const provider = resolveCacheProvider(options?.providerName, logContext);
41
88
  if (options?.allEntries) {
42
- await provider.deleteByPattern(cacheName + '*');
89
+ try {
90
+ await provider.deleteByPattern(cacheName + '*');
91
+ }
92
+ catch (error) {
93
+ (0, cache_logger_1.logCacheEvent)('cache.operation_failed', { ...logContext, operation: 'evict', error });
94
+ throw error;
95
+ }
96
+ (0, cache_logger_1.logCacheEvent)('cache.evict_completed', { ...logContext, scope: 'allEntries' });
43
97
  }
44
98
  else {
45
- const cacheKey = resolveCacheKey(cacheName, options?.key, args);
46
- provider.delete(cacheKey);
99
+ const cacheKey = resolveCacheKey(options?.key, args, logContext);
100
+ dispatchCacheDelete(provider, cacheKey, logContext);
47
101
  }
48
102
  return result;
49
103
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cache-evict.js","sourceRoot":"","sources":["../../src/decorators/cache-evict.ts"],"names":[],"mappings":";;;AA8CA,gCAwBC;AAtED,6EAAwE;AACxE,qDAAiD;AAkBjD;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,SAAiB,EAAE,WAAyC,EAAE,IAAe;IACpG,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,CAAC;QACH,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,SAAiB,EAAE,OAA2B;IACvE,OAAO,UACL,OAAe,EACf,YAAoB,EACpB,UAA8B;QAE9B,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAG,IAAe;YACnD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAEtD,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,CAAC;YAC3C,MAAM,QAAQ,GAAG,+CAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAEzD,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;gBACxB,MAAM,QAAQ,CAAC,eAAe,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;gBAChE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,2EAAwE;AAA/D,gIAAA,qBAAqB,OAAA"}
1
+ {"version":3,"file":"cache-evict.js","sourceRoot":"","sources":["../../src/decorators/cache-evict.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,6 @@ export interface CacheOptions {
32
32
  * @param cacheName 缓存名称
33
33
  * @param options 配置项
34
34
  */
35
- export declare function Cache(cacheName: string, options?: CacheOptions): <T>(_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => void;
35
+ export declare function Cache(cacheName: string, options?: CacheOptions): (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => void;
36
36
  export { CacheProviderRegistry } from '../core/cache-provider-registry';
37
37
  //# sourceMappingURL=cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/decorators/cache.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAK1B;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,gBAAgB,CAAC;CACxB;AA4CD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAC5C,CAAC,EAChB,SAAS,MAAM,EACf,cAAc,MAAM,EACpB,YAAY,kBAAkB,UAsCjC;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/decorators/cache.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAO1B;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AA0FD;;;;;GAKG;AACH,wBAAgB,KAAK,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,GACvB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,KAAK,IAAI,CAiEjF;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC"}
@@ -3,29 +3,63 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CacheProviderRegistry = void 0;
4
4
  exports.Cache = Cache;
5
5
  require("reflect-metadata");
6
+ const cache_logger_1 = require("../core/cache-logger");
6
7
  const cache_provider_registry_1 = require("../core/cache-provider-registry");
7
8
  const key_builder_1 = require("../core/key-builder");
8
9
  const pending_cache_1 = require("../core/pending-cache");
9
10
  const pendingCache = new pending_cache_1.PendingCache();
11
+ /**
12
+ * 获取配置指向的缓存 Provider,并在解析失败时记录原始错误。
13
+ * @param providerName decorator 配置中的 Provider 名称。
14
+ * @param logContext 当前方法的稳定日志上下文。
15
+ * @returns 已注册的缓存 Provider。
16
+ * @throws Provider 注册表抛出的原始错误。
17
+ */
18
+ function resolveCacheProvider(providerName, logContext) {
19
+ try {
20
+ return cache_provider_registry_1.CacheProviderRegistry.get(providerName);
21
+ }
22
+ catch (error) {
23
+ (0, cache_logger_1.logCacheEvent)('cache.operation_failed', { ...logContext, operation: 'provider_resolution', error });
24
+ throw error;
25
+ }
26
+ }
27
+ /**
28
+ * 保持 fire-and-forget 语义提交缓存写入,仅捕获调用当下可观察的同步失败。
29
+ * @param request 写入所需 Provider、entry 和无业务数据日志上下文。
30
+ * @returns 无返回值;异步写入 Promise 不会被等待或消费。
31
+ * @throws Provider set 同步抛出的原始错误。
32
+ */
33
+ function dispatchCacheWrite(request) {
34
+ try {
35
+ request.provider.set(request.cacheKey, request.entry, request.ttl);
36
+ }
37
+ catch (error) {
38
+ (0, cache_logger_1.logCacheEvent)('cache.operation_failed', { ...request.logContext, operation: 'write', error });
39
+ throw error;
40
+ }
41
+ (0, cache_logger_1.logCacheEvent)('cache.write_dispatched', { ...request.logContext, entryType: request.entryType });
42
+ }
10
43
  /**
11
44
  * 解析缓存 key
12
- * @param cacheName 缓存名称
13
45
  * @param keyResolver key 解析器
14
46
  * @param args 方法参数数组
47
+ * @param logContext 不包含业务参数和值的日志上下文
15
48
  * @returns 解析后的缓存 key
16
49
  */
17
- function resolveCacheKey(cacheName, keyResolver, args) {
50
+ function resolveCacheKey(keyResolver, args, logContext) {
18
51
  if (keyResolver === undefined || keyResolver === null) {
19
- return key_builder_1.KeyBuilder.build(cacheName, args);
52
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, args);
20
53
  }
21
54
  if (typeof keyResolver === 'string') {
22
- return key_builder_1.KeyBuilder.build(cacheName, [keyResolver]);
55
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, [keyResolver]);
23
56
  }
24
57
  try {
25
- return key_builder_1.KeyBuilder.build(cacheName, [keyResolver(...args)]);
58
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, [keyResolver(...args)]);
26
59
  }
27
- catch {
28
- return key_builder_1.KeyBuilder.build(cacheName, args);
60
+ catch (_error) {
61
+ (0, cache_logger_1.logCacheEvent)('cache.key_fallback', { ...logContext, reason: 'resolver_error' });
62
+ return key_builder_1.KeyBuilder.build(logContext.cacheName, args);
29
63
  }
30
64
  }
31
65
  /**
@@ -35,32 +69,60 @@ function resolveCacheKey(cacheName, keyResolver, args) {
35
69
  * @param options 配置项
36
70
  */
37
71
  function Cache(cacheName, options) {
38
- return function (_target, _propertyKey, descriptor) {
72
+ return function (_target, propertyKey, descriptor) {
39
73
  const originalMethod = descriptor.value;
40
- descriptor.value = async function (...args) {
41
- const cacheKey = resolveCacheKey(cacheName, options?.key, args);
42
- const providerName = options?.providerName;
43
- const provider = cache_provider_registry_1.CacheProviderRegistry.get(providerName);
44
- const cached = await provider.get(cacheKey);
45
- if (cached !== undefined) {
46
- const entry = cached;
47
- if ('error' in entry) {
48
- throw entry.error;
49
- }
50
- return entry.value;
51
- }
74
+ const logContext = {
75
+ cacheName,
76
+ methodName: propertyKey,
77
+ providerName: (0, cache_logger_1.cacheProviderLabel)(options?.providerName),
78
+ };
79
+ descriptor.value = function (...args) {
80
+ const cacheKey = resolveCacheKey(options?.key, args, logContext);
52
81
  const pending = pendingCache.get(cacheKey);
53
82
  if (pending) {
83
+ (0, cache_logger_1.logCacheEvent)('cache.pending_hit', logContext);
54
84
  return pending;
55
85
  }
56
86
  const promise = (async () => {
87
+ const provider = resolveCacheProvider(options?.providerName, logContext);
88
+ let cached;
89
+ try {
90
+ cached = await provider.get(cacheKey);
91
+ }
92
+ catch (error) {
93
+ (0, cache_logger_1.logCacheEvent)('cache.operation_failed', { ...logContext, operation: 'read', error });
94
+ throw error;
95
+ }
96
+ if (cached !== undefined) {
97
+ if ('error' in cached) {
98
+ (0, cache_logger_1.logCacheEvent)('cache.hit', { ...logContext, entryType: 'error' });
99
+ throw cached.error;
100
+ }
101
+ (0, cache_logger_1.logCacheEvent)('cache.hit', { ...logContext, entryType: 'value' });
102
+ return cached.value;
103
+ }
104
+ (0, cache_logger_1.logCacheEvent)('cache.miss', logContext);
57
105
  try {
58
- const result = await originalMethod.apply(this, args);
59
- provider.set(cacheKey, { value: result }, options?.ttl);
106
+ const result = (await originalMethod.apply(this, args));
107
+ dispatchCacheWrite({
108
+ provider,
109
+ cacheKey,
110
+ entry: { value: result },
111
+ entryType: 'value',
112
+ ttl: options?.ttl,
113
+ logContext,
114
+ });
60
115
  return result;
61
116
  }
62
117
  catch (error) {
63
- provider.set(cacheKey, { error }, options?.ttl);
118
+ dispatchCacheWrite({
119
+ provider,
120
+ cacheKey,
121
+ entry: { error },
122
+ entryType: 'error',
123
+ ttl: options?.ttl,
124
+ logContext,
125
+ });
64
126
  throw error;
65
127
  }
66
128
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/decorators/cache.ts"],"names":[],"mappings":";;;AAoFA,sBA0CC;AA9HD,4BAA0B;AAC1B,6EAAwE;AACxE,qDAAiD;AACjD,yDAAqD;AAoDrD,MAAM,YAAY,GAAG,IAAI,4BAAY,EAAE,CAAC;AAExC;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,SAAiB,EAAE,WAAyC,EAAE,IAAe;IACpG,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,CAAC;QACH,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,wBAAU,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,KAAK,CAAC,SAAiB,EAAE,OAAsB;IAC7D,OAAO,UACL,OAAe,EACf,YAAoB,EACpB,UAA8B;QAE9B,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAG,IAAe;YACnD,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAChE,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,CAAC;YAC3C,MAAM,QAAQ,GAAG,+CAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAEzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,MAAuB,CAAC;gBACtC,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;oBACrB,MAAM,KAAK,CAAC,KAAK,CAAC;gBACpB,CAAC;gBACD,OAAO,KAAK,CAAC,KAAK,CAAC;YACrB,CAAC;YAED,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAI,QAAQ,CAAC,CAAC;YAC9C,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,OAAO,CAAC;YACjB,CAAC;YAED,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC1B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACtD,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAmB,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;oBACzE,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAmB,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;oBACjE,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;YAEL,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpC,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,2EAAwE;AAA/D,gIAAA,qBAAqB,OAAA"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/decorators/cache.ts"],"names":[],"mappings":";;;AAoIA,sBAoEC;AAxMD,4BAA0B;AAC1B,uDAA+F;AAE/F,6EAAwE;AACxE,qDAAiD;AACjD,yDAAqD;AA6DrD,MAAM,YAAY,GAAG,IAAI,4BAAY,EAAE,CAAC;AAExC;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,YAAgC,EAAE,UAA2B;IACvF,IAAI,CAAC;QACD,OAAO,+CAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAA,4BAAa,EAAC,wBAAwB,EAAE,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,CAAC;QACpG,MAAM,KAAK,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CAAI,OAA6B;IACxD,IAAI,CAAC;QACD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAA,4BAAa,EAAC,wBAAwB,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9F,MAAM,KAAK,CAAC;IAChB,CAAC;IACD,IAAA,4BAAa,EAAC,wBAAwB,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;AACrG,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACpB,WAAyC,EACzC,IAAe,EACf,UAA2B;IAE3B,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACpD,OAAO,wBAAU,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,wBAAU,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC;QACD,OAAO,wBAAU,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QACd,IAAA,4BAAa,EAAC,oBAAoB,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACjF,OAAO,wBAAU,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAgB,KAAK,CACjB,SAAiB,EACjB,OAAsB;IAEtB,OAAO,UAAa,OAAe,EAAE,WAAmB,EAAE,UAA8B;QACpF,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QACxC,MAAM,UAAU,GAAoB;YAChC,SAAS;YACT,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE,IAAA,iCAAkB,EAAC,OAAO,EAAE,YAAY,CAAC;SAC1D,CAAC;QAEF,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAe;YAC3C,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YAEjE,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAI,QAAQ,CAAC,CAAC;YAC9C,IAAI,OAAO,EAAE,CAAC;gBACV,IAAA,4BAAa,EAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;gBAC/C,OAAO,OAAO,CAAC;YACnB,CAAC;YAED,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;gBACxB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;gBACzE,IAAI,MAAiC,CAAC;gBACtC,IAAI,CAAC;oBACD,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAgB,QAAQ,CAAC,CAAC;gBACzD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,IAAA,4BAAa,EAAC,wBAAwB,EAAE,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;oBACrF,MAAM,KAAK,CAAC;gBAChB,CAAC;gBACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACvB,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;wBACpB,IAAA,4BAAa,EAAC,WAAW,EAAE,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;wBAClE,MAAM,MAAM,CAAC,KAAK,CAAC;oBACvB,CAAC;oBACD,IAAA,4BAAa,EAAC,WAAW,EAAE,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;oBAClE,OAAO,MAAM,CAAC,KAAK,CAAC;gBACxB,CAAC;gBACD,IAAA,4BAAa,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC;gBAExC,IAAI,CAAC;oBACD,MAAM,MAAM,GAAG,CAAC,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAM,CAAC;oBAC7D,kBAAkB,CAAC;wBACf,QAAQ;wBACR,QAAQ;wBACR,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;wBACxB,SAAS,EAAE,OAAO;wBAClB,GAAG,EAAE,OAAO,EAAE,GAAG;wBACjB,UAAU;qBACb,CAAC,CAAC;oBACH,OAAO,MAAM,CAAC;gBAClB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,kBAAkB,CAAC;wBACf,QAAQ;wBACR,QAAQ;wBACR,KAAK,EAAE,EAAE,KAAK,EAAE;wBAChB,SAAS,EAAE,OAAO;wBAClB,GAAG,EAAE,OAAO,EAAE,GAAG;wBACjB,UAAU;qBACb,CAAC,CAAC;oBACH,MAAM,KAAK,CAAC;gBAChB,CAAC;YACL,CAAC,CAAC,EAAE,CAAC;YAEL,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpC,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC;IACN,CAAC,CAAC;AACN,CAAC;AAED,2EAAwE;AAA/D,gIAAA,qBAAqB,OAAA"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
+ export { createIoredisCacheClient } from './adapters/ioredis-cache-client';
2
+ export { createNodeRedisCacheClient } from './adapters/node-redis-cache-client';
1
3
  export * from './core/cache-provider';
2
4
  export * from './core/cache-provider-registry';
3
5
  export * from './core/key-builder';
4
6
  export * from './core/native-cache';
5
7
  export * from './core/pending-cache';
8
+ export * from './core/redis-cache-client';
6
9
  export * from './core/redis-cache';
7
10
  export * from './decorators/cache';
8
11
  export * from './decorators/cache-evict';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -14,11 +14,17 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.createNodeRedisCacheClient = exports.createIoredisCacheClient = void 0;
18
+ var ioredis_cache_client_1 = require("./adapters/ioredis-cache-client");
19
+ Object.defineProperty(exports, "createIoredisCacheClient", { enumerable: true, get: function () { return ioredis_cache_client_1.createIoredisCacheClient; } });
20
+ var node_redis_cache_client_1 = require("./adapters/node-redis-cache-client");
21
+ Object.defineProperty(exports, "createNodeRedisCacheClient", { enumerable: true, get: function () { return node_redis_cache_client_1.createNodeRedisCacheClient; } });
17
22
  __exportStar(require("./core/cache-provider"), exports);
18
23
  __exportStar(require("./core/cache-provider-registry"), exports);
19
24
  __exportStar(require("./core/key-builder"), exports);
20
25
  __exportStar(require("./core/native-cache"), exports);
21
26
  __exportStar(require("./core/pending-cache"), exports);
27
+ __exportStar(require("./core/redis-cache-client"), exports);
22
28
  __exportStar(require("./core/redis-cache"), exports);
23
29
  __exportStar(require("./decorators/cache"), exports);
24
30
  __exportStar(require("./decorators/cache-evict"), exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,wDAAsC;AACtC,iEAA+C;AAC/C,qDAAmC;AACnC,sDAAoC;AACpC,uDAAqC;AACrC,qDAAmC;AACnC,qDAAmC;AACnC,2DAAyC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,wEAA2E;AAAlE,gIAAA,wBAAwB,OAAA;AACjC,8EAAgF;AAAvE,qIAAA,0BAA0B,OAAA;AACnC,wDAAsC;AACtC,iEAA+C;AAC/C,qDAAmC;AACnC,sDAAoC;AACpC,uDAAqC;AACrC,4DAA0C;AAC1C,qDAAmC;AACnC,qDAAmC;AACnC,2DAAyC"}
package/jest.config.js CHANGED
@@ -1,14 +1,11 @@
1
- module.exports = {
2
- preset: 'ts-jest',
3
- testEnvironment: 'node',
4
- roots: ['<rootDir>'],
5
- testMatch: ['**/test/**/*.test.ts'],
6
- moduleFileExtensions: ['ts', 'js', 'json'],
7
- collectCoverageFrom: [
8
- 'src/**/*.ts',
9
- '!src/**/*.d.ts'
10
- ],
11
- transform: {
12
- '^.+\\.ts$': 'ts-jest'
13
- }
14
- };
1
+ module.exports = {
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', { tsconfig: '<rootDir>/../../tsconfig.test.json' }],
10
+ },
11
+ };
package/package.json CHANGED
@@ -1,30 +1,27 @@
1
1
  {
2
- "name": "@jintianxiayu/cache-decorator",
3
- "version": "0.1.2",
4
- "description": "Method caching decorators for TypeScript",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "scripts": {
8
- "build": "tsc",
9
- "test": "jest",
10
- "typecheck": "tsc --noEmit"
11
- },
12
- "dependencies": {
13
- "reflect-metadata": "^0.2.2"
14
- },
15
- "devDependencies": {
16
- "@types/ioredis": "^4.28.10",
17
- "@types/node": "^22.10.0",
18
- "ioredis": "^5.10.1",
19
- "jest": "^29.7.0",
20
- "ts-jest": "^29.2.0",
21
- "typescript": "^5.7.0"
22
- },
23
- "peerDependencies": {
24
- "reflect-metadata": "^0.2.2"
25
- },
26
- "publishConfig": {
27
- "access": "public"
28
- },
29
- "gitHead": "357e736abbe6b25a707663c1b9e027b2e8b532a6"
30
- }
2
+ "name": "@jintianxiayu/cache-decorator",
3
+ "version": "1.0.0",
4
+ "description": "Method caching decorators for TypeScript",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "dependencies": {
8
+ "reflect-metadata": "^0.2.2"
9
+ },
10
+ "peerDependencies": {
11
+ "@jintianxiayu/logger": "^1.0.0"
12
+ },
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "devDependencies": {
17
+ "ioredis": "^5.10.1",
18
+ "redis": "^5.12.1",
19
+ "@jintianxiayu/logger": "^1.0.0"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "test": "jest",
24
+ "clean": "rimraf dist",
25
+ "typecheck": "tsc --noEmit"
26
+ }
27
+ }
@@ -0,0 +1,89 @@
1
+ import { IoredisCacheClientSource, RedisCacheClient } from '../core/redis-cache-client';
2
+ import { createRedisScanPattern, stripRedisKeyPrefix } from './redis-key-prefix';
3
+
4
+ function normalizeGetResponse(response: unknown): string | null {
5
+ if (typeof response === 'string' || response === null) {
6
+ return response;
7
+ }
8
+ throw new TypeError('Expected Redis GET to return a string or null');
9
+ }
10
+
11
+ function validateOkResponse(command: string, response: unknown): void {
12
+ if (response !== 'OK') {
13
+ throw new TypeError(`Expected Redis ${command} to return "OK"`);
14
+ }
15
+ }
16
+
17
+ function validateDeleteResponse(response: unknown): void {
18
+ if (typeof response !== 'number' || !Number.isInteger(response) || response < 0) {
19
+ throw new TypeError('Expected Redis DEL to return a non-negative integer');
20
+ }
21
+ }
22
+
23
+ function normalizeScanResponse(
24
+ response: unknown,
25
+ keyPrefix: string
26
+ ): { readonly cursor: string; readonly keys: readonly string[] } {
27
+ if (
28
+ !Array.isArray(response) ||
29
+ response.length !== 2 ||
30
+ typeof response[0] !== 'string' ||
31
+ !Array.isArray(response[1]) ||
32
+ !response[1].every((key: unknown) => typeof key === 'string')
33
+ ) {
34
+ throw new TypeError('Expected ioredis SCAN to return a [cursor, keys] tuple');
35
+ }
36
+ return {
37
+ cursor: response[0],
38
+ keys: response[1].map((key: string) => stripRedisKeyPrefix(keyPrefix, key)),
39
+ };
40
+ }
41
+
42
+ /**
43
+ * 将调用方的 ioredis 连接适配为客户端无关的缓存命令,不创建或关闭连接。
44
+ * @param client 使用默认字符串响应映射的 ioredis 普通客户端。
45
+ * @returns 复用该连接并恢复逻辑 key 的 Redis 缓存客户端。
46
+ * @throws 返回对象的命令方法传播客户端错误;非标准响应拒绝为 TypeError。
47
+ */
48
+ export function createIoredisCacheClient(client: IoredisCacheClientSource): RedisCacheClient {
49
+ const keyPrefix = client.options.keyPrefix ?? '';
50
+ return {
51
+ /** @inheritdoc */
52
+ async get(key: string): Promise<string | null> {
53
+ return normalizeGetResponse(await client.get(key));
54
+ },
55
+ /** @inheritdoc */
56
+ async set({ key, value, ttlSeconds }): Promise<void> {
57
+ if (ttlSeconds === undefined) {
58
+ validateOkResponse('SET', await client.set(key, value));
59
+ return;
60
+ }
61
+ validateOkResponse('SETEX', await client.setex(key, ttlSeconds, value));
62
+ },
63
+ /** @inheritdoc */
64
+ async deleteMany(keys: readonly string[]): Promise<void> {
65
+ if (keys.length === 0) {
66
+ return;
67
+ }
68
+ validateDeleteResponse(await client.del(...keys));
69
+ },
70
+ /** @inheritdoc */
71
+ async scan({ cursor, pattern, count }): Promise<{
72
+ readonly cursor: string;
73
+ readonly keys: readonly string[];
74
+ }> {
75
+ const response = await client.scan(
76
+ cursor,
77
+ 'MATCH',
78
+ createRedisScanPattern(keyPrefix, pattern),
79
+ 'COUNT',
80
+ count
81
+ );
82
+ return normalizeScanResponse(response, keyPrefix);
83
+ },
84
+ /** @inheritdoc */
85
+ async flushDatabase(): Promise<void> {
86
+ validateOkResponse('FLUSHDB', await client.flushdb());
87
+ },
88
+ };
89
+ }