@bejibun/cache 0.1.12 → 0.1.14
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 +26 -0
- package/README.md +7 -1
- package/builders/CacheBuilder.d.ts +1 -0
- package/builders/CacheBuilder.js +72 -43
- package/config/cache.js +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,32 @@ All notable changes to this project will be documented in this file.
|
|
|
3
3
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
## [v0.1.14](https://github.com/crenata/bejibun-cache/compare/v0.1.12...v0.1.14) - 2025-12-12
|
|
7
|
+
|
|
8
|
+
### 🩹 Fixes
|
|
9
|
+
- Redis connection with Cache own settings - [#1](https://github.com/crenata/bejibun-core/issues/1)
|
|
10
|
+
|
|
11
|
+
### 📖 Changes
|
|
12
|
+
What's New :
|
|
13
|
+
- Adding `ttl` supports for file scheme.
|
|
14
|
+
|
|
15
|
+
#### How does it work?
|
|
16
|
+
When you use a cache and include a `ttl`, the system generates a `unix timestamp` and adds it with specified `ttl`.
|
|
17
|
+
Then system will write it to a file in the format `ttl|file`, separated by the `|` symbol.
|
|
18
|
+
|
|
19
|
+
When you call data from the cache, the system creates metadata consisting of the `ttl` and `data` by splitting them with `|`.
|
|
20
|
+
The system then checks if the `ttl` is empty and returns the data.
|
|
21
|
+
|
|
22
|
+
Or if the `ttl` is present, the system checks whether the `current timestamp` <= `ttl`?
|
|
23
|
+
If so, the data is returned. Otherwise, the cache file will be deleted and returned null.
|
|
24
|
+
|
|
25
|
+
### ❤️Contributors
|
|
26
|
+
- Havea Crenata ([@crenata](https://github.com/crenata))
|
|
27
|
+
|
|
28
|
+
**Full Changelog**: https://github.com/crenata/bejibun-cache/blob/master/CHANGELOG.md
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
6
32
|
## [v0.1.12](https://github.com/crenata/bejibun-cache/compare/v0.1.11...v0.1.12) - 2025-12-04
|
|
7
33
|
|
|
8
34
|
### 🩹 Fixes
|
package/README.md
CHANGED
|
@@ -38,10 +38,16 @@ config/cache.ts
|
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
```ts
|
|
41
|
+
import App from "@bejibun/app";
|
|
42
|
+
|
|
41
43
|
const config: Record<string, any> = {
|
|
42
|
-
connection: "
|
|
44
|
+
connection: "local",
|
|
43
45
|
|
|
44
46
|
connections: {
|
|
47
|
+
local: {
|
|
48
|
+
path: App.Path.storagePath("cache") // absolute path
|
|
49
|
+
},
|
|
50
|
+
|
|
45
51
|
redis: {
|
|
46
52
|
host: "127.0.0.100",
|
|
47
53
|
port: 6379,
|
package/builders/CacheBuilder.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import App from "@bejibun/app";
|
|
2
2
|
import Logger from "@bejibun/logger";
|
|
3
3
|
import Redis from "@bejibun/redis";
|
|
4
|
-
import
|
|
4
|
+
import Luxon from "@bejibun/utils/facades/Luxon";
|
|
5
|
+
import { defineValue, isEmpty, isNotEmpty } from "@bejibun/utils";
|
|
5
6
|
import fs from "fs";
|
|
6
7
|
import path from "path";
|
|
7
8
|
import CacheConfig from "../config/cache";
|
|
@@ -9,6 +10,7 @@ import CacheException from "../exceptions/CacheException";
|
|
|
9
10
|
export default class CacheBuilder {
|
|
10
11
|
conf;
|
|
11
12
|
prefix;
|
|
13
|
+
redis;
|
|
12
14
|
constructor() {
|
|
13
15
|
const configPath = App.Path.configPath("cache.ts");
|
|
14
16
|
let config;
|
|
@@ -16,8 +18,20 @@ export default class CacheBuilder {
|
|
|
16
18
|
config = require(configPath).default;
|
|
17
19
|
else
|
|
18
20
|
config = CacheConfig;
|
|
21
|
+
const redisConnection = defineValue(config.connections?.redis, {
|
|
22
|
+
host: "127.0.0.1",
|
|
23
|
+
port: 6379,
|
|
24
|
+
password: "",
|
|
25
|
+
database: 0
|
|
26
|
+
});
|
|
19
27
|
this.conf = config;
|
|
20
28
|
this.prefix = "bejibun-cache";
|
|
29
|
+
this.redis = Redis.setClient({
|
|
30
|
+
host: redisConnection.host,
|
|
31
|
+
port: redisConnection.port,
|
|
32
|
+
password: redisConnection.password,
|
|
33
|
+
database: redisConnection.database
|
|
34
|
+
});
|
|
21
35
|
}
|
|
22
36
|
get config() {
|
|
23
37
|
if (isEmpty(this.conf))
|
|
@@ -25,16 +39,7 @@ export default class CacheBuilder {
|
|
|
25
39
|
return this.conf;
|
|
26
40
|
}
|
|
27
41
|
key(key) {
|
|
28
|
-
|
|
29
|
-
return defaultKey;
|
|
30
|
-
/*if (forceDefault) return defaultKey;
|
|
31
|
-
|
|
32
|
-
switch (this.config.connection) {
|
|
33
|
-
case "local":
|
|
34
|
-
return `${Luxon.DateTime.now().toUnixInteger()}-${defaultKey}`;
|
|
35
|
-
default:
|
|
36
|
-
return defaultKey;
|
|
37
|
-
}*/
|
|
42
|
+
return `${this.prefix}-${key.replaceAll("/", "-").replaceAll(" ", "-")}`;
|
|
38
43
|
}
|
|
39
44
|
connection() {
|
|
40
45
|
return this.config.connections[this.config.connection];
|
|
@@ -45,31 +50,50 @@ export default class CacheBuilder {
|
|
|
45
50
|
file(key) {
|
|
46
51
|
return Bun.file(this.filePath(key));
|
|
47
52
|
}
|
|
48
|
-
async setFile(key, data) {
|
|
53
|
+
async setFile(key, data, ttl) {
|
|
54
|
+
ttl = defineValue(ttl, "");
|
|
55
|
+
if (isNotEmpty(ttl))
|
|
56
|
+
ttl = Luxon.DateTime.now().toUnixInteger() + ttl;
|
|
49
57
|
await fs.promises.mkdir(this.connection().path, { recursive: true });
|
|
50
|
-
return await Bun.write(this.filePath(key), data);
|
|
58
|
+
return await Bun.write(this.filePath(key), `${ttl}|${data}`);
|
|
51
59
|
}
|
|
52
60
|
async getFile(key) {
|
|
61
|
+
let metadata = {
|
|
62
|
+
ttl: null,
|
|
63
|
+
data: null
|
|
64
|
+
};
|
|
53
65
|
const file = this.file(key);
|
|
54
|
-
if (await file.exists())
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
if (await file.exists()) {
|
|
67
|
+
const raw = await file.text();
|
|
68
|
+
const [unix, ...rest] = raw.split("|");
|
|
69
|
+
const ttl = Number(unix);
|
|
70
|
+
const data = rest.join("|");
|
|
71
|
+
if (isEmpty(ttl) || Luxon.DateTime.now().toUnixInteger() <= ttl)
|
|
72
|
+
metadata = {
|
|
73
|
+
ttl: defineValue(Number(ttl)),
|
|
74
|
+
data
|
|
75
|
+
};
|
|
76
|
+
else
|
|
77
|
+
await this.file(key).delete();
|
|
78
|
+
}
|
|
79
|
+
return metadata;
|
|
57
80
|
}
|
|
58
81
|
async remember(key, callback, ttl) {
|
|
59
82
|
let data;
|
|
60
83
|
switch (this.config.connection) {
|
|
61
84
|
case "local":
|
|
62
|
-
|
|
85
|
+
const raw = await this.getFile(key);
|
|
86
|
+
data = raw.data;
|
|
63
87
|
if (isEmpty(data)) {
|
|
64
88
|
data = callback();
|
|
65
|
-
await this.setFile(key, data);
|
|
89
|
+
await this.setFile(key, data, ttl);
|
|
66
90
|
}
|
|
67
91
|
break;
|
|
68
92
|
case "redis":
|
|
69
|
-
data = await
|
|
93
|
+
data = await this.redis.get(this.key(key));
|
|
70
94
|
if (isEmpty(data)) {
|
|
71
95
|
data = callback();
|
|
72
|
-
await
|
|
96
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
73
97
|
}
|
|
74
98
|
break;
|
|
75
99
|
default:
|
|
@@ -82,10 +106,11 @@ export default class CacheBuilder {
|
|
|
82
106
|
let data;
|
|
83
107
|
switch (this.config.connection) {
|
|
84
108
|
case "local":
|
|
85
|
-
|
|
109
|
+
const raw = await this.getFile(key);
|
|
110
|
+
data = raw.data;
|
|
86
111
|
break;
|
|
87
112
|
case "redis":
|
|
88
|
-
data = await
|
|
113
|
+
data = await this.redis.get(this.key(key));
|
|
89
114
|
break;
|
|
90
115
|
default:
|
|
91
116
|
data = false;
|
|
@@ -97,10 +122,11 @@ export default class CacheBuilder {
|
|
|
97
122
|
let data;
|
|
98
123
|
switch (this.config.connection) {
|
|
99
124
|
case "local":
|
|
100
|
-
|
|
125
|
+
const raw = await this.getFile(key);
|
|
126
|
+
data = raw.data;
|
|
101
127
|
break;
|
|
102
128
|
case "redis":
|
|
103
|
-
data = await
|
|
129
|
+
data = await this.redis.get(this.key(key));
|
|
104
130
|
break;
|
|
105
131
|
default:
|
|
106
132
|
data = false;
|
|
@@ -114,10 +140,11 @@ export default class CacheBuilder {
|
|
|
114
140
|
try {
|
|
115
141
|
switch (this.config.connection) {
|
|
116
142
|
case "local":
|
|
117
|
-
|
|
143
|
+
const raw = await this.getFile(key);
|
|
144
|
+
data = raw.data;
|
|
118
145
|
break;
|
|
119
146
|
case "redis":
|
|
120
|
-
data = await
|
|
147
|
+
data = await this.redis.get(this.key(key));
|
|
121
148
|
break;
|
|
122
149
|
default:
|
|
123
150
|
data = null;
|
|
@@ -126,10 +153,10 @@ export default class CacheBuilder {
|
|
|
126
153
|
if (isEmpty(data)) {
|
|
127
154
|
switch (this.config.connection) {
|
|
128
155
|
case "local":
|
|
129
|
-
await this.setFile(key, value);
|
|
156
|
+
await this.setFile(key, value, ttl);
|
|
130
157
|
break;
|
|
131
158
|
case "redis":
|
|
132
|
-
await
|
|
159
|
+
await this.redis.set(this.key(key), value, ttl);
|
|
133
160
|
break;
|
|
134
161
|
default:
|
|
135
162
|
break;
|
|
@@ -151,10 +178,10 @@ export default class CacheBuilder {
|
|
|
151
178
|
try {
|
|
152
179
|
switch (this.config.connection) {
|
|
153
180
|
case "local":
|
|
154
|
-
await this.setFile(key, value);
|
|
181
|
+
await this.setFile(key, value, ttl);
|
|
155
182
|
break;
|
|
156
183
|
case "redis":
|
|
157
|
-
await
|
|
184
|
+
await this.redis.set(this.key(key), value, ttl);
|
|
158
185
|
break;
|
|
159
186
|
default:
|
|
160
187
|
break;
|
|
@@ -177,7 +204,7 @@ export default class CacheBuilder {
|
|
|
177
204
|
}
|
|
178
205
|
break;
|
|
179
206
|
case "redis":
|
|
180
|
-
await
|
|
207
|
+
await this.redis.del(this.key(key));
|
|
181
208
|
break;
|
|
182
209
|
default:
|
|
183
210
|
break;
|
|
@@ -187,25 +214,26 @@ export default class CacheBuilder {
|
|
|
187
214
|
let data;
|
|
188
215
|
switch (this.config.connection) {
|
|
189
216
|
case "local":
|
|
190
|
-
|
|
217
|
+
const raw = await this.getFile(key);
|
|
218
|
+
data = Number(raw.data);
|
|
191
219
|
if (isEmpty(data)) {
|
|
192
220
|
data = 1;
|
|
193
|
-
await this.setFile(key, String(data));
|
|
221
|
+
await this.setFile(key, String(data), ttl);
|
|
194
222
|
}
|
|
195
223
|
else {
|
|
196
224
|
data++;
|
|
197
|
-
await this.setFile(key, String(data));
|
|
225
|
+
await this.setFile(key, String(data), ttl);
|
|
198
226
|
}
|
|
199
227
|
break;
|
|
200
228
|
case "redis":
|
|
201
|
-
data = Number(await
|
|
229
|
+
data = Number(await this.redis.get(this.key(key)));
|
|
202
230
|
if (isEmpty(data)) {
|
|
203
231
|
data = 1;
|
|
204
|
-
await
|
|
232
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
205
233
|
}
|
|
206
234
|
else {
|
|
207
235
|
data++;
|
|
208
|
-
await
|
|
236
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
209
237
|
}
|
|
210
238
|
break;
|
|
211
239
|
default:
|
|
@@ -218,25 +246,26 @@ export default class CacheBuilder {
|
|
|
218
246
|
let data;
|
|
219
247
|
switch (this.config.connection) {
|
|
220
248
|
case "local":
|
|
221
|
-
|
|
249
|
+
const raw = await this.getFile(key);
|
|
250
|
+
data = Number(raw.data);
|
|
222
251
|
if (isEmpty(data)) {
|
|
223
252
|
data = -1;
|
|
224
|
-
await this.setFile(key, String(data));
|
|
253
|
+
await this.setFile(key, String(data), ttl);
|
|
225
254
|
}
|
|
226
255
|
else {
|
|
227
256
|
data--;
|
|
228
|
-
await this.setFile(key, String(data));
|
|
257
|
+
await this.setFile(key, String(data), ttl);
|
|
229
258
|
}
|
|
230
259
|
break;
|
|
231
260
|
case "redis":
|
|
232
|
-
data = Number(await
|
|
261
|
+
data = Number(await this.redis.get(this.key(key)));
|
|
233
262
|
if (isEmpty(data)) {
|
|
234
263
|
data = -1;
|
|
235
|
-
await
|
|
264
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
236
265
|
}
|
|
237
266
|
else {
|
|
238
267
|
data--;
|
|
239
|
-
await
|
|
268
|
+
await this.redis.set(this.key(key), data, ttl);
|
|
240
269
|
}
|
|
241
270
|
break;
|
|
242
271
|
default:
|
package/config/cache.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.14",
|
|
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",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@bejibun/app": "^0.1.22",
|
|
39
39
|
"@bejibun/logger": "^0.1.22",
|
|
40
|
-
"@bejibun/redis": "^0.1.
|
|
41
|
-
"@bejibun/utils": "^0.1.
|
|
40
|
+
"@bejibun/redis": "^0.1.36",
|
|
41
|
+
"@bejibun/utils": "^0.1.27"
|
|
42
42
|
}
|
|
43
43
|
}
|