fixed caching

This commit is contained in:
2026-03-26 13:10:00 -07:00
parent 38d50a814f
commit 81d42662ee
2 changed files with 232 additions and 55 deletions

View File

@@ -21,11 +21,22 @@ export type LibraryCacheSnapshot = {
searchCache: Record<string, number[]>
}
export type LibraryCacheStats = {
snapshotCount: number
staleSnapshotCount: number
totalBytes: number
activeBytes: number
trackCount: number
searchEntryCount: number
updatedAt: number | null
}
const DATABASE_NAME = 'api-mediaplayer-library-cache'
const DATABASE_VERSION = 1
const STORE_NAME = 'snapshots'
const MAX_TRACKS = 5000
const MAX_SEARCHES = 250
const textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null
export function buildLibraryCacheKey(servers: CacheServerDescriptor[]) {
return servers.map((server) => `${server.id}:${server.host}:${server.port ?? ''}:${server.ssl ? 'https' : 'http'}`).join('|')
@@ -66,6 +77,18 @@ function withStore<T>(mode: IDBTransactionMode, handler: (store: IDBObjectStore)
})
}
function estimateRecordBytes(record: LibraryCacheRecord) {
const payload = JSON.stringify(record)
if (!textEncoder) return payload.length
return textEncoder.encode(payload).length
}
async function listLibraryCacheRecords(): Promise<LibraryCacheRecord[]> {
if (typeof indexedDB === 'undefined') return []
const records = await withStore<LibraryCacheRecord[]>('readonly', (store) => store.getAll())
return Array.isArray(records) ? records : []
}
export async function loadLibraryCache(cacheKey: string): Promise<LibraryCacheSnapshot | null> {
if (!cacheKey || typeof indexedDB === 'undefined') return null
@@ -78,6 +101,47 @@ export async function loadLibraryCache(cacheKey: string): Promise<LibraryCacheSn
}
}
export async function pruneLibraryCache(activeCacheKey: string) {
if (!activeCacheKey || typeof indexedDB === 'undefined') return 0
const records = await listLibraryCacheRecords()
const staleKeys = records
.map((record) => record.cacheKey)
.filter((cacheKey) => cacheKey !== activeCacheKey)
if (staleKeys.length === 0) return 0
await Promise.all(staleKeys.map((cacheKey) => withStore('readwrite', (store) => store.delete(cacheKey))))
return staleKeys.length
}
export async function getLibraryCacheStats(activeCacheKey: string): Promise<LibraryCacheStats> {
if (!activeCacheKey || typeof indexedDB === 'undefined') {
return {
snapshotCount: 0,
staleSnapshotCount: 0,
totalBytes: 0,
activeBytes: 0,
trackCount: 0,
searchEntryCount: 0,
updatedAt: null,
}
}
const records = await listLibraryCacheRecords()
const activeRecord = records.find((record) => record.cacheKey === activeCacheKey)
return {
snapshotCount: records.length,
staleSnapshotCount: records.filter((record) => record.cacheKey !== activeCacheKey).length,
totalBytes: records.reduce((sum, record) => sum + estimateRecordBytes(record), 0),
activeBytes: activeRecord ? estimateRecordBytes(activeRecord) : 0,
trackCount: activeRecord?.tracks.length ?? 0,
searchEntryCount: activeRecord ? Object.keys(activeRecord.searchCache || {}).length : 0,
updatedAt: activeRecord?.updatedAt ?? null,
}
}
export async function saveLibraryCache(cacheKey: string, tracks: Track[], searchCache: Record<string, number[]>) {
if (!cacheKey || typeof indexedDB === 'undefined') return
@@ -96,4 +160,5 @@ export async function saveLibraryCache(cacheKey: string, tracks: Track[], search
}
await withStore('readwrite', (store) => store.put(record))
await pruneLibraryCache(cacheKey)
}