Files
oysqn.app/app/composables/useAppCache.ts

75 lines
2.2 KiB
TypeScript

import { weekMonday } from '~/utils/toronto'
const TTL_MS = 24 * 60 * 60 * 1000
interface CacheEntry<T> {
data: T
ts: number
}
function storageKey(key: string) {
return `cache:${key}`
}
export function useAppCache() {
function set<T>(key: string, data: T): void {
try {
localStorage.setItem(storageKey(key), JSON.stringify({ data, ts: Date.now() } satisfies CacheEntry<T>))
} catch { /* quota exceeded or unavailable */ }
}
/** Returns data only if fresh (< 24 h). Returns null if stale or absent. */
function get<T>(key: string): T | null {
try {
const raw = localStorage.getItem(storageKey(key))
if (!raw) return null
const entry = JSON.parse(raw) as CacheEntry<T>
if (Date.now() - entry.ts > TTL_MS) return null
return entry.data
} catch { return null }
}
/** Returns data regardless of age — for offline fallback when cache is stale. */
function peek<T>(key: string): T | null {
try {
const raw = localStorage.getItem(storageKey(key))
if (!raw) return null
return (JSON.parse(raw) as CacheEntry<T>).data
} catch { return null }
}
/** Returns age in ms, or null if absent. */
function age(key: string): number | null {
try {
const raw = localStorage.getItem(storageKey(key))
if (!raw) return null
return Date.now() - (JSON.parse(raw) as CacheEntry<unknown>).ts
} catch { return null }
}
function invalidate(key: string): void {
localStorage.removeItem(storageKey(key))
}
/** Removes all cache entries whose key starts with prefix. */
function invalidatePrefix(prefix: string): void {
const full = storageKey(prefix)
const toRemove: string[] = []
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i)
if (k?.startsWith(full)) toRemove.push(k)
}
toRemove.forEach(k => localStorage.removeItem(k))
}
/**
* Cache key for schedule data (intervals or slots) for the ISO week containing
* the given UTC ISO timestamp. Desktop and mobile both key to week-Monday.
*/
function weekKey(utcIso: string): string {
return weekMonday(utcIso.slice(0, 10))
}
return { set, get, peek, age, invalidate, invalidatePrefix, weekKey }
}