@sebspark/promise-cache 2.1.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -13
- package/dist/index.d.mts +28 -23
- package/dist/index.d.ts +28 -23
- package/dist/index.js +190 -40
- package/dist/index.mjs +189 -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,26 +267,67 @@ 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;
|
|
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) {
|
|
177
296
|
throw new Error(`Error setting data in redis: ${error}`);
|
|
178
297
|
}
|
|
179
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* Get a value from the cache.
|
|
301
|
+
* @param key Cache key.
|
|
302
|
+
* @returns GetType<T> value
|
|
303
|
+
*/
|
|
304
|
+
async get(key) {
|
|
305
|
+
if (!this.client) {
|
|
306
|
+
throw new Error("Client not initialized");
|
|
307
|
+
}
|
|
308
|
+
try {
|
|
309
|
+
const data = await this.client.get(key);
|
|
310
|
+
if (!data) {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
const storedData = JSON.parse(data);
|
|
314
|
+
const deserialized = JSON.parse(storedData.value);
|
|
315
|
+
return {
|
|
316
|
+
...storedData,
|
|
317
|
+
value: deserialize(deserialized)
|
|
318
|
+
};
|
|
319
|
+
} catch (error) {
|
|
320
|
+
throw new Error(`Error getting data from redis: ${error}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Delete a value from the cache.
|
|
325
|
+
* @param key Cache key
|
|
326
|
+
*/
|
|
180
327
|
async delete(key) {
|
|
328
|
+
var _a;
|
|
181
329
|
if (!this.client || !this.client.isReady) {
|
|
182
|
-
|
|
330
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
183
331
|
return;
|
|
184
332
|
}
|
|
185
333
|
try {
|
|
@@ -194,6 +342,7 @@ var Persistor = class {
|
|
|
194
342
|
var persistors = {};
|
|
195
343
|
var getPersistor = ({
|
|
196
344
|
redis,
|
|
345
|
+
logger,
|
|
197
346
|
onError,
|
|
198
347
|
onSuccess,
|
|
199
348
|
clientId
|
|
@@ -204,17 +353,18 @@ var getPersistor = ({
|
|
|
204
353
|
redis,
|
|
205
354
|
onError: (error) => {
|
|
206
355
|
onError == null ? void 0 : onError(error);
|
|
207
|
-
|
|
356
|
+
logger == null ? void 0 : logger.error(
|
|
208
357
|
`\u274C REDIS | Client Error | ${connectionName} | ${redis == null ? void 0 : redis.url}: ${error}`
|
|
209
358
|
);
|
|
210
359
|
},
|
|
211
360
|
onSuccess: () => {
|
|
212
361
|
onSuccess == null ? void 0 : onSuccess();
|
|
213
|
-
|
|
362
|
+
logger == null ? void 0 : logger.info(
|
|
214
363
|
`\u{1F4E6} REDIS | Connection Ready | ${connectionName} | ${redis == null ? void 0 : redis.url}`
|
|
215
364
|
);
|
|
216
365
|
},
|
|
217
|
-
clientId
|
|
366
|
+
clientId,
|
|
367
|
+
logger
|
|
218
368
|
});
|
|
219
369
|
}
|
|
220
370
|
return persistors[connectionName];
|
|
@@ -235,13 +385,15 @@ var PromiseCache = class {
|
|
|
235
385
|
caseSensitive = false,
|
|
236
386
|
redis,
|
|
237
387
|
onSuccess,
|
|
238
|
-
onError
|
|
388
|
+
onError,
|
|
389
|
+
logger
|
|
239
390
|
}) {
|
|
240
391
|
this.persistor = getPersistor({
|
|
241
392
|
redis,
|
|
242
393
|
onError,
|
|
243
394
|
onSuccess,
|
|
244
|
-
clientId: this.clientId
|
|
395
|
+
clientId: this.clientId,
|
|
396
|
+
logger
|
|
245
397
|
});
|
|
246
398
|
this.caseSensitive = caseSensitive;
|
|
247
399
|
if (ttlInSeconds) {
|
|
@@ -256,14 +408,14 @@ var PromiseCache = class {
|
|
|
256
408
|
return await this.persistor.size();
|
|
257
409
|
}
|
|
258
410
|
/**
|
|
259
|
-
*
|
|
411
|
+
* Override a value in the cache.
|
|
260
412
|
* @param key Cache key.
|
|
261
413
|
* @param value Cache value.
|
|
262
414
|
* @param ttlInSeconds Time to live in seconds.
|
|
263
415
|
*/
|
|
264
416
|
async override(key, value, ttlInSeconds) {
|
|
265
417
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
266
|
-
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds
|
|
418
|
+
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds : this.ttl;
|
|
267
419
|
await this.persistor.set(effectiveKey, {
|
|
268
420
|
value,
|
|
269
421
|
timestamp: Date.now(),
|
|
@@ -315,8 +467,6 @@ var PromiseCache = class {
|
|
|
315
467
|
};
|
|
316
468
|
// Annotate the CommonJS export names for ESM import in node:
|
|
317
469
|
0 && (module.exports = {
|
|
318
|
-
LocalStorage,
|
|
319
470
|
Persistor,
|
|
320
|
-
PromiseCache
|
|
321
|
-
createLocalMemoryClient
|
|
471
|
+
PromiseCache
|
|
322
472
|
});
|
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,26 +240,67 @@ 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;
|
|
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) {
|
|
148
269
|
throw new Error(`Error setting data in redis: ${error}`);
|
|
149
270
|
}
|
|
150
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Get a value from the cache.
|
|
274
|
+
* @param key Cache key.
|
|
275
|
+
* @returns GetType<T> value
|
|
276
|
+
*/
|
|
277
|
+
async get(key) {
|
|
278
|
+
if (!this.client) {
|
|
279
|
+
throw new Error("Client not initialized");
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
const data = await this.client.get(key);
|
|
283
|
+
if (!data) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
const storedData = JSON.parse(data);
|
|
287
|
+
const deserialized = JSON.parse(storedData.value);
|
|
288
|
+
return {
|
|
289
|
+
...storedData,
|
|
290
|
+
value: deserialize(deserialized)
|
|
291
|
+
};
|
|
292
|
+
} catch (error) {
|
|
293
|
+
throw new Error(`Error getting data from redis: ${error}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Delete a value from the cache.
|
|
298
|
+
* @param key Cache key
|
|
299
|
+
*/
|
|
151
300
|
async delete(key) {
|
|
301
|
+
var _a;
|
|
152
302
|
if (!this.client || !this.client.isReady) {
|
|
153
|
-
|
|
303
|
+
(_a = this.logger) == null ? void 0 : _a.error("Client not ready");
|
|
154
304
|
return;
|
|
155
305
|
}
|
|
156
306
|
try {
|
|
@@ -165,6 +315,7 @@ var Persistor = class {
|
|
|
165
315
|
var persistors = {};
|
|
166
316
|
var getPersistor = ({
|
|
167
317
|
redis,
|
|
318
|
+
logger,
|
|
168
319
|
onError,
|
|
169
320
|
onSuccess,
|
|
170
321
|
clientId
|
|
@@ -175,17 +326,18 @@ var getPersistor = ({
|
|
|
175
326
|
redis,
|
|
176
327
|
onError: (error) => {
|
|
177
328
|
onError == null ? void 0 : onError(error);
|
|
178
|
-
|
|
329
|
+
logger == null ? void 0 : logger.error(
|
|
179
330
|
`\u274C REDIS | Client Error | ${connectionName} | ${redis == null ? void 0 : redis.url}: ${error}`
|
|
180
331
|
);
|
|
181
332
|
},
|
|
182
333
|
onSuccess: () => {
|
|
183
334
|
onSuccess == null ? void 0 : onSuccess();
|
|
184
|
-
|
|
335
|
+
logger == null ? void 0 : logger.info(
|
|
185
336
|
`\u{1F4E6} REDIS | Connection Ready | ${connectionName} | ${redis == null ? void 0 : redis.url}`
|
|
186
337
|
);
|
|
187
338
|
},
|
|
188
|
-
clientId
|
|
339
|
+
clientId,
|
|
340
|
+
logger
|
|
189
341
|
});
|
|
190
342
|
}
|
|
191
343
|
return persistors[connectionName];
|
|
@@ -206,13 +358,15 @@ var PromiseCache = class {
|
|
|
206
358
|
caseSensitive = false,
|
|
207
359
|
redis,
|
|
208
360
|
onSuccess,
|
|
209
|
-
onError
|
|
361
|
+
onError,
|
|
362
|
+
logger
|
|
210
363
|
}) {
|
|
211
364
|
this.persistor = getPersistor({
|
|
212
365
|
redis,
|
|
213
366
|
onError,
|
|
214
367
|
onSuccess,
|
|
215
|
-
clientId: this.clientId
|
|
368
|
+
clientId: this.clientId,
|
|
369
|
+
logger
|
|
216
370
|
});
|
|
217
371
|
this.caseSensitive = caseSensitive;
|
|
218
372
|
if (ttlInSeconds) {
|
|
@@ -227,14 +381,14 @@ var PromiseCache = class {
|
|
|
227
381
|
return await this.persistor.size();
|
|
228
382
|
}
|
|
229
383
|
/**
|
|
230
|
-
*
|
|
384
|
+
* Override a value in the cache.
|
|
231
385
|
* @param key Cache key.
|
|
232
386
|
* @param value Cache value.
|
|
233
387
|
* @param ttlInSeconds Time to live in seconds.
|
|
234
388
|
*/
|
|
235
389
|
async override(key, value, ttlInSeconds) {
|
|
236
390
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
237
|
-
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds
|
|
391
|
+
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds : this.ttl;
|
|
238
392
|
await this.persistor.set(effectiveKey, {
|
|
239
393
|
value,
|
|
240
394
|
timestamp: Date.now(),
|
|
@@ -285,8 +439,6 @@ var PromiseCache = class {
|
|
|
285
439
|
}
|
|
286
440
|
};
|
|
287
441
|
export {
|
|
288
|
-
LocalStorage,
|
|
289
442
|
Persistor,
|
|
290
|
-
PromiseCache
|
|
291
|
-
createLocalMemoryClient
|
|
443
|
+
PromiseCache
|
|
292
444
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebspark/promise-cache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
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
|
}
|