@expo/entity-cache-adapter-redis 0.43.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.
- package/build/GenericRedisCacher.d.ts +28 -3
- package/build/GenericRedisCacher.js +10 -1
- package/build/GenericRedisCacher.js.map +1 -1
- package/package.json +9 -9
- package/src/GenericRedisCacher.ts +40 -3
- package/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts +3 -1
- package/src/__integration-tests__/GenericRedisCacher-full-integration-test.ts +3 -1
- package/src/__integration-tests__/GenericRedisCacher-integration-test.ts +3 -1
- package/src/__integration-tests__/errors-test.ts +3 -1
- package/src/__tests__/GenericRedisCacher-test.ts +64 -7
|
@@ -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
|
-
*
|
|
78
|
+
* Configuration for cache invalidation strategy.
|
|
54
79
|
*/
|
|
55
|
-
|
|
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,
|
|
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.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"description": "Redis cache adapter for @expo/entity",
|
|
5
5
|
"files": [
|
|
6
6
|
"build",
|
|
@@ -28,27 +28,27 @@
|
|
|
28
28
|
"author": "Expo",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@expo/entity": "^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.
|
|
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",
|
|
42
|
-
"eslint": "^
|
|
43
|
-
"eslint-config-universe": "^
|
|
44
|
-
"eslint-plugin-tsdoc": "^0.
|
|
42
|
+
"eslint": "^9.26.0",
|
|
43
|
+
"eslint-config-universe": "^15.0.3",
|
|
44
|
+
"eslint-plugin-tsdoc": "^0.4.0",
|
|
45
45
|
"ioredis": "^5.6.0",
|
|
46
46
|
"jest": "^29.7.0",
|
|
47
|
-
"prettier": "^3.
|
|
47
|
+
"prettier": "^3.5.3",
|
|
48
48
|
"prettier-plugin-organize-imports": "^4.1.0",
|
|
49
|
-
"ts-jest": "^29.3.
|
|
49
|
+
"ts-jest": "^29.3.2",
|
|
50
50
|
"ts-mockito": "^2.6.1",
|
|
51
51
|
"typescript": "^5.8.3"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
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
|
-
*
|
|
111
|
+
* Configuration for cache invalidation strategy.
|
|
81
112
|
*/
|
|
82
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
297
|
+
invalidationConfig: {
|
|
298
|
+
invalidationStrategy: RedisCacheInvalidationStrategy.CURRENT_CACHE_KEY_VERSION,
|
|
299
|
+
},
|
|
243
300
|
},
|
|
244
301
|
entityConfiguration,
|
|
245
302
|
);
|