import {ctx, isNil} from "@welshman/lib" import {LOCAL_RELAY_URL, getFilterResultCardinality} from "@welshman/util" import type {TrustedEvent, Filter} from "@welshman/util" import {subscribe as baseSubscribe, SubscriptionEvent} from "@welshman/net" import type {SubscribeRequestWithHandlers} from "@welshman/net" import {repository} from './core' export type PartialSubscribeRequest = Partial & {filters: Filter[]} export const subscribe = (request: PartialSubscribeRequest) => { const events: TrustedEvent[] = [] // If we already have all results for any filter, don't send the filter to the network if (request.closeOnEose) { for (const filter of request.filters.splice(0)) { const cardinality = getFilterResultCardinality(filter) if (!isNil(cardinality)) { const results = repository.query([filter]) if (results.length === cardinality) { for (const event of results) { events.push(event) } break } } request.filters.push(filter) } } // Make sure to query our local relay too const delay = ctx.app.requestDelay const authTimeout = ctx.app.authTimeout const timeout = request.closeOnEose ? ctx.app.requestTimeout : 0 const sub = baseSubscribe({delay, timeout, authTimeout, relays: [], ...request}) // Keep cached results async so the caller can set up handlers setTimeout(() => { for (const event of events) { sub.emitter.emit(SubscriptionEvent.Event, LOCAL_RELAY_URL, event) } }) return sub } export const load = (request: PartialSubscribeRequest) => new Promise(resolve => { const sub = subscribe({closeOnEose: true, timeout: ctx.app.requestTimeout, ...request}) const events: TrustedEvent[] = [] sub.emitter.on(SubscriptionEvent.Event, (url: string, e: TrustedEvent) => events.push(e)) sub.emitter.on(SubscriptionEvent.Complete, () => resolve(events)) })