feat: add setup/cache page

This commit is contained in:
2024-06-11 00:25:33 +03:00
parent 02f7c33b91
commit b0b41fcdc5
2 changed files with 134 additions and 0 deletions

View File

@ -0,0 +1,65 @@
import {Injectable} from '@angular/core';
interface CacheEntry<T> {
data: T;
expiry: number;
}
@Injectable({
providedIn: 'root'
})
export class CacheService {
private handleQuotaExceeded(): void {
const keys: string[] = [];
const expiries: number[] = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (!key) continue;
const cacheEntry = JSON.parse(localStorage.getItem(key) as string) as CacheEntry<any>;
keys.push(key);
expiries.push(cacheEntry.expiry);
}
// Удаляем самый старый элемент
const oldestIndex = expiries.indexOf(Math.min(...expiries));
localStorage.removeItem(keys[oldestIndex]);
}
private isQuotaExceededError(e: unknown): e is DOMException {
return e instanceof DOMException && (
e.name === 'QuotaExceededError' ||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED'
);
}
set<T>(key: string, data: T, ttl: number): void {
const expiry = Date.now() + ttl;
const cacheEntry: CacheEntry<T> = {data, expiry};
try {
localStorage.setItem(key, JSON.stringify(cacheEntry));
} catch (e) {
if (this.isQuotaExceededError(e)) {
this.handleQuotaExceeded();
localStorage.setItem(key, JSON.stringify(cacheEntry));
} else {
throw e;
}
}
}
get<T>(key: string): T | null {
const cached = localStorage.getItem(key);
if (!cached) return null;
const cacheEntry = JSON.parse(cached) as CacheEntry<T>;
if (Date.now() > cacheEntry.expiry) {
localStorage.removeItem(key);
return null;
}
return cacheEntry.data;
}
}