You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.5 KiB
150 lines
3.5 KiB
/** |
|
* Event caching with IndexedDB |
|
*/ |
|
|
|
import { getDB } from './indexeddb-store.js'; |
|
import type { NostrEvent } from '../../types/nostr.js'; |
|
|
|
export interface CachedEvent extends NostrEvent { |
|
cached_at: number; |
|
} |
|
|
|
/** |
|
* Store an event in cache |
|
*/ |
|
export async function cacheEvent(event: NostrEvent): Promise<void> { |
|
try { |
|
const db = await getDB(); |
|
const cached: CachedEvent = { |
|
...event, |
|
cached_at: Date.now() |
|
}; |
|
await db.put('events', cached); |
|
} catch (error) { |
|
console.debug('Error caching event:', error); |
|
// Don't throw - caching failures shouldn't break the app |
|
} |
|
} |
|
|
|
/** |
|
* Store multiple events in cache |
|
*/ |
|
export async function cacheEvents(events: NostrEvent[]): Promise<void> { |
|
try { |
|
const db = await getDB(); |
|
const tx = db.transaction('events', 'readwrite'); |
|
for (const event of events) { |
|
const cached: CachedEvent = { |
|
...event, |
|
cached_at: Date.now() |
|
}; |
|
await tx.store.put(cached); |
|
} |
|
await tx.done; |
|
} catch (error) { |
|
console.debug('Error caching events:', error); |
|
// Don't throw - caching failures shouldn't break the app |
|
} |
|
} |
|
|
|
/** |
|
* Get event by ID from cache |
|
*/ |
|
export async function getEvent(id: string): Promise<CachedEvent | undefined> { |
|
try { |
|
const db = await getDB(); |
|
return await db.get('events', id); |
|
} catch (error) { |
|
console.debug('Error getting event from cache:', error); |
|
return undefined; |
|
} |
|
} |
|
|
|
/** |
|
* Get events by kind |
|
*/ |
|
export async function getEventsByKind(kind: number, limit?: number): Promise<CachedEvent[]> { |
|
try { |
|
const db = await getDB(); |
|
const tx = db.transaction('events', 'readonly'); |
|
const index = tx.store.index('kind'); |
|
const events: CachedEvent[] = []; |
|
let count = 0; |
|
|
|
for await (const cursor of index.iterate(kind)) { |
|
if (limit && count >= limit) break; |
|
events.push(cursor.value); |
|
count++; |
|
} |
|
|
|
await tx.done; |
|
|
|
return events.sort((a, b) => b.created_at - a.created_at); |
|
} catch (error) { |
|
console.debug('Error getting events by kind from cache:', error); |
|
return []; |
|
} |
|
} |
|
|
|
/** |
|
* Get events by pubkey |
|
*/ |
|
export async function getEventsByPubkey(pubkey: string, limit?: number): Promise<CachedEvent[]> { |
|
try { |
|
const db = await getDB(); |
|
const tx = db.transaction('events', 'readonly'); |
|
const index = tx.store.index('pubkey'); |
|
const events: CachedEvent[] = []; |
|
let count = 0; |
|
|
|
for await (const cursor of index.iterate(pubkey)) { |
|
if (limit && count >= limit) break; |
|
events.push(cursor.value); |
|
count++; |
|
} |
|
|
|
await tx.done; |
|
|
|
return events.sort((a, b) => b.created_at - a.created_at); |
|
} catch (error) { |
|
console.debug('Error getting events by pubkey from cache:', error); |
|
return []; |
|
} |
|
} |
|
|
|
/** |
|
* Delete an event by ID from cache |
|
*/ |
|
export async function deleteEvent(id: string): Promise<void> { |
|
const db = await getDB(); |
|
await db.delete('events', id); |
|
} |
|
|
|
/** |
|
* Delete multiple events by ID from cache |
|
*/ |
|
export async function deleteEvents(ids: string[]): Promise<void> { |
|
const db = await getDB(); |
|
const tx = db.transaction('events', 'readwrite'); |
|
for (const id of ids) { |
|
await tx.store.delete(id); |
|
} |
|
await tx.done; |
|
} |
|
|
|
/** |
|
* Clear old events (older than specified timestamp) |
|
*/ |
|
export async function clearOldEvents(olderThan: number): Promise<void> { |
|
const db = await getDB(); |
|
const tx = db.transaction('events', 'readwrite'); |
|
const index = tx.store.index('created_at'); |
|
|
|
for await (const cursor of index.iterate()) { |
|
if (cursor.value.created_at < olderThan) { |
|
await cursor.delete(); |
|
} |
|
} |
|
|
|
await tx.done; |
|
}
|
|
|