Skip to content

Commit 3352b90

Browse files
arnabrahmandreamorosileandrodamascena
authored
feat(idempotency): support for Valkey- and Redis OSS-compatible cache (#3896)
Co-authored-by: Andrea Amorosi <[email protected]> Co-authored-by: Leandro Damascena <[email protected]>
1 parent 2554800 commit 3352b90

17 files changed

+974
-35
lines changed

package-lock.json

+30-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/idempotency/package.json

+25-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@
5252
"import": "./lib/esm/types/DynamoDBPersistence.js",
5353
"require": "./lib/cjs/types/DynamoDBPersistence.js"
5454
},
55+
"./cache": {
56+
"import": "./lib/esm/persistence/CachePersistenceLayer.js",
57+
"require": "./lib/cjs/persistence/CachePersistenceLayer.js"
58+
},
59+
"./cache/types": {
60+
"import": "./lib/esm/types/CachePersistence.js",
61+
"require": "./lib/cjs/types/CachePersistence.js"
62+
},
5563
"./middleware": {
5664
"import": "./lib/esm/middleware/makeHandlerIdempotent.js",
5765
"require": "./lib/cjs/middleware/makeHandlerIdempotent.js"
@@ -75,6 +83,14 @@
7583
"lib/cjs/types/DynamoDBPersistence.d.ts",
7684
"lib/esm/types/DynamoDBPersistence.d.ts"
7785
],
86+
"cache": [
87+
"lib/cjs/persistence/CachePersistenceLayer.d.ts",
88+
"lib/esm/persistence/CachePersistenceLayer.d.ts"
89+
],
90+
"cache/types": [
91+
"lib/cjs/types/CachePersistence.d.ts",
92+
"lib/esm/types/CachePersistence.d.ts"
93+
],
7894
"middleware": [
7995
"lib/cjs/middleware/makeHandlerIdempotent.d.ts",
8096
"lib/esm/middleware/makeHandlerIdempotent.d.ts"
@@ -104,7 +120,9 @@
104120
"peerDependencies": {
105121
"@aws-sdk/client-dynamodb": ">=3.x",
106122
"@aws-sdk/lib-dynamodb": ">=3.x",
107-
"@middy/core": "4.x || 5.x || 6.x"
123+
"@middy/core": "4.x || 5.x || 6.x",
124+
"@redis/client": "^5.0.1",
125+
"@valkey/valkey-glide": "^1.3.4"
108126
},
109127
"peerDependenciesMeta": {
110128
"@aws-sdk/client-dynamodb": {
@@ -115,6 +133,12 @@
115133
},
116134
"@middy/core": {
117135
"optional": true
136+
},
137+
"@redis/client": {
138+
"optional": true
139+
},
140+
"@valkey/valkey-glide": {
141+
"optional": true
118142
}
119143
},
120144
"keywords": [

packages/idempotency/src/constants.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { BasePersistenceAttributes } from './types/BasePersistenceLayer.js';
12
/**
23
* Number of times to retry a request in case of `IdempotencyInconsistentStateError`
34
*
@@ -20,4 +21,22 @@ const IdempotencyRecordStatus = {
2021
EXPIRED: 'EXPIRED',
2122
} as const;
2223

23-
export { IdempotencyRecordStatus, MAX_RETRIES };
24+
/**
25+
* Base persistence attribute key names for persistence layers
26+
*/
27+
const PERSISTENCE_ATTRIBUTE_KEY_MAPPINGS: Record<
28+
keyof Required<BasePersistenceAttributes>,
29+
string
30+
> = {
31+
statusAttr: 'status',
32+
expiryAttr: 'expiration',
33+
inProgressExpiryAttr: 'in_progress_expiration',
34+
dataAttr: 'data',
35+
validationKeyAttr: 'validation',
36+
} as const;
37+
38+
export {
39+
IdempotencyRecordStatus,
40+
MAX_RETRIES,
41+
PERSISTENCE_ATTRIBUTE_KEY_MAPPINGS,
42+
};

packages/idempotency/src/errors.ts

+11
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ class IdempotencyKeyError extends IdempotencyUnknownError {
113113
}
114114
}
115115

116+
/**
117+
* Error with the persistence layer's consistency, needs to be removed
118+
*/
119+
class IdempotencyPersistenceConsistencyError extends IdempotencyUnknownError {
120+
public constructor(message: string, options?: ErrorOptions) {
121+
super(message, options);
122+
this.name = 'IdempotencyPersistenceConsistencyError';
123+
}
124+
}
125+
116126
export {
117127
IdempotencyUnknownError,
118128
IdempotencyItemAlreadyExistsError,
@@ -122,5 +132,6 @@ export {
122132
IdempotencyValidationError,
123133
IdempotencyInconsistentStateError,
124134
IdempotencyPersistenceLayerError,
135+
IdempotencyPersistenceConsistencyError,
125136
IdempotencyKeyError,
126137
};

packages/idempotency/src/index.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ export {
1212
export { IdempotencyConfig } from './IdempotencyConfig.js';
1313
export { makeIdempotent } from './makeIdempotent.js';
1414
export { idempotent } from './idempotencyDecorator.js';
15-
export { IdempotencyRecordStatus } from './constants.js';
15+
export {
16+
IdempotencyRecordStatus,
17+
PERSISTENCE_ATTRIBUTE_KEY_MAPPINGS,
18+
} from './constants.js';

packages/idempotency/src/persistence/BasePersistenceLayer.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ abstract class BasePersistenceLayer implements BasePersistenceLayerInterface {
3030
// envVarsService is always initialized in the constructor
3131
private envVarsService!: EnvironmentVariablesService;
3232
private eventKeyJmesPath?: string;
33-
private expiresAfterSeconds: number = 60 * 60; // 1 hour default
33+
protected expiresAfterSeconds: number = 60 * 60; // 1 hour default
3434
private hashFunction = 'md5';
3535
private payloadValidationEnabled = false;
3636
private throwOnNoIdempotencyKey = false;

0 commit comments

Comments
 (0)