87 lines
2.9 KiB
TypeScript
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
|
|
}
|