story-research-zapwall/lib/sponsoring.ts
2026-01-06 17:10:07 +01:00

87 lines
2.9 KiB
TypeScript

import { getSponsoringByAuthor } from './sponsoringQueries'
import { objectCache } from './objectCache'
import type { Article } from '@/types/nostr'
import type { Sponsoring } from '@/types/nostr'
/**
* Get total sponsoring for an author by their pubkey from IndexedDB cache
* This is much faster than network queries
* Returns both the amount and whether the cache was empty (to avoid duplicate calls)
*/
async function getAuthorSponsoringFromCache(pubkey: string): Promise<{ amount: number; cacheWasEmpty: boolean }> {
try {
const allSponsoring = await objectCache.getAll('sponsoring')
const sponsoringList = allSponsoring as Sponsoring[]
// If cache is empty, return immediately
if (sponsoringList.length === 0) {
return { amount: 0, cacheWasEmpty: true }
}
// Filter by author pubkey and sum amounts
const amount = sponsoringList
.filter((sponsoring) => sponsoring.authorPubkey === pubkey)
.reduce((total, sponsoring) => total + sponsoring.amount, 0)
return { amount, cacheWasEmpty: false }
} catch (error) {
console.error('Error calculating author sponsoring from cache:', error)
return { amount: 0, cacheWasEmpty: true }
}
}
/**
* Get total sponsoring for an author by their pubkey
* First tries cache, then falls back to network query if needed
* If cache is empty, returns 0 immediately (very fast, no network request)
*/
export async function getAuthorSponsoring(pubkey: string, useCacheOnly: boolean = true): Promise<number> {
try {
// Try cache first (much faster)
const { amount: cachedAmount, cacheWasEmpty } = await getAuthorSponsoringFromCache(pubkey)
// If cache is empty, return 0 immediately (no network request)
if (cacheWasEmpty) {
return 0
}
if (cachedAmount > 0 || useCacheOnly) {
return cachedAmount
}
// Fallback to network query if cache exists but cacheOnly is false
const sponsoringList = await getSponsoringByAuthor(pubkey, 5000)
return sponsoringList.reduce((total, sponsoring) => total + sponsoring.amount, 0)
} catch (error) {
console.error('Error calculating author sponsoring:', error)
return 0
}
}
/**
* Get sponsoring for multiple authors (for sorting)
* Returns a map of pubkey -> total sponsoring
*/
export function getAuthorsSponsoring(pubkeys: string[]): Map<string, number> {
const sponsoringMap = new Map<string, number>()
// For now, we'll extract sponsoring from articles that are already loaded
// In a real implementation, we'd query all presentation articles
// For performance, we'll use the sponsoring from the article's totalSponsoring field
pubkeys.forEach((pubkey) => {
sponsoringMap.set(pubkey, 0)
})
return sponsoringMap
}
/**
* Get sponsoring from an article (if it's a presentation article)
*/
export function getSponsoringFromArticle(article: Article): number {
if (article.isPresentation && article.totalSponsoring !== undefined) {
return article.totalSponsoring
}
return 0
}