@expo/entity-cache-adapter-redis 0.45.0 → 0.47.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 → src/GenericRedisCacher.d.ts} +1 -1
- package/build/{GenericRedisCacher.js → src/GenericRedisCacher.js} +7 -10
- package/build/src/GenericRedisCacher.js.map +1 -0
- package/build/{RedisCacheAdapterProvider.d.ts → src/RedisCacheAdapterProvider.d.ts} +2 -2
- package/build/src/RedisCacheAdapterProvider.js +16 -0
- package/build/src/RedisCacheAdapterProvider.js.map +1 -0
- package/build/{RedisCommon.d.ts → src/RedisCommon.d.ts} +17 -0
- package/build/{RedisCommon.js → src/RedisCommon.js} +21 -0
- package/build/src/RedisCommon.js.map +1 -0
- package/build/src/errors/wrapNativeRedisCallAsync.d.ts +1 -0
- package/build/{errors → src/errors}/wrapNativeRedisCallAsync.js +1 -1
- package/build/src/errors/wrapNativeRedisCallAsync.js.map +1 -0
- package/build/src/index.d.ts +9 -0
- package/build/{index.js → src/index.js} +2 -10
- package/build/src/index.js.map +1 -0
- package/build/src/utils/getSurroundingCacheKeyVersionsForInvalidation.js.map +1 -0
- package/package.json +16 -26
- package/src/GenericRedisCacher.ts +5 -7
- package/src/RedisCacheAdapterProvider.ts +4 -4
- package/src/RedisCommon.ts +22 -1
- package/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts +5 -3
- package/src/__integration-tests__/GenericRedisCacher-full-integration-test.ts +29 -2
- package/src/__integration-tests__/GenericRedisCacher-integration-test.ts +11 -2
- package/src/__integration-tests__/errors-test.ts +4 -2
- package/src/__testfixtures__/RedisTestEntity.ts +13 -6
- package/src/__testfixtures__/createRedisIntegrationTestEntityCompanionProvider.ts +3 -3
- package/src/__tests__/GenericRedisCacher-test.ts +4 -3
- package/src/errors/__tests__/wrapNativeRedisCallAsync-test.ts +2 -1
- package/src/errors/wrapNativeRedisCallAsync.ts +1 -1
- package/src/index.ts +2 -3
- package/src/utils/__tests__/getSurroundingCacheKeyVersionsForInvalidation-test.ts +2 -0
- package/LICENSE +0 -21
- package/build/GenericRedisCacher.js.map +0 -1
- package/build/RedisCacheAdapterProvider.js +0 -18
- package/build/RedisCacheAdapterProvider.js.map +0 -1
- package/build/RedisCommon.js.map +0 -1
- package/build/errors/wrapNativeRedisCallAsync.d.ts +0 -1
- package/build/errors/wrapNativeRedisCallAsync.js.map +0 -1
- package/build/index.d.ts +0 -10
- package/build/index.js.map +0 -1
- package/build/tsconfig.build.tsbuildinfo +0 -1
- package/build/utils/getSurroundingCacheKeyVersionsForInvalidation.js.map +0 -1
- /package/build/{utils → src/utils}/getSurroundingCacheKeyVersionsForInvalidation.d.ts +0 -0
- /package/build/{utils → src/utils}/getSurroundingCacheKeyVersionsForInvalidation.js +0 -0
|
@@ -79,7 +79,7 @@ export interface GenericRedisCacheContext {
|
|
|
79
79
|
*/
|
|
80
80
|
invalidationConfig: GenericRedisCacheInvalidationConfig;
|
|
81
81
|
}
|
|
82
|
-
export
|
|
82
|
+
export declare class GenericRedisCacher<TFields extends Record<string, any>, TIDField extends keyof TFields> implements IEntityGenericCacher<TFields, TIDField> {
|
|
83
83
|
private readonly context;
|
|
84
84
|
private readonly entityConfiguration;
|
|
85
85
|
constructor(context: GenericRedisCacheContext, entityConfiguration: EntityConfiguration<TFields, TIDField>);
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RedisCacheInvalidationStrategy = void 0;
|
|
3
|
+
exports.GenericRedisCacher = exports.RedisCacheInvalidationStrategy = void 0;
|
|
7
4
|
const entity_1 = require("@expo/entity");
|
|
8
5
|
const RedisCommon_1 = require("./RedisCommon");
|
|
9
|
-
const wrapNativeRedisCallAsync_1 =
|
|
6
|
+
const wrapNativeRedisCallAsync_1 = require("./errors/wrapNativeRedisCallAsync");
|
|
10
7
|
const getSurroundingCacheKeyVersionsForInvalidation_1 = require("./utils/getSurroundingCacheKeyVersionsForInvalidation");
|
|
11
8
|
// Sentinel value we store in Redis to negatively cache a database miss.
|
|
12
9
|
// The sentinel value is distinct from any (positively) cached value.
|
|
@@ -44,7 +41,7 @@ class GenericRedisCacher {
|
|
|
44
41
|
if (keys.length === 0) {
|
|
45
42
|
return new Map();
|
|
46
43
|
}
|
|
47
|
-
const redisResults = await (0, wrapNativeRedisCallAsync_1.
|
|
44
|
+
const redisResults = await (0, wrapNativeRedisCallAsync_1.wrapNativeRedisCallAsync)(() => this.context.redisClient.mget(...keys));
|
|
48
45
|
const results = new Map();
|
|
49
46
|
for (let i = 0; i < keys.length; i++) {
|
|
50
47
|
const key = keys[i];
|
|
@@ -76,7 +73,7 @@ class GenericRedisCacher {
|
|
|
76
73
|
objectMap.forEach((object, key) => {
|
|
77
74
|
redisTransaction = redisTransaction.set(key, JSON.stringify((0, entity_1.transformFieldsToCacheObject)(this.entityConfiguration, RedisCommon_1.redisTransformerMap, object)), 'EX', this.context.ttlSecondsPositive);
|
|
78
75
|
});
|
|
79
|
-
await (0, wrapNativeRedisCallAsync_1.
|
|
76
|
+
await (0, wrapNativeRedisCallAsync_1.wrapNativeRedisCallAsync)(() => redisTransaction.exec());
|
|
80
77
|
}
|
|
81
78
|
async cacheDBMissesAsync(keys) {
|
|
82
79
|
if (keys.length === 0) {
|
|
@@ -86,13 +83,13 @@ class GenericRedisCacher {
|
|
|
86
83
|
keys.forEach((key) => {
|
|
87
84
|
redisTransaction = redisTransaction.set(key, DOES_NOT_EXIST_REDIS, 'EX', this.context.ttlSecondsNegative);
|
|
88
85
|
});
|
|
89
|
-
await (0, wrapNativeRedisCallAsync_1.
|
|
86
|
+
await (0, wrapNativeRedisCallAsync_1.wrapNativeRedisCallAsync)(() => redisTransaction.exec());
|
|
90
87
|
}
|
|
91
88
|
async invalidateManyAsync(keys) {
|
|
92
89
|
if (keys.length === 0) {
|
|
93
90
|
return;
|
|
94
91
|
}
|
|
95
|
-
await (0, wrapNativeRedisCallAsync_1.
|
|
92
|
+
await (0, wrapNativeRedisCallAsync_1.wrapNativeRedisCallAsync)(() => this.context.redisClient.del(...keys));
|
|
96
93
|
}
|
|
97
94
|
makeCacheKeyForCacheKeyVersion(key, value, cacheKeyVersion) {
|
|
98
95
|
const cacheKeyType = key.getLoadMethodType();
|
|
@@ -117,5 +114,5 @@ class GenericRedisCacher {
|
|
|
117
114
|
}
|
|
118
115
|
}
|
|
119
116
|
}
|
|
120
|
-
exports.
|
|
117
|
+
exports.GenericRedisCacher = GenericRedisCacher;
|
|
121
118
|
//# sourceMappingURL=GenericRedisCacher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenericRedisCacher.js","sourceRoot":"","sources":["../../src/GenericRedisCacher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityConfiguration, IEntityCacheAdapter, IEntityCacheAdapterProvider } from '@expo/entity';
|
|
2
2
|
import { GenericRedisCacheContext } from './GenericRedisCacher';
|
|
3
|
-
export
|
|
3
|
+
export declare class RedisCacheAdapterProvider implements IEntityCacheAdapterProvider {
|
|
4
4
|
private readonly context;
|
|
5
5
|
constructor(context: GenericRedisCacheContext);
|
|
6
6
|
getCacheAdapter<TFields extends Record<string, any>, TIDField extends keyof TFields>(entityConfiguration: EntityConfiguration<TFields, TIDField>): IEntityCacheAdapter<TFields, TIDField>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisCacheAdapterProvider = void 0;
|
|
4
|
+
const entity_1 = require("@expo/entity");
|
|
5
|
+
const GenericRedisCacher_1 = require("./GenericRedisCacher");
|
|
6
|
+
class RedisCacheAdapterProvider {
|
|
7
|
+
context;
|
|
8
|
+
constructor(context) {
|
|
9
|
+
this.context = context;
|
|
10
|
+
}
|
|
11
|
+
getCacheAdapter(entityConfiguration) {
|
|
12
|
+
return new entity_1.GenericEntityCacheAdapter(new GenericRedisCacher_1.GenericRedisCacher(this.context, entityConfiguration));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.RedisCacheAdapterProvider = RedisCacheAdapterProvider;
|
|
16
|
+
//# sourceMappingURL=RedisCacheAdapterProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisCacheAdapterProvider.js","sourceRoot":"","sources":["../../src/RedisCacheAdapterProvider.ts"],"names":[],"mappings":";;;AAAA,yCAKsB;AAEtB,6DAAoF;AAEpF,MAAa,yBAAyB;IACP;IAA7B,YAA6B,OAAiC;QAAjC,YAAO,GAAP,OAAO,CAA0B;IAAG,CAAC;IAElE,eAAe,CACb,mBAA2D;QAE3D,OAAO,IAAI,kCAAyB,CAAC,IAAI,uCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAClG,CAAC;CACF;AARD,8DAQC"}
|
|
@@ -15,4 +15,21 @@ export declare const redisTransformerMap: Map<string, {
|
|
|
15
15
|
*/
|
|
16
16
|
write: (val: Date) => string;
|
|
17
17
|
read: (val: any) => any;
|
|
18
|
+
} | {
|
|
19
|
+
/**
|
|
20
|
+
* All Redis fields are serialized to JSON before being written.
|
|
21
|
+
* In the case of buffers, they need to be explicitly reconstructed
|
|
22
|
+
* as JavaScript Buffer objects upon retrieval. We also explicitly
|
|
23
|
+
* serialize them to base64 strings to ensure no underlying Redis
|
|
24
|
+
* changes affect the fields.
|
|
25
|
+
*
|
|
26
|
+
* Write behavior: Value to write will always be either a Buffer or null.
|
|
27
|
+
* Behavior is to pass through null and convert buffers
|
|
28
|
+
* to base64 strings.
|
|
29
|
+
* Read behavior: Value will always be either null or a base64 string.
|
|
30
|
+
* behavior is to convert base64 strings back into Buffer
|
|
31
|
+
* objects and pass through null.
|
|
32
|
+
*/
|
|
33
|
+
write: (val: Buffer) => string | null;
|
|
34
|
+
read: (val: any) => any;
|
|
18
35
|
}>;
|
|
@@ -24,5 +24,26 @@ exports.redisTransformerMap = new Map([
|
|
|
24
24
|
read: (val) => (val ? new Date(val) : val),
|
|
25
25
|
},
|
|
26
26
|
],
|
|
27
|
+
[
|
|
28
|
+
entity_1.BufferField.name,
|
|
29
|
+
{
|
|
30
|
+
/**
|
|
31
|
+
* All Redis fields are serialized to JSON before being written.
|
|
32
|
+
* In the case of buffers, they need to be explicitly reconstructed
|
|
33
|
+
* as JavaScript Buffer objects upon retrieval. We also explicitly
|
|
34
|
+
* serialize them to base64 strings to ensure no underlying Redis
|
|
35
|
+
* changes affect the fields.
|
|
36
|
+
*
|
|
37
|
+
* Write behavior: Value to write will always be either a Buffer or null.
|
|
38
|
+
* Behavior is to pass through null and convert buffers
|
|
39
|
+
* to base64 strings.
|
|
40
|
+
* Read behavior: Value will always be either null or a base64 string.
|
|
41
|
+
* behavior is to convert base64 strings back into Buffer
|
|
42
|
+
* objects and pass through null.
|
|
43
|
+
*/
|
|
44
|
+
write: (val) => (val ? val.toString('base64') : null),
|
|
45
|
+
read: (val) => (val ? Buffer.from(val, 'base64') : val),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
27
48
|
]);
|
|
28
49
|
//# sourceMappingURL=RedisCommon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisCommon.js","sourceRoot":"","sources":["../../src/RedisCommon.ts"],"names":[],"mappings":";;;AAAA,yCAAsD;AAEzC,QAAA,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACzC;QACE,kBAAS,CAAC,IAAI;QACd;YACE;;;;;;;;;;;;;eAaG;YACH,KAAK,EAAE,CAAC,GAAS,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,IAAI;YAChD,IAAI,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;SAChD;KACF;IACD;QACE,oBAAW,CAAC,IAAI;QAChB;YACE;;;;;;;;;;;;;eAaG;YACH,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7D,IAAI,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;SAC7D;KACF;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function wrapNativeRedisCallAsync<T>(fn: () => Promise<T>): Promise<T>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.wrapNativeRedisCallAsync = wrapNativeRedisCallAsync;
|
|
4
4
|
const entity_1 = require("@expo/entity");
|
|
5
5
|
async function wrapNativeRedisCallAsync(fn) {
|
|
6
6
|
try {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapNativeRedisCallAsync.js","sourceRoot":"","sources":["../../../src/errors/wrapNativeRedisCallAsync.ts"],"names":[],"mappings":";;AAEA,4DAcC;AAhBD,yCAAgE;AAEzD,KAAK,UAAU,wBAAwB,CAAI,EAAoB;IACpE,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,CAAC;QACV,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,yCAAgC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACZ,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QACxB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* @module @expo/entity-cache-adapter-redis
|
|
4
|
+
*/
|
|
5
|
+
export * from './GenericRedisCacher';
|
|
6
|
+
export * from './RedisCacheAdapterProvider';
|
|
7
|
+
export * from './RedisCommon';
|
|
8
|
+
export * from './errors/wrapNativeRedisCallAsync';
|
|
9
|
+
export * from './utils/getSurroundingCacheKeyVersionsForInvalidation';
|
|
@@ -18,18 +18,10 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
18
18
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
19
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
20
|
};
|
|
21
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
-
};
|
|
24
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.wrapNativeRedisCallAsync = exports.RedisCacheAdapterProvider = exports.GenericRedisCacher = void 0;
|
|
26
|
-
var GenericRedisCacher_1 = require("./GenericRedisCacher");
|
|
27
|
-
Object.defineProperty(exports, "GenericRedisCacher", { enumerable: true, get: function () { return __importDefault(GenericRedisCacher_1).default; } });
|
|
28
22
|
__exportStar(require("./GenericRedisCacher"), exports);
|
|
29
|
-
|
|
30
|
-
Object.defineProperty(exports, "RedisCacheAdapterProvider", { enumerable: true, get: function () { return __importDefault(RedisCacheAdapterProvider_1).default; } });
|
|
23
|
+
__exportStar(require("./RedisCacheAdapterProvider"), exports);
|
|
31
24
|
__exportStar(require("./RedisCommon"), exports);
|
|
32
|
-
|
|
33
|
-
Object.defineProperty(exports, "wrapNativeRedisCallAsync", { enumerable: true, get: function () { return __importDefault(wrapNativeRedisCallAsync_1).default; } });
|
|
25
|
+
__exportStar(require("./errors/wrapNativeRedisCallAsync"), exports);
|
|
34
26
|
__exportStar(require("./utils/getSurroundingCacheKeyVersionsForInvalidation"), exports);
|
|
35
27
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,iCAAiC;AACjC;;;GAGG;;;;;;;;;;;;;;;;AAEH,uDAAqC;AACrC,8DAA4C;AAC5C,gDAA8B;AAC9B,oEAAkD;AAClD,wFAAsE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSurroundingCacheKeyVersionsForInvalidation.js","sourceRoot":"","sources":["../../../src/utils/getSurroundingCacheKeyVersionsForInvalidation.ts"],"names":[],"mappings":";;AAAA,sGAQC;AARD,SAAgB,6CAA6C,CAC3D,eAAuB;IAEvB,OAAO;QACL,GAAG,CAAC,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;QACvD,eAAe;QACf,eAAe,GAAG,CAAC;KACpB,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/entity-cache-adapter-redis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0",
|
|
4
4
|
"description": "Redis cache adapter for @expo/entity",
|
|
5
5
|
"files": [
|
|
6
6
|
"build",
|
|
7
|
+
"!*.tsbuildinfo",
|
|
8
|
+
"!__*",
|
|
7
9
|
"src"
|
|
8
10
|
],
|
|
9
|
-
"main": "build/index.js",
|
|
10
|
-
"types": "build/index.d.ts",
|
|
11
|
+
"main": "build/src/index.js",
|
|
12
|
+
"types": "build/src/index.d.ts",
|
|
11
13
|
"scripts": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"clean": "
|
|
15
|
-
"lint": "eslint src",
|
|
16
|
-
"lint-fix": "
|
|
17
|
-
"test": "
|
|
18
|
-
"integration": "
|
|
19
|
-
"integration-no-setup": "jest --config ../../resources/jest-integration.config.js --rootDir . --runInBand --passWithNoTests",
|
|
20
|
-
"ctix": "ctix build --config ../../.ctirc && ../../resources/prepend-barrel.sh '@expo/entity-cache-adapter-redis'"
|
|
14
|
+
"build": "tsc --build",
|
|
15
|
+
"prepack": "rm -rf build && yarn build",
|
|
16
|
+
"clean": "yarn build --clean",
|
|
17
|
+
"lint": "yarn run --top-level eslint src",
|
|
18
|
+
"lint-fix": "yarn lint --fix",
|
|
19
|
+
"test": "yarn test:all --rootDir $(pwd)",
|
|
20
|
+
"integration": "yarn integration:all --rootDir $(pwd)"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=16"
|
|
@@ -28,27 +28,17 @@
|
|
|
28
28
|
"author": "Expo",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@expo/entity": "
|
|
31
|
+
"@expo/entity": "workspace:^"
|
|
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": "
|
|
39
|
-
"@
|
|
40
|
-
"@types/node": "^20.14.1",
|
|
41
|
-
"ctix": "^2.7.0",
|
|
42
|
-
"eslint": "^9.26.0",
|
|
43
|
-
"eslint-config-universe": "^15.0.3",
|
|
44
|
-
"eslint-plugin-tsdoc": "^0.4.0",
|
|
38
|
+
"@expo/entity-testing-utils": "workspace:^",
|
|
39
|
+
"@jest/globals": "^30.0.0",
|
|
45
40
|
"ioredis": "^5.6.0",
|
|
46
|
-
"jest": "^29.7.0",
|
|
47
|
-
"prettier": "^3.5.3",
|
|
48
|
-
"prettier-plugin-organize-imports": "^4.1.0",
|
|
49
|
-
"ts-jest": "^29.3.2",
|
|
50
41
|
"ts-mockito": "^2.6.1",
|
|
51
42
|
"typescript": "^5.8.3"
|
|
52
|
-
}
|
|
53
|
-
"gitHead": "fe2d246f87adc98a13cc7c1ae57f3628769560c9"
|
|
43
|
+
}
|
|
54
44
|
}
|
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
CacheLoadResult,
|
|
3
3
|
CacheStatus,
|
|
4
4
|
EntityConfiguration,
|
|
5
|
-
transformCacheObjectToFields,
|
|
6
|
-
transformFieldsToCacheObject,
|
|
7
5
|
IEntityGenericCacher,
|
|
8
6
|
IEntityLoadKey,
|
|
9
7
|
IEntityLoadValue,
|
|
8
|
+
transformCacheObjectToFields,
|
|
9
|
+
transformFieldsToCacheObject,
|
|
10
10
|
} from '@expo/entity';
|
|
11
11
|
|
|
12
12
|
import { redisTransformerMap } from './RedisCommon';
|
|
13
|
-
import wrapNativeRedisCallAsync from './errors/wrapNativeRedisCallAsync';
|
|
13
|
+
import { wrapNativeRedisCallAsync } from './errors/wrapNativeRedisCallAsync';
|
|
14
14
|
import { getSurroundingCacheKeyVersionsForInvalidation } from './utils/getSurroundingCacheKeyVersionsForInvalidation';
|
|
15
15
|
|
|
16
16
|
// Sentinel value we store in Redis to negatively cache a database miss.
|
|
@@ -113,10 +113,8 @@ export interface GenericRedisCacheContext {
|
|
|
113
113
|
invalidationConfig: GenericRedisCacheInvalidationConfig;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
export
|
|
117
|
-
|
|
118
|
-
TIDField extends keyof TFields,
|
|
119
|
-
> implements IEntityGenericCacher<TFields, TIDField>
|
|
116
|
+
export class GenericRedisCacher<TFields extends Record<string, any>, TIDField extends keyof TFields>
|
|
117
|
+
implements IEntityGenericCacher<TFields, TIDField>
|
|
120
118
|
{
|
|
121
119
|
constructor(
|
|
122
120
|
private readonly context: GenericRedisCacheContext,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
IEntityCacheAdapterProvider,
|
|
3
2
|
EntityConfiguration,
|
|
4
|
-
IEntityCacheAdapter,
|
|
5
3
|
GenericEntityCacheAdapter,
|
|
4
|
+
IEntityCacheAdapter,
|
|
5
|
+
IEntityCacheAdapterProvider,
|
|
6
6
|
} from '@expo/entity';
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import { GenericRedisCacheContext, GenericRedisCacher } from './GenericRedisCacher';
|
|
9
9
|
|
|
10
|
-
export
|
|
10
|
+
export class RedisCacheAdapterProvider implements IEntityCacheAdapterProvider {
|
|
11
11
|
constructor(private readonly context: GenericRedisCacheContext) {}
|
|
12
12
|
|
|
13
13
|
getCacheAdapter<TFields extends Record<string, any>, TIDField extends keyof TFields>(
|
package/src/RedisCommon.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DateField } from '@expo/entity';
|
|
1
|
+
import { BufferField, DateField } from '@expo/entity';
|
|
2
2
|
|
|
3
3
|
export const redisTransformerMap = new Map([
|
|
4
4
|
[
|
|
@@ -22,4 +22,25 @@ export const redisTransformerMap = new Map([
|
|
|
22
22
|
read: (val: any) => (val ? new Date(val) : val),
|
|
23
23
|
},
|
|
24
24
|
],
|
|
25
|
+
[
|
|
26
|
+
BufferField.name,
|
|
27
|
+
{
|
|
28
|
+
/**
|
|
29
|
+
* All Redis fields are serialized to JSON before being written.
|
|
30
|
+
* In the case of buffers, they need to be explicitly reconstructed
|
|
31
|
+
* as JavaScript Buffer objects upon retrieval. We also explicitly
|
|
32
|
+
* serialize them to base64 strings to ensure no underlying Redis
|
|
33
|
+
* changes affect the fields.
|
|
34
|
+
*
|
|
35
|
+
* Write behavior: Value to write will always be either a Buffer or null.
|
|
36
|
+
* Behavior is to pass through null and convert buffers
|
|
37
|
+
* to base64 strings.
|
|
38
|
+
* Read behavior: Value will always be either null or a base64 string.
|
|
39
|
+
* behavior is to convert base64 strings back into Buffer
|
|
40
|
+
* objects and pass through null.
|
|
41
|
+
*/
|
|
42
|
+
write: (val: Buffer) => (val ? val.toString('base64') : null),
|
|
43
|
+
read: (val: any) => (val ? Buffer.from(val, 'base64') : val),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
25
46
|
]);
|
|
@@ -6,19 +6,21 @@ import {
|
|
|
6
6
|
ViewerContext,
|
|
7
7
|
zipToMap,
|
|
8
8
|
} from '@expo/entity';
|
|
9
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
|
9
10
|
import invariant from 'invariant';
|
|
10
11
|
import Redis from 'ioredis';
|
|
11
12
|
import nullthrows from 'nullthrows';
|
|
12
13
|
import { URL } from 'url';
|
|
13
14
|
import { v4 as uuidv4 } from 'uuid';
|
|
14
15
|
|
|
15
|
-
import
|
|
16
|
+
import {
|
|
17
|
+
GenericRedisCacheContext,
|
|
18
|
+
GenericRedisCacher,
|
|
16
19
|
IRedis,
|
|
17
20
|
IRedisTransaction,
|
|
18
|
-
GenericRedisCacheContext,
|
|
19
21
|
RedisCacheInvalidationStrategy,
|
|
20
22
|
} from '../GenericRedisCacher';
|
|
21
|
-
import RedisTestEntity,
|
|
23
|
+
import { RedisTestEntity, RedisTestEntityFields } from '../__testfixtures__/RedisTestEntity';
|
|
22
24
|
import { createRedisIntegrationTestEntityCompanionProvider } from '../__testfixtures__/createRedisIntegrationTestEntityCompanionProvider';
|
|
23
25
|
|
|
24
26
|
class BatchedRedis implements IRedis {
|
|
@@ -7,15 +7,17 @@ import {
|
|
|
7
7
|
ViewerContext,
|
|
8
8
|
} from '@expo/entity';
|
|
9
9
|
import { enforceAsyncResult } from '@expo/results';
|
|
10
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, it } from '@jest/globals';
|
|
10
11
|
import Redis from 'ioredis';
|
|
11
12
|
import { URL } from 'url';
|
|
12
13
|
import { v4 as uuidv4 } from 'uuid';
|
|
13
14
|
|
|
14
|
-
import
|
|
15
|
+
import {
|
|
15
16
|
GenericRedisCacheContext,
|
|
17
|
+
GenericRedisCacher,
|
|
16
18
|
RedisCacheInvalidationStrategy,
|
|
17
19
|
} from '../GenericRedisCacher';
|
|
18
|
-
import RedisTestEntity,
|
|
20
|
+
import { RedisTestEntity, RedisTestEntityFields } from '../__testfixtures__/RedisTestEntity';
|
|
19
21
|
import { createRedisIntegrationTestEntityCompanionProvider } from '../__testfixtures__/createRedisIntegrationTestEntityCompanionProvider';
|
|
20
22
|
|
|
21
23
|
class TestViewerContext extends ViewerContext {}
|
|
@@ -62,6 +64,8 @@ describe(GenericRedisCacher, () => {
|
|
|
62
64
|
|
|
63
65
|
const entity1Created = await RedisTestEntity.creator(viewerContext)
|
|
64
66
|
.setField('name', 'blah')
|
|
67
|
+
.setField('dateField', new Date())
|
|
68
|
+
.setField('bufferField', Buffer.from('hello world'))
|
|
65
69
|
.createAsync();
|
|
66
70
|
|
|
67
71
|
// loading an entity should put it in cache
|
|
@@ -205,4 +209,27 @@ describe(GenericRedisCacher, () => {
|
|
|
205
209
|
const entity3 = await RedisTestEntity.loader(vc2).loadByFieldEqualingAsync('name', '');
|
|
206
210
|
expect(entity3?.getID()).toEqual(entity1.getID());
|
|
207
211
|
});
|
|
212
|
+
|
|
213
|
+
it('caches and restores buffer fields', async () => {
|
|
214
|
+
const viewerContext = new TestViewerContext(
|
|
215
|
+
createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext),
|
|
216
|
+
);
|
|
217
|
+
const buffer = Buffer.from('hello world');
|
|
218
|
+
const entity1 = await enforceAsyncResult(
|
|
219
|
+
RedisTestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
220
|
+
.setField('bufferField', buffer)
|
|
221
|
+
.createAsync(),
|
|
222
|
+
);
|
|
223
|
+
expect(entity1.getField('bufferField')).toEqual(buffer);
|
|
224
|
+
|
|
225
|
+
const entity2 = await RedisTestEntity.loader(viewerContext).loadByIDAsync(entity1.getID());
|
|
226
|
+
expect(entity2.getField('bufferField')).toEqual(buffer);
|
|
227
|
+
|
|
228
|
+
// simulate new request
|
|
229
|
+
const vc2 = new TestViewerContext(
|
|
230
|
+
createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext),
|
|
231
|
+
);
|
|
232
|
+
const entity3 = await RedisTestEntity.loader(vc2).loadByIDAsync(entity1.getID());
|
|
233
|
+
expect(entity3.getField('bufferField')).toEqual(buffer);
|
|
234
|
+
});
|
|
208
235
|
});
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { CacheStatus, ViewerContext } from '@expo/entity';
|
|
2
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, it } from '@jest/globals';
|
|
2
3
|
import Redis from 'ioredis';
|
|
3
4
|
import { URL } from 'url';
|
|
4
5
|
|
|
5
|
-
import
|
|
6
|
+
import {
|
|
6
7
|
GenericRedisCacheContext,
|
|
8
|
+
GenericRedisCacher,
|
|
7
9
|
RedisCacheInvalidationStrategy,
|
|
8
10
|
} from '../GenericRedisCacher';
|
|
9
|
-
import
|
|
11
|
+
import {
|
|
12
|
+
RedisTestEntity,
|
|
10
13
|
redisTestEntityConfiguration,
|
|
11
14
|
RedisTestEntityFields,
|
|
12
15
|
} from '../__testfixtures__/RedisTestEntity';
|
|
@@ -52,9 +55,11 @@ describe(GenericRedisCacher, () => {
|
|
|
52
55
|
redisTestEntityConfiguration,
|
|
53
56
|
);
|
|
54
57
|
const date = new Date();
|
|
58
|
+
const buffer = Buffer.from('hello world');
|
|
55
59
|
const entity1Created = await RedisTestEntity.creator(viewerContext)
|
|
56
60
|
.setField('name', 'blah')
|
|
57
61
|
.setField('dateField', date)
|
|
62
|
+
.setField('bufferField', buffer)
|
|
58
63
|
.createAsync();
|
|
59
64
|
const testKey = `test-id-key-${entity1Created.getID()}`;
|
|
60
65
|
const objectMap = new Map<string, Readonly<RedisTestEntityFields>>([
|
|
@@ -77,6 +82,7 @@ describe(GenericRedisCacher, () => {
|
|
|
77
82
|
});
|
|
78
83
|
expect(loadedObjectMap.size).toBe(1);
|
|
79
84
|
});
|
|
85
|
+
|
|
80
86
|
it('has correct negative caching behaviour', async () => {
|
|
81
87
|
const genericRedisCacher = new GenericRedisCacher(
|
|
82
88
|
genericRedisCacheContext,
|
|
@@ -89,6 +95,7 @@ describe(GenericRedisCacher, () => {
|
|
|
89
95
|
const cacheLoadResult = loadedObjectMap.get(testKey)!;
|
|
90
96
|
expect(cacheLoadResult.status).toBe(CacheStatus.NEGATIVE);
|
|
91
97
|
});
|
|
98
|
+
|
|
92
99
|
it('has correct invalidation behaviour', async () => {
|
|
93
100
|
const viewerContext = new TestViewerContext(
|
|
94
101
|
createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext),
|
|
@@ -98,9 +105,11 @@ describe(GenericRedisCacher, () => {
|
|
|
98
105
|
redisTestEntityConfiguration,
|
|
99
106
|
);
|
|
100
107
|
const date = new Date();
|
|
108
|
+
const buffer = Buffer.from('hello world');
|
|
101
109
|
const entity1Created = await RedisTestEntity.creator(viewerContext)
|
|
102
110
|
.setField('name', 'blah')
|
|
103
111
|
.setField('dateField', date)
|
|
112
|
+
.setField('bufferField', buffer)
|
|
104
113
|
.createAsync();
|
|
105
114
|
const testKey = `test-id-key-${entity1Created.getID()}`;
|
|
106
115
|
const objectMap = new Map<string, Readonly<RedisTestEntityFields>>([
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { EntityCacheAdapterTransientError, ViewerContext } from '@expo/entity';
|
|
2
|
+
import { beforeAll, beforeEach, describe, expect, it } from '@jest/globals';
|
|
2
3
|
import Redis from 'ioredis';
|
|
3
4
|
import { URL } from 'url';
|
|
4
5
|
|
|
5
|
-
import
|
|
6
|
+
import {
|
|
6
7
|
GenericRedisCacheContext,
|
|
8
|
+
GenericRedisCacher,
|
|
7
9
|
RedisCacheInvalidationStrategy,
|
|
8
10
|
} from '../GenericRedisCacher';
|
|
9
|
-
import RedisTestEntity from '../__testfixtures__/RedisTestEntity';
|
|
11
|
+
import { RedisTestEntity } from '../__testfixtures__/RedisTestEntity';
|
|
10
12
|
import { createRedisIntegrationTestEntityCompanionProvider } from '../__testfixtures__/createRedisIntegrationTestEntityCompanionProvider';
|
|
11
13
|
|
|
12
14
|
class TestViewerContext extends ViewerContext {}
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AlwaysAllowPrivacyPolicyRule,
|
|
3
|
-
|
|
4
|
-
ViewerContext,
|
|
3
|
+
BufferField,
|
|
5
4
|
DateField,
|
|
6
|
-
StringField,
|
|
7
|
-
EntityConfiguration,
|
|
8
|
-
EntityCompanionDefinition,
|
|
9
5
|
Entity,
|
|
6
|
+
EntityCompanionDefinition,
|
|
7
|
+
EntityConfiguration,
|
|
8
|
+
EntityPrivacyPolicy,
|
|
9
|
+
StringField,
|
|
10
10
|
UUIDField,
|
|
11
|
+
ViewerContext,
|
|
11
12
|
} from '@expo/entity';
|
|
12
13
|
|
|
13
14
|
export type RedisTestEntityFields = {
|
|
14
15
|
id: string;
|
|
15
16
|
name: string;
|
|
16
17
|
dateField: Date | null;
|
|
18
|
+
bufferField: Buffer | null;
|
|
17
19
|
};
|
|
18
20
|
|
|
19
|
-
export
|
|
21
|
+
export class RedisTestEntity extends Entity<RedisTestEntityFields, 'id', ViewerContext> {
|
|
20
22
|
static defineCompanionDefinition(): EntityCompanionDefinition<
|
|
21
23
|
RedisTestEntityFields,
|
|
22
24
|
'id',
|
|
@@ -67,11 +69,16 @@ export const redisTestEntityConfiguration = new EntityConfiguration<RedisTestEnt
|
|
|
67
69
|
dateField: new DateField({
|
|
68
70
|
columnName: 'date_field',
|
|
69
71
|
}),
|
|
72
|
+
bufferField: new BufferField({
|
|
73
|
+
columnName: 'buffer_field',
|
|
74
|
+
cache: true,
|
|
75
|
+
}),
|
|
70
76
|
},
|
|
71
77
|
databaseAdapterFlavor: 'postgres',
|
|
72
78
|
cacheAdapterFlavor: 'redis',
|
|
73
79
|
compositeFieldDefinitions: [
|
|
74
80
|
{ compositeField: ['id', 'name'], cache: true },
|
|
75
81
|
{ compositeField: ['id', 'dateField'], cache: true },
|
|
82
|
+
{ compositeField: ['id', 'bufferField'], cache: true },
|
|
76
83
|
],
|
|
77
84
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
NoOpEntityMetricsAdapter,
|
|
3
|
-
IEntityMetricsAdapter,
|
|
4
2
|
EntityCompanionProvider,
|
|
3
|
+
IEntityMetricsAdapter,
|
|
4
|
+
NoOpEntityMetricsAdapter,
|
|
5
5
|
} from '@expo/entity';
|
|
6
6
|
import { StubDatabaseAdapterProvider, StubQueryContextProvider } from '@expo/entity-testing-utils';
|
|
7
7
|
|
|
8
8
|
import { GenericRedisCacheContext } from '../GenericRedisCacher';
|
|
9
|
-
import RedisCacheAdapterProvider from '../RedisCacheAdapterProvider';
|
|
9
|
+
import { RedisCacheAdapterProvider } from '../RedisCacheAdapterProvider';
|
|
10
10
|
|
|
11
11
|
// share across all in calls in test to simulate postgres
|
|
12
12
|
const adapterProvider = new StubDatabaseAdapterProvider();
|
|
@@ -5,10 +5,11 @@ import {
|
|
|
5
5
|
SingleFieldValueHolder,
|
|
6
6
|
UUIDField,
|
|
7
7
|
} from '@expo/entity';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { describe, expect, it } from '@jest/globals';
|
|
9
|
+
import { Pipeline, Redis } from 'ioredis';
|
|
10
|
+
import { anything, instance, mock, verify, when } from 'ts-mockito';
|
|
10
11
|
|
|
11
|
-
import GenericRedisCacher,
|
|
12
|
+
import { GenericRedisCacher, RedisCacheInvalidationStrategy } from '../GenericRedisCacher';
|
|
12
13
|
|
|
13
14
|
type BlahFields = {
|
|
14
15
|
id: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EntityCacheAdapterTransientError } from '@expo/entity';
|
|
2
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
3
|
|
|
3
|
-
import wrapNativeRedisCallAsync from '../wrapNativeRedisCallAsync';
|
|
4
|
+
import { wrapNativeRedisCallAsync } from '../wrapNativeRedisCallAsync';
|
|
4
5
|
|
|
5
6
|
describe(wrapNativeRedisCallAsync, () => {
|
|
6
7
|
it('rethrows literals', async () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EntityCacheAdapterTransientError } from '@expo/entity';
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export async function wrapNativeRedisCallAsync<T>(fn: () => Promise<T>): Promise<T> {
|
|
4
4
|
try {
|
|
5
5
|
return await fn();
|
|
6
6
|
} catch (e) {
|
package/src/index.ts
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* @module @expo/entity-cache-adapter-redis
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export { default as GenericRedisCacher } from './GenericRedisCacher';
|
|
8
7
|
export * from './GenericRedisCacher';
|
|
9
|
-
export
|
|
8
|
+
export * from './RedisCacheAdapterProvider';
|
|
10
9
|
export * from './RedisCommon';
|
|
11
|
-
export
|
|
10
|
+
export * from './errors/wrapNativeRedisCallAsync';
|
|
12
11
|
export * from './utils/getSurroundingCacheKeyVersionsForInvalidation';
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
The MIT License (MIT)
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2020-present 650 Industries, Inc. (aka Expo)
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GenericRedisCacher.js","sourceRoot":"","sources":["../src/GenericRedisCacher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const entity_1 = require("@expo/entity");
|
|
7
|
-
const GenericRedisCacher_1 = __importDefault(require("./GenericRedisCacher"));
|
|
8
|
-
class RedisCacheAdapterProvider {
|
|
9
|
-
context;
|
|
10
|
-
constructor(context) {
|
|
11
|
-
this.context = context;
|
|
12
|
-
}
|
|
13
|
-
getCacheAdapter(entityConfiguration) {
|
|
14
|
-
return new entity_1.GenericEntityCacheAdapter(new GenericRedisCacher_1.default(this.context, entityConfiguration));
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
exports.default = RedisCacheAdapterProvider;
|
|
18
|
-
//# sourceMappingURL=RedisCacheAdapterProvider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RedisCacheAdapterProvider.js","sourceRoot":"","sources":["../src/RedisCacheAdapterProvider.ts"],"names":[],"mappings":";;;;;AAAA,yCAKsB;AAEtB,8EAAoF;AAEpF,MAAqB,yBAAyB;IACf;IAA7B,YAA6B,OAAiC;QAAjC,YAAO,GAAP,OAAO,CAA0B;IAAG,CAAC;IAElE,eAAe,CACb,mBAA2D;QAE3D,OAAO,IAAI,kCAAyB,CAAC,IAAI,4BAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAClG,CAAC;CACF;AARD,4CAQC"}
|
package/build/RedisCommon.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RedisCommon.js","sourceRoot":"","sources":["../src/RedisCommon.ts"],"names":[],"mappings":";;;AAAA,yCAAyC;AAE5B,QAAA,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACzC;QACE,kBAAS,CAAC,IAAI;QACd;YACE;;;;;;;;;;;;;eAaG;YACH,KAAK,EAAE,CAAC,GAAS,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,IAAI;YAChD,IAAI,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;SAChD;KACF;CACF,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function wrapNativeRedisCallAsync<T>(fn: () => Promise<T>): Promise<T>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wrapNativeRedisCallAsync.js","sourceRoot":"","sources":["../../src/errors/wrapNativeRedisCallAsync.ts"],"names":[],"mappings":";;AAEA,2CAcC;AAhBD,yCAAgE;AAEjD,KAAK,UAAU,wBAAwB,CAAI,EAAoB;IAC5E,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,CAAC;QACV,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,yCAAgC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACZ,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QACxB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/build/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @packageDocumentation
|
|
3
|
-
* @module @expo/entity-cache-adapter-redis
|
|
4
|
-
*/
|
|
5
|
-
export { default as GenericRedisCacher } from './GenericRedisCacher';
|
|
6
|
-
export * from './GenericRedisCacher';
|
|
7
|
-
export { default as RedisCacheAdapterProvider } from './RedisCacheAdapterProvider';
|
|
8
|
-
export * from './RedisCommon';
|
|
9
|
-
export { default as wrapNativeRedisCallAsync } from './errors/wrapNativeRedisCallAsync';
|
|
10
|
-
export * from './utils/getSurroundingCacheKeyVersionsForInvalidation';
|
package/build/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,iCAAiC;AACjC;;;GAGG;;;;;;;;;;;;;;;;;;;;AAEH,2DAAqE;AAA5D,yIAAA,OAAO,OAAsB;AACtC,uDAAqC;AACrC,yEAAmF;AAA1E,uJAAA,OAAO,OAA6B;AAC7C,gDAA8B;AAC9B,8EAAwF;AAA/E,qJAAA,OAAO,OAA4B;AAC5C,wFAAsE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["../src/genericrediscacher.ts","../src/rediscacheadapterprovider.ts","../src/rediscommon.ts","../src/index.ts","../src/errors/wrapnativerediscallasync.ts","../src/utils/getsurroundingcachekeyversionsforinvalidation.ts"],"version":"5.8.3"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getSurroundingCacheKeyVersionsForInvalidation.js","sourceRoot":"","sources":["../../src/utils/getSurroundingCacheKeyVersionsForInvalidation.ts"],"names":[],"mappings":";;AAAA,sGAQC;AARD,SAAgB,6CAA6C,CAC3D,eAAuB;IAEvB,OAAO;QACL,GAAG,CAAC,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;QACvD,eAAe;QACf,eAAe,GAAG,CAAC;KACpB,CAAC;AACJ,CAAC"}
|
|
File without changes
|
|
File without changes
|