@expo/entity-cache-adapter-redis 0.55.0 → 0.58.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.
- package/README.md +1 -1
- package/build/src/GenericRedisCacher.js +1 -1
- package/package.json +5 -5
- package/src/GenericRedisCacher.ts +1 -1
- package/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts +10 -9
- package/src/__integration-tests__/GenericRedisCacher-full-integration-test.ts +10 -9
- package/src/__integration-tests__/GenericRedisCacher-integration-test.ts +1 -1
- package/src/__integration-tests__/errors-test.ts +1 -1
- package/src/__tests__/GenericRedisCacher-test.ts +10 -10
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ const genericRedisCacherContext = {
|
|
|
16
16
|
makeKeyFn(...parts: string[]): string {
|
|
17
17
|
const delimiter = ':';
|
|
18
18
|
const escapedParts = parts.map((part) =>
|
|
19
|
-
part.
|
|
19
|
+
part.replaceAll('\\', '\\\\').replaceAll(delimiter, `\\${delimiter}`)
|
|
20
20
|
);
|
|
21
21
|
return escapedParts.join(delimiter);
|
|
22
22
|
},
|
|
@@ -94,7 +94,7 @@ class GenericRedisCacher {
|
|
|
94
94
|
makeCacheKeyForCacheKeyVersion(key, value, cacheKeyVersion) {
|
|
95
95
|
const cacheKeyType = key.getLoadMethodType();
|
|
96
96
|
const parts = key.createCacheKeyPartsForLoadValue(this.entityConfiguration, value);
|
|
97
|
-
return this.context.makeKeyFn(this.context.cacheKeyPrefix, cacheKeyType, this.entityConfiguration.tableName, `
|
|
97
|
+
return this.context.makeKeyFn(this.context.cacheKeyPrefix, cacheKeyType, this.entityConfiguration.tableName, `v3.${cacheKeyVersion}`, ...parts);
|
|
98
98
|
}
|
|
99
99
|
makeCacheKeyForStorage(key, value) {
|
|
100
100
|
return this.makeCacheKeyForCacheKeyVersion(key, value, this.entityConfiguration.cacheKeyVersion);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/entity-cache-adapter-redis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.58.0",
|
|
4
4
|
"description": "Redis cache adapter for @expo/entity",
|
|
5
5
|
"files": [
|
|
6
6
|
"build",
|
|
@@ -28,18 +28,18 @@
|
|
|
28
28
|
"author": "Expo",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@expo/entity": "^0.
|
|
31
|
+
"@expo/entity": "^0.58.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.
|
|
38
|
+
"@expo/entity-testing-utils": "^0.58.0",
|
|
39
39
|
"@jest/globals": "30.2.0",
|
|
40
|
-
"ioredis": "5.
|
|
40
|
+
"ioredis": "5.10.0",
|
|
41
41
|
"ts-mockito": "2.6.1",
|
|
42
42
|
"typescript": "5.9.3"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "7dab49a36dafae2adba126ba6084512abab1afe1"
|
|
45
45
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Batcher } from '@expo/batcher';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
GenericEntityCacheAdapter,
|
|
4
4
|
SingleFieldHolder,
|
|
5
5
|
SingleFieldValueHolder,
|
|
6
6
|
ViewerContext,
|
|
@@ -80,7 +80,7 @@ describe(GenericRedisCacher, () => {
|
|
|
80
80
|
makeKeyFn(...parts: string[]): string {
|
|
81
81
|
const delimiter = ':';
|
|
82
82
|
const escapedParts = parts.map((part) =>
|
|
83
|
-
part.
|
|
83
|
+
part.replaceAll('\\', '\\\\').replaceAll(delimiter, `\\${delimiter}`),
|
|
84
84
|
);
|
|
85
85
|
return escapedParts.join(delimiter);
|
|
86
86
|
},
|
|
@@ -109,12 +109,11 @@ describe(GenericRedisCacher, () => {
|
|
|
109
109
|
|
|
110
110
|
const mgetSpy = jest.spyOn(redis, 'mget');
|
|
111
111
|
|
|
112
|
-
const genericCacher =
|
|
113
|
-
RedisTestEntity
|
|
114
|
-
|
|
115
|
-
RedisTestEntityFields,
|
|
116
|
-
|
|
117
|
-
>;
|
|
112
|
+
const genericCacher = (
|
|
113
|
+
viewerContext.entityCompanionProvider.getCompanionForEntity(RedisTestEntity)[
|
|
114
|
+
'tableDataCoordinator'
|
|
115
|
+
]['cacheAdapter'] as GenericEntityCacheAdapter<RedisTestEntityFields, 'id'>
|
|
116
|
+
)['genericCacher'];
|
|
118
117
|
|
|
119
118
|
const entity1Created = await RedisTestEntity.creator(viewerContext)
|
|
120
119
|
.setField('name', 'blah')
|
|
@@ -187,7 +186,9 @@ describe(GenericRedisCacher, () => {
|
|
|
187
186
|
expect(entityNonExistentResult2.ok).toBe(false);
|
|
188
187
|
|
|
189
188
|
// invalidate from cache to ensure it invalidates correctly in both caches
|
|
190
|
-
await RedisTestEntity.
|
|
189
|
+
await RedisTestEntity.invalidationUtils(viewerContext).invalidateFieldsAsync(
|
|
190
|
+
entity1.getAllFields(),
|
|
191
|
+
);
|
|
191
192
|
await expect(redis.get(cacheKeyEntity1)).resolves.toBeNull();
|
|
192
193
|
await expect(redis.get(cacheKeyEntity1NameField)).resolves.toBeNull();
|
|
193
194
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CompositeFieldHolder,
|
|
3
3
|
CompositeFieldValueHolder,
|
|
4
|
-
|
|
4
|
+
GenericEntityCacheAdapter,
|
|
5
5
|
SingleFieldHolder,
|
|
6
6
|
SingleFieldValueHolder,
|
|
7
7
|
ViewerContext,
|
|
@@ -31,7 +31,7 @@ describe(GenericRedisCacher, () => {
|
|
|
31
31
|
makeKeyFn(...parts: string[]): string {
|
|
32
32
|
const delimiter = ':';
|
|
33
33
|
const escapedParts = parts.map((part) =>
|
|
34
|
-
part.
|
|
34
|
+
part.replaceAll('\\', '\\\\').replaceAll(delimiter, `\\${delimiter}`),
|
|
35
35
|
);
|
|
36
36
|
return escapedParts.join(delimiter);
|
|
37
37
|
},
|
|
@@ -55,12 +55,11 @@ describe(GenericRedisCacher, () => {
|
|
|
55
55
|
const viewerContext = new TestViewerContext(
|
|
56
56
|
createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext),
|
|
57
57
|
);
|
|
58
|
-
const genericCacher =
|
|
59
|
-
RedisTestEntity
|
|
60
|
-
|
|
61
|
-
RedisTestEntityFields,
|
|
62
|
-
|
|
63
|
-
>;
|
|
58
|
+
const genericCacher = (
|
|
59
|
+
viewerContext.entityCompanionProvider.getCompanionForEntity(RedisTestEntity)[
|
|
60
|
+
'tableDataCoordinator'
|
|
61
|
+
]['cacheAdapter'] as GenericEntityCacheAdapter<RedisTestEntityFields, 'id'>
|
|
62
|
+
)['genericCacher'];
|
|
64
63
|
|
|
65
64
|
const entity1Created = await RedisTestEntity.creator(viewerContext)
|
|
66
65
|
.setField('name', 'blah')
|
|
@@ -144,7 +143,9 @@ describe(GenericRedisCacher, () => {
|
|
|
144
143
|
expect(entityNonExistentCompositeResult2).toBe(null);
|
|
145
144
|
|
|
146
145
|
// invalidate from cache to ensure it invalidates correctly
|
|
147
|
-
await RedisTestEntity.
|
|
146
|
+
await RedisTestEntity.invalidationUtils(viewerContext).invalidateFieldsAsync(
|
|
147
|
+
entity1.getAllFields(),
|
|
148
|
+
);
|
|
148
149
|
const cachedValueNullKeys = genericCacher.makeCacheKeysForInvalidation(
|
|
149
150
|
new SingleFieldHolder('id'),
|
|
150
151
|
new SingleFieldValueHolder(entity1.getID()),
|
|
@@ -26,7 +26,7 @@ describe(GenericRedisCacher, () => {
|
|
|
26
26
|
makeKeyFn(...parts: string[]): string {
|
|
27
27
|
const delimiter = ':';
|
|
28
28
|
const escapedParts = parts.map((part) =>
|
|
29
|
-
part.
|
|
29
|
+
part.replaceAll('\\', '\\\\').replaceAll(delimiter, `\\${delimiter}`),
|
|
30
30
|
);
|
|
31
31
|
return escapedParts.join(delimiter);
|
|
32
32
|
},
|
|
@@ -23,7 +23,7 @@ describe(GenericRedisCacher, () => {
|
|
|
23
23
|
makeKeyFn(...parts: string[]): string {
|
|
24
24
|
const delimiter = ':';
|
|
25
25
|
const escapedParts = parts.map((part) =>
|
|
26
|
-
part.
|
|
26
|
+
part.replaceAll('\\', '\\\\').replaceAll(delimiter, `\\${delimiter}`),
|
|
27
27
|
);
|
|
28
28
|
return escapedParts.join(delimiter);
|
|
29
29
|
},
|
|
@@ -109,7 +109,7 @@ describe(GenericRedisCacher, () => {
|
|
|
109
109
|
return pipeline;
|
|
110
110
|
},
|
|
111
111
|
);
|
|
112
|
-
when(mockPipeline.exec()).thenResolve(
|
|
112
|
+
when(mockPipeline.exec()).thenResolve([]);
|
|
113
113
|
const pipeline = instance(mockPipeline);
|
|
114
114
|
|
|
115
115
|
const mockRedisClient = mock<Redis>();
|
|
@@ -154,7 +154,7 @@ describe(GenericRedisCacher, () => {
|
|
|
154
154
|
return pipeline;
|
|
155
155
|
},
|
|
156
156
|
);
|
|
157
|
-
when(mockPipeline.exec()).thenResolve(
|
|
157
|
+
when(mockPipeline.exec()).thenResolve([]);
|
|
158
158
|
const pipeline = instance(mockPipeline);
|
|
159
159
|
|
|
160
160
|
const mockRedisClient = mock<Redis>();
|
|
@@ -212,7 +212,7 @@ describe(GenericRedisCacher, () => {
|
|
|
212
212
|
new SingleFieldValueHolder('wat'),
|
|
213
213
|
);
|
|
214
214
|
expect(cacheKeys).toHaveLength(1);
|
|
215
|
-
expect(cacheKeys[0]).toBe('hello-:single:blah:
|
|
215
|
+
expect(cacheKeys[0]).toBe('hello-:single:blah:v3.2:id:wat');
|
|
216
216
|
|
|
217
217
|
await genericCacher.invalidateManyAsync(cacheKeys);
|
|
218
218
|
verify(mockRedisClient.del(...cacheKeys)).once();
|
|
@@ -240,9 +240,9 @@ describe(GenericRedisCacher, () => {
|
|
|
240
240
|
new SingleFieldValueHolder('wat'),
|
|
241
241
|
);
|
|
242
242
|
expect(cacheKeys).toHaveLength(3);
|
|
243
|
-
expect(cacheKeys[0]).toBe('hello-:single:blah:
|
|
244
|
-
expect(cacheKeys[1]).toBe('hello-:single:blah:
|
|
245
|
-
expect(cacheKeys[2]).toBe('hello-:single:blah:
|
|
243
|
+
expect(cacheKeys[0]).toBe('hello-:single:blah:v3.1:id:wat');
|
|
244
|
+
expect(cacheKeys[1]).toBe('hello-:single:blah:v3.2:id:wat');
|
|
245
|
+
expect(cacheKeys[2]).toBe('hello-:single:blah:v3.3:id:wat');
|
|
246
246
|
|
|
247
247
|
await genericCacher.invalidateManyAsync(cacheKeys);
|
|
248
248
|
verify(mockRedisClient.del(...cacheKeys)).once();
|
|
@@ -278,10 +278,10 @@ describe(GenericRedisCacher, () => {
|
|
|
278
278
|
new SingleFieldValueHolder('wat'),
|
|
279
279
|
);
|
|
280
280
|
expect(cacheKeys).toHaveLength(4);
|
|
281
|
-
expect(cacheKeys[0]).toBe('hello-:single:blah:
|
|
282
|
-
expect(cacheKeys[1]).toBe('hello-:single:blah:
|
|
283
|
-
expect(cacheKeys[2]).toBe('hello-:single:blah:
|
|
284
|
-
expect(cacheKeys[3]).toBe('hello-:single:blah:
|
|
281
|
+
expect(cacheKeys[0]).toBe('hello-:single:blah:v3.2:id:wat');
|
|
282
|
+
expect(cacheKeys[1]).toBe('hello-:single:blah:v3.3:id:wat');
|
|
283
|
+
expect(cacheKeys[2]).toBe('hello-:single:blah:v3.4:id:wat');
|
|
284
|
+
expect(cacheKeys[3]).toBe('hello-:single:blah:v3.5:id:wat');
|
|
285
285
|
|
|
286
286
|
await genericCacher.invalidateManyAsync(cacheKeys);
|
|
287
287
|
verify(mockRedisClient.del(...cacheKeys)).once();
|