UNPKG

nostr-relaypool

Version:

A Nostr RelayPool implementation in TypeScript using only nostr-tools library as a dependency.

76 lines (71 loc) 2.32 kB
import {type Filter, matchFilter, type Event} from "nostr-tools"; import type {OnEvent} from "./on-event-filters"; export class EventDemultiplexer { filterAndOnEventByEvent: Map<string, [Filter, OnEvent][]> = new Map(); #addEventUsingEventKey( event: Event, afterEose: boolean, url: string | undefined, eventKey: string ) { const filterAndOnEvent = this.filterAndOnEventByEvent.get(eventKey); if (filterAndOnEvent) { for (const [filter, onEvent] of filterAndOnEvent) { if (matchFilter(filter, event)) { onEvent(event, afterEose, url); } } } } onEvent(event: Event, afterEose: boolean, url: string | undefined) { this.#addEventUsingEventKey(event, afterEose, url, `ids:${event.id}`); this.#addEventUsingEventKey( event, afterEose, url, `authors:${event.pubkey}` ); for (const tag of event.tags) { this.#addEventUsingEventKey( event, afterEose, url, `#${tag[0]}:${tag[1]}` ); } this.#addEventUsingEventKey(event, afterEose, url, `kinds:${event.kind}`); this.#addEventUsingEventKey(event, afterEose, url, ""); } subscribe(filters: Filter[], onEvent: OnEvent) { for (const filter of filters) { let added = false; for (const key of ["ids", "authors", ...filterTags(filter), "kinds"]) { if (key in filter) { // @ts-ignore for (const value of filter[key]) { const eventKey = `${key}:${value}`; const filterAndOnEvent = this.filterAndOnEventByEvent.get(eventKey); if (filterAndOnEvent) { filterAndOnEvent.push([filter, onEvent]); } else { this.filterAndOnEventByEvent.set(eventKey, [[filter, onEvent]]); } } added = true; break; } } if (!added) { const eventKey = ""; const filterAndOnEvent = this.filterAndOnEventByEvent.get(eventKey); if (filterAndOnEvent) { filterAndOnEvent.push([filter, onEvent]); } else { this.filterAndOnEventByEvent.set(eventKey, [[filter, onEvent]]); } } } } } const filterTags = (filter: Filter): string[] => Object.keys(filter).filter((key) => key.startsWith("#"));