@sebspark/promise-cache 0.2.0 → 0.2.2
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/dist/index.d.mts +31 -3
- package/dist/index.d.ts +31 -3
- package/dist/index.js +105 -9
- package/dist/index.mjs +105 -9
- package/package.json +4 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type GetType<T> = {
|
|
2
|
+
value: T;
|
|
3
|
+
ttl: number;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
};
|
|
6
|
+
type SetParams<T> = {
|
|
7
|
+
value: T;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
ttl: number;
|
|
10
|
+
};
|
|
11
|
+
declare class Persistor {
|
|
12
|
+
private client;
|
|
13
|
+
status: 'connected' | 'disconnected';
|
|
14
|
+
constructor();
|
|
15
|
+
connect(): Promise<void>;
|
|
16
|
+
size(): Promise<number>;
|
|
17
|
+
get<T>(key: string): Promise<GetType<T> | null>;
|
|
18
|
+
set<T>(key: string, { value, timestamp, ttl }: SetParams<T>): Promise<void>;
|
|
19
|
+
delete(key: string): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare class PromiseCache<U> {
|
|
23
|
+
persistor: Persistor;
|
|
3
24
|
private readonly caseSensitive;
|
|
4
25
|
private readonly ttl;
|
|
5
26
|
/**
|
|
@@ -12,7 +33,14 @@ declare class PromiseCache<T, U> {
|
|
|
12
33
|
* Cache size.
|
|
13
34
|
* @returns The number of entries in the cache.
|
|
14
35
|
*/
|
|
15
|
-
size(): number
|
|
36
|
+
size(): Promise<number>;
|
|
37
|
+
/**
|
|
38
|
+
* Set a value in the cache.
|
|
39
|
+
* @param key Cache key.
|
|
40
|
+
* @param value Cache value.
|
|
41
|
+
* @param ttlInSeconds Time to live in seconds.
|
|
42
|
+
*/
|
|
43
|
+
override<U>(key: string, value: U, ttlInSeconds?: number): Promise<void>;
|
|
16
44
|
/**
|
|
17
45
|
* A simple promise cache wrapper.
|
|
18
46
|
* @param key Cache key.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type GetType<T> = {
|
|
2
|
+
value: T;
|
|
3
|
+
ttl: number;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
};
|
|
6
|
+
type SetParams<T> = {
|
|
7
|
+
value: T;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
ttl: number;
|
|
10
|
+
};
|
|
11
|
+
declare class Persistor {
|
|
12
|
+
private client;
|
|
13
|
+
status: 'connected' | 'disconnected';
|
|
14
|
+
constructor();
|
|
15
|
+
connect(): Promise<void>;
|
|
16
|
+
size(): Promise<number>;
|
|
17
|
+
get<T>(key: string): Promise<GetType<T> | null>;
|
|
18
|
+
set<T>(key: string, { value, timestamp, ttl }: SetParams<T>): Promise<void>;
|
|
19
|
+
delete(key: string): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare class PromiseCache<U> {
|
|
23
|
+
persistor: Persistor;
|
|
3
24
|
private readonly caseSensitive;
|
|
4
25
|
private readonly ttl;
|
|
5
26
|
/**
|
|
@@ -12,7 +33,14 @@ declare class PromiseCache<T, U> {
|
|
|
12
33
|
* Cache size.
|
|
13
34
|
* @returns The number of entries in the cache.
|
|
14
35
|
*/
|
|
15
|
-
size(): number
|
|
36
|
+
size(): Promise<number>;
|
|
37
|
+
/**
|
|
38
|
+
* Set a value in the cache.
|
|
39
|
+
* @param key Cache key.
|
|
40
|
+
* @param value Cache value.
|
|
41
|
+
* @param ttlInSeconds Time to live in seconds.
|
|
42
|
+
*/
|
|
43
|
+
override<U>(key: string, value: U, ttlInSeconds?: number): Promise<void>;
|
|
16
44
|
/**
|
|
17
45
|
* A simple promise cache wrapper.
|
|
18
46
|
* @param key Cache key.
|
package/dist/index.js
CHANGED
|
@@ -24,9 +24,93 @@ __export(src_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(src_exports);
|
|
26
26
|
|
|
27
|
+
// src/persistor.ts
|
|
28
|
+
var import_redis = require("redis");
|
|
29
|
+
var REDIS_HOST = process.env.REDIS_HOST || "127.0.0.1";
|
|
30
|
+
var REDIS_PORT = process.env.REDIS_PORT || 6379;
|
|
31
|
+
var REDIS_URL = `redis://${REDIS_HOST}:${REDIS_PORT}`;
|
|
32
|
+
var Persistor = class {
|
|
33
|
+
client;
|
|
34
|
+
status = "disconnected";
|
|
35
|
+
constructor() {
|
|
36
|
+
this.connect();
|
|
37
|
+
}
|
|
38
|
+
async connect() {
|
|
39
|
+
try {
|
|
40
|
+
this.client = await (0, import_redis.createClient)({ url: REDIS_URL });
|
|
41
|
+
this.client.on("error", (err) => {
|
|
42
|
+
console.error(`\u274C REDIS | Client Error | ${REDIS_URL}`, err);
|
|
43
|
+
this.status = "disconnected";
|
|
44
|
+
});
|
|
45
|
+
this.client.connect();
|
|
46
|
+
await new Promise((resolve, reject) => {
|
|
47
|
+
if (!this.client) {
|
|
48
|
+
reject("Client not initialized");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.client.on("connect", () => {
|
|
52
|
+
console.info(`\u{1F4E6} REDIS | Connection Ready | ${REDIS_URL}`);
|
|
53
|
+
this.status = "connected";
|
|
54
|
+
resolve(true);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error(`\u274C REDIS | Connection Error | ${REDIS_URL}`, err);
|
|
59
|
+
this.status = "disconnected";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async size() {
|
|
63
|
+
if (!this.client) {
|
|
64
|
+
throw new Error("Client not initialized");
|
|
65
|
+
}
|
|
66
|
+
return await this.client.DBSIZE();
|
|
67
|
+
}
|
|
68
|
+
async get(key) {
|
|
69
|
+
if (!this.client) {
|
|
70
|
+
throw new Error("Client not initialized");
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const result = await this.client.get(key);
|
|
74
|
+
if (!result) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return JSON.parse(result);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error(`Error getting data from redis: ${error}`);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async set(key, { value, timestamp, ttl }) {
|
|
84
|
+
if (!this.client) {
|
|
85
|
+
throw new Error("Client not initialized");
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const serializedData = JSON.stringify({ value, ttl, timestamp });
|
|
89
|
+
await this.client.set(key, serializedData, {
|
|
90
|
+
EX: ttl / 1e3
|
|
91
|
+
});
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error(`Error setting data in redis: ${error}`);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async delete(key) {
|
|
98
|
+
if (!this.client) {
|
|
99
|
+
throw new Error("Client not initialized");
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
await this.client.del(key);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error(`Error deleting data from redis: ${error}`);
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
var persistor = new Persistor();
|
|
110
|
+
|
|
27
111
|
// src/promiseCache.ts
|
|
28
112
|
var PromiseCache = class {
|
|
29
|
-
|
|
113
|
+
persistor;
|
|
30
114
|
caseSensitive;
|
|
31
115
|
ttl;
|
|
32
116
|
// Time to live in milliseconds.
|
|
@@ -36,7 +120,7 @@ var PromiseCache = class {
|
|
|
36
120
|
* @param caseSensitive Set to true if you want to differentiate between keys with different casing.
|
|
37
121
|
*/
|
|
38
122
|
constructor(ttlInSeconds, caseSensitive = false) {
|
|
39
|
-
this.
|
|
123
|
+
this.persistor = persistor;
|
|
40
124
|
this.caseSensitive = caseSensitive;
|
|
41
125
|
this.ttl = ttlInSeconds * 1e3;
|
|
42
126
|
}
|
|
@@ -44,8 +128,23 @@ var PromiseCache = class {
|
|
|
44
128
|
* Cache size.
|
|
45
129
|
* @returns The number of entries in the cache.
|
|
46
130
|
*/
|
|
47
|
-
size() {
|
|
48
|
-
return this.
|
|
131
|
+
async size() {
|
|
132
|
+
return await this.persistor.size();
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Set a value in the cache.
|
|
136
|
+
* @param key Cache key.
|
|
137
|
+
* @param value Cache value.
|
|
138
|
+
* @param ttlInSeconds Time to live in seconds.
|
|
139
|
+
*/
|
|
140
|
+
async override(key, value, ttlInSeconds) {
|
|
141
|
+
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
142
|
+
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds * 1e3 : this.ttl;
|
|
143
|
+
await this.persistor.set(effectiveKey, {
|
|
144
|
+
value,
|
|
145
|
+
timestamp: Date.now(),
|
|
146
|
+
ttl: effectiveTTL
|
|
147
|
+
});
|
|
49
148
|
}
|
|
50
149
|
/**
|
|
51
150
|
* A simple promise cache wrapper.
|
|
@@ -58,7 +157,7 @@ var PromiseCache = class {
|
|
|
58
157
|
const now = Date.now();
|
|
59
158
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
60
159
|
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds * 1e3 : this.ttl;
|
|
61
|
-
const cached = this.
|
|
160
|
+
const cached = await this.persistor.get(effectiveKey);
|
|
62
161
|
if (cached) {
|
|
63
162
|
if (cached.ttl !== effectiveTTL) {
|
|
64
163
|
console.error(
|
|
@@ -68,14 +167,11 @@ var PromiseCache = class {
|
|
|
68
167
|
return cached.value;
|
|
69
168
|
}
|
|
70
169
|
const response = await delegate();
|
|
71
|
-
this.
|
|
170
|
+
this.persistor.set(effectiveKey, {
|
|
72
171
|
value: response,
|
|
73
172
|
timestamp: now,
|
|
74
173
|
ttl: effectiveTTL
|
|
75
174
|
});
|
|
76
|
-
setTimeout(() => {
|
|
77
|
-
this.cache.delete(effectiveKey);
|
|
78
|
-
}, effectiveTTL);
|
|
79
175
|
return response;
|
|
80
176
|
}
|
|
81
177
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,90 @@
|
|
|
1
|
+
// src/persistor.ts
|
|
2
|
+
import { createClient } from "redis";
|
|
3
|
+
var REDIS_HOST = process.env.REDIS_HOST || "127.0.0.1";
|
|
4
|
+
var REDIS_PORT = process.env.REDIS_PORT || 6379;
|
|
5
|
+
var REDIS_URL = `redis://${REDIS_HOST}:${REDIS_PORT}`;
|
|
6
|
+
var Persistor = class {
|
|
7
|
+
client;
|
|
8
|
+
status = "disconnected";
|
|
9
|
+
constructor() {
|
|
10
|
+
this.connect();
|
|
11
|
+
}
|
|
12
|
+
async connect() {
|
|
13
|
+
try {
|
|
14
|
+
this.client = await createClient({ url: REDIS_URL });
|
|
15
|
+
this.client.on("error", (err) => {
|
|
16
|
+
console.error(`\u274C REDIS | Client Error | ${REDIS_URL}`, err);
|
|
17
|
+
this.status = "disconnected";
|
|
18
|
+
});
|
|
19
|
+
this.client.connect();
|
|
20
|
+
await new Promise((resolve, reject) => {
|
|
21
|
+
if (!this.client) {
|
|
22
|
+
reject("Client not initialized");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.client.on("connect", () => {
|
|
26
|
+
console.info(`\u{1F4E6} REDIS | Connection Ready | ${REDIS_URL}`);
|
|
27
|
+
this.status = "connected";
|
|
28
|
+
resolve(true);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error(`\u274C REDIS | Connection Error | ${REDIS_URL}`, err);
|
|
33
|
+
this.status = "disconnected";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async size() {
|
|
37
|
+
if (!this.client) {
|
|
38
|
+
throw new Error("Client not initialized");
|
|
39
|
+
}
|
|
40
|
+
return await this.client.DBSIZE();
|
|
41
|
+
}
|
|
42
|
+
async get(key) {
|
|
43
|
+
if (!this.client) {
|
|
44
|
+
throw new Error("Client not initialized");
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const result = await this.client.get(key);
|
|
48
|
+
if (!result) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return JSON.parse(result);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error(`Error getting data from redis: ${error}`);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async set(key, { value, timestamp, ttl }) {
|
|
58
|
+
if (!this.client) {
|
|
59
|
+
throw new Error("Client not initialized");
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const serializedData = JSON.stringify({ value, ttl, timestamp });
|
|
63
|
+
await this.client.set(key, serializedData, {
|
|
64
|
+
EX: ttl / 1e3
|
|
65
|
+
});
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error(`Error setting data in redis: ${error}`);
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async delete(key) {
|
|
72
|
+
if (!this.client) {
|
|
73
|
+
throw new Error("Client not initialized");
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
await this.client.del(key);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error(`Error deleting data from redis: ${error}`);
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var persistor = new Persistor();
|
|
84
|
+
|
|
1
85
|
// src/promiseCache.ts
|
|
2
86
|
var PromiseCache = class {
|
|
3
|
-
|
|
87
|
+
persistor;
|
|
4
88
|
caseSensitive;
|
|
5
89
|
ttl;
|
|
6
90
|
// Time to live in milliseconds.
|
|
@@ -10,7 +94,7 @@ var PromiseCache = class {
|
|
|
10
94
|
* @param caseSensitive Set to true if you want to differentiate between keys with different casing.
|
|
11
95
|
*/
|
|
12
96
|
constructor(ttlInSeconds, caseSensitive = false) {
|
|
13
|
-
this.
|
|
97
|
+
this.persistor = persistor;
|
|
14
98
|
this.caseSensitive = caseSensitive;
|
|
15
99
|
this.ttl = ttlInSeconds * 1e3;
|
|
16
100
|
}
|
|
@@ -18,8 +102,23 @@ var PromiseCache = class {
|
|
|
18
102
|
* Cache size.
|
|
19
103
|
* @returns The number of entries in the cache.
|
|
20
104
|
*/
|
|
21
|
-
size() {
|
|
22
|
-
return this.
|
|
105
|
+
async size() {
|
|
106
|
+
return await this.persistor.size();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Set a value in the cache.
|
|
110
|
+
* @param key Cache key.
|
|
111
|
+
* @param value Cache value.
|
|
112
|
+
* @param ttlInSeconds Time to live in seconds.
|
|
113
|
+
*/
|
|
114
|
+
async override(key, value, ttlInSeconds) {
|
|
115
|
+
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
116
|
+
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds * 1e3 : this.ttl;
|
|
117
|
+
await this.persistor.set(effectiveKey, {
|
|
118
|
+
value,
|
|
119
|
+
timestamp: Date.now(),
|
|
120
|
+
ttl: effectiveTTL
|
|
121
|
+
});
|
|
23
122
|
}
|
|
24
123
|
/**
|
|
25
124
|
* A simple promise cache wrapper.
|
|
@@ -32,7 +131,7 @@ var PromiseCache = class {
|
|
|
32
131
|
const now = Date.now();
|
|
33
132
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
34
133
|
const effectiveTTL = ttlInSeconds !== void 0 ? ttlInSeconds * 1e3 : this.ttl;
|
|
35
|
-
const cached = this.
|
|
134
|
+
const cached = await this.persistor.get(effectiveKey);
|
|
36
135
|
if (cached) {
|
|
37
136
|
if (cached.ttl !== effectiveTTL) {
|
|
38
137
|
console.error(
|
|
@@ -42,14 +141,11 @@ var PromiseCache = class {
|
|
|
42
141
|
return cached.value;
|
|
43
142
|
}
|
|
44
143
|
const response = await delegate();
|
|
45
|
-
this.
|
|
144
|
+
this.persistor.set(effectiveKey, {
|
|
46
145
|
value: response,
|
|
47
146
|
timestamp: now,
|
|
48
147
|
ttl: effectiveTTL
|
|
49
148
|
});
|
|
50
|
-
setTimeout(() => {
|
|
51
|
-
this.cache.delete(effectiveKey);
|
|
52
|
-
}, effectiveTTL);
|
|
53
149
|
return response;
|
|
54
150
|
}
|
|
55
151
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebspark/promise-cache",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -15,5 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"tsconfig": "*"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"redis": "^4.6.13"
|
|
18
21
|
}
|
|
19
22
|
}
|