flamecache 1.0.0 → 1.0.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/README.md +5 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
[](https://bundlephobia.com/package/flamecache)
|
|
7
|
-
[](https://github.com/iamanishroy/flamecache/actions)
|
|
8
7
|
|
|
9
8
|
> A Redis-like caching layer for Firebase Realtime Database with automatic expiration, counters, and batch operations.
|
|
10
9
|
|
|
@@ -47,6 +46,7 @@ const cache = createCache({
|
|
|
47
46
|
},
|
|
48
47
|
rootPath: 'my-cache', // Root path in Firebase (default: 'flamecache')
|
|
49
48
|
ttl: 3600, // Default TTL: 1 hour
|
|
49
|
+
disableCache: false, // Optional: disable cache interactions (useful for testing/development)
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
// Basic usage
|
|
@@ -446,6 +446,10 @@ interface CacheConfig {
|
|
|
446
446
|
|
|
447
447
|
// Enable debug logs (default: false)
|
|
448
448
|
debug?: boolean;
|
|
449
|
+
|
|
450
|
+
// Disable all cache operations (default: false)
|
|
451
|
+
// When true: get/mget return null, set/mset/del do nothing, wrap always fetches
|
|
452
|
+
disableCache?: boolean;
|
|
449
453
|
}
|
|
450
454
|
|
|
451
455
|
// Example with all options
|
package/dist/index.d.mts
CHANGED
|
@@ -6,6 +6,7 @@ interface CacheConfig {
|
|
|
6
6
|
rootPath?: string;
|
|
7
7
|
ttl?: number;
|
|
8
8
|
debug?: boolean;
|
|
9
|
+
disableCache?: boolean;
|
|
9
10
|
}
|
|
10
11
|
interface CacheEntry<T> {
|
|
11
12
|
data: T;
|
|
@@ -17,6 +18,7 @@ declare class FirebaseCache {
|
|
|
17
18
|
private root;
|
|
18
19
|
private ttl;
|
|
19
20
|
private debug;
|
|
21
|
+
private disableCache;
|
|
20
22
|
constructor(config: CacheConfig);
|
|
21
23
|
private path;
|
|
22
24
|
private log;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ interface CacheConfig {
|
|
|
6
6
|
rootPath?: string;
|
|
7
7
|
ttl?: number;
|
|
8
8
|
debug?: boolean;
|
|
9
|
+
disableCache?: boolean;
|
|
9
10
|
}
|
|
10
11
|
interface CacheEntry<T> {
|
|
11
12
|
data: T;
|
|
@@ -17,6 +18,7 @@ declare class FirebaseCache {
|
|
|
17
18
|
private root;
|
|
18
19
|
private ttl;
|
|
19
20
|
private debug;
|
|
21
|
+
private disableCache;
|
|
20
22
|
constructor(config: CacheConfig);
|
|
21
23
|
private path;
|
|
22
24
|
private log;
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ var FirebaseCache = class {
|
|
|
17
17
|
this.root = config.rootPath || "flamecache";
|
|
18
18
|
this.ttl = config.ttl || 3600;
|
|
19
19
|
this.debug = config.debug || false;
|
|
20
|
+
this.disableCache = config.disableCache || false;
|
|
20
21
|
}
|
|
21
22
|
path(key) {
|
|
22
23
|
return `${this.root}/${key}`;
|
|
@@ -25,6 +26,10 @@ var FirebaseCache = class {
|
|
|
25
26
|
if (this.debug) console.log("[Flamecache]", ...args);
|
|
26
27
|
}
|
|
27
28
|
async get(key) {
|
|
29
|
+
if (this.disableCache) {
|
|
30
|
+
this.log("get ignored (cache disabled):", key);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
28
33
|
try {
|
|
29
34
|
const snapshot = await database.get(database.ref(this.db, this.path(key)));
|
|
30
35
|
if (!snapshot.exists()) {
|
|
@@ -45,6 +50,10 @@ var FirebaseCache = class {
|
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
async set(key, data, ttl) {
|
|
53
|
+
if (this.disableCache) {
|
|
54
|
+
this.log("set ignored (cache disabled):", key);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
48
57
|
try {
|
|
49
58
|
const seconds = ttl !== void 0 ? ttl : this.ttl;
|
|
50
59
|
const entry = {
|
|
@@ -59,6 +68,10 @@ var FirebaseCache = class {
|
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
70
|
async del(key) {
|
|
71
|
+
if (this.disableCache) {
|
|
72
|
+
this.log("del ignored (cache disabled):", key);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
62
75
|
try {
|
|
63
76
|
await database.remove(database.ref(this.db, this.path(key)));
|
|
64
77
|
this.log("del:", key);
|
|
@@ -78,9 +91,17 @@ var FirebaseCache = class {
|
|
|
78
91
|
return data;
|
|
79
92
|
}
|
|
80
93
|
async mget(keys) {
|
|
94
|
+
if (this.disableCache) {
|
|
95
|
+
this.log("mget ignored (cache disabled)");
|
|
96
|
+
return keys.map(() => null);
|
|
97
|
+
}
|
|
81
98
|
return Promise.all(keys.map((k) => this.get(k)));
|
|
82
99
|
}
|
|
83
100
|
async mset(entries, ttl) {
|
|
101
|
+
if (this.disableCache) {
|
|
102
|
+
this.log("mset ignored (cache disabled)");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
84
105
|
try {
|
|
85
106
|
const seconds = ttl !== void 0 ? ttl : this.ttl;
|
|
86
107
|
const exp = seconds > 0 ? Date.now() + seconds * 1e3 : null;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cache.ts"],"names":["app","getApps","initializeApp","getDatabase","get","ref","set","remove","update","goOffline","increment"],"mappings":";;;;;;AAcO,IAAM,gBAAN,MAAoB;AAAA,EAMzB,YAAY,MAAA,EAAqB;AAC/B,IAAA,IAAIA,KAAA;AACJ,IAAA,MAAM,WAAA,GAAcC,aAAQ,CAAE,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,MAAU,MAAA,CAAO,QAAA,IAAY,WAAA,CAAY,CAAA;AACnF,IAAA,IAAI,WAAA,EAAa;AACf,MAAAD,KAAA,GAAM,WAAA;AAAA,IACR,CAAA,MAAO;AACL,MAAAA,KAAA,GAAME,iBAAA,CAAc,MAAA,CAAO,QAAA,EAAU,MAAA,CAAO,YAAY,WAAW,CAAA;AAAA,IACrE;AAEA,IAAA,IAAA,CAAK,EAAA,GAAKC,qBAAYH,KAAG,CAAA;AACzB,IAAA,IAAA,CAAK,IAAA,GAAO,OAAO,QAAA,IAAY,YAAA;AAC/B,IAAA,IAAA,CAAK,GAAA,GAAM,OAAO,GAAA,IAAO,IAAA;AACzB,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAO,KAAA,IAAS,KAAA;AAAA,EAC/B;AAAA,EAEQ,KAAK,GAAA,EAAqB;AAChC,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA;AAAA,EAC5B;AAAA,EAEQ,OAAO,IAAA,EAAmB;AAChC,IAAA,IAAI,KAAK,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,cAAA,EAAgB,GAAG,IAAI,CAAA;AAAA,EACrD;AAAA,EAEA,MAAM,IAAa,GAAA,EAAgC;AACjD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAMI,YAAA,CAAIC,YAAA,CAAI,IAAA,CAAK,IAAI,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AACvD,MAAA,IAAI,CAAC,QAAA,CAAS,MAAA,EAAO,EAAG;AACtB,QAAA,IAAA,CAAK,GAAA,CAAI,SAAS,GAAG,CAAA;AACrB,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,KAAA,GAAuB,SAAS,GAAA,EAAI;AAE1C,MAAA,IAAI,MAAM,GAAA,IAAO,IAAA,CAAK,GAAA,EAAI,GAAI,MAAM,GAAA,EAAK;AACvC,QAAA,IAAA,CAAK,GAAA,CAAI,YAAY,GAAG,CAAA;AACxB,QAAA,MAAM,IAAA,CAAK,IAAI,GAAG,CAAA;AAClB,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,GAAG,CAAA;AACpB,MAAA,OAAO,KAAA,CAAM,IAAA;AAAA,IACf,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA;AAC/B,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,GAAA,CAAa,GAAA,EAAa,IAAA,EAAS,GAAA,EAA6B;AACpE,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,GAAA,KAAQ,KAAA,CAAA,GAAY,GAAA,GAAM,IAAA,CAAK,GAAA;AAC/C,MAAA,MAAM,KAAA,GAAuB;AAAA,QAC3B,IAAA;AAAA,QACA,KAAK,OAAA,GAAU,CAAA,GAAI,KAAK,GAAA,EAAI,GAAK,UAAU,GAAA,GAAQ;AAAA,OACrD;AAEA,MAAA,MAAMC,YAAA,CAAID,aAAI,IAAA,CAAK,EAAA,EAAI,KAAK,IAAA,CAAK,GAAG,CAAC,CAAA,EAAG,KAAK,CAAA;AAC7C,MAAA,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,GAAA,EAAK,CAAA,CAAA,EAAI,OAAO,CAAA,EAAA,CAAI,CAAA;AAAA,IACvC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA;AAC/B,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,GAAA,EAA4B;AACpC,IAAA,IAAI;AACF,MAAA,MAAME,eAAA,CAAOF,aAAI,IAAA,CAAK,EAAA,EAAI,KAAK,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AACzC,MAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,GAAA,EAA+B;AACvC,IAAA,OAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,KAAO,IAAA;AAAA,EACnC;AAAA,EAEA,MAAM,IAAA,CACJ,GAAA,EACA,OAAA,EACA,GAAA,EACY;AACZ,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,GAAA,CAAO,GAAG,CAAA;AACpC,IAAA,IAAI,MAAA,KAAW,MAAM,OAAO,MAAA;AAE5B,IAAA,IAAA,CAAK,GAAA,CAAI,UAAU,GAAG,CAAA;AACtB,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,EAAQ;AAC3B,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,EAAM,GAAG,CAAA;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAc,IAAA,EAAuC;AACzD,IAAA,OAAO,OAAA,CAAQ,IAAI,IAAA,CAAK,GAAA,CAAI,OAAK,IAAA,CAAK,GAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,EAClD;AAAA,EAEA,MAAM,IAAA,CAAK,OAAA,EAA8B,GAAA,EAA6B;AACpE,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,GAAA,KAAQ,KAAA,CAAA,GAAY,GAAA,GAAM,IAAA,CAAK,GAAA;AAC/C,MAAA,MAAM,MAAM,OAAA,GAAU,CAAA,GAAI,KAAK,GAAA,EAAI,GAAK,UAAU,GAAA,GAAQ,IAAA;AAC1D,MAAA,MAAM,UAA2C,EAAC;AAElD,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AACjD,QAAA,OAAA,CAAQ,GAAG,CAAA,GAAI;AAAA,UACb,IAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAMG,gBAAOH,YAAA,CAAI,IAAA,CAAK,IAAI,IAAA,CAAK,IAAI,GAAG,OAAO,CAAA;AAC7C,MAAA,IAAA,CAAK,IAAI,OAAA,EAAS,MAAA,CAAO,KAAK,OAAO,CAAA,CAAE,QAAQ,MAAM,CAAA;AAAA,IACvD,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,eAAe,GAAG,CAAA;AAC3B,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,IAAA,EAA+B;AACxC,IAAA,IAAI;AACF,MAAA,MAAM,UAAgC,EAAC;AACvC,MAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,QAAA,OAAA,CAAQ,GAAG,CAAA,GAAI,IAAA;AAAA,MACjB;AAEA,MAAA,MAAMG,gBAAOH,YAAA,CAAI,IAAA,CAAK,IAAI,IAAA,CAAK,IAAI,GAAG,OAAO,CAAA;AAC7C,MAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAA;AAAA,IACvC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,eAAe,GAAG,CAAA;AAC3B,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI;AACF,MAAA,MAAME,gBAAOF,YAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAA,CAAK,IAAI,CAAC,CAAA;AACpC,MAAA,IAAA,CAAK,IAAI,aAAa,CAAA;AAAA,IACxB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,gBAAgB,GAAG,CAAA;AAC5B,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,UAAA,GAA4B;AAChC,IAAA,MAAMI,kBAAA,CAAU,KAAK,EAAE,CAAA;AACvB,IAAA,IAAA,CAAK,IAAI,cAAc,CAAA;AAAA,EACzB;AAAA,EAEA,MAAM,KAAA,CAAM,GAAA,EAAa,GAAA,EAAgC;AACvD,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AAC/B,IAAA,IAAI,IAAA,KAAS,MAAM,OAAO,KAAA;AAC1B,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,EAAM,GAAG,CAAA;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAc,GAAA,EAAgC;AAClD,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAO,GAAG,CAAA;AAClC,IAAA,IAAI,IAAA,KAAS,IAAA,EAAM,MAAM,IAAA,CAAK,IAAI,GAAG,CAAA;AACrC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,IAAA,CAAK,GAAA,EAAa,EAAA,GAAa,CAAA,EAAoB;AACvD,IAAA,MAAM,EAAA,GAAK,EAAA,IAAM,CAAA,GAAI,MAAA,GAAS,MAAA;AAC9B,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AAC1B,MAAA,MAAM,KAAA,GAAQJ,YAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAI,CAAA;AAE/B,MAAA,MAAMG,gBAAO,KAAA,EAAO;AAAA,QAClB,MAAA,EAAQE,mBAAU,EAAE,CAAA;AAAA,QACpB,KAAA,EAAO,KAAK,GAAA,GAAM,CAAA,GAAI,KAAK,GAAA,EAAI,GAAK,IAAA,CAAK,GAAA,GAAM,GAAA,GAAQ;AAAA,OACxD,CAAA;AAED,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,GAAA,CAAY,GAAG,CAAA;AAC3C,MAAA,MAAM,IAAA,GAAO,EAAA,IAAM,CAAA,GAAI,GAAA,GAAM,EAAA;AAC7B,MAAA,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA,EAAG,IAAI,CAAA,EAAG,EAAE,CAAA,SAAA,CAAW,CAAA;AAC/C,MAAA,OAAO,QAAA,IAAY,CAAA;AAAA,IACrB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,CAAA,MAAA,EAAS,EAAE,CAAA,CAAA,CAAA,EAAK,KAAK,GAAG,CAAA;AACjC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,GAAA,EAAa,EAAA,GAAa,CAAA,EAAoB;AACvD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,CAAC,EAAE,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAM,MAAA,CAAO,GAAA,EAAa,GAAA,EAA+B;AACvD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAMN,YAAA,CAAIC,YAAA,CAAI,IAAA,CAAK,IAAI,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AACvD,MAAA,IAAI,CAAC,QAAA,CAAS,MAAA,EAAO,EAAG;AACtB,QAAA,IAAA,CAAK,GAAA,CAAI,kCAAkC,GAAG,CAAA;AAC9C,QAAA,OAAO,KAAA;AAAA,MACT;AAEA,MAAA,MAAM,KAAA,GAAyB,SAAS,GAAA,EAAI;AAC5C,MAAA,KAAA,CAAM,MAAM,GAAA,GAAM,CAAA,GAAI,KAAK,GAAA,EAAI,GAAK,MAAM,GAAA,GAAQ,IAAA;AAElD,MAAA,MAAMC,YAAA,CAAID,aAAI,IAAA,CAAK,EAAA,EAAI,KAAK,IAAA,CAAK,GAAG,CAAC,CAAA,EAAG,KAAK,CAAA;AAC7C,MAAA,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,GAAA,EAAK,CAAA,CAAA,EAAI,GAAG,CAAA,EAAA,CAAI,CAAA;AACpC,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,GAAA,EAAK,GAAG,CAAA;AAClC,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,GAAA,EAA8B;AACzC,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAMD,YAAA,CAAIC,YAAA,CAAI,IAAA,CAAK,IAAI,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AACvD,MAAA,IAAI,CAAC,QAAA,CAAS,MAAA,EAAO,EAAG,OAAO,CAAA;AAE/B,MAAA,MAAM,KAAA,GAAyB,SAAS,GAAA,EAAI;AAE5C,MAAA,IAAI,CAAC,KAAA,CAAM,GAAA,EAAK,OAAO,CAAA,CAAA;AAEvB,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAA,CAAO,KAAA,CAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,IAAK,GAAI,CAAC,CAAA;AACzE,MAAA,OAAO,SAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA;AAC/B,MAAA,OAAO,CAAA;AAAA,IACT;AAAA,EACF;AACF;AAEO,SAAS,YAAY,MAAA,EAAoC;AAC9D,EAAA,OAAO,IAAI,cAAc,MAAM,CAAA;AACjC","file":"index.js","sourcesContent":["import { initializeApp, getApps } from 'firebase/app';\nimport { \n getDatabase, \n ref, \n get, \n set, \n remove, \n goOffline,\n update,\n increment,\n Database \n} from 'firebase/database';\nimport { CacheConfig, CacheEntry } from './types';\n\nexport class FirebaseCache {\n private db: Database;\n private root: string;\n private ttl: number;\n private debug: boolean;\n\n constructor(config: CacheConfig) {\n let app;\n const existingApp = getApps().find(a => a.name === (config.rootPath || '[DEFAULT]'));\n if (existingApp) {\n app = existingApp;\n } else {\n app = initializeApp(config.firebase, config.rootPath || '[DEFAULT]');\n }\n \n this.db = getDatabase(app);\n this.root = config.rootPath || 'flamecache';\n this.ttl = config.ttl || 3600;\n this.debug = config.debug || false;\n }\n\n private path(key: string): string {\n return `${this.root}/${key}`;\n }\n\n private log(...args: any[]): void {\n if (this.debug) console.log('[Flamecache]', ...args);\n }\n\n async get<T = any>(key: string): Promise<T | null> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('miss:', key);\n return null;\n }\n\n const entry: CacheEntry<T> = snapshot.val();\n \n if (entry.exp && Date.now() > entry.exp) {\n this.log('expired:', key);\n await this.del(key);\n return null;\n }\n\n this.log('hit:', key);\n return entry.data;\n } catch (err) {\n this.log('error get:', key, err);\n return null;\n }\n }\n\n async set<T = any>(key: string, data: T, ttl?: number): Promise<void> {\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const entry: CacheEntry<T> = {\n data,\n exp: seconds > 0 ? Date.now() + (seconds * 1000) : null\n };\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('set:', key, `(${seconds}s)`);\n } catch (err) {\n this.log('error set:', key, err);\n throw err;\n }\n }\n\n async del(key: string): Promise<void> {\n try {\n await remove(ref(this.db, this.path(key)));\n this.log('del:', key);\n } catch (err) {\n this.log('error del:', key, err);\n }\n }\n\n async has(key: string): Promise<boolean> {\n return (await this.get(key)) !== null;\n }\n\n async wrap<T = any>(\n key: string,\n fetchFn: () => Promise<T>,\n ttl?: number\n ): Promise<T> {\n const cached = await this.get<T>(key);\n if (cached !== null) return cached;\n\n this.log('fetch:', key);\n const data = await fetchFn();\n await this.set(key, data, ttl);\n return data;\n }\n\n async mget<T = any>(keys: string[]): Promise<(T | null)[]> {\n return Promise.all(keys.map(k => this.get<T>(k)));\n }\n\n async mset(entries: Record<string, any>, ttl?: number): Promise<void> {\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const exp = seconds > 0 ? Date.now() + (seconds * 1000) : null;\n const updates: Record<string, CacheEntry<any>> = {};\n \n for (const [key, data] of Object.entries(entries)) {\n updates[key] = {\n data,\n exp\n };\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mset:', Object.keys(entries).length, 'keys');\n } catch (err) {\n this.log('error mset:', err);\n throw err;\n }\n }\n\n async mdel(keys: string[]): Promise<void> {\n try {\n const updates: Record<string, null> = {};\n for (const key of keys) {\n updates[key] = null;\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mdel:', keys.length, 'keys');\n } catch (err) {\n this.log('error mdel:', err);\n throw err;\n }\n }\n\n async clear(): Promise<void> {\n try {\n await remove(ref(this.db, this.root));\n this.log('cleared all');\n } catch (err) {\n this.log('error clear:', err);\n throw err;\n }\n }\n\n async disconnect(): Promise<void> {\n await goOffline(this.db);\n this.log('disconnected');\n }\n\n async touch(key: string, ttl?: number): Promise<boolean> {\n const data = await this.get(key);\n if (data === null) return false;\n await this.set(key, data, ttl);\n return true;\n }\n\n async pull<T = any>(key: string): Promise<T | null> {\n const data = await this.get<T>(key);\n if (data !== null) await this.del(key);\n return data;\n }\n\n async incr(key: string, by: number = 1): Promise<number> {\n const op = by >= 0 ? 'incr' : 'decr';\n try {\n const path = this.path(key);\n const dbRef = ref(this.db, path);\n \n await update(dbRef, {\n 'data': increment(by),\n 'exp': this.ttl > 0 ? Date.now() + (this.ttl * 1000) : null\n });\n\n const newValue = await this.get<number>(key);\n const sign = by >= 0 ? '+' : '';\n this.log(`${op}:`, key, `${sign}${by} (atomic)`);\n return newValue ?? 0;\n } catch (err) {\n this.log(`error ${op}:`, key, err);\n throw err;\n }\n }\n\n async decr(key: string, by: number = 1): Promise<number> {\n return this.incr(key, -by);\n }\n\n async expire(key: string, ttl: number): Promise<boolean> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('expire failed - key not found:', key);\n return false;\n }\n\n const entry: CacheEntry<any> = snapshot.val();\n entry.exp = ttl > 0 ? Date.now() + (ttl * 1000) : null;\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('expire:', key, `(${ttl}s)`);\n return true;\n } catch (err) {\n this.log('error expire:', key, err);\n return false;\n }\n }\n\n async getTtl(key: string): Promise<number> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) return 0;\n\n const entry: CacheEntry<any> = snapshot.val();\n \n if (!entry.exp) return -1;\n \n const remaining = Math.max(0, Math.floor((entry.exp - Date.now()) / 1000));\n return remaining;\n } catch (err) {\n this.log('error ttl:', key, err);\n return 0;\n }\n }\n}\n\nexport function createCache(config: CacheConfig): FirebaseCache {\n return new FirebaseCache(config);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts"],"names":["app","getApps","initializeApp","getDatabase","get","ref","set","remove","update","goOffline","increment"],"mappings":"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","file":"index.js","sourcesContent":["import { initializeApp, getApps } from 'firebase/app';\nimport { \n getDatabase, \n ref, \n get, \n set, \n remove, \n goOffline,\n update,\n increment,\n Database \n} from 'firebase/database';\nimport { CacheConfig, CacheEntry } from './types';\n\nexport class FirebaseCache {\n private db: Database;\n private root: string;\n private ttl: number;\n private debug: boolean;\n private disableCache: boolean;\n\n constructor(config: CacheConfig) {\n let app;\n const existingApp = getApps().find(a => a.name === (config.rootPath || '[DEFAULT]'));\n if (existingApp) {\n app = existingApp;\n } else {\n app = initializeApp(config.firebase, config.rootPath || '[DEFAULT]');\n }\n \n this.db = getDatabase(app);\n this.root = config.rootPath || 'flamecache';\n this.ttl = config.ttl || 3600;\n this.debug = config.debug || false;\n this.disableCache = config.disableCache || false;\n }\n\n private path(key: string): string {\n return `${this.root}/${key}`;\n }\n\n private log(...args: any[]): void {\n if (this.debug) console.log('[Flamecache]', ...args);\n }\n\n async get<T = any>(key: string): Promise<T | null> {\n if (this.disableCache) {\n this.log('get ignored (cache disabled):', key);\n return null;\n }\n\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('miss:', key);\n return null;\n }\n\n const entry: CacheEntry<T> = snapshot.val();\n \n if (entry.exp && Date.now() > entry.exp) {\n this.log('expired:', key);\n await this.del(key);\n return null;\n }\n\n this.log('hit:', key);\n return entry.data;\n } catch (err) {\n this.log('error get:', key, err);\n return null;\n }\n }\n\n async set<T = any>(key: string, data: T, ttl?: number): Promise<void> {\n if (this.disableCache) {\n this.log('set ignored (cache disabled):', key);\n return;\n }\n\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const entry: CacheEntry<T> = {\n data,\n exp: seconds > 0 ? Date.now() + (seconds * 1000) : null\n };\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('set:', key, `(${seconds}s)`);\n } catch (err) {\n this.log('error set:', key, err);\n throw err;\n }\n }\n\n async del(key: string): Promise<void> {\n if (this.disableCache) {\n this.log('del ignored (cache disabled):', key);\n return;\n }\n\n try {\n await remove(ref(this.db, this.path(key)));\n this.log('del:', key);\n } catch (err) {\n this.log('error del:', key, err);\n }\n }\n\n async has(key: string): Promise<boolean> {\n return (await this.get(key)) !== null;\n }\n\n async wrap<T = any>(\n key: string,\n fetchFn: () => Promise<T>,\n ttl?: number\n ): Promise<T> {\n const cached = await this.get<T>(key);\n if (cached !== null) return cached;\n\n this.log('fetch:', key);\n const data = await fetchFn();\n await this.set(key, data, ttl);\n return data;\n }\n\n async mget<T = any>(keys: string[]): Promise<(T | null)[]> {\n if (this.disableCache) {\n this.log('mget ignored (cache disabled)');\n return keys.map(() => null);\n }\n return Promise.all(keys.map(k => this.get<T>(k)));\n }\n\n async mset(entries: Record<string, any>, ttl?: number): Promise<void> {\n if (this.disableCache) {\n this.log('mset ignored (cache disabled)');\n return;\n }\n\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const exp = seconds > 0 ? Date.now() + (seconds * 1000) : null;\n const updates: Record<string, CacheEntry<any>> = {};\n \n for (const [key, data] of Object.entries(entries)) {\n updates[key] = {\n data,\n exp\n };\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mset:', Object.keys(entries).length, 'keys');\n } catch (err) {\n this.log('error mset:', err);\n throw err;\n }\n }\n\n async mdel(keys: string[]): Promise<void> {\n try {\n const updates: Record<string, null> = {};\n for (const key of keys) {\n updates[key] = null;\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mdel:', keys.length, 'keys');\n } catch (err) {\n this.log('error mdel:', err);\n throw err;\n }\n }\n\n async clear(): Promise<void> {\n try {\n await remove(ref(this.db, this.root));\n this.log('cleared all');\n } catch (err) {\n this.log('error clear:', err);\n throw err;\n }\n }\n\n async disconnect(): Promise<void> {\n await goOffline(this.db);\n this.log('disconnected');\n }\n\n async touch(key: string, ttl?: number): Promise<boolean> {\n const data = await this.get(key);\n if (data === null) return false;\n await this.set(key, data, ttl);\n return true;\n }\n\n async pull<T = any>(key: string): Promise<T | null> {\n const data = await this.get<T>(key);\n if (data !== null) await this.del(key);\n return data;\n }\n\n async incr(key: string, by: number = 1): Promise<number> {\n const op = by >= 0 ? 'incr' : 'decr';\n try {\n const path = this.path(key);\n const dbRef = ref(this.db, path);\n \n await update(dbRef, {\n 'data': increment(by),\n 'exp': this.ttl > 0 ? Date.now() + (this.ttl * 1000) : null\n });\n\n const newValue = await this.get<number>(key);\n const sign = by >= 0 ? '+' : '';\n this.log(`${op}:`, key, `${sign}${by} (atomic)`);\n return newValue ?? 0;\n } catch (err) {\n this.log(`error ${op}:`, key, err);\n throw err;\n }\n }\n\n async decr(key: string, by: number = 1): Promise<number> {\n return this.incr(key, -by);\n }\n\n async expire(key: string, ttl: number): Promise<boolean> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('expire failed - key not found:', key);\n return false;\n }\n\n const entry: CacheEntry<any> = snapshot.val();\n entry.exp = ttl > 0 ? Date.now() + (ttl * 1000) : null;\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('expire:', key, `(${ttl}s)`);\n return true;\n } catch (err) {\n this.log('error expire:', key, err);\n return false;\n }\n }\n\n async getTtl(key: string): Promise<number> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) return 0;\n\n const entry: CacheEntry<any> = snapshot.val();\n \n if (!entry.exp) return -1;\n \n const remaining = Math.max(0, Math.floor((entry.exp - Date.now()) / 1000));\n return remaining;\n } catch (err) {\n this.log('error ttl:', key, err);\n return 0;\n }\n }\n}\n\nexport function createCache(config: CacheConfig): FirebaseCache {\n return new FirebaseCache(config);\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -15,6 +15,7 @@ var FirebaseCache = class {
|
|
|
15
15
|
this.root = config.rootPath || "flamecache";
|
|
16
16
|
this.ttl = config.ttl || 3600;
|
|
17
17
|
this.debug = config.debug || false;
|
|
18
|
+
this.disableCache = config.disableCache || false;
|
|
18
19
|
}
|
|
19
20
|
path(key) {
|
|
20
21
|
return `${this.root}/${key}`;
|
|
@@ -23,6 +24,10 @@ var FirebaseCache = class {
|
|
|
23
24
|
if (this.debug) console.log("[Flamecache]", ...args);
|
|
24
25
|
}
|
|
25
26
|
async get(key) {
|
|
27
|
+
if (this.disableCache) {
|
|
28
|
+
this.log("get ignored (cache disabled):", key);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
26
31
|
try {
|
|
27
32
|
const snapshot = await get(ref(this.db, this.path(key)));
|
|
28
33
|
if (!snapshot.exists()) {
|
|
@@ -43,6 +48,10 @@ var FirebaseCache = class {
|
|
|
43
48
|
}
|
|
44
49
|
}
|
|
45
50
|
async set(key, data, ttl) {
|
|
51
|
+
if (this.disableCache) {
|
|
52
|
+
this.log("set ignored (cache disabled):", key);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
46
55
|
try {
|
|
47
56
|
const seconds = ttl !== void 0 ? ttl : this.ttl;
|
|
48
57
|
const entry = {
|
|
@@ -57,6 +66,10 @@ var FirebaseCache = class {
|
|
|
57
66
|
}
|
|
58
67
|
}
|
|
59
68
|
async del(key) {
|
|
69
|
+
if (this.disableCache) {
|
|
70
|
+
this.log("del ignored (cache disabled):", key);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
60
73
|
try {
|
|
61
74
|
await remove(ref(this.db, this.path(key)));
|
|
62
75
|
this.log("del:", key);
|
|
@@ -76,9 +89,17 @@ var FirebaseCache = class {
|
|
|
76
89
|
return data;
|
|
77
90
|
}
|
|
78
91
|
async mget(keys) {
|
|
92
|
+
if (this.disableCache) {
|
|
93
|
+
this.log("mget ignored (cache disabled)");
|
|
94
|
+
return keys.map(() => null);
|
|
95
|
+
}
|
|
79
96
|
return Promise.all(keys.map((k) => this.get(k)));
|
|
80
97
|
}
|
|
81
98
|
async mset(entries, ttl) {
|
|
99
|
+
if (this.disableCache) {
|
|
100
|
+
this.log("mset ignored (cache disabled)");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
82
103
|
try {
|
|
83
104
|
const seconds = ttl !== void 0 ? ttl : this.ttl;
|
|
84
105
|
const exp = seconds > 0 ? Date.now() + seconds * 1e3 : null;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cache.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { initializeApp, getApps } from 'firebase/app';\nimport { \n getDatabase, \n ref, \n get, \n set, \n remove, \n goOffline,\n update,\n increment,\n Database \n} from 'firebase/database';\nimport { CacheConfig, CacheEntry } from './types';\n\nexport class FirebaseCache {\n private db: Database;\n private root: string;\n private ttl: number;\n private debug: boolean;\n\n constructor(config: CacheConfig) {\n let app;\n const existingApp = getApps().find(a => a.name === (config.rootPath || '[DEFAULT]'));\n if (existingApp) {\n app = existingApp;\n } else {\n app = initializeApp(config.firebase, config.rootPath || '[DEFAULT]');\n }\n \n this.db = getDatabase(app);\n this.root = config.rootPath || 'flamecache';\n this.ttl = config.ttl || 3600;\n this.debug = config.debug || false;\n }\n\n private path(key: string): string {\n return `${this.root}/${key}`;\n }\n\n private log(...args: any[]): void {\n if (this.debug) console.log('[Flamecache]', ...args);\n }\n\n async get<T = any>(key: string): Promise<T | null> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('miss:', key);\n return null;\n }\n\n const entry: CacheEntry<T> = snapshot.val();\n \n if (entry.exp && Date.now() > entry.exp) {\n this.log('expired:', key);\n await this.del(key);\n return null;\n }\n\n this.log('hit:', key);\n return entry.data;\n } catch (err) {\n this.log('error get:', key, err);\n return null;\n }\n }\n\n async set<T = any>(key: string, data: T, ttl?: number): Promise<void> {\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const entry: CacheEntry<T> = {\n data,\n exp: seconds > 0 ? Date.now() + (seconds * 1000) : null\n };\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('set:', key, `(${seconds}s)`);\n } catch (err) {\n this.log('error set:', key, err);\n throw err;\n }\n }\n\n async del(key: string): Promise<void> {\n try {\n await remove(ref(this.db, this.path(key)));\n this.log('del:', key);\n } catch (err) {\n this.log('error del:', key, err);\n }\n }\n\n async has(key: string): Promise<boolean> {\n return (await this.get(key)) !== null;\n }\n\n async wrap<T = any>(\n key: string,\n fetchFn: () => Promise<T>,\n ttl?: number\n ): Promise<T> {\n const cached = await this.get<T>(key);\n if (cached !== null) return cached;\n\n this.log('fetch:', key);\n const data = await fetchFn();\n await this.set(key, data, ttl);\n return data;\n }\n\n async mget<T = any>(keys: string[]): Promise<(T | null)[]> {\n return Promise.all(keys.map(k => this.get<T>(k)));\n }\n\n async mset(entries: Record<string, any>, ttl?: number): Promise<void> {\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const exp = seconds > 0 ? Date.now() + (seconds * 1000) : null;\n const updates: Record<string, CacheEntry<any>> = {};\n \n for (const [key, data] of Object.entries(entries)) {\n updates[key] = {\n data,\n exp\n };\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mset:', Object.keys(entries).length, 'keys');\n } catch (err) {\n this.log('error mset:', err);\n throw err;\n }\n }\n\n async mdel(keys: string[]): Promise<void> {\n try {\n const updates: Record<string, null> = {};\n for (const key of keys) {\n updates[key] = null;\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mdel:', keys.length, 'keys');\n } catch (err) {\n this.log('error mdel:', err);\n throw err;\n }\n }\n\n async clear(): Promise<void> {\n try {\n await remove(ref(this.db, this.root));\n this.log('cleared all');\n } catch (err) {\n this.log('error clear:', err);\n throw err;\n }\n }\n\n async disconnect(): Promise<void> {\n await goOffline(this.db);\n this.log('disconnected');\n }\n\n async touch(key: string, ttl?: number): Promise<boolean> {\n const data = await this.get(key);\n if (data === null) return false;\n await this.set(key, data, ttl);\n return true;\n }\n\n async pull<T = any>(key: string): Promise<T | null> {\n const data = await this.get<T>(key);\n if (data !== null) await this.del(key);\n return data;\n }\n\n async incr(key: string, by: number = 1): Promise<number> {\n const op = by >= 0 ? 'incr' : 'decr';\n try {\n const path = this.path(key);\n const dbRef = ref(this.db, path);\n \n await update(dbRef, {\n 'data': increment(by),\n 'exp': this.ttl > 0 ? Date.now() + (this.ttl * 1000) : null\n });\n\n const newValue = await this.get<number>(key);\n const sign = by >= 0 ? '+' : '';\n this.log(`${op}:`, key, `${sign}${by} (atomic)`);\n return newValue ?? 0;\n } catch (err) {\n this.log(`error ${op}:`, key, err);\n throw err;\n }\n }\n\n async decr(key: string, by: number = 1): Promise<number> {\n return this.incr(key, -by);\n }\n\n async expire(key: string, ttl: number): Promise<boolean> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('expire failed - key not found:', key);\n return false;\n }\n\n const entry: CacheEntry<any> = snapshot.val();\n entry.exp = ttl > 0 ? Date.now() + (ttl * 1000) : null;\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('expire:', key, `(${ttl}s)`);\n return true;\n } catch (err) {\n this.log('error expire:', key, err);\n return false;\n }\n }\n\n async getTtl(key: string): Promise<number> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) return 0;\n\n const entry: CacheEntry<any> = snapshot.val();\n \n if (!entry.exp) return -1;\n \n const remaining = Math.max(0, Math.floor((entry.exp - Date.now()) / 1000));\n return remaining;\n } catch (err) {\n this.log('error ttl:', key, err);\n return 0;\n }\n }\n}\n\nexport function createCache(config: CacheConfig): FirebaseCache {\n return new FirebaseCache(config);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { initializeApp, getApps } from 'firebase/app';\nimport { \n getDatabase, \n ref, \n get, \n set, \n remove, \n goOffline,\n update,\n increment,\n Database \n} from 'firebase/database';\nimport { CacheConfig, CacheEntry } from './types';\n\nexport class FirebaseCache {\n private db: Database;\n private root: string;\n private ttl: number;\n private debug: boolean;\n private disableCache: boolean;\n\n constructor(config: CacheConfig) {\n let app;\n const existingApp = getApps().find(a => a.name === (config.rootPath || '[DEFAULT]'));\n if (existingApp) {\n app = existingApp;\n } else {\n app = initializeApp(config.firebase, config.rootPath || '[DEFAULT]');\n }\n \n this.db = getDatabase(app);\n this.root = config.rootPath || 'flamecache';\n this.ttl = config.ttl || 3600;\n this.debug = config.debug || false;\n this.disableCache = config.disableCache || false;\n }\n\n private path(key: string): string {\n return `${this.root}/${key}`;\n }\n\n private log(...args: any[]): void {\n if (this.debug) console.log('[Flamecache]', ...args);\n }\n\n async get<T = any>(key: string): Promise<T | null> {\n if (this.disableCache) {\n this.log('get ignored (cache disabled):', key);\n return null;\n }\n\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('miss:', key);\n return null;\n }\n\n const entry: CacheEntry<T> = snapshot.val();\n \n if (entry.exp && Date.now() > entry.exp) {\n this.log('expired:', key);\n await this.del(key);\n return null;\n }\n\n this.log('hit:', key);\n return entry.data;\n } catch (err) {\n this.log('error get:', key, err);\n return null;\n }\n }\n\n async set<T = any>(key: string, data: T, ttl?: number): Promise<void> {\n if (this.disableCache) {\n this.log('set ignored (cache disabled):', key);\n return;\n }\n\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const entry: CacheEntry<T> = {\n data,\n exp: seconds > 0 ? Date.now() + (seconds * 1000) : null\n };\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('set:', key, `(${seconds}s)`);\n } catch (err) {\n this.log('error set:', key, err);\n throw err;\n }\n }\n\n async del(key: string): Promise<void> {\n if (this.disableCache) {\n this.log('del ignored (cache disabled):', key);\n return;\n }\n\n try {\n await remove(ref(this.db, this.path(key)));\n this.log('del:', key);\n } catch (err) {\n this.log('error del:', key, err);\n }\n }\n\n async has(key: string): Promise<boolean> {\n return (await this.get(key)) !== null;\n }\n\n async wrap<T = any>(\n key: string,\n fetchFn: () => Promise<T>,\n ttl?: number\n ): Promise<T> {\n const cached = await this.get<T>(key);\n if (cached !== null) return cached;\n\n this.log('fetch:', key);\n const data = await fetchFn();\n await this.set(key, data, ttl);\n return data;\n }\n\n async mget<T = any>(keys: string[]): Promise<(T | null)[]> {\n if (this.disableCache) {\n this.log('mget ignored (cache disabled)');\n return keys.map(() => null);\n }\n return Promise.all(keys.map(k => this.get<T>(k)));\n }\n\n async mset(entries: Record<string, any>, ttl?: number): Promise<void> {\n if (this.disableCache) {\n this.log('mset ignored (cache disabled)');\n return;\n }\n\n try {\n const seconds = ttl !== undefined ? ttl : this.ttl;\n const exp = seconds > 0 ? Date.now() + (seconds * 1000) : null;\n const updates: Record<string, CacheEntry<any>> = {};\n \n for (const [key, data] of Object.entries(entries)) {\n updates[key] = {\n data,\n exp\n };\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mset:', Object.keys(entries).length, 'keys');\n } catch (err) {\n this.log('error mset:', err);\n throw err;\n }\n }\n\n async mdel(keys: string[]): Promise<void> {\n try {\n const updates: Record<string, null> = {};\n for (const key of keys) {\n updates[key] = null;\n }\n \n await update(ref(this.db, this.root), updates);\n this.log('mdel:', keys.length, 'keys');\n } catch (err) {\n this.log('error mdel:', err);\n throw err;\n }\n }\n\n async clear(): Promise<void> {\n try {\n await remove(ref(this.db, this.root));\n this.log('cleared all');\n } catch (err) {\n this.log('error clear:', err);\n throw err;\n }\n }\n\n async disconnect(): Promise<void> {\n await goOffline(this.db);\n this.log('disconnected');\n }\n\n async touch(key: string, ttl?: number): Promise<boolean> {\n const data = await this.get(key);\n if (data === null) return false;\n await this.set(key, data, ttl);\n return true;\n }\n\n async pull<T = any>(key: string): Promise<T | null> {\n const data = await this.get<T>(key);\n if (data !== null) await this.del(key);\n return data;\n }\n\n async incr(key: string, by: number = 1): Promise<number> {\n const op = by >= 0 ? 'incr' : 'decr';\n try {\n const path = this.path(key);\n const dbRef = ref(this.db, path);\n \n await update(dbRef, {\n 'data': increment(by),\n 'exp': this.ttl > 0 ? Date.now() + (this.ttl * 1000) : null\n });\n\n const newValue = await this.get<number>(key);\n const sign = by >= 0 ? '+' : '';\n this.log(`${op}:`, key, `${sign}${by} (atomic)`);\n return newValue ?? 0;\n } catch (err) {\n this.log(`error ${op}:`, key, err);\n throw err;\n }\n }\n\n async decr(key: string, by: number = 1): Promise<number> {\n return this.incr(key, -by);\n }\n\n async expire(key: string, ttl: number): Promise<boolean> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) {\n this.log('expire failed - key not found:', key);\n return false;\n }\n\n const entry: CacheEntry<any> = snapshot.val();\n entry.exp = ttl > 0 ? Date.now() + (ttl * 1000) : null;\n \n await set(ref(this.db, this.path(key)), entry);\n this.log('expire:', key, `(${ttl}s)`);\n return true;\n } catch (err) {\n this.log('error expire:', key, err);\n return false;\n }\n }\n\n async getTtl(key: string): Promise<number> {\n try {\n const snapshot = await get(ref(this.db, this.path(key)));\n if (!snapshot.exists()) return 0;\n\n const entry: CacheEntry<any> = snapshot.val();\n \n if (!entry.exp) return -1;\n \n const remaining = Math.max(0, Math.floor((entry.exp - Date.now()) / 1000));\n return remaining;\n } catch (err) {\n this.log('error ttl:', key, err);\n return 0;\n }\n }\n}\n\nexport function createCache(config: CacheConfig): FirebaseCache {\n return new FirebaseCache(config);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flamecache",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Simple and robust caching layer using Firebase Realtime Database",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"url": "https://github.com/iamanishroy/flamecache.git"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"firebase": "^10.0.0 || ^11.0.0"
|
|
46
|
+
"firebase": "^10.0.0 || ^11.0.0 || ^12.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/js": "^9.39.2",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@typescript-eslint/parser": "^6.0.0",
|
|
54
54
|
"dotenv": "^17.2.3",
|
|
55
55
|
"eslint": "^8.0.0",
|
|
56
|
-
"firebase": "^
|
|
56
|
+
"firebase": "^12.7.0",
|
|
57
57
|
"jest": "^29.5.0",
|
|
58
58
|
"prettier": "^3.0.0",
|
|
59
59
|
"ts-jest": "^29.1.0",
|