Files
boris/src/services/highlights/fetchForUrl.ts
Gigi 2e59bc9375 feat(highlights): add optional session cache with TTL
- Add in-memory cache with 60s TTL for article/url/author queries
- Check cache before network fetch to reduce redundant queries
- Support force flag to bypass cache when needed
- Stream cached results through onHighlight callback for consistency
2025-10-18 10:04:13 +02:00

70 lines
2.2 KiB
TypeScript

import { RelayPool } from 'applesauce-relay'
import { NostrEvent } from 'nostr-tools'
import { Highlight } from '../../types/highlights'
import { KINDS } from '../../config/kinds'
import { eventToHighlight, dedupeHighlights, sortHighlights } from '../highlightEventProcessor'
import { UserSettings } from '../settingsService'
import { rebroadcastEvents } from '../rebroadcastService'
import { queryEvents } from '../dataFetch'
import { highlightCache } from './cache'
export const fetchHighlightsForUrl = async (
relayPool: RelayPool,
url: string,
onHighlight?: (highlight: Highlight) => void,
settings?: UserSettings,
force = false
): Promise<Highlight[]> => {
// Check cache first unless force refresh
if (!force) {
const cacheKey = highlightCache.urlKey(url)
const cached = highlightCache.get(cacheKey)
if (cached) {
console.log(`📌 Using cached highlights for URL (${cached.length} items)`)
// Stream cached highlights if callback provided
if (onHighlight) {
cached.forEach(h => onHighlight(h))
}
return cached
}
}
try {
const seenIds = new Set<string>()
const rawEvents: NostrEvent[] = await queryEvents(
relayPool,
{ kinds: [KINDS.Highlights], '#r': [url] },
{
onEvent: (event: NostrEvent) => {
if (seenIds.has(event.id)) return
seenIds.add(event.id)
if (onHighlight) onHighlight(eventToHighlight(event))
}
}
)
console.log(`📌 Fetched ${rawEvents.length} highlight events for URL:`, url)
// Rebroadcast events - but don't let errors here break the highlight display
try {
await rebroadcastEvents(rawEvents, relayPool, settings)
} catch (err) {
console.warn('Failed to rebroadcast highlight events:', err)
}
const uniqueEvents = dedupeHighlights(rawEvents)
const highlights: Highlight[] = uniqueEvents.map(eventToHighlight)
const sorted = sortHighlights(highlights)
// Cache the results
const cacheKey = highlightCache.urlKey(url)
highlightCache.set(cacheKey, sorted)
return sorted
} catch (err) {
console.error('Error fetching highlights for URL:', err)
return []
}
}