diff --git a/lib/cache-manager.ts b/lib/cache-manager.ts index 20327b7..8fc01bd 100644 --- a/lib/cache-manager.ts +++ b/lib/cache-manager.ts @@ -32,35 +32,47 @@ export async function initDatabase(): Promise { export async function cacheChapter(chapter: BibleChapter): Promise { if (!db) await initDatabase() - const entry: CacheEntry = { - chapterId: chapter.id, - data: chapter, - timestamp: Date.now(), - expiresAt: Date.now() + CACHE_DURATION_MS - } - return new Promise((resolve, reject) => { + const entry: CacheEntry = { + chapterId: chapter.id, + data: chapter, + timestamp: Date.now(), + expiresAt: Date.now() + CACHE_DURATION_MS + } + const transaction = db!.transaction([STORE_NAME], 'readwrite') const store = transaction.objectStore(STORE_NAME) - // Delete oldest entries if over limit + // First, check if we need to delete oldest entry const countRequest = store.count() countRequest.onsuccess = () => { if (countRequest.result >= MAX_CACHE_SIZE) { + // Delete oldest entry const index = store.index('timestamp') - const oldestRequest = index.openCursor() - oldestRequest.onsuccess = (event) => { + const deleteRequest = index.openCursor() + let deleted = false + + deleteRequest.onsuccess = (event) => { const cursor = (event.target as IDBRequest).result - if (cursor) { + if (cursor && !deleted) { cursor.delete() + deleted = true + // Continue with adding new entry after delete + const putRequest = store.put(entry) + putRequest.onerror = () => reject(putRequest.error) + putRequest.onsuccess = () => resolve() } } + deleteRequest.onerror = () => reject(deleteRequest.error) + } else { + // Just add the entry + const putRequest = store.put(entry) + putRequest.onerror = () => reject(putRequest.error) + putRequest.onsuccess = () => resolve() } } - const request = store.put(entry) - request.onerror = () => reject(request.error) - request.onsuccess = () => resolve() + countRequest.onerror = () => reject(countRequest.error) }) } @@ -90,16 +102,19 @@ export async function clearExpiredCache(): Promise { return new Promise((resolve, reject) => { const transaction = db!.transaction([STORE_NAME], 'readwrite') const store = transaction.objectStore(STORE_NAME) - const index = store.index('timestamp') - const range = IDBKeyRange.upperBound(Date.now() - CACHE_DURATION_MS) - const request = index.openCursor(range) + const request = store.openCursor() + const now = Date.now() request.onsuccess = (event) => { const cursor = (event.target as IDBRequest).result if (cursor) { - cursor.delete() + const entry = cursor.value as CacheEntry + if (entry.expiresAt < now) { + cursor.delete() + } cursor.continue() } else { + // Cursor is done, resolve resolve() } }