story-research-zapwall/types/nostr-tools-extended.ts
2026-01-13 14:49:19 +01:00

88 lines
2.6 KiB
TypeScript

import { SimplePool } from 'nostr-tools'
import type { Filter } from 'nostr-tools'
import type { Event } from 'nostr-tools'
/**
* Subscription interface matching nostr-tools 2.x API
*/
export interface Subscription {
on(event: 'event', callback: (event: Event) => void): void
on(event: 'eose', callback: () => void): void
unsub(): void
}
/**
* Type for SimplePool with subscribe method (for backward compatibility)
* Note: SimplePool already has subscribe method, this is just for type compatibility
*/
export type SimplePoolWithSub = SimplePool
/**
* Helper to create a subscription compatible with the old API
*/
export function createSubscription(
pool: SimplePool,
relays: string[],
filters: Filter[]
): Subscription {
const state = createSubscriptionState()
const subscription = pool.subscribe(relays, filters[0] ?? {}, {
onevent: (event: Event) => onSubscriptionEvent({ state, event }),
oneose: () => onSubscriptionEose({ state }),
})
return buildSubscriptionWrapper({ state, subscription })
}
function createSubscriptionState(): {
events: Event[]
eoseReceived: boolean
eventCallbacks: Array<(event: Event) => void>
eoseCallbacks: Array<() => void>
} {
return { events: [], eoseReceived: false, eventCallbacks: [], eoseCallbacks: [] }
}
function onSubscriptionEvent(params: { state: ReturnType<typeof createSubscriptionState>; event: Event }): void {
params.state.events.push(params.event)
params.state.eventCallbacks.forEach((cb) => cb(params.event))
}
function onSubscriptionEose(params: { state: ReturnType<typeof createSubscriptionState> }): void {
const { state } = params
state.eoseReceived = true
state.eoseCallbacks.forEach((cb) => cb())
}
function buildSubscriptionWrapper(params: {
state: ReturnType<typeof createSubscriptionState>
subscription: { close: () => void }
}): Subscription {
return {
on(event: 'event' | 'eose', callback: ((event: Event) => void) | (() => void)): void {
handleSubscriptionOn({ state: params.state, event, callback })
},
unsub(): void {
params.subscription.close()
},
}
}
function handleSubscriptionOn(params: {
state: ReturnType<typeof createSubscriptionState>
event: 'event' | 'eose'
callback: ((event: Event) => void) | (() => void)
}): void {
if (params.event === 'event') {
const eventCb = params.callback as (event: Event) => void
params.state.eventCallbacks.push(eventCb)
params.state.events.forEach((e) => eventCb(e))
return
}
const eoseCb = params.callback as () => void
if (params.state.eoseReceived) {
eoseCb()
return
}
params.state.eoseCallbacks.push(eoseCb)
}