story-research-zapwall/lib/seriesQueries.ts

104 lines
2.6 KiB
TypeScript

import type { Event } from 'nostr-tools'
import { nostrService } from './nostr'
import type { SimplePoolWithSub } from '@/types/nostr-tools-extended'
import type { Series } from '@/types/nostr'
import { parseSeriesFromEvent } from './nostrEventParsing'
import { buildTagFilter } from './nostrTagSystem'
import { getPrimaryRelaySync } from './config'
function buildSeriesFilters(authorPubkey: string) {
const tagFilter = buildTagFilter({
type: 'series',
authorPubkey,
})
return [
{
kinds: tagFilter.kinds as number[],
...(tagFilter.authors ? { authors: tagFilter.authors as string[] } : {}),
...(tagFilter['#series'] ? { '#series': tagFilter['#series'] as string[] } : {}),
},
]
}
export function getSeriesByAuthor(authorPubkey: string, timeoutMs: number = 5000): Promise<Series[]> {
const pool = nostrService.getPool()
if (!pool) {
throw new Error('Pool not initialized')
}
const poolWithSub = pool as SimplePoolWithSub
const filters = buildSeriesFilters(authorPubkey)
return new Promise<Series[]>((resolve) => {
const results: Series[] = []
const relayUrl = getPrimaryRelaySync()
const sub = poolWithSub.sub([relayUrl], filters)
let finished = false
const done = () => {
if (finished) {
return
}
finished = true
sub.unsub()
resolve(results)
}
sub.on('event', (event: Event) => {
const parsed = parseSeriesFromEvent(event)
if (parsed) {
results.push(parsed)
}
})
sub.on('eose', () => done())
setTimeout(() => done(), timeoutMs).unref?.()
})
}
function buildSeriesByIdFilters(seriesId: string) {
return [
{
kinds: [1],
ids: [seriesId],
...buildTagFilter({
type: 'series',
}),
},
]
}
export function getSeriesById(seriesId: string, timeoutMs: number = 5000): Promise<Series | null> {
const pool = nostrService.getPool()
if (!pool) {
throw new Error('Pool not initialized')
}
const poolWithSub = pool as SimplePoolWithSub
const filters = buildSeriesByIdFilters(seriesId)
return new Promise<Series | null>((resolve) => {
const relayUrl = getPrimaryRelaySync()
const sub = poolWithSub.sub([relayUrl], filters)
let finished = false
const done = (value: Series | null) => {
if (finished) {
return
}
finished = true
sub.unsub()
resolve(value)
}
sub.on('event', (event: Event) => {
const parsed = parseSeriesFromEvent(event)
if (parsed) {
done(parsed)
}
})
sub.on('eose', () => done(null))
setTimeout(() => done(null), timeoutMs).unref?.()
})
}