@bejibun/cache 0.1.12 → 0.1.13

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 CHANGED
@@ -3,6 +3,31 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  ---
5
5
 
6
+ ## [v0.1.13](https://github.com/crenata/bejibun-cache/compare/v0.1.12...v0.1.13) - 2025-12-12
7
+
8
+ ### 🩹 Fixes
9
+
10
+ ### 📖 Changes
11
+ What's New :
12
+ - Adding `ttl` supports for file scheme.
13
+
14
+ #### How does it work?
15
+ When you use a cache and include a `ttl`, the system generates a `unix timestamp` and adds it with specified `ttl`.
16
+ Then system will write it to a file in the format `ttl|file`, separated by the `|` symbol.
17
+
18
+ When you call data from the cache, the system creates metadata consisting of the `ttl` and `data` by splitting them with `|`.
19
+ The system then checks if the `ttl` is empty and returns the data.
20
+
21
+ Or if the `ttl` is present, the system checks whether the `current timestamp` <= `ttl`?
22
+ If so, the data is returned. Otherwise, the cache file will be deleted and returned null.
23
+
24
+ ### ❤️Contributors
25
+ - Havea Crenata ([@crenata](https://github.com/crenata))
26
+
27
+ **Full Changelog**: https://github.com/crenata/bejibun-cache/blob/master/CHANGELOG.md
28
+
29
+ ---
30
+
6
31
  ## [v0.1.12](https://github.com/crenata/bejibun-cache/compare/v0.1.11...v0.1.12) - 2025-12-04
7
32
 
8
33
  ### 🩹 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: "redis",
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,
@@ -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 { isEmpty, isNotEmpty } from "@bejibun/utils";
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";
@@ -45,24 +46,43 @@ export default class CacheBuilder {
45
46
  file(key) {
46
47
  return Bun.file(this.filePath(key));
47
48
  }
48
- async setFile(key, data) {
49
+ async setFile(key, data, ttl) {
50
+ ttl = defineValue(ttl, "");
51
+ if (isNotEmpty(ttl))
52
+ ttl = Luxon.DateTime.now().toUnixInteger() + ttl;
49
53
  await fs.promises.mkdir(this.connection().path, { recursive: true });
50
- return await Bun.write(this.filePath(key), data);
54
+ return await Bun.write(this.filePath(key), `${ttl}|${data}`);
51
55
  }
52
56
  async getFile(key) {
57
+ let metadata = {
58
+ ttl: null,
59
+ data: null
60
+ };
53
61
  const file = this.file(key);
54
- if (await file.exists())
55
- return await file.text();
56
- return null;
62
+ if (await file.exists()) {
63
+ const raw = await file.text();
64
+ const [unix, ...rest] = raw.split("|");
65
+ const ttl = Number(unix);
66
+ const data = rest.join("|");
67
+ if (isEmpty(ttl) || Luxon.DateTime.now().toUnixInteger() <= ttl)
68
+ metadata = {
69
+ ttl: defineValue(Number(ttl)),
70
+ data
71
+ };
72
+ else
73
+ await this.file(key).delete();
74
+ }
75
+ return metadata;
57
76
  }
58
77
  async remember(key, callback, ttl) {
59
78
  let data;
60
79
  switch (this.config.connection) {
61
80
  case "local":
62
- data = await this.getFile(key);
81
+ const raw = await this.getFile(key);
82
+ data = raw.data;
63
83
  if (isEmpty(data)) {
64
84
  data = callback();
65
- await this.setFile(key, data);
85
+ await this.setFile(key, data, ttl);
66
86
  }
67
87
  break;
68
88
  case "redis":
@@ -82,7 +102,8 @@ export default class CacheBuilder {
82
102
  let data;
83
103
  switch (this.config.connection) {
84
104
  case "local":
85
- data = await this.getFile(key);
105
+ const raw = await this.getFile(key);
106
+ data = raw.data;
86
107
  break;
87
108
  case "redis":
88
109
  data = await Redis.get(this.key(key));
@@ -97,7 +118,8 @@ export default class CacheBuilder {
97
118
  let data;
98
119
  switch (this.config.connection) {
99
120
  case "local":
100
- data = await this.getFile(key);
121
+ const raw = await this.getFile(key);
122
+ data = raw.data;
101
123
  break;
102
124
  case "redis":
103
125
  data = await Redis.get(this.key(key));
@@ -114,7 +136,8 @@ export default class CacheBuilder {
114
136
  try {
115
137
  switch (this.config.connection) {
116
138
  case "local":
117
- data = await this.getFile(key);
139
+ const raw = await this.getFile(key);
140
+ data = raw.data;
118
141
  break;
119
142
  case "redis":
120
143
  data = await Redis.get(this.key(key));
@@ -126,7 +149,7 @@ export default class CacheBuilder {
126
149
  if (isEmpty(data)) {
127
150
  switch (this.config.connection) {
128
151
  case "local":
129
- await this.setFile(key, value);
152
+ await this.setFile(key, value, ttl);
130
153
  break;
131
154
  case "redis":
132
155
  await Redis.set(this.key(key), value, ttl);
@@ -151,7 +174,7 @@ export default class CacheBuilder {
151
174
  try {
152
175
  switch (this.config.connection) {
153
176
  case "local":
154
- await this.setFile(key, value);
177
+ await this.setFile(key, value, ttl);
155
178
  break;
156
179
  case "redis":
157
180
  await Redis.set(this.key(key), value, ttl);
@@ -187,14 +210,15 @@ export default class CacheBuilder {
187
210
  let data;
188
211
  switch (this.config.connection) {
189
212
  case "local":
190
- data = Number(await this.getFile(key));
213
+ const raw = await this.getFile(key);
214
+ data = Number(raw.data);
191
215
  if (isEmpty(data)) {
192
216
  data = 1;
193
- await this.setFile(key, String(data));
217
+ await this.setFile(key, String(data), ttl);
194
218
  }
195
219
  else {
196
220
  data++;
197
- await this.setFile(key, String(data));
221
+ await this.setFile(key, String(data), ttl);
198
222
  }
199
223
  break;
200
224
  case "redis":
@@ -218,14 +242,15 @@ export default class CacheBuilder {
218
242
  let data;
219
243
  switch (this.config.connection) {
220
244
  case "local":
221
- data = Number(await this.getFile(key));
245
+ const raw = await this.getFile(key);
246
+ data = Number(raw.data);
222
247
  if (isEmpty(data)) {
223
248
  data = -1;
224
- await this.setFile(key, String(data));
249
+ await this.setFile(key, String(data), ttl);
225
250
  }
226
251
  else {
227
252
  data--;
228
- await this.setFile(key, String(data));
253
+ await this.setFile(key, String(data), ttl);
229
254
  }
230
255
  break;
231
256
  case "redis":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bejibun/cache",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "author": "Havea Crenata <havea.crenata@gmail.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -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.34",
41
- "@bejibun/utils": "^0.1.23"
40
+ "@bejibun/redis": "^0.1.36",
41
+ "@bejibun/utils": "^0.1.27"
42
42
  }
43
43
  }