@expo/entity-cache-adapter-redis 0.44.0 → 0.45.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.
@@ -22,8 +22,33 @@ export declare enum RedisCacheInvalidationStrategy {
22
22
  * some machines may be operating on an old version of the code and thus an old cacheKeyVersion, and some the new version.
23
23
  * This strategy generates cache keys for both old and potential future new versions.
24
24
  */
25
- SURROUNDING_CACHE_KEY_VERSIONS = "surrounding-cache-key-versions"
25
+ SURROUNDING_CACHE_KEY_VERSIONS = "surrounding-cache-key-versions",
26
+ /**
27
+ * Invalidate cache keys based on user-specified function from the current cacheKeyVersion to a list of cache key
28
+ * versions to invalidate.
29
+ */
30
+ CUSTOM = "custom"
26
31
  }
32
+ export type GenericRedisCacheInvalidationConfig = {
33
+ /**
34
+ * Invalidation strategy for the cache.
35
+ */
36
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION;
37
+ } | {
38
+ /**
39
+ * Invalidation strategy for the cache.
40
+ */
41
+ invalidationStrategy: RedisCacheInvalidationStrategy.SURROUNDING_CACHE_KEY_VERSIONS;
42
+ } | {
43
+ /**
44
+ * Invalidation strategy for the cache.
45
+ */
46
+ invalidationStrategy: RedisCacheInvalidationStrategy.CUSTOM;
47
+ /**
48
+ * Function that takes the current cache key version and returns the cache key versions to invalidate.
49
+ */
50
+ cacheKeyVersionsToInvalidateFn: (cacheKeyVersion: number) => readonly number[];
51
+ };
27
52
  export interface GenericRedisCacheContext {
28
53
  /**
29
54
  * Instance of ioredis.Redis
@@ -50,9 +75,9 @@ export interface GenericRedisCacheContext {
50
75
  */
51
76
  ttlSecondsNegative: number;
52
77
  /**
53
- * Invalidation strategy for the cache.
78
+ * Configuration for cache invalidation strategy.
54
79
  */
55
- invalidationStrategy: RedisCacheInvalidationStrategy;
80
+ invalidationConfig: GenericRedisCacheInvalidationConfig;
56
81
  }
57
82
  export default class GenericRedisCacher<TFields extends Record<string, any>, TIDField extends keyof TFields> implements IEntityGenericCacher<TFields, TIDField> {
58
83
  private readonly context;
@@ -27,6 +27,11 @@ var RedisCacheInvalidationStrategy;
27
27
  * This strategy generates cache keys for both old and potential future new versions.
28
28
  */
29
29
  RedisCacheInvalidationStrategy["SURROUNDING_CACHE_KEY_VERSIONS"] = "surrounding-cache-key-versions";
30
+ /**
31
+ * Invalidate cache keys based on user-specified function from the current cacheKeyVersion to a list of cache key
32
+ * versions to invalidate.
33
+ */
34
+ RedisCacheInvalidationStrategy["CUSTOM"] = "custom";
30
35
  })(RedisCacheInvalidationStrategy || (exports.RedisCacheInvalidationStrategy = RedisCacheInvalidationStrategy = {}));
31
36
  class GenericRedisCacher {
32
37
  context;
@@ -98,13 +103,17 @@ class GenericRedisCacher {
98
103
  return this.makeCacheKeyForCacheKeyVersion(key, value, this.entityConfiguration.cacheKeyVersion);
99
104
  }
100
105
  makeCacheKeysForInvalidation(key, value) {
101
- switch (this.context.invalidationStrategy) {
106
+ switch (this.context.invalidationConfig.invalidationStrategy) {
102
107
  case RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION:
103
108
  return [
104
109
  this.makeCacheKeyForCacheKeyVersion(key, value, this.entityConfiguration.cacheKeyVersion),
105
110
  ];
106
111
  case RedisCacheInvalidationStrategy.SURROUNDING_CACHE_KEY_VERSIONS:
107
112
  return (0, getSurroundingCacheKeyVersionsForInvalidation_1.getSurroundingCacheKeyVersionsForInvalidation)(this.entityConfiguration.cacheKeyVersion).map((cacheKeyVersion) => this.makeCacheKeyForCacheKeyVersion(key, value, cacheKeyVersion));
113
+ case RedisCacheInvalidationStrategy.CUSTOM:
114
+ return this.context.invalidationConfig
115
+ .cacheKeyVersionsToInvalidateFn(this.entityConfiguration.cacheKeyVersion)
116
+ .map((cacheKeyVersion) => this.makeCacheKeyForCacheKeyVersion(key, value, cacheKeyVersion));
108
117
  }
109
118
  }
110
119
  }
@@ -1 +1 @@
1
- {"version":3,"file":"GenericRedisCacher.js","sourceRoot":"","sources":["../src/GenericRedisCacher.ts"],"names":[],"mappings":";;;;;;AAAA,yCASsB;AAEtB,+CAAoD;AACpD,iGAAyE;AACzE,yHAAsH;AAEtH,wEAAwE;AACxE,qEAAqE;AACrE,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAahC;;GAEG;AACH,IAAY,8BAaX;AAbD,WAAY,8BAA8B;IACxC;;OAEG;IACH,yFAAuD,CAAA;IAEvD;;;;;OAKG;IACH,mGAAiE,CAAA;AACnE,CAAC,EAbW,8BAA8B,8CAA9B,8BAA8B,QAazC;AAsCD,MAAqB,kBAAkB;IAMlB;IACA;IAFnB,YACmB,OAAiC,EACjC,mBAA2D;QAD3D,YAAO,GAAP,OAAO,CAA0B;QACjC,wBAAmB,GAAnB,mBAAmB,CAAwC;IAC3E,CAAC;IAEG,KAAK,CAAC,aAAa,CACxB,IAAuB;QAEvB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAA,kCAAwB,EAAC,GAAG,EAAE,CACvD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CACvC,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoC,CAAC;QAC5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;YACrB,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAEpC,IAAI,WAAW,KAAK,oBAAoB,EAAE,CAAC;gBACzC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;oBACf,MAAM,EAAE,oBAAW,CAAC,QAAQ;iBAC7B,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,WAAW,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;oBACf,MAAM,EAAE,oBAAW,CAAC,GAAG;oBACvB,IAAI,EAAE,IAAA,qCAA4B,EAChC,IAAI,CAAC,mBAAmB,EACxB,iCAAmB,EACnB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CACxB;iBACF,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;oBACf,MAAM,EAAE,oBAAW,CAAC,IAAI;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,SAAiD;QAC3E,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,IAAI,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACxD,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YAChC,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CACrC,GAAG,EACH,IAAI,CAAC,SAAS,CACZ,IAAA,qCAA4B,EAAC,IAAI,CAAC,mBAAmB,EAAE,iCAAmB,EAAE,MAAM,CAAC,CACpF,EACD,IAAI,EACJ,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAChC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,MAAM,IAAA,kCAAwB,EAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,IAAuB;QACrD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CACrC,GAAG,EACH,oBAAoB,EACpB,IAAI,EACJ,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAChC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,MAAM,IAAA,kCAAwB,EAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAAC,IAAuB;QACtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,MAAM,IAAA,kCAAwB,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC;IAEO,8BAA8B,CAIpC,GAAa,EAAE,KAAiB,EAAE,eAAuB;QACzD,MAAM,YAAY,GAAG,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,+BAA+B,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAC3B,IAAI,CAAC,OAAO,CAAC,cAAc,EAC3B,YAAY,EACZ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAClC,MAAM,eAAe,EAAE,EACvB,GAAG,KAAK,CACT,CAAC;IACJ,CAAC;IAEM,sBAAsB,CAI3B,GAAa,EAAE,KAAiB;QAChC,OAAO,IAAI,CAAC,8BAA8B,CACxC,GAAG,EACH,KAAK,EACL,IAAI,CAAC,mBAAmB,CAAC,eAAe,CACzC,CAAC;IACJ,CAAC;IAEM,4BAA4B,CAIjC,GAAa,EAAE,KAAiB;QAChC,QAAQ,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;YAC1C,KAAK,8BAA8B,CAAC,yBAAyB;gBAC3D,OAAO;oBACL,IAAI,CAAC,8BAA8B,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC;iBAC1F,CAAC;YACJ,KAAK,8BAA8B,CAAC,8BAA8B;gBAChE,OAAO,IAAA,6FAA6C,EAClD,IAAI,CAAC,mBAAmB,CAAC,eAAe,CACzC,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE,CACxB,IAAI,CAAC,8BAA8B,CAAC,GAAG,EAAE,KAAK,EAAE,eAAe,CAAC,CACjE,CAAC;QACN,CAAC;IACH,CAAC;CACF;AA1ID,qCA0IC"}
1
+ {"version":3,"file":"GenericRedisCacher.js","sourceRoot":"","sources":["../src/GenericRedisCacher.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/entity-cache-adapter-redis",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "Redis cache adapter for @expo/entity",
5
5
  "files": [
6
6
  "build",
@@ -28,14 +28,14 @@
28
28
  "author": "Expo",
29
29
  "license": "MIT",
30
30
  "dependencies": {
31
- "@expo/entity": "^0.44.0"
31
+ "@expo/entity": "^0.45.0"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "ioredis": ">=5"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@expo/batcher": "^1.0.0",
38
- "@expo/entity-testing-utils": "^0.44.0",
38
+ "@expo/entity-testing-utils": "^0.45.0",
39
39
  "@types/jest": "^29.5.14",
40
40
  "@types/node": "^20.14.1",
41
41
  "ctix": "^2.7.0",
@@ -50,5 +50,5 @@
50
50
  "ts-mockito": "^2.6.1",
51
51
  "typescript": "^5.8.3"
52
52
  },
53
- "gitHead": "b9b09933e5a5b02037aa4688c5969705a29995c0"
53
+ "gitHead": "fe2d246f87adc98a13cc7c1ae57f3628769560c9"
54
54
  }
@@ -44,8 +44,39 @@ export enum RedisCacheInvalidationStrategy {
44
44
  * This strategy generates cache keys for both old and potential future new versions.
45
45
  */
46
46
  SURROUNDING_CACHE_KEY_VERSIONS = 'surrounding-cache-key-versions',
47
+
48
+ /**
49
+ * Invalidate cache keys based on user-specified function from the current cacheKeyVersion to a list of cache key
50
+ * versions to invalidate.
51
+ */
52
+ CUSTOM = 'custom',
47
53
  }
48
54
 
55
+ export type GenericRedisCacheInvalidationConfig =
56
+ | {
57
+ /**
58
+ * Invalidation strategy for the cache.
59
+ */
60
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION;
61
+ }
62
+ | {
63
+ /**
64
+ * Invalidation strategy for the cache.
65
+ */
66
+ invalidationStrategy: RedisCacheInvalidationStrategy.SURROUNDING_CACHE_KEY_VERSIONS;
67
+ }
68
+ | {
69
+ /**
70
+ * Invalidation strategy for the cache.
71
+ */
72
+ invalidationStrategy: RedisCacheInvalidationStrategy.CUSTOM;
73
+
74
+ /**
75
+ * Function that takes the current cache key version and returns the cache key versions to invalidate.
76
+ */
77
+ cacheKeyVersionsToInvalidateFn: (cacheKeyVersion: number) => readonly number[];
78
+ };
79
+
49
80
  export interface GenericRedisCacheContext {
50
81
  /**
51
82
  * Instance of ioredis.Redis
@@ -77,9 +108,9 @@ export interface GenericRedisCacheContext {
77
108
  ttlSecondsNegative: number;
78
109
 
79
110
  /**
80
- * Invalidation strategy for the cache.
111
+ * Configuration for cache invalidation strategy.
81
112
  */
82
- invalidationStrategy: RedisCacheInvalidationStrategy;
113
+ invalidationConfig: GenericRedisCacheInvalidationConfig;
83
114
  }
84
115
 
85
116
  export default class GenericRedisCacher<
@@ -207,7 +238,7 @@ export default class GenericRedisCacher<
207
238
  TSerializedLoadValue,
208
239
  TLoadValue extends IEntityLoadValue<TSerializedLoadValue>,
209
240
  >(key: TLoadKey, value: TLoadValue): readonly string[] {
210
- switch (this.context.invalidationStrategy) {
241
+ switch (this.context.invalidationConfig.invalidationStrategy) {
211
242
  case RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION:
212
243
  return [
213
244
  this.makeCacheKeyForCacheKeyVersion(key, value, this.entityConfiguration.cacheKeyVersion),
@@ -218,6 +249,12 @@ export default class GenericRedisCacher<
218
249
  ).map((cacheKeyVersion) =>
219
250
  this.makeCacheKeyForCacheKeyVersion(key, value, cacheKeyVersion),
220
251
  );
252
+ case RedisCacheInvalidationStrategy.CUSTOM:
253
+ return this.context.invalidationConfig
254
+ .cacheKeyVersionsToInvalidateFn(this.entityConfiguration.cacheKeyVersion)
255
+ .map((cacheKeyVersion) =>
256
+ this.makeCacheKeyForCacheKeyVersion(key, value, cacheKeyVersion),
257
+ );
221
258
  }
222
259
  }
223
260
  }
@@ -85,7 +85,9 @@ describe(GenericRedisCacher, () => {
85
85
  cacheKeyPrefix: 'test-',
86
86
  ttlSecondsPositive: 86400, // 1 day
87
87
  ttlSecondsNegative: 600, // 10 minutes
88
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
88
+ invalidationConfig: {
89
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
90
+ },
89
91
  };
90
92
  });
91
93
 
@@ -36,7 +36,9 @@ describe(GenericRedisCacher, () => {
36
36
  cacheKeyPrefix: 'test-',
37
37
  ttlSecondsPositive: 86400, // 1 day
38
38
  ttlSecondsNegative: 600, // 10 minutes
39
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
39
+ invalidationConfig: {
40
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
41
+ },
40
42
  };
41
43
  });
42
44
 
@@ -30,7 +30,9 @@ describe(GenericRedisCacher, () => {
30
30
  cacheKeyPrefix: 'test-',
31
31
  ttlSecondsPositive: 86400, // 1 day
32
32
  ttlSecondsNegative: 600, // 10 minutes
33
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
33
+ invalidationConfig: {
34
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
35
+ },
34
36
  };
35
37
  });
36
38
 
@@ -28,7 +28,9 @@ describe(GenericRedisCacher, () => {
28
28
  cacheKeyPrefix: 'test-',
29
29
  ttlSecondsPositive: 86400, // 1 day
30
30
  ttlSecondsNegative: 600, // 10 minutes
31
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
31
+ invalidationConfig: {
32
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
33
+ },
32
34
  };
33
35
  });
34
36
 
@@ -44,7 +44,9 @@ describe(GenericRedisCacher, () => {
44
44
  cacheKeyPrefix: 'hello-',
45
45
  ttlSecondsPositive: 1,
46
46
  ttlSecondsNegative: 2,
47
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
47
+ invalidationConfig: {
48
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
49
+ },
48
50
  },
49
51
  entityConfiguration,
50
52
  );
@@ -84,7 +86,9 @@ describe(GenericRedisCacher, () => {
84
86
  cacheKeyPrefix: 'hello-',
85
87
  ttlSecondsPositive: 1,
86
88
  ttlSecondsNegative: 2,
87
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
89
+ invalidationConfig: {
90
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
91
+ },
88
92
  },
89
93
  entityConfiguration,
90
94
  );
@@ -117,7 +121,9 @@ describe(GenericRedisCacher, () => {
117
121
  cacheKeyPrefix: 'hello-',
118
122
  ttlSecondsPositive: 1,
119
123
  ttlSecondsNegative: 2,
120
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
124
+ invalidationConfig: {
125
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
126
+ },
121
127
  },
122
128
  entityConfiguration,
123
129
  );
@@ -160,7 +166,9 @@ describe(GenericRedisCacher, () => {
160
166
  cacheKeyPrefix: 'hello-',
161
167
  ttlSecondsPositive: 1,
162
168
  ttlSecondsNegative: 2,
163
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
169
+ invalidationConfig: {
170
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
171
+ },
164
172
  },
165
173
  entityConfiguration,
166
174
  );
@@ -192,7 +200,9 @@ describe(GenericRedisCacher, () => {
192
200
  cacheKeyPrefix: 'hello-',
193
201
  ttlSecondsPositive: 1,
194
202
  ttlSecondsNegative: 2,
195
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
203
+ invalidationConfig: {
204
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
205
+ },
196
206
  },
197
207
  entityConfiguration,
198
208
  );
@@ -201,6 +211,7 @@ describe(GenericRedisCacher, () => {
201
211
  new SingleFieldValueHolder('wat'),
202
212
  );
203
213
  expect(cacheKeys).toHaveLength(1);
214
+ expect(cacheKeys[0]).toBe('hello-:single:blah:v2.2:id:wat');
204
215
 
205
216
  await genericCacher.invalidateManyAsync(cacheKeys);
206
217
  verify(mockRedisClient.del(...cacheKeys)).once();
@@ -217,7 +228,9 @@ describe(GenericRedisCacher, () => {
217
228
  cacheKeyPrefix: 'hello-',
218
229
  ttlSecondsPositive: 1,
219
230
  ttlSecondsNegative: 2,
220
- invalidationStrategy: RedisCacheInvalidationStrategy.SURROUNDING_CACHE_KEY_VERSIONS,
231
+ invalidationConfig: {
232
+ invalidationStrategy: RedisCacheInvalidationStrategy.SURROUNDING_CACHE_KEY_VERSIONS,
233
+ },
221
234
  },
222
235
  entityConfiguration,
223
236
  );
@@ -226,6 +239,48 @@ describe(GenericRedisCacher, () => {
226
239
  new SingleFieldValueHolder('wat'),
227
240
  );
228
241
  expect(cacheKeys).toHaveLength(3);
242
+ expect(cacheKeys[0]).toBe('hello-:single:blah:v2.1:id:wat');
243
+ expect(cacheKeys[1]).toBe('hello-:single:blah:v2.2:id:wat');
244
+ expect(cacheKeys[2]).toBe('hello-:single:blah:v2.3:id:wat');
245
+
246
+ await genericCacher.invalidateManyAsync(cacheKeys);
247
+ verify(mockRedisClient.del(...cacheKeys)).once();
248
+ });
249
+
250
+ it('invalidates correctly with RedisCacheInvalidationStrategy.CUSTOM', async () => {
251
+ const mockRedisClient = mock<Redis>();
252
+ when(mockRedisClient.del()).thenResolve(1);
253
+
254
+ const genericCacher = new GenericRedisCacher(
255
+ {
256
+ redisClient: instance(mockRedisClient),
257
+ makeKeyFn: (...parts) => parts.join(':'),
258
+ cacheKeyPrefix: 'hello-',
259
+ ttlSecondsPositive: 1,
260
+ ttlSecondsNegative: 2,
261
+ invalidationConfig: {
262
+ invalidationStrategy: RedisCacheInvalidationStrategy.CUSTOM,
263
+ cacheKeyVersionsToInvalidateFn(cacheKeyVersion) {
264
+ return [
265
+ cacheKeyVersion,
266
+ cacheKeyVersion + 1,
267
+ cacheKeyVersion + 2,
268
+ cacheKeyVersion + 3,
269
+ ];
270
+ },
271
+ },
272
+ },
273
+ entityConfiguration,
274
+ );
275
+ const cacheKeys = genericCacher['makeCacheKeysForInvalidation'](
276
+ new SingleFieldHolder('id'),
277
+ new SingleFieldValueHolder('wat'),
278
+ );
279
+ expect(cacheKeys).toHaveLength(4);
280
+ expect(cacheKeys[0]).toBe('hello-:single:blah:v2.2:id:wat');
281
+ expect(cacheKeys[1]).toBe('hello-:single:blah:v2.3:id:wat');
282
+ expect(cacheKeys[2]).toBe('hello-:single:blah:v2.4:id:wat');
283
+ expect(cacheKeys[3]).toBe('hello-:single:blah:v2.5:id:wat');
229
284
 
230
285
  await genericCacher.invalidateManyAsync(cacheKeys);
231
286
  verify(mockRedisClient.del(...cacheKeys)).once();
@@ -239,7 +294,9 @@ describe(GenericRedisCacher, () => {
239
294
  cacheKeyPrefix: 'hello-',
240
295
  ttlSecondsPositive: 1,
241
296
  ttlSecondsNegative: 2,
242
- invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
297
+ invalidationConfig: {
298
+ invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
299
+ },
243
300
  },
244
301
  entityConfiguration,
245
302
  );