@sebspark/promise-cache 2.1.2 → 3.0.1
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 +153 -13
- package/dist/index.d.mts +28 -23
- package/dist/index.d.ts +28 -23
- package/dist/index.js +195 -40
- package/dist/index.mjs +194 -37
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -1,23 +1,163 @@
|
|
|
1
1
|
# `@sebspark/promise-cache`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Simple caching wrapper
|
|
4
|
+
|
|
5
|
+
## **Features**
|
|
6
|
+
|
|
7
|
+
- **PromiseCache**: Simple caching wraper for promises
|
|
8
|
+
- **Persistor**: Simple Key/Value caching wrapper, can be used with redis or with local memory.
|
|
9
|
+
|
|
10
|
+
## **Installation**
|
|
11
|
+
|
|
12
|
+
To install promise-cache, use `yarn`:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
yarn install @sebspark/promise-cache
|
|
16
|
+
```
|
|
17
|
+
## **Usage**
|
|
18
|
+
|
|
19
|
+
### **PromiseCache Class**
|
|
20
|
+
|
|
21
|
+
| Params | Type | Default |Description |
|
|
22
|
+
|---------------|----------|---------|---------------------------------------------|
|
|
23
|
+
| redis | RedisClientOptions | undefined |Redis instance url, skip if use local memory |
|
|
24
|
+
| ttlInSeconds | number | undefined |Persist time in Seconds |
|
|
25
|
+
| caseSensituve | boolean | false |Retrieving cache with case sensitive |
|
|
26
|
+
| onSuccess | function | undefined |Callback function if connection is success |
|
|
27
|
+
| onError | function | undefined |Callback function if there is an error |
|
|
28
|
+
| logger | winston Logger | undefined |Logger |
|
|
4
29
|
|
|
5
30
|
```typescript
|
|
31
|
+
import { PromiseCache } from '@sebspark/promise-cache'
|
|
32
|
+
|
|
33
|
+
// with redis
|
|
34
|
+
const cacheInRedis = new PromiseCache<T>({
|
|
35
|
+
redis: REDIS_URL,
|
|
36
|
+
ttlInSeconds: ttl,
|
|
37
|
+
caseSensitive: true
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// without redis
|
|
41
|
+
const cacheLocalMemory = new PromiseCache<T>({
|
|
42
|
+
ttlInSeconds: ttl,
|
|
43
|
+
caseSensitive: true
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## **PromiseCache Methods**
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// Wrap
|
|
51
|
+
/* Simple promise cache wrapper
|
|
52
|
+
* @param key Cache key.
|
|
53
|
+
* @param delegate The function to execute if the key is not in the cache.
|
|
54
|
+
* @param ttlInSeconds Time to live in seconds.
|
|
55
|
+
* @param ttlKeyInSeconds The key in the response object that contains the TTL.
|
|
56
|
+
* @returns The result of the delegate function.
|
|
57
|
+
*/
|
|
58
|
+
const ttl = 5 // 5 seconds
|
|
59
|
+
const delegate = new Promise((reject, resolve) => { resolve(123)})
|
|
60
|
+
const response = await cacheInRedis.wrap('Key', delegate, ttl)
|
|
61
|
+
expect(response).toBe(123)
|
|
62
|
+
|
|
63
|
+
// Size
|
|
6
64
|
/*
|
|
7
|
-
|
|
65
|
+
* Cache size
|
|
66
|
+
* @returns The number of entries in the cache
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
const entries = await cacheInRedis.size()
|
|
70
|
+
expect(entries).toBe(1)
|
|
71
|
+
|
|
72
|
+
// Find
|
|
73
|
+
/**
|
|
74
|
+
* Get a value from the cache.
|
|
75
|
+
* @param key Cache key.
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
const cachedValue = await cacheInRedis.find('Key')
|
|
79
|
+
expect(cachedValue).toBe(123)
|
|
80
|
+
|
|
81
|
+
// Override
|
|
82
|
+
/**
|
|
83
|
+
* Set a value in the cache.
|
|
84
|
+
* @param key Cache key.
|
|
85
|
+
* @param value Cache value.
|
|
86
|
+
* @param ttlInSeconds? Time to live in seconds.
|
|
8
87
|
*/
|
|
9
|
-
import { PromiseCache } from '@sebspark/promise-cache'
|
|
10
88
|
|
|
11
|
-
//
|
|
12
|
-
const
|
|
89
|
+
await cacheInRedis.override('Key', 234) // keep the same ttl
|
|
90
|
+
const cached = cacheInRedis.find('Key')
|
|
91
|
+
expect(cached).toBe(234)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### **Persistor Class**
|
|
95
|
+
|
|
96
|
+
| Params | Type | Default |Description |
|
|
97
|
+
|---------------|----------|---------|---------------------------------------------|
|
|
98
|
+
| redis | RedisClientOptions | undefined |Redis instance url, skip if use local memory |
|
|
99
|
+
| onSuccess | function | undefined |Callback function if connection is success |
|
|
100
|
+
| onError | function | undefined |Callback function if there is an error |
|
|
101
|
+
| logger | winston Logger | undefined |Logger |
|
|
102
|
+
| clientId | any | undefined |Object internal id |
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { Persistor } from '@sebspark/promise-cache'
|
|
13
106
|
|
|
14
|
-
|
|
107
|
+
// with redis
|
|
108
|
+
const store = new Persistor<T>({
|
|
109
|
+
redis: REDIS_URL,
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// without redis
|
|
113
|
+
const store = new Persistor<T>()
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## **Persistor Methods**
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
15
119
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Size
|
|
122
|
+
* @returns The number of entries in the cache
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
const size = await store.size()
|
|
126
|
+
expect(size).toBe(0)
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Set
|
|
130
|
+
* Set a value in the cache.
|
|
131
|
+
* @param key Cache key.
|
|
132
|
+
* @param object.value Value to set in the cache.
|
|
133
|
+
* @param object.ttl Time to live in seconds.
|
|
134
|
+
* @param object.timestamp Timestamp
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
await store.set<number>('MyKey', {
|
|
138
|
+
value: 123,
|
|
139
|
+
ttl: 10 // In seconds, default undefined
|
|
140
|
+
timestamp: Date.now() // default Date.now()
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get a value from the cache.
|
|
145
|
+
* @param key Cache key.
|
|
146
|
+
* @returns GetType<T> value
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
const cached = await store.get('MyKey')
|
|
150
|
+
expect(cached).toBe({
|
|
151
|
+
value: 43,
|
|
152
|
+
ttl: 10,
|
|
153
|
+
timestamp: // The timestamp
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Delete a value from the cache.
|
|
158
|
+
* @param key Cache key
|
|
159
|
+
*/
|
|
19
160
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```
|
|
161
|
+
await store.delete('MyKey')
|
|
162
|
+
expect(await store.get('MyKey').toBe(null)
|
|
163
|
+
```
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RedisClientOptions, createClient } from 'redis';
|
|
2
2
|
export { RedisClientOptions } from 'redis';
|
|
3
|
+
import { Logger } from 'winston';
|
|
3
4
|
import { UUID } from 'node:crypto';
|
|
4
5
|
|
|
5
6
|
type GetType<T> = {
|
|
@@ -9,29 +10,47 @@ type GetType<T> = {
|
|
|
9
10
|
};
|
|
10
11
|
type SetParams<T> = {
|
|
11
12
|
value: T;
|
|
12
|
-
timestamp
|
|
13
|
+
timestamp?: number;
|
|
13
14
|
ttl?: number;
|
|
14
15
|
};
|
|
15
16
|
type PersistorConstructorType = {
|
|
16
17
|
redis?: RedisClientOptions;
|
|
17
18
|
clientId?: UUID;
|
|
18
|
-
onError
|
|
19
|
-
onSuccess
|
|
19
|
+
onError?: (error: string) => void;
|
|
20
|
+
onSuccess?: () => void;
|
|
21
|
+
logger?: Logger;
|
|
20
22
|
};
|
|
21
23
|
declare class Persistor {
|
|
22
24
|
client: ReturnType<typeof createClient> | null;
|
|
23
25
|
private clientId?;
|
|
24
26
|
private onError;
|
|
25
27
|
private onSuccess;
|
|
28
|
+
private logger;
|
|
26
29
|
private readonly redis?;
|
|
27
|
-
constructor({ redis, clientId, onSuccess, onError, }: PersistorConstructorType);
|
|
30
|
+
constructor({ redis, clientId, onSuccess, onError, logger, }: PersistorConstructorType);
|
|
28
31
|
startConnection(): Promise<void>;
|
|
29
32
|
size(): Promise<number>;
|
|
30
|
-
get<T>(key: string): Promise<GetType<T> | null>;
|
|
31
33
|
getClientId(): UUID | undefined;
|
|
32
34
|
getIsClientConnected(): boolean;
|
|
33
35
|
private createOptions;
|
|
36
|
+
/**
|
|
37
|
+
* Set a value in the cache.
|
|
38
|
+
* @param key Cache key.
|
|
39
|
+
* @param object.value Value to set in the cache.
|
|
40
|
+
* @param object.ttl Time to live in seconds.
|
|
41
|
+
* @param object.timestamp Timestamp
|
|
42
|
+
*/
|
|
34
43
|
set<T>(key: string, { value, timestamp, ttl }: SetParams<T>): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Get a value from the cache.
|
|
46
|
+
* @param key Cache key.
|
|
47
|
+
* @returns GetType<T> value
|
|
48
|
+
*/
|
|
49
|
+
get<T>(key: string): Promise<GetType<T> | null>;
|
|
50
|
+
/**
|
|
51
|
+
* Delete a value from the cache.
|
|
52
|
+
* @param key Cache key
|
|
53
|
+
*/
|
|
35
54
|
delete(key: string): Promise<void>;
|
|
36
55
|
}
|
|
37
56
|
|
|
@@ -41,6 +60,7 @@ type PromiseCacheOptions = {
|
|
|
41
60
|
redis?: RedisClientOptions;
|
|
42
61
|
onError?: (error: string) => void;
|
|
43
62
|
onSuccess?: () => void;
|
|
63
|
+
logger?: Logger;
|
|
44
64
|
};
|
|
45
65
|
declare class PromiseCache<U> {
|
|
46
66
|
persistor: Persistor;
|
|
@@ -52,14 +72,14 @@ declare class PromiseCache<U> {
|
|
|
52
72
|
* @param ttlInSeconds Default cache TTL.
|
|
53
73
|
* @param caseSensitive Set to true if you want to differentiate between keys with different casing.
|
|
54
74
|
*/
|
|
55
|
-
constructor({ ttlInSeconds, caseSensitive, redis, onSuccess, onError, }: PromiseCacheOptions);
|
|
75
|
+
constructor({ ttlInSeconds, caseSensitive, redis, onSuccess, onError, logger, }: PromiseCacheOptions);
|
|
56
76
|
/**
|
|
57
77
|
* Cache size.
|
|
58
78
|
* @returns The number of entries in the cache.
|
|
59
79
|
*/
|
|
60
80
|
size(): Promise<number>;
|
|
61
81
|
/**
|
|
62
|
-
*
|
|
82
|
+
* Override a value in the cache.
|
|
63
83
|
* @param key Cache key.
|
|
64
84
|
* @param value Cache value.
|
|
65
85
|
* @param ttlInSeconds Time to live in seconds.
|
|
@@ -81,19 +101,4 @@ declare class PromiseCache<U> {
|
|
|
81
101
|
wrap(key: string, delegate: () => Promise<U>, ttlInSeconds?: number, ttlKeyInSeconds?: string): Promise<U>;
|
|
82
102
|
}
|
|
83
103
|
|
|
84
|
-
|
|
85
|
-
client: Map<any, any>;
|
|
86
|
-
isReady: boolean;
|
|
87
|
-
get(key: string): any;
|
|
88
|
-
set(key: string, value: string, options?: {
|
|
89
|
-
PX: number;
|
|
90
|
-
}): void;
|
|
91
|
-
del(key: string): void;
|
|
92
|
-
clear(): void;
|
|
93
|
-
DBSIZE(): Promise<number>;
|
|
94
|
-
on(event: string, callback: (message: string) => void): this;
|
|
95
|
-
connect(): Promise<this>;
|
|
96
|
-
}
|
|
97
|
-
declare const createLocalMemoryClient: () => LocalStorage;
|
|
98
|
-
|
|
99
|
-
export { LocalStorage, Persistor, type PersistorConstructorType, PromiseCache, type PromiseCacheOptions, createLocalMemoryClient };
|
|
104
|
+
export { Persistor, type PersistorConstructorType, PromiseCache, type PromiseCacheOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RedisClientOptions, createClient } from 'redis';
|
|
2
2
|
export { RedisClientOptions } from 'redis';
|
|
3
|
+
import { Logger } from 'winston';
|
|
3
4
|
import { UUID } from 'node:crypto';
|
|
4
5
|
|
|
5
6
|
type GetType<T> = {
|
|
@@ -9,29 +10,47 @@ type GetType<T> = {
|
|
|
9
10
|
};
|
|
10
11
|
type SetParams<T> = {
|
|
11
12
|
value: T;
|
|
12
|
-
timestamp
|
|
13
|
+
timestamp?: number;
|
|
13
14
|
ttl?: number;
|
|
14
15
|
};
|
|
15
16
|
type PersistorConstructorType = {
|
|
16
17
|
redis?: RedisClientOptions;
|
|
17
18
|
clientId?: UUID;
|
|
18
|
-
onError
|
|
19
|
-
onSuccess
|
|
19
|
+
onError?: (error: string) => void;
|
|
20
|
+
onSuccess?: () => void;
|
|
21
|
+
logger?: Logger;
|
|
20
22
|
};
|
|
21
23
|
declare class Persistor {
|
|
22
24
|
client: ReturnType<typeof createClient> | null;
|
|
23
25
|
private clientId?;
|
|
24
26
|
private onError;
|
|
25
27
|
private onSuccess;
|
|
28
|
+
private logger;
|
|
26
29
|
private readonly redis?;
|
|
27
|
-
constructor({ redis, clientId, onSuccess, onError, }: PersistorConstructorType);
|
|
30
|
+
constructor({ redis, clientId, onSuccess, onError, logger, }: PersistorConstructorType);
|
|
28
31
|
startConnection(): Promise<void>;
|
|
29
32
|
size(): Promise<number>;
|
|
30
|
-
get<T>(key: string): Promise<GetType<T> | null>;
|
|
31
33
|
getClientId(): UUID | undefined;
|
|
32
34
|
getIsClientConnected(): boolean;
|
|
33
35
|
private createOptions;
|
|
36
|
+
/**
|
|
37
|
+
* Set a value in the cache.
|
|
38
|
+
* @param key Cache key.
|
|
39
|
+
* @param object.value Value to set in the cache.
|
|
40
|
+
* @param object.ttl Time to live in seconds.
|
|
41
|
+
* @param object.timestamp Timestamp
|
|
42
|
+
*/
|
|
34
43
|
set<T>(key: string, { value, timestamp, ttl }: SetParams<T>): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Get a value from the cache.
|
|
46
|
+
* @param key Cache key.
|
|
47
|
+
* @returns GetType<T> value
|
|
48
|
+
*/
|
|
49
|
+
get<T>(key: string): Promise<GetType<T> | null>;
|
|
50
|
+
/**
|
|
51
|
+
* Delete a value from the cache.
|
|
52
|
+
* @param key Cache key
|
|
53
|
+
*/
|
|
35
54
|
delete(key: string): Promise<void>;
|
|
36
55
|
}
|
|
37
56
|
|
|
@@ -41,6 +60,7 @@ type PromiseCacheOptions = {
|
|
|
41
60
|
redis?: RedisClientOptions;
|
|
42
61
|
onError?: (error: string) => void;
|
|
43
62
|
onSuccess?: () => void;
|
|
63
|
+
logger?: Logger;
|
|
44
64
|
};
|
|
45
65
|
declare class PromiseCache<U> {
|
|
46
66
|
persistor: Persistor;
|
|
@@ -52,14 +72,14 @@ declare class PromiseCache<U> {
|
|
|
52
72
|
* @param ttlInSeconds Default cache TTL.
|
|
53
73
|
* @param caseSensitive Set to true if you want to differentiate between keys with different casing.
|
|
54
74
|
*/
|
|
55
|
-
constructor({ ttlInSeconds, caseSensitive, redis, onSuccess, onError, }: PromiseCacheOptions);
|
|
75
|
+
constructor({ ttlInSeconds, caseSensitive, redis, onSuccess, onError, logger, }: PromiseCacheOptions);
|
|
56
76
|
/**
|
|
57
77
|
* Cache size.
|
|
58
78
|
* @returns The number of entries in the cache.
|
|
59
79
|
*/
|
|
60
80
|
size(): Promise<number>;
|
|
61
81
|
/**
|
|
62
|
-
*
|
|
82
|
+
* Override a value in the cache.
|
|
63
83
|
* @param key Cache key.
|
|
64
84
|
* @param value Cache value.
|
|
65
85
|
* @param ttlInSeconds Time to live in seconds.
|
|
@@ -81,19 +101,4 @@ declare class PromiseCache<U> {
|
|
|
81
101
|
wrap(key: string, delegate: () => Promise<U>, ttlInSeconds?: number, ttlKeyInSeconds?: string): Promise<U>;
|
|
82
102
|
}
|
|
83
103
|
|
|
84
|
-
|
|
85
|
-
client: Map<any, any>;
|
|
86
|
-
isReady: boolean;
|
|
87
|
-
get(key: string): any;
|
|
88
|
-
set(key: string, value: string, options?: {
|
|
89
|
-
PX: number;
|
|
90
|
-
}): void;
|
|
91
|
-
del(key: string): void;
|
|
92
|
-
clear(): void;
|
|
93
|
-
DBSIZE(): Promise<number>;
|
|
94
|
-
on(event: string, callback: (message: string) => void): this;
|
|
95
|
-
connect(): Promise<this>;
|
|
96
|
-
}
|
|
97
|
-
declare const createLocalMemoryClient: () => LocalStorage;
|
|
98
|
-
|
|
99
|
-
export { LocalStorage, Persistor, type PersistorConstructorType, PromiseCache, type PromiseCacheOptions, createLocalMemoryClient };
|
|
104
|
+
export { Persistor, type PersistorConstructorType, PromiseCache, type PromiseCacheOptions };
|
package/dist/index.js
CHANGED
|
@@ -20,10 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
LocalStorage: () => LocalStorage,
|
|
24
23
|
Persistor: () => Persistor,
|
|
25
|
-
PromiseCache: () => PromiseCache
|
|
26
|
-
createLocalMemoryClient: () => createLocalMemoryClient
|
|
24
|
+
PromiseCache: () => PromiseCache
|
|
27
25
|
});
|
|
28
26
|
module.exports = __toCommonJS(src_exports);
|
|
29
27
|
|
|
@@ -74,24 +72,144 @@ var createLocalMemoryClient = () => {
|
|
|
74
72
|
return localStorage;
|
|
75
73
|
};
|
|
76
74
|
|
|
75
|
+
// src/serializerUtils.ts
|
|
76
|
+
function serialize(value) {
|
|
77
|
+
const type = typeof value;
|
|
78
|
+
if (value === null) {
|
|
79
|
+
return JSON.stringify({ type: "null" });
|
|
80
|
+
}
|
|
81
|
+
if (value === void 0) {
|
|
82
|
+
return JSON.stringify({ type: "undefined" });
|
|
83
|
+
}
|
|
84
|
+
switch (type) {
|
|
85
|
+
case "string":
|
|
86
|
+
case "number":
|
|
87
|
+
case "boolean":
|
|
88
|
+
return JSON.stringify({ type, value });
|
|
89
|
+
case "bigint":
|
|
90
|
+
return JSON.stringify({ type: "bigint", value: value.toString() });
|
|
91
|
+
case "object": {
|
|
92
|
+
if (Array.isArray(value)) {
|
|
93
|
+
return JSON.stringify({ type: "array", value: value.map(serialize) });
|
|
94
|
+
}
|
|
95
|
+
if (value instanceof Map) {
|
|
96
|
+
const entries = Array.from(value.entries()).map(([key, val]) => [
|
|
97
|
+
serialize(key),
|
|
98
|
+
serialize(val)
|
|
99
|
+
]);
|
|
100
|
+
return JSON.stringify({ type: "map", value: entries });
|
|
101
|
+
}
|
|
102
|
+
if (value instanceof Set) {
|
|
103
|
+
const entries = Array.from(value).map(serialize);
|
|
104
|
+
return JSON.stringify({ type: "set", value: entries });
|
|
105
|
+
}
|
|
106
|
+
if (value.constructor === Object) {
|
|
107
|
+
const entries = Object.entries(value).reduce(
|
|
108
|
+
(acc, [key, val]) => {
|
|
109
|
+
acc[key] = serialize(val);
|
|
110
|
+
return acc;
|
|
111
|
+
},
|
|
112
|
+
{}
|
|
113
|
+
);
|
|
114
|
+
return JSON.stringify({ type: "object", value: entries });
|
|
115
|
+
}
|
|
116
|
+
throw new Error("Cannot serialize non-plain objects");
|
|
117
|
+
}
|
|
118
|
+
default:
|
|
119
|
+
throw new Error(`Unsupported type: ${type}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function deserializePrimitives(serialized) {
|
|
123
|
+
let parsed = serialized;
|
|
124
|
+
if (typeof serialized === "string") {
|
|
125
|
+
parsed = JSON.parse(serialized);
|
|
126
|
+
}
|
|
127
|
+
switch (parsed.type) {
|
|
128
|
+
case "string":
|
|
129
|
+
return parsed.value;
|
|
130
|
+
case "number":
|
|
131
|
+
return Number(parsed.value);
|
|
132
|
+
case "boolean":
|
|
133
|
+
return Boolean(parsed.value);
|
|
134
|
+
case "undefined":
|
|
135
|
+
return void 0;
|
|
136
|
+
case "bigint":
|
|
137
|
+
return BigInt(parsed.value);
|
|
138
|
+
case "null":
|
|
139
|
+
return null;
|
|
140
|
+
default:
|
|
141
|
+
throw new Error(
|
|
142
|
+
`Unsupported type during deserialization: ${JSON.stringify(parsed)}`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function deserialize(serialized) {
|
|
147
|
+
let parsed = serialized;
|
|
148
|
+
if (typeof serialized === "string") {
|
|
149
|
+
parsed = JSON.parse(serialized);
|
|
150
|
+
}
|
|
151
|
+
switch (parsed.type) {
|
|
152
|
+
case "string":
|
|
153
|
+
case "number":
|
|
154
|
+
case "boolean":
|
|
155
|
+
case "undefined":
|
|
156
|
+
case "bigint":
|
|
157
|
+
case "null":
|
|
158
|
+
return deserializePrimitives(parsed);
|
|
159
|
+
case "array":
|
|
160
|
+
return parsed.value.map(deserialize);
|
|
161
|
+
case "map": {
|
|
162
|
+
const map = /* @__PURE__ */ new Map();
|
|
163
|
+
for (const [key, val] of parsed.value) {
|
|
164
|
+
map.set(deserialize(key), deserialize(val));
|
|
165
|
+
}
|
|
166
|
+
return map;
|
|
167
|
+
}
|
|
168
|
+
case "set": {
|
|
169
|
+
const set = /* @__PURE__ */ new Set();
|
|
170
|
+
for (const item of parsed.value) {
|
|
171
|
+
set.add(deserialize(item));
|
|
172
|
+
}
|
|
173
|
+
return set;
|
|
174
|
+
}
|
|
175
|
+
case "object": {
|
|
176
|
+
const obj = {};
|
|
177
|
+
for (const [key, val] of Object.entries(parsed.value)) {
|
|
178
|
+
obj[key] = deserialize(val);
|
|
179
|
+
}
|
|
180
|
+
return obj;
|
|
181
|
+
}
|
|
182
|
+
default:
|
|
183
|
+
throw new Error(`Unsupported type during deserialization: ${parsed}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
77
187
|
// src/persistor.ts
|
|
78
188
|
var CACHE_CLIENT = import_redis.createClient;
|
|
79
189
|
var isTestRunning = process.env.NODE_ENV === "test";
|
|
190
|
+
function toMillis(seconds) {
|
|
191
|
+
return seconds * 1e3;
|
|
192
|
+
}
|
|
80
193
|
var Persistor = class {
|
|
81
194
|
client = null;
|
|
82
195
|
clientId;
|
|
83
196
|
onError;
|
|
84
197
|
onSuccess;
|
|
198
|
+
logger;
|
|
85
199
|
redis;
|
|
86
200
|
constructor({
|
|
87
201
|
redis,
|
|
88
202
|
clientId,
|
|
89
203
|
onSuccess,
|
|
90
|
-
onError
|
|
204
|
+
onError,
|
|
205
|
+
logger
|
|
91
206
|
}) {
|
|
92
|
-
this.onError = onError
|
|
93
|
-
|
|
207
|
+
this.onError = onError || (() => {
|
|
208
|
+
});
|
|
209
|
+
this.onSuccess = onSuccess || (() => {
|
|
210
|
+
});
|
|
94
211
|
this.clientId = clientId;
|
|
212
|
+
this.logger = logger;
|
|
95
213
|
if (redis && !isTestRunning) {
|
|
96
214
|
this.redis = redis;
|
|
97
215
|
} else {
|
|
@@ -102,11 +220,12 @@ var Persistor = class {
|
|
|
102
220
|
}
|
|
103
221
|
}
|
|
104
222
|
async startConnection() {
|
|
223
|
+
var _a;
|
|
105
224
|
try {
|
|
106
225
|
await new Promise((resolve, reject) => {
|
|
107
|
-
var
|
|
226
|
+
var _a2;
|
|
108
227
|
this.client = CACHE_CLIENT({
|
|
109
|
-
url: (
|
|
228
|
+
url: (_a2 = this.redis) == null ? void 0 : _a2.url,
|
|
110
229
|
socket: {
|
|
111
230
|
reconnectStrategy: (retries, cause) => {
|
|
112
231
|
console.error(cause);
|
|
@@ -120,15 +239,17 @@ var Persistor = class {
|
|
|
120
239
|
this.onSuccess();
|
|
121
240
|
resolve(true);
|
|
122
241
|
}).on("reconnecting", () => {
|
|
123
|
-
|
|
242
|
+
var _a3;
|
|
243
|
+
(_a3 = this.logger) == null ? void 0 : _a3.info("reconnecting...", this.clientId);
|
|
124
244
|
}).on("end", () => {
|
|
125
|
-
|
|
245
|
+
var _a3;
|
|
246
|
+
(_a3 = this.logger) == null ? void 0 : _a3.info("end...", this.clientId);
|
|
126
247
|
});
|
|
127
248
|
this.client.connect();
|
|
128
249
|
});
|
|
129
250
|
} catch (ex) {
|
|
130
251
|
this.onError(`${ex}`);
|
|
131
|
-
|
|
252
|
+
(_a = this.logger) == null ? void 0 : _a.error(ex);
|
|
132
253
|
}
|
|
133
254
|
}
|
|
134
255
|
async size() {
|
|
@@ -137,20 +258,6 @@ var Persistor = class {
|
|
|
137
258
|
}
|
|
138
259
|
return await this.client.DBSIZE();
|
|
139
260
|
}
|
|
140
|
-
async get(key) {
|
|
141
|
-
if (!this.client) {
|
|
142
|
-
throw new Error("Client not initialized");
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
const result = await this.client.get(key);
|
|
146
|
-
if (!result) {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
return JSON.parse(result);
|
|
150
|
-
} catch (error) {
|
|
151
|
-
throw new Error(`Error getting data from redis: ${error}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
261
|
getClientId() {
|
|
155
262
|
return this.clientId;
|
|
156
263
|
}
|
|
@@ -160,31 +267,77 @@ var Persistor = class {
|
|
|
160
267
|
}
|
|
161
268
|
createOptions(ttl) {
|
|
162
269
|
if (ttl !== null && ttl !== void 0) {
|
|
163
|
-
return { PX: Math.round(ttl) };
|
|
270
|
+
return { PX: Math.round(toMillis(ttl)) };
|
|
164
271
|
}
|
|
165
272
|
return {};
|
|
166
273
|
}
|
|
167
|
-
|
|
274
|
+
/**
|
|
275
|
+
* Set a value in the cache.
|
|
276
|
+
* @param key Cache key.
|
|
277
|
+
* @param object.value Value to set in the cache.
|
|
278
|
+
* @param object.ttl Time to live in seconds.
|
|
279
|
+
* @param object.timestamp Timestamp
|
|
280
|
+
*/
|
|
281
|
+
async set(key, { value, timestamp = Date.now(), ttl }) {
|
|
282
|
+
var _a, _b;
|
|
168
283
|
if (!this.client || !this.client.isReady) {
|
|
169
|
-
|
|
284
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
170
285
|
return;
|
|
171
286
|
}
|
|
172
287
|
try {
|
|
173
|
-
const serializedData = JSON.stringify({
|
|
288
|
+
const serializedData = JSON.stringify({
|
|
289
|
+
value: serialize(value),
|
|
290
|
+
ttl,
|
|
291
|
+
timestamp
|
|
292
|
+
});
|
|
174
293
|
const options = this.createOptions(ttl);
|
|
175
294
|
await this.client.set(key, serializedData, options);
|
|
176
295
|
} catch (error) {
|
|
296
|
+
(_b = this.logger) == null ? void 0 : _b.error(`Error setting data in redis: ${error}`);
|
|
177
297
|
throw new Error(`Error setting data in redis: ${error}`);
|
|
178
298
|
}
|
|
179
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Get a value from the cache.
|
|
302
|
+
* @param key Cache key.
|
|
303
|
+
* @returns GetType<T> value
|
|
304
|
+
*/
|
|
305
|
+
async get(key) {
|
|
306
|
+
var _a, _b;
|
|
307
|
+
if (!this.client) {
|
|
308
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
const data = await this.client.get(key);
|
|
313
|
+
if (!data) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
const storedData = JSON.parse(data);
|
|
317
|
+
const deserialized = JSON.parse(storedData.value);
|
|
318
|
+
return {
|
|
319
|
+
...storedData,
|
|
320
|
+
value: deserialize(deserialized)
|
|
321
|
+
};
|
|
322
|
+
} catch (error) {
|
|
323
|
+
(_b = this.logger) == null ? void 0 : _b.error(`Error getting data in redis: ${error}`);
|
|
324
|
+
throw new Error(`Error getting data from redis: ${error}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Delete a value from the cache.
|
|
329
|
+
* @param key Cache key
|
|
330
|
+
*/
|
|
180
331
|
async delete(key) {
|
|
332
|
+
var _a, _b;
|
|
181
333
|
if (!this.client || !this.client.isReady) {
|
|
182
|
-
|
|
334
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
183
335
|
return;
|
|
184
336
|
}
|
|
185
337
|
try {
|
|
186
338
|
await this.client.del(key);
|
|
187
339
|
} catch (error) {
|
|
340
|
+
(_b = this.logger) == null ? void 0 : _b.error(`Error deleting data from redis: ${error}`);
|
|
188
341
|
throw new Error(`Error deleting data from redis: ${error}`);
|
|
189
342
|
}
|
|
190
343
|
}
|
|
@@ -194,6 +347,7 @@ var Persistor = class {
|
|
|
194
347
|
var persistors = {};
|
|
195
348
|
var getPersistor = ({
|
|
196
349
|
redis,
|
|
350
|
+
logger,
|
|
197
351
|
onError,
|
|
198
352
|
onSuccess,
|
|
199
353
|
clientId
|
|
@@ -204,17 +358,18 @@ var getPersistor = ({
|
|
|
204
358
|
redis,
|
|
205
359
|
onError: (error) => {
|
|
206
360
|
onError == null ? void 0 : onError(error);
|
|
207
|
-
|
|
361
|
+
logger == null ? void 0 : logger.error(
|
|
208
362
|
`\u274C REDIS | Client Error | ${connectionName} | ${redis == null ? void 0 : redis.url}: ${error}`
|
|
209
363
|
);
|
|
210
364
|
},
|
|
211
365
|
onSuccess: () => {
|
|
212
366
|
onSuccess == null ? void 0 : onSuccess();
|
|
213
|
-
|
|
367
|
+
logger == null ? void 0 : logger.info(
|
|
214
368
|
`\u{1F4E6} REDIS | Connection Ready | ${connectionName} | ${redis == null ? void 0 : redis.url}`
|
|
215
369
|
);
|
|
216
370
|
},
|
|
217
|
-
clientId
|
|
371
|
+
clientId,
|
|
372
|
+
logger
|
|
218
373
|
});
|
|
219
374
|
}
|
|
220
375
|
return persistors[connectionName];
|
|
@@ -235,13 +390,15 @@ var PromiseCache = class {
|
|
|
235
390
|
caseSensitive = false,
|
|
236
391
|
redis,
|
|
237
392
|
onSuccess,
|
|
238
|
-
onError
|
|
393
|
+
onError,
|
|
394
|
+
logger
|
|
239
395
|
}) {
|
|
240
396
|
this.persistor = getPersistor({
|
|
241
397
|
redis,
|
|
242
398
|
onError,
|
|
243
399
|
onSuccess,
|
|
244
|
-
clientId: this.clientId
|
|
400
|
+
clientId: this.clientId,
|
|
401
|
+
logger
|
|
245
402
|
});
|
|
246
403
|
this.caseSensitive = caseSensitive;
|
|
247
404
|
if (ttlInSeconds) {
|
|
@@ -256,14 +413,14 @@ var PromiseCache = class {
|
|
|
256
413
|
return await this.persistor.size();
|
|
257
414
|
}
|
|
258
415
|
/**
|
|
259
|
-
*
|
|
416
|
+
* Override a value in the cache.
|
|
260
417
|
* @param key Cache key.
|
|
261
418
|
* @param value Cache value.
|
|
262
419
|
* @param ttlInSeconds Time to live in seconds.
|
|
263
420
|
*/
|
|
264
421
|
async override(key, value, ttlInSeconds) {
|
|
265
422
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
266
|
-
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds
|
|
423
|
+
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds : this.ttl;
|
|
267
424
|
await this.persistor.set(effectiveKey, {
|
|
268
425
|
value,
|
|
269
426
|
timestamp: Date.now(),
|
|
@@ -315,8 +472,6 @@ var PromiseCache = class {
|
|
|
315
472
|
};
|
|
316
473
|
// Annotate the CommonJS export names for ESM import in node:
|
|
317
474
|
0 && (module.exports = {
|
|
318
|
-
LocalStorage,
|
|
319
475
|
Persistor,
|
|
320
|
-
PromiseCache
|
|
321
|
-
createLocalMemoryClient
|
|
476
|
+
PromiseCache
|
|
322
477
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -45,24 +45,144 @@ var createLocalMemoryClient = () => {
|
|
|
45
45
|
return localStorage;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
// src/serializerUtils.ts
|
|
49
|
+
function serialize(value) {
|
|
50
|
+
const type = typeof value;
|
|
51
|
+
if (value === null) {
|
|
52
|
+
return JSON.stringify({ type: "null" });
|
|
53
|
+
}
|
|
54
|
+
if (value === void 0) {
|
|
55
|
+
return JSON.stringify({ type: "undefined" });
|
|
56
|
+
}
|
|
57
|
+
switch (type) {
|
|
58
|
+
case "string":
|
|
59
|
+
case "number":
|
|
60
|
+
case "boolean":
|
|
61
|
+
return JSON.stringify({ type, value });
|
|
62
|
+
case "bigint":
|
|
63
|
+
return JSON.stringify({ type: "bigint", value: value.toString() });
|
|
64
|
+
case "object": {
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
return JSON.stringify({ type: "array", value: value.map(serialize) });
|
|
67
|
+
}
|
|
68
|
+
if (value instanceof Map) {
|
|
69
|
+
const entries = Array.from(value.entries()).map(([key, val]) => [
|
|
70
|
+
serialize(key),
|
|
71
|
+
serialize(val)
|
|
72
|
+
]);
|
|
73
|
+
return JSON.stringify({ type: "map", value: entries });
|
|
74
|
+
}
|
|
75
|
+
if (value instanceof Set) {
|
|
76
|
+
const entries = Array.from(value).map(serialize);
|
|
77
|
+
return JSON.stringify({ type: "set", value: entries });
|
|
78
|
+
}
|
|
79
|
+
if (value.constructor === Object) {
|
|
80
|
+
const entries = Object.entries(value).reduce(
|
|
81
|
+
(acc, [key, val]) => {
|
|
82
|
+
acc[key] = serialize(val);
|
|
83
|
+
return acc;
|
|
84
|
+
},
|
|
85
|
+
{}
|
|
86
|
+
);
|
|
87
|
+
return JSON.stringify({ type: "object", value: entries });
|
|
88
|
+
}
|
|
89
|
+
throw new Error("Cannot serialize non-plain objects");
|
|
90
|
+
}
|
|
91
|
+
default:
|
|
92
|
+
throw new Error(`Unsupported type: ${type}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function deserializePrimitives(serialized) {
|
|
96
|
+
let parsed = serialized;
|
|
97
|
+
if (typeof serialized === "string") {
|
|
98
|
+
parsed = JSON.parse(serialized);
|
|
99
|
+
}
|
|
100
|
+
switch (parsed.type) {
|
|
101
|
+
case "string":
|
|
102
|
+
return parsed.value;
|
|
103
|
+
case "number":
|
|
104
|
+
return Number(parsed.value);
|
|
105
|
+
case "boolean":
|
|
106
|
+
return Boolean(parsed.value);
|
|
107
|
+
case "undefined":
|
|
108
|
+
return void 0;
|
|
109
|
+
case "bigint":
|
|
110
|
+
return BigInt(parsed.value);
|
|
111
|
+
case "null":
|
|
112
|
+
return null;
|
|
113
|
+
default:
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Unsupported type during deserialization: ${JSON.stringify(parsed)}`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function deserialize(serialized) {
|
|
120
|
+
let parsed = serialized;
|
|
121
|
+
if (typeof serialized === "string") {
|
|
122
|
+
parsed = JSON.parse(serialized);
|
|
123
|
+
}
|
|
124
|
+
switch (parsed.type) {
|
|
125
|
+
case "string":
|
|
126
|
+
case "number":
|
|
127
|
+
case "boolean":
|
|
128
|
+
case "undefined":
|
|
129
|
+
case "bigint":
|
|
130
|
+
case "null":
|
|
131
|
+
return deserializePrimitives(parsed);
|
|
132
|
+
case "array":
|
|
133
|
+
return parsed.value.map(deserialize);
|
|
134
|
+
case "map": {
|
|
135
|
+
const map = /* @__PURE__ */ new Map();
|
|
136
|
+
for (const [key, val] of parsed.value) {
|
|
137
|
+
map.set(deserialize(key), deserialize(val));
|
|
138
|
+
}
|
|
139
|
+
return map;
|
|
140
|
+
}
|
|
141
|
+
case "set": {
|
|
142
|
+
const set = /* @__PURE__ */ new Set();
|
|
143
|
+
for (const item of parsed.value) {
|
|
144
|
+
set.add(deserialize(item));
|
|
145
|
+
}
|
|
146
|
+
return set;
|
|
147
|
+
}
|
|
148
|
+
case "object": {
|
|
149
|
+
const obj = {};
|
|
150
|
+
for (const [key, val] of Object.entries(parsed.value)) {
|
|
151
|
+
obj[key] = deserialize(val);
|
|
152
|
+
}
|
|
153
|
+
return obj;
|
|
154
|
+
}
|
|
155
|
+
default:
|
|
156
|
+
throw new Error(`Unsupported type during deserialization: ${parsed}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
48
160
|
// src/persistor.ts
|
|
49
161
|
var CACHE_CLIENT = createClient;
|
|
50
162
|
var isTestRunning = process.env.NODE_ENV === "test";
|
|
163
|
+
function toMillis(seconds) {
|
|
164
|
+
return seconds * 1e3;
|
|
165
|
+
}
|
|
51
166
|
var Persistor = class {
|
|
52
167
|
client = null;
|
|
53
168
|
clientId;
|
|
54
169
|
onError;
|
|
55
170
|
onSuccess;
|
|
171
|
+
logger;
|
|
56
172
|
redis;
|
|
57
173
|
constructor({
|
|
58
174
|
redis,
|
|
59
175
|
clientId,
|
|
60
176
|
onSuccess,
|
|
61
|
-
onError
|
|
177
|
+
onError,
|
|
178
|
+
logger
|
|
62
179
|
}) {
|
|
63
|
-
this.onError = onError
|
|
64
|
-
|
|
180
|
+
this.onError = onError || (() => {
|
|
181
|
+
});
|
|
182
|
+
this.onSuccess = onSuccess || (() => {
|
|
183
|
+
});
|
|
65
184
|
this.clientId = clientId;
|
|
185
|
+
this.logger = logger;
|
|
66
186
|
if (redis && !isTestRunning) {
|
|
67
187
|
this.redis = redis;
|
|
68
188
|
} else {
|
|
@@ -73,11 +193,12 @@ var Persistor = class {
|
|
|
73
193
|
}
|
|
74
194
|
}
|
|
75
195
|
async startConnection() {
|
|
196
|
+
var _a;
|
|
76
197
|
try {
|
|
77
198
|
await new Promise((resolve, reject) => {
|
|
78
|
-
var
|
|
199
|
+
var _a2;
|
|
79
200
|
this.client = CACHE_CLIENT({
|
|
80
|
-
url: (
|
|
201
|
+
url: (_a2 = this.redis) == null ? void 0 : _a2.url,
|
|
81
202
|
socket: {
|
|
82
203
|
reconnectStrategy: (retries, cause) => {
|
|
83
204
|
console.error(cause);
|
|
@@ -91,15 +212,17 @@ var Persistor = class {
|
|
|
91
212
|
this.onSuccess();
|
|
92
213
|
resolve(true);
|
|
93
214
|
}).on("reconnecting", () => {
|
|
94
|
-
|
|
215
|
+
var _a3;
|
|
216
|
+
(_a3 = this.logger) == null ? void 0 : _a3.info("reconnecting...", this.clientId);
|
|
95
217
|
}).on("end", () => {
|
|
96
|
-
|
|
218
|
+
var _a3;
|
|
219
|
+
(_a3 = this.logger) == null ? void 0 : _a3.info("end...", this.clientId);
|
|
97
220
|
});
|
|
98
221
|
this.client.connect();
|
|
99
222
|
});
|
|
100
223
|
} catch (ex) {
|
|
101
224
|
this.onError(`${ex}`);
|
|
102
|
-
|
|
225
|
+
(_a = this.logger) == null ? void 0 : _a.error(ex);
|
|
103
226
|
}
|
|
104
227
|
}
|
|
105
228
|
async size() {
|
|
@@ -108,20 +231,6 @@ var Persistor = class {
|
|
|
108
231
|
}
|
|
109
232
|
return await this.client.DBSIZE();
|
|
110
233
|
}
|
|
111
|
-
async get(key) {
|
|
112
|
-
if (!this.client) {
|
|
113
|
-
throw new Error("Client not initialized");
|
|
114
|
-
}
|
|
115
|
-
try {
|
|
116
|
-
const result = await this.client.get(key);
|
|
117
|
-
if (!result) {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
return JSON.parse(result);
|
|
121
|
-
} catch (error) {
|
|
122
|
-
throw new Error(`Error getting data from redis: ${error}`);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
234
|
getClientId() {
|
|
126
235
|
return this.clientId;
|
|
127
236
|
}
|
|
@@ -131,31 +240,77 @@ var Persistor = class {
|
|
|
131
240
|
}
|
|
132
241
|
createOptions(ttl) {
|
|
133
242
|
if (ttl !== null && ttl !== void 0) {
|
|
134
|
-
return { PX: Math.round(ttl) };
|
|
243
|
+
return { PX: Math.round(toMillis(ttl)) };
|
|
135
244
|
}
|
|
136
245
|
return {};
|
|
137
246
|
}
|
|
138
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Set a value in the cache.
|
|
249
|
+
* @param key Cache key.
|
|
250
|
+
* @param object.value Value to set in the cache.
|
|
251
|
+
* @param object.ttl Time to live in seconds.
|
|
252
|
+
* @param object.timestamp Timestamp
|
|
253
|
+
*/
|
|
254
|
+
async set(key, { value, timestamp = Date.now(), ttl }) {
|
|
255
|
+
var _a, _b;
|
|
139
256
|
if (!this.client || !this.client.isReady) {
|
|
140
|
-
|
|
257
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
141
258
|
return;
|
|
142
259
|
}
|
|
143
260
|
try {
|
|
144
|
-
const serializedData = JSON.stringify({
|
|
261
|
+
const serializedData = JSON.stringify({
|
|
262
|
+
value: serialize(value),
|
|
263
|
+
ttl,
|
|
264
|
+
timestamp
|
|
265
|
+
});
|
|
145
266
|
const options = this.createOptions(ttl);
|
|
146
267
|
await this.client.set(key, serializedData, options);
|
|
147
268
|
} catch (error) {
|
|
269
|
+
(_b = this.logger) == null ? void 0 : _b.error(`Error setting data in redis: ${error}`);
|
|
148
270
|
throw new Error(`Error setting data in redis: ${error}`);
|
|
149
271
|
}
|
|
150
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Get a value from the cache.
|
|
275
|
+
* @param key Cache key.
|
|
276
|
+
* @returns GetType<T> value
|
|
277
|
+
*/
|
|
278
|
+
async get(key) {
|
|
279
|
+
var _a, _b;
|
|
280
|
+
if (!this.client) {
|
|
281
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const data = await this.client.get(key);
|
|
286
|
+
if (!data) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
const storedData = JSON.parse(data);
|
|
290
|
+
const deserialized = JSON.parse(storedData.value);
|
|
291
|
+
return {
|
|
292
|
+
...storedData,
|
|
293
|
+
value: deserialize(deserialized)
|
|
294
|
+
};
|
|
295
|
+
} catch (error) {
|
|
296
|
+
(_b = this.logger) == null ? void 0 : _b.error(`Error getting data in redis: ${error}`);
|
|
297
|
+
throw new Error(`Error getting data from redis: ${error}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Delete a value from the cache.
|
|
302
|
+
* @param key Cache key
|
|
303
|
+
*/
|
|
151
304
|
async delete(key) {
|
|
305
|
+
var _a, _b;
|
|
152
306
|
if (!this.client || !this.client.isReady) {
|
|
153
|
-
|
|
307
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
154
308
|
return;
|
|
155
309
|
}
|
|
156
310
|
try {
|
|
157
311
|
await this.client.del(key);
|
|
158
312
|
} catch (error) {
|
|
313
|
+
(_b = this.logger) == null ? void 0 : _b.error(`Error deleting data from redis: ${error}`);
|
|
159
314
|
throw new Error(`Error deleting data from redis: ${error}`);
|
|
160
315
|
}
|
|
161
316
|
}
|
|
@@ -165,6 +320,7 @@ var Persistor = class {
|
|
|
165
320
|
var persistors = {};
|
|
166
321
|
var getPersistor = ({
|
|
167
322
|
redis,
|
|
323
|
+
logger,
|
|
168
324
|
onError,
|
|
169
325
|
onSuccess,
|
|
170
326
|
clientId
|
|
@@ -175,17 +331,18 @@ var getPersistor = ({
|
|
|
175
331
|
redis,
|
|
176
332
|
onError: (error) => {
|
|
177
333
|
onError == null ? void 0 : onError(error);
|
|
178
|
-
|
|
334
|
+
logger == null ? void 0 : logger.error(
|
|
179
335
|
`\u274C REDIS | Client Error | ${connectionName} | ${redis == null ? void 0 : redis.url}: ${error}`
|
|
180
336
|
);
|
|
181
337
|
},
|
|
182
338
|
onSuccess: () => {
|
|
183
339
|
onSuccess == null ? void 0 : onSuccess();
|
|
184
|
-
|
|
340
|
+
logger == null ? void 0 : logger.info(
|
|
185
341
|
`\u{1F4E6} REDIS | Connection Ready | ${connectionName} | ${redis == null ? void 0 : redis.url}`
|
|
186
342
|
);
|
|
187
343
|
},
|
|
188
|
-
clientId
|
|
344
|
+
clientId,
|
|
345
|
+
logger
|
|
189
346
|
});
|
|
190
347
|
}
|
|
191
348
|
return persistors[connectionName];
|
|
@@ -206,13 +363,15 @@ var PromiseCache = class {
|
|
|
206
363
|
caseSensitive = false,
|
|
207
364
|
redis,
|
|
208
365
|
onSuccess,
|
|
209
|
-
onError
|
|
366
|
+
onError,
|
|
367
|
+
logger
|
|
210
368
|
}) {
|
|
211
369
|
this.persistor = getPersistor({
|
|
212
370
|
redis,
|
|
213
371
|
onError,
|
|
214
372
|
onSuccess,
|
|
215
|
-
clientId: this.clientId
|
|
373
|
+
clientId: this.clientId,
|
|
374
|
+
logger
|
|
216
375
|
});
|
|
217
376
|
this.caseSensitive = caseSensitive;
|
|
218
377
|
if (ttlInSeconds) {
|
|
@@ -227,14 +386,14 @@ var PromiseCache = class {
|
|
|
227
386
|
return await this.persistor.size();
|
|
228
387
|
}
|
|
229
388
|
/**
|
|
230
|
-
*
|
|
389
|
+
* Override a value in the cache.
|
|
231
390
|
* @param key Cache key.
|
|
232
391
|
* @param value Cache value.
|
|
233
392
|
* @param ttlInSeconds Time to live in seconds.
|
|
234
393
|
*/
|
|
235
394
|
async override(key, value, ttlInSeconds) {
|
|
236
395
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
237
|
-
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds
|
|
396
|
+
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds : this.ttl;
|
|
238
397
|
await this.persistor.set(effectiveKey, {
|
|
239
398
|
value,
|
|
240
399
|
timestamp: Date.now(),
|
|
@@ -285,8 +444,6 @@ var PromiseCache = class {
|
|
|
285
444
|
}
|
|
286
445
|
};
|
|
287
446
|
export {
|
|
288
|
-
LocalStorage,
|
|
289
447
|
Persistor,
|
|
290
|
-
PromiseCache
|
|
291
|
-
createLocalMemoryClient
|
|
448
|
+
PromiseCache
|
|
292
449
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebspark/promise-cache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"tsconfig": "*"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"redis": "4.7.0"
|
|
23
|
-
"@sebspark/retry": "*"
|
|
22
|
+
"redis": "4.7.0"
|
|
24
23
|
}
|
|
25
24
|
}
|