@bejibun/cache 0.1.13 → 0.1.15
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/CHANGELOG.md +44 -1
- package/README.md +4 -1
- package/builders/CacheBuilder.d.ts +5 -1
- package/builders/CacheBuilder.js +69 -36
- package/config/cache.js +4 -1
- package/enums/CacheDriverEnum.d.ts +5 -0
- package/enums/CacheDriverEnum.js +6 -0
- package/enums/index.d.ts +1 -0
- package/enums/index.js +1 -0
- package/facades/Cache.d.ts +2 -0
- package/facades/Cache.js +3 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,10 +3,53 @@ All notable changes to this project will be documented in this file.
|
|
|
3
3
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
## [v0.1.
|
|
6
|
+
## [v0.1.15](https://github.com/crenata/bejibun-cache/compare/v0.1.14...v0.1.15) - 2025-12-14
|
|
7
7
|
|
|
8
8
|
### 🩹 Fixes
|
|
9
9
|
|
|
10
|
+
### 📖 Changes
|
|
11
|
+
What's New :
|
|
12
|
+
- Added `connection()` to override cache connection.
|
|
13
|
+
|
|
14
|
+
Makes it more flexible by overriding connections at runtime.
|
|
15
|
+
|
|
16
|
+
- Added `driver` configuration.
|
|
17
|
+
|
|
18
|
+
#### What's its use?
|
|
19
|
+
The cache connection name is no longer static as before.
|
|
20
|
+
|
|
21
|
+
e.g. :
|
|
22
|
+
```text
|
|
23
|
+
connections: {
|
|
24
|
+
local: {
|
|
25
|
+
path: App.Path.storagePath("cache") // absolute path
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
You can now create a connection with any name and specify which driver to use.
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
connections: {
|
|
34
|
+
custom_name: {
|
|
35
|
+
driver: CacheDriverEnum.Local, // "local", "redis"
|
|
36
|
+
path: App.Path.storagePath("custom-cache")
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### ❤️Contributors
|
|
42
|
+
- Havea Crenata ([@crenata](https://github.com/crenata))
|
|
43
|
+
|
|
44
|
+
**Full Changelog**: https://github.com/crenata/bejibun-cache/blob/master/CHANGELOG.md
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## [v0.1.14](https://github.com/crenata/bejibun-cache/compare/v0.1.12...v0.1.14) - 2025-12-12
|
|
49
|
+
|
|
50
|
+
### 🩹 Fixes
|
|
51
|
+
- Redis connection with Cache own configuration - [#1](https://github.com/crenata/bejibun-core/issues/1)
|
|
52
|
+
|
|
10
53
|
### 📖 Changes
|
|
11
54
|
What's New :
|
|
12
55
|
- Adding `ttl` supports for file scheme.
|
package/README.md
CHANGED
|
@@ -39,17 +39,20 @@ config/cache.ts
|
|
|
39
39
|
|
|
40
40
|
```ts
|
|
41
41
|
import App from "@bejibun/app";
|
|
42
|
+
import CacheDriverEnum from "@bejibun/utils/enums/CacheDriverEnum";
|
|
42
43
|
|
|
43
44
|
const config: Record<string, any> = {
|
|
44
45
|
connection: "local",
|
|
45
46
|
|
|
46
47
|
connections: {
|
|
47
48
|
local: {
|
|
49
|
+
driver: CacheDriverEnum.Local,
|
|
48
50
|
path: App.Path.storagePath("cache") // absolute path
|
|
49
51
|
},
|
|
50
52
|
|
|
51
53
|
redis: {
|
|
52
|
-
|
|
54
|
+
driver: CacheDriverEnum.Redis,
|
|
55
|
+
host: "127.0.0.1",
|
|
53
56
|
port: 6379,
|
|
54
57
|
password: "",
|
|
55
58
|
database: 0
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
export default class CacheBuilder {
|
|
2
2
|
protected conf: Record<string, any>;
|
|
3
|
+
protected conn?: string;
|
|
3
4
|
protected prefix: string;
|
|
5
|
+
protected redis: Record<string, Function>;
|
|
4
6
|
constructor();
|
|
5
7
|
private get config();
|
|
8
|
+
private get currentConnection();
|
|
9
|
+
private get driver();
|
|
6
10
|
private key;
|
|
7
|
-
private connection;
|
|
8
11
|
private filePath;
|
|
9
12
|
private file;
|
|
10
13
|
private setFile;
|
|
11
14
|
private getFile;
|
|
15
|
+
connection(conn: string): CacheBuilder;
|
|
12
16
|
remember(key: string, callback: Function, ttl?: number): Promise<any>;
|
|
13
17
|
has(key: string): Promise<boolean>;
|
|
14
18
|
get(key: string): Promise<any>;
|
package/builders/CacheBuilder.js
CHANGED
|
@@ -3,13 +3,17 @@ import Logger from "@bejibun/logger";
|
|
|
3
3
|
import Redis from "@bejibun/redis";
|
|
4
4
|
import Luxon from "@bejibun/utils/facades/Luxon";
|
|
5
5
|
import { defineValue, isEmpty, isNotEmpty } from "@bejibun/utils";
|
|
6
|
+
import Enum from "@bejibun/utils/facades/Enum";
|
|
6
7
|
import fs from "fs";
|
|
7
8
|
import path from "path";
|
|
8
9
|
import CacheConfig from "../config/cache";
|
|
9
10
|
import CacheException from "../exceptions/CacheException";
|
|
11
|
+
import CacheDriverEnum from "../enums/CacheDriverEnum";
|
|
10
12
|
export default class CacheBuilder {
|
|
11
13
|
conf;
|
|
14
|
+
conn;
|
|
12
15
|
prefix;
|
|
16
|
+
redis;
|
|
13
17
|
constructor() {
|
|
14
18
|
const configPath = App.Path.configPath("cache.ts");
|
|
15
19
|
let config;
|
|
@@ -17,31 +21,56 @@ export default class CacheBuilder {
|
|
|
17
21
|
config = require(configPath).default;
|
|
18
22
|
else
|
|
19
23
|
config = CacheConfig;
|
|
24
|
+
const redisConnection = defineValue(config.connections?.redis, {
|
|
25
|
+
host: "127.0.0.1",
|
|
26
|
+
port: 6379,
|
|
27
|
+
password: "",
|
|
28
|
+
database: 0
|
|
29
|
+
});
|
|
20
30
|
this.conf = config;
|
|
21
31
|
this.prefix = "bejibun-cache";
|
|
32
|
+
this.redis = Redis.setClient({
|
|
33
|
+
host: redisConnection.host,
|
|
34
|
+
port: redisConnection.port,
|
|
35
|
+
password: redisConnection.password,
|
|
36
|
+
database: redisConnection.database
|
|
37
|
+
});
|
|
22
38
|
}
|
|
23
39
|
get config() {
|
|
24
40
|
if (isEmpty(this.conf))
|
|
25
41
|
throw new CacheException("There is no config provided.");
|
|
26
42
|
return this.conf;
|
|
27
43
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
44
|
+
get currentConnection() {
|
|
45
|
+
return this.config.connections[defineValue(this.conn, this.config.connection)];
|
|
46
|
+
}
|
|
47
|
+
get driver() {
|
|
48
|
+
const driver = defineValue(this.currentConnection?.driver);
|
|
49
|
+
if (isEmpty(driver))
|
|
50
|
+
throw new CacheException(`Missing "driver" on cache config.`);
|
|
51
|
+
if (!Enum.setEnums(CacheDriverEnum).hasValue(driver))
|
|
52
|
+
throw new CacheException(`Not supported "driver" cache.`);
|
|
53
|
+
switch (driver) {
|
|
34
54
|
case "local":
|
|
35
|
-
|
|
55
|
+
if (isEmpty(this.currentConnection?.path))
|
|
56
|
+
throw new CacheException(`Missing "path" for "local" cache configuration.`);
|
|
57
|
+
break;
|
|
58
|
+
case "redis":
|
|
59
|
+
if (isEmpty(this.currentConnection?.host))
|
|
60
|
+
throw new CacheException(`Missing "host" for "redis" cache configuration.`);
|
|
61
|
+
if (isEmpty(this.currentConnection?.port))
|
|
62
|
+
throw new CacheException(`Missing "port" for "redis" cache configuration.`);
|
|
63
|
+
break;
|
|
36
64
|
default:
|
|
37
|
-
|
|
38
|
-
}
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
return driver;
|
|
39
68
|
}
|
|
40
|
-
|
|
41
|
-
return this.
|
|
69
|
+
key(key) {
|
|
70
|
+
return `${this.prefix}-${key.replaceAll("/", "-").replaceAll(" ", "-")}`;
|
|
42
71
|
}
|
|
43
72
|
filePath(key) {
|
|
44
|
-
return path.resolve(this.
|
|
73
|
+
return path.resolve(this.currentConnection.path, `${this.key(key)}.cache`);
|
|
45
74
|
}
|
|
46
75
|
file(key) {
|
|
47
76
|
return Bun.file(this.filePath(key));
|
|
@@ -50,7 +79,7 @@ export default class CacheBuilder {
|
|
|
50
79
|
ttl = defineValue(ttl, "");
|
|
51
80
|
if (isNotEmpty(ttl))
|
|
52
81
|
ttl = Luxon.DateTime.now().toUnixInteger() + ttl;
|
|
53
|
-
await fs.promises.mkdir(this.
|
|
82
|
+
await fs.promises.mkdir(this.currentConnection.path, { recursive: true });
|
|
54
83
|
return await Bun.write(this.filePath(key), `${ttl}|${data}`);
|
|
55
84
|
}
|
|
56
85
|
async getFile(key) {
|
|
@@ -74,9 +103,13 @@ export default class CacheBuilder {
|
|
|
74
103
|
}
|
|
75
104
|
return metadata;
|
|
76
105
|
}
|
|
106
|
+
connection(conn) {
|
|
107
|
+
this.conn = conn;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
77
110
|
async remember(key, callback, ttl) {
|
|
78
111
|
let data;
|
|
79
|
-
switch (this.
|
|
112
|
+
switch (this.driver) {
|
|
80
113
|
case "local":
|
|
81
114
|
const raw = await this.getFile(key);
|
|
82
115
|
data = raw.data;
|
|
@@ -86,10 +119,10 @@ export default class CacheBuilder {
|
|
|
86
119
|
}
|
|
87
120
|
break;
|
|
88
121
|
case "redis":
|
|
89
|
-
data = await
|
|
122
|
+
data = await this.redis.get(this.key(key));
|
|
90
123
|
if (isEmpty(data)) {
|
|
91
124
|
data = callback();
|
|
92
|
-
await
|
|
125
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
93
126
|
}
|
|
94
127
|
break;
|
|
95
128
|
default:
|
|
@@ -100,13 +133,13 @@ export default class CacheBuilder {
|
|
|
100
133
|
}
|
|
101
134
|
async has(key) {
|
|
102
135
|
let data;
|
|
103
|
-
switch (this.
|
|
136
|
+
switch (this.driver) {
|
|
104
137
|
case "local":
|
|
105
138
|
const raw = await this.getFile(key);
|
|
106
139
|
data = raw.data;
|
|
107
140
|
break;
|
|
108
141
|
case "redis":
|
|
109
|
-
data = await
|
|
142
|
+
data = await this.redis.get(this.key(key));
|
|
110
143
|
break;
|
|
111
144
|
default:
|
|
112
145
|
data = false;
|
|
@@ -116,13 +149,13 @@ export default class CacheBuilder {
|
|
|
116
149
|
}
|
|
117
150
|
async get(key) {
|
|
118
151
|
let data;
|
|
119
|
-
switch (this.
|
|
152
|
+
switch (this.driver) {
|
|
120
153
|
case "local":
|
|
121
154
|
const raw = await this.getFile(key);
|
|
122
155
|
data = raw.data;
|
|
123
156
|
break;
|
|
124
157
|
case "redis":
|
|
125
|
-
data = await
|
|
158
|
+
data = await this.redis.get(this.key(key));
|
|
126
159
|
break;
|
|
127
160
|
default:
|
|
128
161
|
data = false;
|
|
@@ -134,25 +167,25 @@ export default class CacheBuilder {
|
|
|
134
167
|
let status = true;
|
|
135
168
|
let data;
|
|
136
169
|
try {
|
|
137
|
-
switch (this.
|
|
170
|
+
switch (this.driver) {
|
|
138
171
|
case "local":
|
|
139
172
|
const raw = await this.getFile(key);
|
|
140
173
|
data = raw.data;
|
|
141
174
|
break;
|
|
142
175
|
case "redis":
|
|
143
|
-
data = await
|
|
176
|
+
data = await this.redis.get(this.key(key));
|
|
144
177
|
break;
|
|
145
178
|
default:
|
|
146
179
|
data = null;
|
|
147
180
|
break;
|
|
148
181
|
}
|
|
149
182
|
if (isEmpty(data)) {
|
|
150
|
-
switch (this.
|
|
183
|
+
switch (this.driver) {
|
|
151
184
|
case "local":
|
|
152
185
|
await this.setFile(key, value, ttl);
|
|
153
186
|
break;
|
|
154
187
|
case "redis":
|
|
155
|
-
await
|
|
188
|
+
await this.redis.set(this.key(key), value, ttl);
|
|
156
189
|
break;
|
|
157
190
|
default:
|
|
158
191
|
break;
|
|
@@ -172,12 +205,12 @@ export default class CacheBuilder {
|
|
|
172
205
|
async put(key, value, ttl) {
|
|
173
206
|
let status = true;
|
|
174
207
|
try {
|
|
175
|
-
switch (this.
|
|
208
|
+
switch (this.driver) {
|
|
176
209
|
case "local":
|
|
177
210
|
await this.setFile(key, value, ttl);
|
|
178
211
|
break;
|
|
179
212
|
case "redis":
|
|
180
|
-
await
|
|
213
|
+
await this.redis.set(this.key(key), value, ttl);
|
|
181
214
|
break;
|
|
182
215
|
default:
|
|
183
216
|
break;
|
|
@@ -190,7 +223,7 @@ export default class CacheBuilder {
|
|
|
190
223
|
return status;
|
|
191
224
|
}
|
|
192
225
|
async forget(key) {
|
|
193
|
-
switch (this.
|
|
226
|
+
switch (this.driver) {
|
|
194
227
|
case "local":
|
|
195
228
|
try {
|
|
196
229
|
await this.file(key).delete();
|
|
@@ -200,7 +233,7 @@ export default class CacheBuilder {
|
|
|
200
233
|
}
|
|
201
234
|
break;
|
|
202
235
|
case "redis":
|
|
203
|
-
await
|
|
236
|
+
await this.redis.del(this.key(key));
|
|
204
237
|
break;
|
|
205
238
|
default:
|
|
206
239
|
break;
|
|
@@ -208,7 +241,7 @@ export default class CacheBuilder {
|
|
|
208
241
|
}
|
|
209
242
|
async increment(key, ttl) {
|
|
210
243
|
let data;
|
|
211
|
-
switch (this.
|
|
244
|
+
switch (this.driver) {
|
|
212
245
|
case "local":
|
|
213
246
|
const raw = await this.getFile(key);
|
|
214
247
|
data = Number(raw.data);
|
|
@@ -222,14 +255,14 @@ export default class CacheBuilder {
|
|
|
222
255
|
}
|
|
223
256
|
break;
|
|
224
257
|
case "redis":
|
|
225
|
-
data = Number(await
|
|
258
|
+
data = Number(await this.redis.get(this.key(key)));
|
|
226
259
|
if (isEmpty(data)) {
|
|
227
260
|
data = 1;
|
|
228
|
-
await
|
|
261
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
229
262
|
}
|
|
230
263
|
else {
|
|
231
264
|
data++;
|
|
232
|
-
await
|
|
265
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
233
266
|
}
|
|
234
267
|
break;
|
|
235
268
|
default:
|
|
@@ -240,7 +273,7 @@ export default class CacheBuilder {
|
|
|
240
273
|
}
|
|
241
274
|
async decrement(key, ttl) {
|
|
242
275
|
let data;
|
|
243
|
-
switch (this.
|
|
276
|
+
switch (this.driver) {
|
|
244
277
|
case "local":
|
|
245
278
|
const raw = await this.getFile(key);
|
|
246
279
|
data = Number(raw.data);
|
|
@@ -254,14 +287,14 @@ export default class CacheBuilder {
|
|
|
254
287
|
}
|
|
255
288
|
break;
|
|
256
289
|
case "redis":
|
|
257
|
-
data = Number(await
|
|
290
|
+
data = Number(await this.redis.get(this.key(key)));
|
|
258
291
|
if (isEmpty(data)) {
|
|
259
292
|
data = -1;
|
|
260
|
-
await
|
|
293
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
261
294
|
}
|
|
262
295
|
else {
|
|
263
296
|
data--;
|
|
264
|
-
await
|
|
297
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
265
298
|
}
|
|
266
299
|
break;
|
|
267
300
|
default:
|
package/config/cache.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import App from "@bejibun/app";
|
|
2
|
+
import CacheDriverEnum from "../enums/CacheDriverEnum";
|
|
2
3
|
const config = {
|
|
3
4
|
connection: "local",
|
|
4
5
|
connections: {
|
|
5
6
|
local: {
|
|
7
|
+
driver: CacheDriverEnum.Local,
|
|
6
8
|
path: App.Path.storagePath("cache") // absolute path
|
|
7
9
|
},
|
|
8
10
|
redis: {
|
|
9
|
-
|
|
11
|
+
driver: CacheDriverEnum.Redis,
|
|
12
|
+
host: "127.0.0.1",
|
|
10
13
|
port: 6379,
|
|
11
14
|
password: "",
|
|
12
15
|
database: 0
|
package/enums/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../enums/CacheDriverEnum";
|
package/enums/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../enums/CacheDriverEnum";
|
package/facades/Cache.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import CacheBuilder from "../builders/CacheBuilder";
|
|
1
2
|
export default class Cache {
|
|
3
|
+
static connection(connection: string): CacheBuilder;
|
|
2
4
|
static remember(key: string, callback: Function, ttl?: number): Promise<any>;
|
|
3
5
|
static has(key: string): Promise<boolean>;
|
|
4
6
|
static get(key: string): Promise<any>;
|
package/facades/Cache.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import CacheBuilder from "../builders/CacheBuilder";
|
|
2
2
|
export default class Cache {
|
|
3
|
+
static connection(connection) {
|
|
4
|
+
return new CacheBuilder().connection(connection);
|
|
5
|
+
}
|
|
3
6
|
static async remember(key, callback, ttl) {
|
|
4
7
|
return new CacheBuilder().remember(key, callback, ttl);
|
|
5
8
|
}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bejibun/cache",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"author": "Havea Crenata <havea.crenata@gmail.com>",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"alias": "bunx tsc-alias -p tsconfig.json",
|
|
30
30
|
"rsync": "rsync -a dist/ ./",
|
|
31
31
|
"clean": "rm -rf dist",
|
|
32
|
-
"build": "bunx tsc -p tsconfig.json && bun run alias && bun run rsync && bun run clean",
|
|
32
|
+
"build": "bun run clean && bunx tsc -p tsconfig.json && bun run alias && bun run rsync && bun run clean",
|
|
33
33
|
"deploy": "bun run build && bun publish --access public"
|
|
34
34
|
},
|
|
35
35
|
"type": "module",
|
|
@@ -38,6 +38,6 @@
|
|
|
38
38
|
"@bejibun/app": "^0.1.22",
|
|
39
39
|
"@bejibun/logger": "^0.1.22",
|
|
40
40
|
"@bejibun/redis": "^0.1.36",
|
|
41
|
-
"@bejibun/utils": "^0.1.
|
|
41
|
+
"@bejibun/utils": "^0.1.28"
|
|
42
42
|
}
|
|
43
43
|
}
|