ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto
1/**
2 * Generic client-side cache with TTL support
3 * Used for simple caching needs on the frontend
4 **/
5export class CacheService<T = any> {
6 private cache = new Map<string, { value: T; expires: number }>();
7 private readonly defaultTTL: number;
8
9 constructor(defaultTTLMs: number = 5 * 60 * 1000) {
10 this.defaultTTL = defaultTTLMs;
11 }
12
13 set(key: string, value: T, ttlMs?: number): void {
14 const ttl = ttlMs ?? this.defaultTTL;
15 this.cache.set(key, {
16 value,
17 expires: Date.now() + ttl,
18 });
19
20 if (this.cache.size > 100) {
21 this.cleanup();
22 }
23 }
24
25 get<U = T>(key: string): U | null {
26 const entry = this.cache.get(key);
27 if (!entry) return null;
28
29 if (Date.now() > entry.expires) {
30 this.cache.delete(key);
31 return null;
32 }
33
34 return entry.value as U;
35 }
36
37 has(key: string): boolean {
38 return this.get(key) !== null;
39 }
40
41 delete(key: string): void {
42 this.cache.delete(key);
43 }
44
45 invalidatePattern(pattern: string): void {
46 for (const key of this.cache.keys()) {
47 if (key.includes(pattern)) {
48 this.cache.delete(key);
49 }
50 }
51 }
52
53 clear(): void {
54 this.cache.clear();
55 }
56
57 cleanup(): void {
58 const now = Date.now();
59 for (const [key, entry] of this.cache.entries()) {
60 if (now > entry.expires) {
61 this.cache.delete(key);
62 }
63 }
64 }
65}