nostr-relaypool
Version:
A Nostr RelayPool implementation in TypeScript using only nostr-tools library as a dependency.
8 lines • 112 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../index.ts", "../merge-similar-filters.ts", "../relay.ts", "../fakejson.ts", "../event-cache.ts", "../author.ts", "../event.ts", "../on-event-filters.ts", "../callback-replayer.ts", "../group-filters-by-relay.ts", "../newest-event-cache.ts", "../relay-pool.ts", "../collect.ts", "../relay-pool-worker.ts"],
"sourcesContent": ["export * from \"./relay-pool\";\nexport * from \"./author\";\nexport * from \"./collect\";\nexport {emitEventsOnNextTick} from \"./on-event-filters\";\nexport * from \"./relay-pool-worker\";\n", "import {stringify} from \"safe-stable-stringify\";\nimport type {Filter} from \"nostr-tools\";\n\nfunction indexForFilter(filter: Filter, key: string): string {\n let new_filter = {...filter};\n // @ts-ignore\n delete new_filter[key];\n return key + stringify(new_filter);\n}\n\n// Combines filters that are similar, and removes empty filters\n// Similarity is defined as having the same values for all keys except one\nexport function mergeSimilarAndRemoveEmptyFilters(filters: Filter[]): Filter[] {\n let r = [];\n let indexByFilter = new Map<string, number>();\n let sets = [];\n for (let filter of filters) {\n let added = false;\n for (let key in filter) {\n if (\n // @ts-ignore\n filter[key] &&\n ([\"ids\", \"authors\", \"kinds\"].includes(key) || key.startsWith(\"#\"))\n ) {\n // @ts-ignore\n if (filter[key].length === 0) {\n added = true;\n break;\n }\n let index_by = indexForFilter(filter, key);\n let index = indexByFilter.get(index_by);\n if (index !== undefined) {\n // @ts-ignore\n let extendedFilter = r[index];\n // remove all other groupings for r[index]\n for (let key2 in extendedFilter) {\n if (key2 !== key) {\n let index_by2 = indexForFilter(extendedFilter, key2);\n indexByFilter.delete(index_by2);\n }\n }\n // // @ts-ignore\n // if (!r[index][key]?.includes(filter[key])) {\n // // @ts-ignore\n // r[index][key].push(filter[key]);\n // }\n if (r[index][key] instanceof Set) {\n // @ts-ignore\n for (let v of filter[key]) {\n // @ts-ignore\n r[index][key].add(v);\n }\n } else {\n // @ts-ignore\n r[index][key] = new Set(r[index][key].concat(filter[key]));\n sets.push([index, key]);\n }\n added = true;\n break;\n }\n }\n }\n if (!added) {\n for (let key in filter) {\n if (\n // @ts-ignore\n filter[key] &&\n ([\"ids\", \"authors\", \"kinds\"].includes(key) || key.startsWith(\"#\"))\n ) {\n let index_by = indexForFilter(filter, key);\n indexByFilter.set(index_by, r.length);\n }\n }\n r.push({...filter});\n }\n }\n for (let [index, key] of sets) {\n // @ts-ignore\n r[index][key] = Array.from(r[index][key]);\n }\n return r;\n}\n", "// allows sub/unsub and publishing before connection is established.\n// Much more refactoring is needed\n// Don't rely on Relay interface, it will change (I'll probably delete a lot of code from here, there's no need for\n// multiple listeners)\n\nimport {type Event, verifySignature, validateEvent} from \"nostr-tools\";\nimport {type Filter, matchFilters} from \"nostr-tools\";\nimport WebSocket from \"isomorphic-ws\";\nimport {getHex64, getSubName} from \"./fakejson\";\n\ntype RelayEvent = \"connect\" | \"disconnect\" | \"error\" | \"notice\" | \"auth\";\n\nexport type Relay = {\n url: string;\n status: number;\n connect: () => Promise<void>;\n close: () => Promise<void>;\n sub: (filters: Filter[], opts?: SubscriptionOptions) => Sub;\n publish: (event: Event) => Pub;\n auth: (event: Event) => Pub;\n on: (type: RelayEvent, cb: any) => void;\n off: (type: RelayEvent, cb: any) => void;\n};\nexport type Pub = {\n on: (type: \"ok\" | \"seen\" | \"failed\", cb: any) => void;\n off: (type: \"ok\" | \"seen\" | \"failed\", cb: any) => void;\n};\nexport type Sub = {\n sub: (filters: Filter[], opts: SubscriptionOptions) => Sub;\n unsub: () => void;\n on: (type: \"event\" | \"eose\", cb: any) => void;\n off: (type: \"event\" | \"eose\", cb: any) => void;\n};\n\ntype SubscriptionOptions = {\n skipVerification?: boolean;\n id?: string;\n eventIds?: Set<string>;\n};\nexport function relayInit(\n url: string,\n alreadyHaveEvent?: (id: string) => (Event & {id: string}) | undefined,\n autoReconnect?: boolean\n): Relay {\n return new RelayC(url, alreadyHaveEvent, autoReconnect).relayInit();\n}\nclass RelayC {\n url: string;\n alreadyHaveEvent?: (id: string) => (Event & {id: string}) | undefined;\n logging: boolean = false;\n constructor(\n url: string,\n alreadyHaveEvent?: (id: string) => (Event & {id: string}) | undefined,\n autoReconnect?: boolean\n ) {\n this.url = url;\n this.alreadyHaveEvent = alreadyHaveEvent;\n this.autoReconnect = autoReconnect;\n }\n autoReconnect?: boolean;\n ws: WebSocket | undefined;\n sendOnConnect: string[] = [];\n openSubs: {[id: string]: {filters: Filter[]} & SubscriptionOptions} = {};\n closedByClient: boolean = false;\n listeners: {\n connect: Array<() => void>;\n disconnect: Array<() => void>;\n error: Array<() => void>;\n notice: Array<(msg: string) => void>;\n auth: Array<(challenge: string) => void>;\n } = {\n connect: [],\n disconnect: [],\n error: [],\n notice: [],\n auth: [],\n };\n subListeners: {\n [subid: string]:\n | {\n event: Array<(event: Event) => void>;\n eose: Array<() => void>;\n }\n | undefined;\n } = {};\n pubListeners: {\n [eventid: string]: {\n ok: Array<() => void>;\n seen: Array<() => void>;\n failed: Array<(reason: string) => void>;\n };\n } = {};\n incomingMessageQueue: string[] = [];\n handleNextInterval: any;\n\n #handleNext() {\n if (this.incomingMessageQueue.length === 0) {\n clearInterval(this.handleNextInterval);\n this.handleNextInterval = null;\n return;\n }\n this.#handleMessage({data: this.incomingMessageQueue.shift()});\n }\n\n async trySend(params: [string, ...any]) {\n const msg = JSON.stringify(params);\n\n if (this.connected) {\n this.ws?.send(msg);\n } else {\n this.sendOnConnect.push(msg);\n }\n }\n resolveClose: (() => void) | undefined = undefined;\n\n async #onclose() {\n if (this.closedByClient) {\n this.listeners.disconnect.forEach((cb) => cb());\n this.resolveClose && this.resolveClose();\n } else {\n if (this.autoReconnect) {\n this.#reconnect();\n }\n }\n }\n reconnectTimeout: number = 0;\n #reconnect() {\n setTimeout(() => {\n this.reconnectTimeout = Math.max(2000, this.reconnectTimeout * 3);\n console.log(\n this.url,\n \"reconnecting after \" + this.reconnectTimeout / 1000 + \"s\"\n );\n this.connect();\n }, this.reconnectTimeout);\n }\n\n async #onmessage(e: any) {\n this.incomingMessageQueue.push(e.data);\n if (!this.handleNextInterval) {\n this.handleNextInterval = setInterval(() => this.#handleNext(), 0);\n }\n }\n\n async #handleMessage(e: any) {\n let data;\n let json: string = e.data.toString();\n if (!json) {\n return;\n }\n let eventId = getHex64(json, \"id\");\n let event = this.alreadyHaveEvent?.(eventId);\n if (event) {\n const listener = this.subListeners[getSubName(json)];\n\n if (!listener) {\n return;\n }\n\n return listener.event.forEach((cb) => cb(event!));\n }\n try {\n data = JSON.parse(json);\n } catch (err) {\n data = e.data;\n }\n\n if (data.length >= 1) {\n switch (data[0]) {\n case \"EVENT\":\n if (this.logging) {\n console.log(data);\n }\n if (data.length !== 3) return; // ignore empty or malformed EVENT\n\n const id = data[1];\n const event = data[2];\n if (!this.openSubs[id]) {\n return;\n }\n if (this.openSubs[id].eventIds?.has(eventId)) {\n return;\n }\n this.openSubs[id].eventIds?.add(eventId);\n\n if (\n validateEvent(event) &&\n this.openSubs[id] &&\n (this.openSubs[id].skipVerification || verifySignature(event)) &&\n matchFilters(this.openSubs[id].filters, event)\n ) {\n this.openSubs[id];\n (this.subListeners[id]?.event || []).forEach((cb) => cb(event));\n }\n return;\n case \"EOSE\": {\n if (data.length !== 2) return; // ignore empty or malformed EOSE\n const id = data[1];\n if (this.logging) {\n console.log(\"EOSE\", this.url, id);\n }\n (this.subListeners[id]?.eose || []).forEach((cb) => cb());\n return;\n }\n case \"OK\": {\n if (data.length < 3) return; // ignore empty or malformed OK\n const id: string = data[1];\n const ok: boolean = data[2];\n const reason: string = data[3] || \"\";\n if (ok) this.pubListeners[id]?.ok.forEach((cb) => cb());\n else this.pubListeners[id]?.failed.forEach((cb) => cb(reason));\n return;\n }\n case \"NOTICE\":\n if (data.length !== 2) return; // ignore empty or malformed NOTICE\n const notice = data[1];\n this.listeners.notice.forEach((cb) => cb(notice));\n return;\n case \"AUTH\":\n if (data.length !== 2) return;\n const challenge = data[1];\n this.listeners.auth.forEach((cb) => cb(challenge));\n return;\n }\n }\n }\n #onopen(opened: () => void) {\n if (this.resolveClose) {\n this.resolveClose();\n return;\n }\n // console.log(\"#onopen setting reconnectTimeout to 0\");\n // this.reconnectTimeout = 0;\n // TODO: Send ephereal messages after subscription, permament before\n for (const subid in this.openSubs) {\n if (this.logging) {\n console.log(\"REQ\", this.url, subid, ...this.openSubs[subid].filters);\n }\n this.trySend([\"REQ\", subid, ...this.openSubs[subid].filters]);\n }\n for (const msg of this.sendOnConnect) {\n if (this.logging) {\n console.log(\"(Relay msg)\", this.url, msg);\n }\n this.ws?.send(msg);\n }\n this.sendOnConnect = [];\n\n this.listeners.connect.forEach((cb) => cb());\n opened();\n }\n\n async connectRelay(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n const ws = new WebSocket(this.url);\n this.ws = ws;\n } catch (err) {\n reject(err);\n return;\n }\n\n this.ws.onopen = this.#onopen.bind(this, resolve);\n this.ws.onerror = (e) => {\n this.listeners.error.forEach((cb) => cb());\n reject(e);\n };\n this.ws.onclose = this.#onclose.bind(this);\n this.ws.onmessage = this.#onmessage.bind(this);\n });\n }\n\n async connect(): Promise<void> {\n if (this.ws?.readyState && this.ws.readyState < 2) return; // ws already open or connecting\n if (this.ws?.readyState === 2) {\n this.ws.close();\n }\n this.ws = undefined;\n await this.connectRelay();\n }\n\n relayInit(): Relay {\n const this2 = this;\n return {\n url: this2.url,\n sub: this2.sub.bind(this2),\n on: this2.on.bind(this2),\n off: this2.off.bind(this2),\n auth: this2.auth.bind(this2),\n publish: this2.publish.bind(this2),\n connect: this2.connect.bind(this2),\n close(): Promise<void> {\n return this2.close();\n },\n get status() {\n return this2.status;\n },\n // @ts-ignore\n relay: this2,\n };\n }\n get status() {\n return this.ws?.readyState ?? 3;\n }\n get connected() {\n return this.ws?.readyState === 1;\n }\n close(): Promise<void> {\n this.closedByClient = true;\n this.ws?.close();\n return new Promise<void>((resolve) => {\n this.resolveClose = resolve;\n });\n }\n on(type: RelayEvent, cb: any) {\n this.listeners[type].push(cb);\n if (type === \"connect\" && this.ws?.readyState === 1) {\n cb();\n }\n }\n\n off(type: RelayEvent, cb: any) {\n const index = this.listeners[type].indexOf(cb);\n if (index !== -1) this.listeners[type].splice(index, 1);\n }\n\n publish(event: Event): Pub {\n return this._publish(event, \"EVENT\");\n }\n\n auth(event: Event): Pub {\n return this._publish(event, \"AUTH\");\n }\n\n private _publish(event: Event, type: string) {\n const this2 = this;\n if (!event.id) throw new Error(`event ${event} has no id`);\n const id = event.id;\n\n let sent = false;\n let mustMonitor = false;\n\n this2\n .trySend([type, event])\n .then(() => {\n sent = true;\n if (mustMonitor) {\n startMonitoring();\n mustMonitor = false;\n }\n })\n .catch(() => {});\n\n const startMonitoring = () => {\n const monitor = this.sub([{ids: [id]}], {\n id: `monitor-${id.slice(0, 5)}`,\n });\n const willUnsub = setTimeout(() => {\n (this2.pubListeners[id]?.failed || []).forEach((cb) =>\n cb(\"event not seen after 5 seconds\")\n );\n monitor.unsub();\n }, 5000);\n monitor.on(\"event\", () => {\n clearTimeout(willUnsub);\n (this2.pubListeners[id]?.seen || []).forEach((cb) => cb());\n });\n };\n\n return {\n on: (type: \"ok\" | \"seen\" | \"failed\", cb: any) => {\n this2.pubListeners[id] = this2.pubListeners[id] || {\n ok: [],\n seen: [],\n failed: [],\n };\n this2.pubListeners[id][type].push(cb);\n\n if (type === \"seen\") {\n if (sent) startMonitoring();\n else mustMonitor = true;\n }\n },\n off: (type: \"ok\" | \"seen\" | \"failed\", cb: any) => {\n const listeners = this2.pubListeners[id];\n if (!listeners) return;\n const idx = listeners[type].indexOf(cb);\n if (idx >= 0) listeners[type].splice(idx, 1);\n },\n };\n }\n\n sub(filters: Filter[], opts: SubscriptionOptions = {}): Sub {\n const this2 = this;\n const subid = opts.id || Math.random().toString().slice(2);\n const skipVerification = opts.skipVerification || false;\n\n this2.openSubs[subid] = {\n id: subid,\n filters,\n skipVerification,\n };\n if (this2.connected) {\n if (this.logging) {\n console.log(\"REQ2\", this.url, subid, ...filters);\n }\n this2.trySend([\"REQ\", subid, ...filters]);\n }\n\n return {\n sub: (newFilters, newOpts = {}) =>\n this.sub(newFilters || filters, {\n skipVerification: newOpts.skipVerification || skipVerification,\n id: subid,\n }),\n unsub: () => {\n delete this2.openSubs[subid];\n delete this2.subListeners[subid];\n if (this2.connected) {\n if (this2.logging) {\n console.log(\"CLOSE\", this.url, subid);\n }\n this2.trySend([\"CLOSE\", subid]);\n }\n },\n on: (type: \"event\" | \"eose\", cb: any): void => {\n this2.subListeners[subid] = this2.subListeners[subid] || {\n event: [],\n eose: [],\n };\n this2.subListeners[subid]![type].push(cb);\n },\n off: (type: \"event\" | \"eose\", cb: any): void => {\n const listeners = this2.subListeners[subid];\n\n if (!listeners) return;\n\n const idx = listeners[type].indexOf(cb);\n if (idx >= 0) listeners[type].splice(idx, 1);\n },\n };\n }\n}\n", "export function getHex64(json: string, field: string): string {\n let len = field.length + 3;\n let idx = json.indexOf(`\"${field}\":`) + len;\n let s = json.slice(idx).indexOf(`\"`) + idx + 1;\n return json.slice(s, s + 64);\n}\n\nexport function getSubName(json: string): string {\n let idx = json.indexOf(`\"EVENT\"`) + 7;\n let sliced = json.slice(idx);\n let idx2 = sliced.indexOf(`\"`) + 1;\n let sliced2 = sliced.slice(idx2);\n return sliced2.slice(0, sliced2.indexOf(`\"`));\n}\n\nexport function getInt(json: string, field: string): number {\n let len = field.length;\n let idx = json.indexOf(`\"${field}\":`) + len + 3;\n let sliced = json.slice(idx);\n let end = Math.min(sliced.indexOf(\",\"), sliced.indexOf(\"}\"));\n return parseInt(sliced.slice(0, end), 10);\n}\n\nexport function matchEventId(json: string, id: string): boolean {\n return id === getHex64(json, \"id\");\n}\n\nexport function matchEventPubkey(json: string, pubkey: string): boolean {\n return pubkey === getHex64(json, \"pubkey\");\n}\n\nexport function matchEventKind(json: string, kind: number): boolean {\n return kind === getInt(json, \"kind\");\n}\n", "import {type Filter, Kind, type Event} from \"nostr-tools\";\n\nexport class EventCache {\n eventsById: Map<string, Event> = new Map();\n metadataByPubKey: Map<string, Event> = new Map();\n contactsByPubKey: Map<string, Event> = new Map();\n authorsKindsByPubKey: Map<string, Map<number, Event[]>> = new Map();\n eventsByTags: Map<string, Event[]> = new Map();\n\n #addEventToAuthorKindsByPubKey(event: Event) {\n const kindsByPubKey = this.authorsKindsByPubKey.get(event.pubkey);\n if (!kindsByPubKey) {\n this.authorsKindsByPubKey.set(\n event.pubkey,\n new Map([[event.kind, [event]]])\n );\n } else {\n const events = kindsByPubKey.get(event.kind);\n if (!events) {\n kindsByPubKey.set(event.kind, [event]);\n } else {\n if (event.kind === Kind.Metadata || event.kind === Kind.Contacts) {\n if (event.created_at > events[0].created_at) {\n events[0] = event;\n }\n } else {\n events.push(event);\n }\n }\n }\n }\n\n #addEventToEventsByTags(event: Event) {\n for (const tag of event.tags) {\n let tag2 = tag[0] + \":\" + tag[1];\n const events = this.eventsByTags.get(tag2);\n if (events) {\n events.push(event);\n } else {\n this.eventsByTags.set(tag2, [event]);\n }\n }\n }\n\n addEvent(event: Event) {\n if (this.getEventById(event.id)) {\n return;\n }\n this.eventsById.set(event.id, event);\n if (event.kind === Kind.Metadata) {\n this.metadataByPubKey.set(event.pubkey, event);\n }\n if (event.kind === Kind.Contacts) {\n this.contactsByPubKey.set(event.pubkey, event);\n }\n this.#addEventToAuthorKindsByPubKey(event);\n this.#addEventToEventsByTags(event);\n }\n\n getEventById(id: string): Event | undefined {\n return this.eventsById.get(id);\n }\n\n hasEventById(id: string): boolean {\n return this.eventsById.has(id);\n }\n\n #getCachedEventsByPubKeyWithUpdatedFilter(\n filter: Filter & {\n relay?: string;\n noCache?: boolean;\n }\n ): {filter: Filter & {relay?: string}; events: Set<Event>} | undefined {\n if (\n filter.noCache ||\n !filter.authors ||\n !filter.kinds ||\n filter.kinds.find(\n (kind) => kind !== Kind.Contacts && kind !== Kind.Metadata\n ) !== undefined\n ) {\n return undefined;\n }\n const authors: string[] = [];\n const events = new Set<Event>();\n for (const author of filter.authors) {\n let contactEvent;\n if (filter.kinds.includes(Kind.Contacts)) {\n contactEvent = this.contactsByPubKey.get(author);\n if (!contactEvent) {\n authors.push(author);\n continue;\n }\n }\n let metadataEvent;\n if (filter.kinds.includes(Kind.Metadata)) {\n metadataEvent = this.metadataByPubKey.get(author);\n if (!metadataEvent) {\n authors.push(author);\n continue;\n }\n }\n if (contactEvent) {\n events.add(contactEvent);\n }\n if (metadataEvent) {\n events.add(metadataEvent);\n }\n }\n return {filter: {...filter, authors}, events};\n }\n\n #getCachedEventsByPubKeyWithUpdatedFilter2(\n filter: Filter & {\n relay?: string;\n noCache?: boolean;\n }\n ): {filter: Filter & {relay?: string}; events: Set<Event>} | undefined {\n if (filter.noCache || !filter.authors) {\n return undefined;\n }\n const events = new Set<Event>();\n for (const author of filter.authors) {\n if (filter.kinds) {\n const kindsByPubKey = this.authorsKindsByPubKey.get(author);\n if (kindsByPubKey) {\n for (const kind of filter.kinds) {\n const events2 = kindsByPubKey.get(kind);\n if (events2) {\n for (const event of events2) {\n events.add(event);\n }\n }\n }\n }\n } else {\n const kindsByPubKey = this.authorsKindsByPubKey.get(author);\n if (kindsByPubKey) {\n for (const events2 of kindsByPubKey.values()) {\n for (const event3 of events2) {\n events.add(event3);\n }\n }\n }\n }\n }\n return {filter, events};\n }\n\n #getCachedEventsByTagsWithUpdatedFilter(\n filter: Filter & {\n relay?: string;\n noCache?: boolean;\n }\n ): {filter: Filter & {relay?: string}; events: Set<Event>} | undefined {\n if (filter.noCache) {\n return undefined;\n }\n const events = new Set<Event>();\n for (const tag in filter) {\n if (tag[0] !== \"#\") {\n continue;\n }\n // @ts-ignore\n let tag2 = tag.slice(1) + \":\" + filter[tag][0];\n const events2 = this.eventsByTags.get(tag2);\n if (events2) {\n for (const event of events2) {\n events.add(event);\n }\n }\n }\n return {filter, events};\n }\n\n #getCachedEventsByIdWithUpdatedFilter(\n filter: Filter & {relay?: string; noCache?: boolean}\n ): {filter: Filter & {relay?: string}; events: Set<Event>} | undefined {\n if (!filter.ids) {\n return undefined;\n }\n\n const events = new Set<Event>();\n const ids: string[] = [];\n for (const id of filter.ids) {\n const event = this.getEventById(id);\n if (event) {\n events.add(event);\n } else {\n ids.push(id);\n }\n }\n return {filter: {...filter, ids}, events};\n }\n\n getCachedEventsWithUpdatedFilters(\n filters: (Filter & {relay?: string; noCache?: boolean})[],\n relays: string[]\n ): {\n filters: (Filter & {relay?: string})[];\n events: Event[];\n } {\n const events: Set<Event> = new Set();\n const new_filters: (Filter & {relay?: string})[] = [];\n for (const filter of filters) {\n const new_data = this.#getCachedEventsByIdWithUpdatedFilter(filter) ||\n // this.#getCachedEventsByPubKeyWithUpdatedFilter(filter) ||\n this.#getCachedEventsByPubKeyWithUpdatedFilter2(filter) ||\n this.#getCachedEventsByTagsWithUpdatedFilter(filter) || {\n filter,\n events: [],\n };\n for (const event of new_data.events) {\n events.add(event);\n }\n new_filters.push(new_data.filter);\n }\n return {filters: new_filters, events: [...events]};\n }\n}\n", "import type {OnEvent, OnEventObject, RelayPool} from \"./relay-pool\";\nimport {type Filter, Kind} from \"nostr-tools\";\nimport type {EventObject} from \"./event\";\n\nexport class Author {\n pubkey: string;\n relayPool: RelayPool;\n relays: string[] | undefined;\n constructor(\n relayPool: RelayPool,\n relays: string[] | undefined,\n pubkey: string\n ) {\n this.pubkey = pubkey;\n this.relayPool = relayPool;\n this.relays = relays;\n }\n\n metaData(cb: (event: EventObject) => void, maxDelayms: number): () => void {\n return this.relayPool.subscribeEventObject(\n [\n {\n authors: [this.pubkey],\n kinds: [Kind.Metadata],\n },\n ],\n this.relays,\n cb,\n maxDelayms\n );\n }\n subscribe(\n filters: Filter[],\n cb: OnEventObject,\n maxDelayms: number\n ): () => void {\n return this.relayPool.subscribeEventObject(\n filters.map((filter) => ({\n authors: [this.pubkey],\n ...filter,\n })),\n this.relays,\n cb,\n maxDelayms\n );\n }\n\n followsPubkeys(\n cb: (pubkeys: string[]) => void,\n maxDelayms: number\n ): () => void {\n return this.relayPool.subscribeEventObject(\n [\n {\n authors: [this.pubkey],\n kinds: [Kind.Contacts],\n },\n ],\n this.relays,\n (event: EventObject) => {\n let r: string[] = [];\n for (const tag of event.tags) {\n if (tag[0] === \"p\") {\n r.push(tag[1]);\n }\n }\n cb(r);\n },\n maxDelayms\n );\n }\n\n // TODO: prioritize relay over other relays for specific authors\n follows(cb: (authors: Author[]) => void, maxDelayms: number): () => void {\n return this.relayPool.subscribeEventObject(\n [\n {\n authors: [this.pubkey],\n kinds: [Kind.Contacts],\n },\n ],\n this.relays,\n (event: EventObject) => {\n let r: Author[] = [];\n for (const tag of event.tags) {\n if (tag[0] === \"p\") {\n let relays = this.relays;\n if (tag[1]) {\n relays = [tag[1], ...(this.relays || [])];\n }\n r.push(new Author(this.relayPool, relays, tag[1]));\n }\n }\n cb(r);\n },\n maxDelayms\n );\n }\n\n secondFollows(\n cb: (pubkeysWithWeight: [string, number][]) => void,\n maxDelayms: number,\n removeDirectFollows = true\n ): () => void {\n return this.followsPubkeys((pubkeys) => {\n let sfollows = new Map<string, number>();\n for (const pubkey of pubkeys) {\n this.relayPool.subscribeEventObject(\n [\n {\n authors: [pubkey],\n kinds: [Kind.Contacts],\n },\n ],\n this.relays,\n (event: EventObject) => {\n let dweight = 1.0 / event.tags.length;\n for (const tag of event.tags) {\n if (tag[0] === \"p\") {\n let weight = sfollows.get(tag[1]);\n if (weight) {\n weight += dweight;\n } else {\n weight = dweight;\n }\n sfollows.set(tag[1], weight);\n }\n }\n if (removeDirectFollows) {\n for (const pubkey of pubkeys) {\n sfollows.delete(pubkey);\n }\n }\n cb(Array.from(sfollows.entries()).sort((a, b) => b[1] - a[1]));\n },\n maxDelayms\n );\n }\n }, maxDelayms);\n }\n\n allEvents(cb: OnEvent, limit = 100, maxDelayms: number): () => void {\n return this.relayPool.subscribe(\n [\n {\n authors: [this.pubkey],\n limit,\n },\n ],\n this.relays,\n cb,\n maxDelayms\n );\n }\n\n referenced(cb: OnEvent, limit = 100, maxDelayms: number): () => void {\n return this.relayPool.subscribe(\n [\n {\n \"#p\": [this.pubkey],\n limit,\n },\n ],\n this.relays,\n cb,\n maxDelayms\n );\n }\n\n followers(cb: OnEvent, limit = 100, maxDelayms: number): () => void {\n return this.relayPool.subscribe(\n [\n {\n \"#p\": [this.pubkey],\n kinds: [Kind.Contacts],\n limit,\n },\n ],\n this.relays,\n cb,\n maxDelayms\n );\n }\n\n sentAndRecievedDMs(cb: OnEvent, limit = 100, maxDelayms: number): () => void {\n return this.relayPool.subscribe(\n [\n {\n authors: [this.pubkey],\n kinds: [Kind.EncryptedDirectMessage],\n limit,\n },\n {\n \"#p\": [this.pubkey],\n kinds: [Kind.EncryptedDirectMessage],\n limit,\n },\n ],\n this.relays,\n cb,\n maxDelayms\n );\n }\n text(cb: OnEvent, limit = 100, maxDelayms: number): () => void {\n return this.relayPool.subscribe(\n [\n {\n authors: [this.pubkey],\n kinds: [Kind.Text],\n limit,\n },\n ],\n this.relays,\n cb,\n maxDelayms\n );\n }\n}\n", "import type {Kind, Event} from \"nostr-tools\";\nimport {Author} from \"./author\";\nimport type {RelayPool} from \"./relay-pool\";\n\nimport type {OnEvent} from \"./on-event-filters\";\nexport class EventObject implements Event {\n id: string;\n kind: Kind;\n pubkey: string;\n tags: string[][];\n created_at: number;\n content: string;\n relayPool: RelayPool;\n relays: string[] | undefined;\n sig: string;\n\n constructor(\n event: Event,\n relayPool: RelayPool,\n relays: string[] | undefined\n ) {\n this.id = event.id;\n this.kind = event.kind;\n this.pubkey = event.pubkey;\n this.tags = event.tags;\n this.created_at = event.created_at;\n this.content = event.content;\n this.relayPool = relayPool;\n this.relays = relays;\n this.sig = event.sig;\n }\n\n referencedAuthors(): Author[] {\n const r: Author[] = [];\n for (const tag of this.tags) {\n if (tag[0] === \"p\") {\n r.push(new Author(this.relayPool, undefined, tag[1]));\n }\n }\n return r;\n }\n referencedEvents(maxDelayms: number): Promise<EventObject>[] {\n const r: Promise<EventObject>[] = [];\n for (const tag of this.tags) {\n if (tag[0] === \"e\") {\n let relays = this.relays;\n if (tag[2]) {\n relays = [tag[2], ...(relays || [])];\n }\n r.push(\n this.relayPool\n // @ts-ignore\n .getEventById(tag[1], relays, maxDelayms)\n .then((e) => new EventObject(e, this.relayPool, this.relays))\n );\n }\n }\n return r;\n }\n\n thread(cb: OnEvent, maxDelayms: number): () => void {\n let relays = this.relays;\n let ids: string[] = [];\n for (const tag of this.tags) {\n if (tag[0] === \"e\") {\n if (tag[2]) {\n relays = [tag[2], ...(relays || [])];\n }\n ids.push(tag[1]);\n }\n }\n\n return this.relayPool.subscribe(\n [{ids}, {\"#e\": ids}],\n relays,\n cb,\n maxDelayms\n );\n }\n}\n", "import {type Filter, Kind, matchFilter, type Event} from \"nostr-tools\";\nimport type {EventObject} from \"./event\";\nexport type OnEventArgs = [\n event: Event,\n afterEose: boolean,\n url: string | undefined\n];\n\nexport type OnEvent = (\n event: Event,\n afterEose: boolean,\n url: string | undefined\n) => void;\n\nexport type OnEventObject = (\n eventObject: EventObject,\n afterEose: boolean,\n url: string | undefined\n) => void;\n\nexport function doNotEmitDuplicateEvents(onEvent: OnEvent): OnEvent {\n let event_ids = new Set();\n return (event: Event, afterEose: boolean, url: string | undefined) => {\n if (event_ids.has(event.id)) return;\n event_ids.add(event.id);\n onEvent(event, afterEose, url);\n };\n}\n\nexport function doNotEmitOlderEvents(onEvent: OnEvent): OnEvent {\n let created_at_by_events_kinds = new Map();\n return (event: Event, afterEose: boolean, url: string | undefined) => {\n if (event.kind === Kind.Metadata || event.kind === Kind.Contacts) {\n let event_kind = event.pubkey + \" \" + event.kind;\n if ((created_at_by_events_kinds.get(event_kind) || 0) > event.created_at)\n return;\n created_at_by_events_kinds.set(event_kind, event.created_at);\n }\n onEvent(event, afterEose, url);\n };\n}\n\nexport function matchOnEventFilters(\n onEvent: OnEvent,\n filters: Filter[]\n): OnEvent {\n return (event: Event, afterEose: boolean, url: string | undefined) => {\n for (let filter of filters) {\n if (matchFilter(filter, event)) {\n onEvent(event, afterEose, url);\n break;\n }\n }\n };\n}\n\nexport function emitEventsOnNextTick(onEvent: OnEvent): OnEvent {\n return (event: Event, afterEose: boolean, url: string | undefined) => {\n setTimeout(() => {\n onEvent(event, afterEose, url);\n }, 0);\n };\n}\n", "// Cancellable<OnEvent> is perfect for this.\nexport type Cancellable<Process> = (process: Process) => () => void;\nexport type Callback<Args extends any[]> = (...args: Args) => void;\n\nexport class CancellableCallbackReplayer<Args extends any[]> {\n events: Args[] = [];\n unsubAll?: () => void;\n subs: Set<Callback<Args>> = new Set();\n constructor(cancellableCallback: Cancellable<Callback<Args>>) {\n this.unsubAll = cancellableCallback((...args: Args) => {\n this.events.push(args);\n for (let sub of this.subs) {\n sub(...args);\n }\n });\n }\n sub(): Cancellable<Callback<Args>> {\n return (callback: Callback<Args>) => {\n this.subs.add(callback);\n this.events.forEach((arg) => callback(...arg));\n return () => {\n this.subs.delete(callback);\n if (this.subs.size === 0) {\n this.unsubAll?.();\n this.unsubAll = undefined;\n }\n };\n };\n }\n}\nexport class CallbackReplayer<\n Args extends any[],\n T extends (...args: Args) => void\n> {\n subs: T[] = [];\n events: Args[] = [];\n onunsub: (() => void) | undefined;\n\n constructor(onunsub: (() => void) | undefined) {\n this.onunsub = onunsub;\n }\n\n event(...args: Args) {\n this.events.push(args);\n this.subs.forEach((sub) => sub(...args));\n }\n\n sub(callback: T) {\n this.events.forEach((event) => callback(...event));\n this.subs.push(callback);\n return () => {\n this.subs = this.subs.filter((sub) => sub !== callback);\n if (this.subs.length === 0) {\n this.onunsub?.();\n this.onunsub = undefined;\n }\n };\n }\n}\n", "import type {Filter, Event} from \"nostr-tools\";\nimport {mergeSimilarAndRemoveEmptyFilters} from \"./merge-similar-filters\";\nimport {\n doNotEmitDuplicateEvents,\n doNotEmitOlderEvents,\n matchOnEventFilters,\n type OnEvent,\n} from \"./on-event-filters\";\nimport type {EventCache} from \"./event-cache\";\nimport type {FilterToSubscribe} from \"./relay-pool\";\nimport {CallbackReplayer} from \"./callback-replayer\";\n\nconst unique = (arr: string[]) => [...new Set(arr)];\n\nexport function groupFiltersByRelayAndEmitCacheHits(\n filters: (Filter & {relay?: string; noCache?: boolean})[],\n relays: string[],\n onEvent: OnEvent,\n options: {\n allowDuplicateEvents?: boolean;\n allowOlderEvents?: boolean;\n logAllEvents?: boolean;\n } = {},\n eventCache?: EventCache\n): [OnEvent, Map<string, Filter[]>] {\n let events: Event[] = [];\n if (eventCache) {\n const cachedEventsWithUpdatedFilters =\n eventCache.getCachedEventsWithUpdatedFilters(filters, relays);\n filters = cachedEventsWithUpdatedFilters.filters;\n events = cachedEventsWithUpdatedFilters.events;\n }\n if (options.logAllEvents) {\n const onEventNow = onEvent; // Nasty bug without introducing a new variable\n onEvent = (event, afterEose, url) => {\n onEventNow(event, afterEose, url);\n };\n }\n if (!options.allowDuplicateEvents) {\n onEvent = doNotEmitDuplicateEvents(onEvent);\n }\n if (!options.allowOlderEvents) {\n onEvent = doNotEmitOlderEvents(onEvent);\n }\n for (const event of events) {\n onEvent(event, false, undefined);\n }\n filters = mergeSimilarAndRemoveEmptyFilters(filters);\n onEvent = matchOnEventFilters(onEvent, filters);\n relays = unique(relays);\n const filtersByRelay = getFiltersByRelay(filters, relays);\n return [onEvent, filtersByRelay];\n}\n\nfunction getFiltersByRelay(\n filters: (Filter & {relay?: string})[],\n relays: string[]\n): Map<string, Filter[]> {\n const filtersByRelay = new Map<string, Filter[]>();\n const filtersWithoutRelay: Filter[] = [];\n for (const filter of filters) {\n const relay = filter.relay;\n if (relay) {\n const relayFilters = filtersByRelay.get(relay);\n if (relayFilters) {\n relayFilters.push(withoutRelay(filter));\n } else {\n filtersByRelay.set(relay, [withoutRelay(filter)]);\n }\n } else {\n filtersWithoutRelay.push(filter);\n }\n }\n if (filtersWithoutRelay.length > 0) {\n for (const relay of relays) {\n const filters = filtersByRelay.get(relay);\n if (filters) {\n filtersByRelay.set(relay, filters.concat(filtersWithoutRelay));\n } else {\n filtersByRelay.set(relay, filtersWithoutRelay);\n }\n }\n }\n return filtersByRelay;\n}\n\nfunction withoutRelay(filter: Filter & {relay?: string}): Filter {\n filter = {...filter};\n delete filter.relay;\n return filter;\n}\n\nexport function batchFiltersByRelay(\n subscribedFilters: FilterToSubscribe[],\n subscriptionCache?: Map<\n string,\n CallbackReplayer<[Event, boolean, string | undefined], OnEvent>\n >\n): [OnEvent, Map<string, Filter[]>, {unsubcb?: () => void}] {\n const filtersByRelay = new Map<string, Filter[]>();\n const onEvents: OnEvent[] = [];\n let counter = 0;\n let unsubOnEoseCounter = 0;\n let allUnsub = {unsubcb: () => {}, unsuboneosecb: () => {}};\n let unsubVirtualSubscription = () => {\n counter--;\n\n if (counter === 0) {\n allUnsub.unsubcb();\n } else if (unsubOnEoseCounter === 0) {\n allUnsub.unsuboneosecb();\n }\n };\n for (const [\n onEvent,\n filtersByRelayBySub,\n unsub,\n unsubscribeOnEose,\n subscriptionCacheKey,\n ] of subscribedFilters) {\n if (!unsub.unsubcb) {\n continue;\n }\n for (const [relay, filters] of filtersByRelayBySub) {\n const filtersByRelayFilters = filtersByRelay.get(relay);\n if (filtersByRelayFilters) {\n filtersByRelay.set(relay, filtersByRelayFilters.concat(filters));\n } else {\n filtersByRelay.set(relay, filters);\n }\n }\n let onEventWithUnsub: OnEvent = (event, afterEose, url) => {\n if (unsub.unsubcb) {\n onEvent(event, afterEose, url);\n }\n };\n\n if (subscriptionCache && subscriptionCacheKey) {\n const callbackReplayer: CallbackReplayer<\n [Event, boolean, string | undefined],\n OnEvent\n > = new CallbackReplayer(unsubVirtualSubscription);\n onEvents.push((event, afterEose, url) => {\n callbackReplayer.event(event, afterEose, url);\n });\n let unsubReplayerVirtualSubscription =\n callbackReplayer.sub(onEventWithUnsub);\n subscriptionCache.set(subscriptionCacheKey, callbackReplayer);\n unsub.unsubcb = () => {\n unsub.unsubcb = undefined;\n unsubReplayerVirtualSubscription();\n if (!unsubscribeOnEose) {\n unsubOnEoseCounter--;\n }\n };\n } else {\n onEvents.push(onEventWithUnsub);\n unsub.unsubcb = () => {\n unsub.unsubcb = undefined;\n unsubVirtualSubscription();\n if (!unsubscribeOnEose) {\n unsubOnEoseCounter--;\n }\n };\n }\n counter++;\n if (!unsubscribeOnEose) {\n unsubOnEoseCounter++;\n }\n }\n\n if (unsubOnEoseCounter === 0) {\n setTimeout(() => {\n allUnsub.unsuboneosecb();\n }, 0);\n } else {\n // console.log(\"NO unsuboneosecb for \", subscribedFilters);\n }\n const onEvent: OnEvent = (event, afterEose, url) => {\n for (const onEvent of onEvents) {\n onEvent(event, afterEose, url);\n }\n };\n subscribedFilters.length = 0;\n return [onEvent, filtersByRelay, allUnsub];\n}\n", "import type {Event, Filter} from \"nostr-tools\";\nimport type {RelayPool} from \"./relay-pool\";\n\nexport class NewestEventCache {\n data: Map<string, Event>;\n promises: Map<string, Promise<Event>>;\n relays: string[];\n kind: number;\n relayPool: RelayPool;\n useps: boolean;\n constructor(\n kind: number,\n relayPool: RelayPool,\n relays?: string[],\n useps?: boolean\n ) {\n this.data = new Map();\n this.promises = new Map();\n this.kind = kind;\n this.relayPool = relayPool;\n this.relays = relays || [\"wss://us.rbr.bio\", \"wss://eu.rbr.bio\"];\n this.useps = useps || false;\n }\n\n async get(pubkey: string): Promise<Event> {\n let value = this.data.get(pubkey);\n if (value) {\n return Promise.resolve(value);\n }\n const promise = this.promises.get(pubkey);\n if (promise) {\n return promise;\n }\n return new Promise((resolve, reject) => {\n let tries = 0;\n const filter: Filter = this.useps\n ? {kinds: [this.kind], \"#p\": [pubkey]}\n : {kinds: [this.kind], authors: [pubkey]};\n // Don't log this instant sending of subscriptions\n const logSubscriptions = this.relayPool.logSubscriptions;\n this.relayPool.logSubscriptions = false;\n this.relayPool.subscribe(\n [filter],\n this.relays,\n (event) => {\n this.data.set(pubkey, event);\n this.promises.delete(pubkey);\n resolve(event);\n },\n undefined,\n (relayUrl) => {\n if (this.relays.includes(relayUrl)) {\n tries++;\n }\n if (tries === this.relays.length) {\n this.promises.delete(pubkey);\n reject(\n `Can't find data2 for ${pubkey} with kind ${\n this.kind\n } on RelayInfoServers ${this.relays.join(\",\")}, ${tries} tries`\n );\n }\n },\n {dontSendOtherFilters: true}\n );\n this.relayPool.logSubscriptions = logSubscriptions;\n });\n }\n}\n", "import type {Filter, Event} from \"nostr-tools\";\nimport {mergeSimilarAndRemoveEmptyFilters} from \"./merge-similar-filters\";\nimport {type Relay, relayInit, type Sub} from \"./relay\";\nimport type {OnEventObject, OnEvent} from \"./on-event-filters\";\nimport {EventCache} from \"./event-cache\";\nimport {EventObject} from \"./event\";\nimport {\n batchFiltersByRelay,\n groupFiltersByRelayAndEmitCacheHits,\n} from \"./group-filters-by-relay\";\nimport type {CallbackReplayer} from \"./callback-replayer\";\nimport {NewestEventCache} from \"./newest-event-cache\";\n\nconst unique = (arr: string[]) => [...new Set(arr)];\n\nexport {type OnEvent, type OnEventObject} from \"./on-event-filters\";\nexport type OnEose = (relayUrl: string, minCreatedAt: number) => void;\nexport type OnEventAndMetadata = (event: Event, metadata: Event) => void;\nexport type FilterToSubscribe = [\n onEvent: OnEvent,\n filtersByRelay: Map<string, Filter[]>,\n unsub: {unsubcb?: () => void},\n unsubscribeOnEose?: boolean,\n subscriptionCacheKey?: string,\n maxDelayms?: number\n];\n\nexport type SubscriptionOptions = {\n allowDuplicateEvents?: boolean;\n allowOlderEvents?: boolean;\n logAllEvents?: boolean;\n unsubscribeOnEose?: boolean;\n defaultRelays?: string[];\n dontSendOtherFilters?: boolean;\n};\n\nfunction parseJSON(json: string | undefined) {\n if (json) {\n return JSON.parse(json);\n }\n}\n\nexport class RelayPool {\n relayByUrl: Map<string, Relay> = new Map();\n noticecbs: Array<(url: string, msg: string) => void> = [];\n errorcbs: Array<(url: string, err: string) => void> = [];\n authcbs: Array<(relay: Relay, challenge: string) => void> = [];\n eventCache?: EventCache;\n minMaxDelayms: number = Infinity;\n filtersToSubscribe: FilterToSubscribe[] = [];\n timer?: ReturnType<typeof setTimeout>;\n externalGetEventById?: (id: string) => Event | undefined;\n logSubscriptions?: boolean = false;\n autoReconnect?: boolean = false;\n startTime: number = new Date().getTime();\n deleteSignatures?: boolean;\n subscriptionCache?: Map<\n string,\n CallbackReplayer<[Event, boolean, string | undefined], OnEvent>\n >;\n skipVerification?: boolean;\n writeRelays: NewestEventCache;\n metadataCache: NewestEventCache;\n contactListCache: NewestEventCache;\n logErrorsAndNotices?: boolean;\n errorsAndNoticesInterval: any;\n\n constructor(\n relays?: string[],\n options: {\n useEventCache?: boolean;\n externalGetEventById?: (id: string) => Event | undefined;\n logSubscriptions?: boolean;\n autoReconnect?: boolean;\n subscriptionCache?: boolean;\n deleteSignatures?: boolean;\n skipVerification?: boolean;\n logErrorsAndNotices?: boolean;\n } = {}\n ) {\n this.externalGetEventById = options.externalGetEventById;\n this.logSubscriptions = options.logSubscriptions;\n this.autoReconnect = options.autoReconnect;\n this.deleteSignatures = options.deleteSignatures;\n this.skipVerification = options.skipVerification;\n this.writeRelays = new NewestEventCache(10003, this, undefined, true);\n this.metadataCache = new NewestEventCache(0, this);\n this.contactListCache = new NewestEventCache(3, this);\n if (options.useEventCache) {\n this.eventCache = new EventCache();\n }\n if (options.subscriptionCache) {\n this.subscriptionCache = new Map();\n }\n if (relays) {\n for (const relay of unique(relays)) {\n this.addOrGetRelay(relay);\n }\n }\n\n this.logErrorsAndNotices = options.logErrorsAndNotices ?? true;\n\n this.onnotice((url, msg) => {\n this.errorsAndNotices.push({\n type: \"notice\",\n url,\n msg,\n time: Date.now() - this.startTime,\n });\n });\n this.onerror((url, msg) => {\n this.errorsAndNotices.push({\n type: \"error\",\n url,\n msg,\n time: Date.now() - this.startTime,\n });\n });\n this.errorsAndNoticesInterval = setInterval(\n () => this.#maybeLogErrorsAndNotices(),\n 1000 * 10\n );\n }\n errorsAndNotices: {\n type: string;\n url: string;\n msg: string | Error;\n time: number;\n }[] = [];\n\n #maybeLogErrorsAndNotices() {\n if (!this.errorsAndNotices.length) {\n return;\n }\n if (!this.logErrorsAndNotices) {\n this.errorsAndNotices = [];\n return;\n }\n if (this.errorsAndNotices.length > 5) {\n console.groupCollapsed(\n \"RelayPool errors and notices with \" +\n this.errorsAndNotices.length +\n \" entries\"\n );\n } else {\n console.group(\"RelayPool errors and notices\");\n }\n console.table(this.errorsAndNotices.map((e) => ({...e, msg: e.msg})));\n console.groupEnd();\n this.errorsAndNotices = [];\n }\n\n addOrGetRelay(relay: string): Relay {\n const origRelayInstance = this.relayByUrl.get(relay);\n if (origRelayInstance) {\n return origRelayInstance;\n }\n const relayInstance = relayInit(\n relay,\n this.externalGetEventById\n ? this.externalGetEventById\n : this.eventCache\n ? (id) => this.eventCache?.getEventById(id)\n : undefined,\n this.autoReconnect\n );\n this.relayByUrl.set(relay, relayInstance);\n relayInstance.connect().then(\n (onfulfilled) => {\n relayInstance?.on(\"notice\", (msg: string) => {\n this.noticecbs.forEach((cb) => cb(relay, msg));\n });\n relayInstance?.on(\"auth\", (msg: string) => {\n this.authcbs.forEach((cb) => cb(relayInstance, msg));\n });\n },\n (onrejected) => {\n this.errorcbs.forEach((cb) => cb(relay, onrejected));\n }\n );\n return relayInstance;\n }\n\n async close() {\n const promises = [];\n for (const relayInstance of this.relayByUrl.values()) {\n promises.push(relayInstance.close());\n }\n this.relayByUrl.clear();\n clearInterval(this.errorsAndNoticesInterval);\n return Promise.all(promises);\n }\n\n removeRelay(url: string) {\n const relay = this.relayByUrl.get(url);\n if (relay) {\n relay.close();\n this.relayByUrl.delete(url);\n }\n }\n\n #subscribeRelay(\n relay: string,\n filters: Filter[],\n onEvent: OnEvent,\n onEose?: OnEose,\n eventIds?: Set<string>\n ): Sub | undefined {\n const mergedAndRemovedEmptyFilters =\n mergeSimilarAndRemoveEmptyFilters(filters);\n if (mergedAndRemovedEmptyFilters.length === 0) {\n return;\n }\n const instance = this.addOrGetRelay(relay);\n const sub = instance.sub(mergedAndRemovedEmptyFilters, {\n skipVerification: this.skipVerification,\n eventIds,\n });\n let afterEose = false;\n let minCreatedAt = Infinity;\n sub.on(\"event\", (nostrEvent: Event) => {\n if (nostrEvent.created_at < minCreatedAt) {\n minCreatedAt = nostrEvent.created_at;\n }\n let event = nostrEvent;\n if (!this.deleteSignatures) {\n event.sig = nostrEvent.sig;\n }\n this.eventCache?.addEvent(event);\n onEvent(event, afterEose, relay);\n });\n sub.on(\"eose\", () => {\n onEose?.(relay, minCreatedAt);\n afterEose = true;\n });\n\n return sub;\n }\n\n #mergeAndRemoveEmptyFiltersByRelay(\n filtersByRelay: Map<string, Filter[]>\n ): Map<string, Filter[]> {\n const mergedAndRemovedEmptyFiltersByRelay = new Map();\n for (const [relay, filters] of filtersByRelay) {\n const mergedAndRemovedEmptyFilters = mergeSimilarAndRemoveEmptyFilters(\n mergeSimilarAndRemoveEmptyFilters(filters)\n );\n if (mergedAndRemovedEmptyFilters.length > 0) {\n mergedAndRemovedEmptyFiltersByRelay.set(\n relay,\n mergedAndRemovedEmptyFilters\n );\n }\n }\n return mergedAndRemovedEmptyFiltersByRelay;\n }\n\n #subscribeRelays(\n filtersByRelay: Map<string, Filter[]>,\n onEvent: OnEvent,\n onEose?: OnEose,\n unsub: {unsubcb?: () => void; unsuboneosecb?: () => void} = {},\n minMaxDelayms?: number\n ): () => void {\n if (filtersByRelay.size === 0) {\n return () => {};\n }\n // Merging here is done to make logging more readable.\n filtersByRelay = this.#mergeAndRemoveEmptyFiltersByRelay(filtersByRelay);\n if (this.logSubscriptions) {\n // console.log(\n // \"RelayPool subscribeRelays: at time\",\n // new Date().getTime() - this.startTime,\n // \"ms, minMaxDelayms=\",\n // minMaxDelayms,\n // \", filtersByRelay: \",\n // filtersByRelay\n // );\n console.group(\"RelayPool subscribeRelays\");\n console.log(\n \"at time\",\n new Date().getTime() - this.startTime,\n \"ms, minMaxDelayms=\",\n minMaxDelayms\n );\n const flattenedFilters: any = {};\n for (const [relay, filters] of filtersByRelay) {\n let i = 0;\n for (const filter of filters) {\n const filter2: any = {...filter};\n if (filter2.authors) {\n filter2.authors = filter2.authors.join();\n filter2[\"authors.length\"] = filter?.authors?.length;\n }\n if (filter2.kinds) {\n filter2.kinds = filter2.kinds.join();\n }\n if (filter2.ids) {\n filter2.ids = filter2.ids.join();\n filter2[\"ids.length\"] = filter?.ids?.length;\n }\n if (filter2[\"#e\"]) {\n filter2[\"#e\"] = filter2[\"#e\"].join();\n filter2[\"#e.length\"] = filter[\"#e\"]!.length;\n }\n if (filter2[\"#p\"]) {\n filter2[\"#p\"] = filter2[\"#p\"].join();\n filter2[\"#p.length\"] = filter[\"#p\"]!.length;\n }\n flattenedFilters[relay + \" \" + i] = filter2;\n i++;\n }\n }\n\n if (Object.keys(flattenedFilters).length > 3) {\n console.groupCollapsed(\n Object.keys(flattenedFilters).length +\n \" filters to \" +\n filtersByRelay.size +\n \" relays\"\n );\n }\n console.table(flattenedFilters);\n if (Object.keys(flattenedFilters).length > 3) {\n console.groupEnd();\n }\n console.groupEnd();\n }\n const subs: Sub[] = [];\n let unsuboneosecbcalled = false;\n let eoseSubs: Sub[] = [];\n unsub.unsuboneosecb = () => {\n unsuboneosecbcalled = true;\n eoseSubs.forEach((sub) => sub.unsub());\n };\n for (const [relay, filters] of filtersByRelay) {\n let subHolder: {sub?: Sub} = {};\n const subOnEose: OnEose = (url, minCreatedAt) => {\n if (onEose) {\n onEose(url, minCreatedAt);\n }\n if (unsuboneosecbcalled) {\n subHolder.sub?.unsub();\n } else {\n if (subHolder.sub) {\n eoseSubs.push(subHolder.sub);\n }\n }\n };\n\n const eventIds = new Set<string>();\n\n const sub = this.#subscribeRelay(\n relay,\n filters,\n onEvent,\n subOnEose,\n eventIds\n );\n if (sub) {\n subHolder.sub = sub;\n subs.push(sub);\n }\n }\n const allUnsub = () => subs.forEach((sub) => sub.unsub());\n unsub.unsubcb = () => {\n allUnsub();\n delete unsub.unsubcb;\n };\n return allUnsub;\n }\n\n sendSubscriptions(onEose?: OnEose, filtersToSubscribe?: FilterToSubscribe[]) {\n clearTimeout(this.timer);\n this.timer = undefined;\n let minMaxDelayms = this.minMaxDelayms;\n this.minMaxDelayms = Infinity;\n\n const [onEvent, filtersByRelay, unsub]: [\n OnEvent,\n Map<string, Filter[]>,\n {unsubcb?: () => void; unsuboneosecb?: () => void}\n ] = batchFiltersByRelay(\n filtersToSubscribe || this.filtersToSubscribe,\n this.subscriptionCache\n );\n\n let allUnsub = this.#subscribeRelays(\n filtersByRelay,\n onEvent,\n onEose,\n unsub,\n minMaxDelayms // For logging\n );\n\n return allUnsub;\n }\n\n #resetTimer(maxDelayms: number) {\n if (this.minMaxDelayms > maxDelayms) {\n this.minMaxDelayms = maxDelayms;\n }\n\n clearTimeout(this.timer);\n this.timer = undefined;\n\n if (this.minMaxDelayms !== Infinity) {\n this.timer = setTimeout(() => {\n this.sendSubscriptions();\n }, this.minMaxDelayms);\n }\n }\n\n async #getRelaysAndSubscribe(\n filters: (Filter & {relay?: string; noCache?: boolean})[],\n onEvent: OnEvent,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ) {\n const allAuthors: Set<string> = new Set();\n for (const filter of filters) {\n if (filter.authors) {\n for (const author of filter.authors) {\n allAuthors.add(author);\n }\n } else {\n if (!options.defaultRelays) {\n throw new Error(\n \"Authors must be specified if no relays are subscribed and no default relays are specified.\"\n );\n }\n }\n }\n const promises = [];\n const allAuthorsArray = [];\n for (const author of allAuthors) {\n promises.push(\n this.writeRelays\n ?.get(author)\n .then((event) => parseJSON(event?.content))\n .catch(() => options?.defaultRelays || [])\n );\n allAuthorsArray.push(author);\n }\n const allRelays: Set<string> = new Set();\n let i = 0;\n for (const promise of promises) {\n const author = allAuthorsArray[i];\n i += 1;\n let relays = await promise;\n if (!Array.isArray(relays)) {\n console.error(\"Couldn't load relays for author \", author);\n continue;\n }\n for (let relay of relays) {\n allRelays.add(relay);\n }\n }\n let allRelaysArray = Array.from(allRelays);\n if (allRelaysArray.length === 0) {\n if (options.defaultRelays) {\n allRelaysArray = options.defaultRelays;\n }\n }\n // if (this.logSubscriptions) {\n // console.log(\n // \"getRelaysAndSubscribe\",\n // \"filters=\",\n // filters,\n // \"allRelaysArray=\",\n // allRelaysArray,\n // \"maxDelayms=\",\n // maxDelayms,\n // \"options=\",\n // options\n // );\n // }\n\n return this.subscribe(\n filters,\n allRelaysArray,\n onEvent,\n maxDelayms,\n onEose,\n options\n );\n }\n\n subscribeEventObject(\n filters: (Filter & {relay?: string; noCache?: boolean})[],\n relays: string[] | undefined,\n onEventObject: OnEventObject,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ): () => void {\n return this.subscribe(filters, relays, (event, afterEose, url) =>\n onEventObject(new EventObject(event, this, relays), afterEose, url)\n );\n }\n\n subscribe(\n filters: (Filter & {relay?: string; noCache?: boolean})[],\n relays: string[] | undefined,\n onEvent: OnEvent,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ): () => void {\n if (maxDelayms !== undefined && onEose) {\n throw new Error(\"maxDelayms and onEose cannot be used together\");\n }\n if (relays === undefined) {\n const promise = this.#getRelaysAndSubscribe(\n filters,\n onEvent,\n maxDelayms,\n onEose,\n options\n );\n return () => {\n promise.then((x) => {\n x();\n });\n };\n }\n let subscriptionCacheKey: string | undefined;\n if (options.unsubscribeOnEose && !onEose) {\n subscriptionCacheKey = JSON.stringify([filters, relays]);\n const cachedSubscription =\n this.subscriptionCache?.get(subscriptionCacheKey);\n if (cachedSubscription) {\n return cachedSubscription.sub(onEvent);\n }\n }\n const [dedupedOnEvent, filtersByRelay] =\n groupFiltersByRelayAndEmitCacheHits(\n filters,\n relays,\n onEvent,\n options,\n this.eventCache\n );\n let unsub: {unsubcb?: () => void} = {unsubcb: () => {}};\n if (\n maxDelayms === undefined &&\n onEose &&\n this.filtersToSubscribe.length > 0 &&\n !options.dontSendOtherFilters\n ) {\n this.sendSubscriptions(); // onEose is not yet supported for batched subscriptions\n }\n const newFilters: FilterToSubscribe = [\n dedupedOnEvent,\n filtersByRelay,\n unsub,\n options.unsubscribeOnEose,\n subscriptionCacheKey,\n maxDelayms,\n ];\n if (options.dontSendOtherFilters) {\n return this.sendSubscriptions(onEose, [newFilters]);\n }\n\n this.filtersToSubscribe.push(newFilters);\n if (maxDelayms === undefined) {\n return this.sendSubscriptions(onEose);\n } else {\n this.#resetTimer(maxDelayms);\n return () => {\n unsub.unsubcb?.();\n delete unsub.unsubcb;\n };\n }\n }\n\n async getEventObjectById(\n id: string,\n relays: string[],\n maxDelayms: number\n ): Promise<EventObject> {\n return this.getEventById(id, relays, maxDelayms).then(\n (event) => new EventObject(event, this, relays)\n );\n }\n\n async getEventById(\n id: string,\n relays: string[],\n maxDelayms: number\n ): Promise<Event> {\n return new Promise((resolve, reject) => {\n this.subscribe(\n [{ids: [id]}],\n relays,\n (event) => {\n resolve(event);\n },\n maxDelayms,\n undefined\n // {unsubscribeOnEose: true}\n );\n });\n }\n\n publish(event: Event, relays: string[]) {\n for (const relay of unique(relays)) {\n const instance = this.addOrGetRelay(relay);\n instance.publish(event);\n }\n }\n\n onnotice(cb: (url: string, msg: string) => void) {\n this.noticecbs.push(cb);\n }\n\n onerror(cb: (url: string, msg: string) => void) {\n this.relayByUrl.forEach((relay: Relay, url: string) =>\n relay.on(\"error\", (msg: string) => cb(url, msg))\n );\n this.errorcbs.push(cb);\n }\n ondisconnect(cb: (url: string, msg: string) => void) {\n this.relayByUrl.forEach((relay: Relay, url: string) =>\n relay.on(\"disconnect\", (msg: string) => cb(url, msg))\n );\n }\n onauth(cb: (relay: Relay, challenge: string) => void) {\n this.authcbs.push(cb);\n }\n getRelayStatuses(): [url: string, staus: number][] {\n return Array.from(this.relayByUrl.entries())\n .map(\n ([url, relay]: [string, Relay]) =>\n [url, relay.status] as [string, number]\n )\n .sort();\n }\n setWriteRelaysForPubKey(\n pubkey: string,\n writeRelays: string[],\n created_at: number\n ) {\n const event: Event = {\n created_at,\n pubkey: \"\",\n id: \"\",\n sig: \"\",\n content: JSON.stringify(writeRelays),\n // @ts-ignore\n kind: 10003,\n tags: [[\"p\", pubkey]],\n };\n this.writeRelays.data.set(pubkey, event);\n }\n setCachedMetadata(pubkey: string, metadata: Event) {\n this.metadataCache.data.set(pubkey, metadata);\n }\n setCachedContactList(pubkey: string, contactList: Event) {\n this.contactListCache.data.set(pubkey, contactList);\n }\n\n subscribeReferencedEvents(\n event: Event,\n onEvent: OnEvent,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ): () => void {\n let ids: string[] = [];\n let authors: string[] = [];\n\n for (const tag of event.tags) {\n if (tag[0] === \"p\") {\n const pubkey = tag[1];\n if (pubkey.length !== 64) {\n console.log(\"bad pubkey\", pubkey, tag);\n continue;\n }\n authors.push(pubkey);\n }\n if (tag[0] === \"e\") {\n const id = tag[1];\n ids.push(id);\n }\n }\n if (ids.length === 0) {\n return () => {};\n }\n if (authors.length === 0) {\n if (options.defaultRelays) {\n return this.subscribe(\n [{ids}],\n options.defaultRelays,\n onEvent,\n maxDelayms,\n onEose,\n options\n );\n } else {\n console.error(\"No authors for ids in event\", event);\n return () => {};\n }\n }\n if (this.logSubscriptions) {\n // console.log(\"subscribeReferencedEvents0: \", ids, authors);\n }\n return this.subscribe(\n [{ids, authors}],\n undefined,\n onEvent,\n maxDelayms,\n onEose,\n options\n );\n }\n\n fetchAndCacheMetadata(pubkey: string): Promise<Event> {\n return this.metadataCache.get(pubkey).catch((e) => {\n this.errorsAndNotices.push({\n type: \"error\",\n msg: `Error fetching metadata for ${pubkey}: ${e}`,\n time: Date.now() - this.startTime,\n url: \"\",\n });\n\n throw new Error(`Error fetching metadata for ${pubkey}: ${e}`);\n });\n }\n\n fetchAndCacheContactList(pubkey: string): Promise<Event> {\n return this.contactListCache.get(pubkey).catch((e) => {\n this.errorsAndNotices.push({\n type: \"error\",\n msg: `Error fetching contact list for ${pubkey}: ${e}`,\n time: Date.now() - this.startTime,\n url: \"\",\n });\n throw new Error(`Error fetching contact list for ${pubkey}: ${e}`);\n });\n }\n\n subscribeReferencedEventsAndPrefetchMetadata(\n event: Event,\n onEvent: OnEvent,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ): () => void {\n for (const tag of event.tags) {\n if (tag[0] === \"p\") {\n const pubkey = tag[1];\n if (pubkey.length !== 64) {\n console.log(\"bad pubkey\", pubkey, tag);\n continue;\n }\n this.fetchAndCacheMetadata(pubkey).catch((e) => {\n this.errorsAndNotices.push({\n type: \"error\",\n url: \"\",\n msg: `Error fetching metadata for ${pubkey}: ${e}`,\n time: Date.now() - this.startTime,\n });\n });\n }\n }\n return this.subscribeReferencedEvents(\n event,\n onEvent,\n maxDelayms,\n onEose,\n options\n );\n }\n\n reconnect() {\n this.relayByUrl.forEach((relay: Relay) => {\n relay.connect().catch((e) => {\n this.errorsAndNotices.push({\n type: \"error\",\n msg: `Error reconnecting to ${relay.url}: ${e}`,\n time: Date.now() - this.startTime,\n url: relay.url,\n });\n });\n });\n }\n}\n", "import type {Event} from \"nostr-tools\";\nimport type {OnEvent} from \"./on-event-filters\";\n\nconst binarySearch = function (a: Event[], target: Event) {\n var l = 0,\n h = a.length - 1,\n m,\n comparison;\n let comparator = function (a: Event, b: Event) {\n return a.created_at - b.created_at;\n };\n while (l <= h) {\n m = (l + h) >>> 1; /* equivalent to Math.floor((l + h) / 2) but faster */\n comparison = comparator(a[m], target);\n if (comparison < 0) {\n l = m + 1;\n } else if (comparison > 0) {\n h = m - 1;\n } else {\n return m;\n }\n }\n return ~l;\n};\n\nconst binaryInsert = function (a: Event[], target: Event) {\n const duplicate = true; // it's OK to have the same created_at multiple times\n var i = binarySearch(a, target);\n if (i >= 0) {\n /* if the binarySearch return value was zero or positive, a matching object was found */\n if (!duplicate) {\n return i;\n }\n } else {\n /* if the return value was negative, the bitwise complement of the return value is the correct index for this object */\n i = ~i;\n }\n a.splice(i, 0, target);\n return i;\n};\n\nexport function collect(\n onEvents: (events: Event[]) => void,\n skipSort: boolean = false\n): OnEvent {\n let events: Event[] = [];\n return (event: Event, afterEose: boolean, url: string | undefined) => {\n if (skipSort) {\n events.push(event);\n } else {\n binaryInsert(events, event);\n }\n onEvents(events);\n };\n}\n", "import type {Event} from \"nostr-tools\";\nimport type {OnEose, OnEvent, SubscriptionOptions} from \"./relay-pool\";\n\nexport class RelayPoolWorker {\n // eslint-disable-next-line no-undef\n private worker: Worker;\n private subscriptionCallbacks = new Map<\n number | string,\n {onEvent: OnEvent; onEose?: OnEose}\n >();\n\n constructor(\n // eslint-disable-next-line no-undef\n worker: Worker,\n relays: string[] = [],\n options: {\n useEventCache?: boolean;\n logSubscriptions?: boolean;\n deleteSignatures?: boolean;\n skipVerification?: boolean;\n autoReconnect?: boolean;\n } = {}\n ) {\n this.worker = worker;\n this.worker.onmessage = this.handleWorkerMessage.bind(this);\n this.worker.postMessage({\n action: \"create_relay_pool\",\n data: {relays, options},\n });\n }\n\n private handleWorkerMessage(event: MessageEvent) {\n const {type, subscriptionId, ...rest} = event.data;\n\n if (type === \"event\" || type === \"eose\") {\n const callbacks = this.subscriptionCallbacks.get(subscriptionId);\n\n if (callbacks) {\n if (type === \"event\") {\n callbacks.onEvent(rest.event, rest.isAfterEose, rest.relayURL);\n } else if (type === \"eose\" && callbacks.onEose) {\n callbacks.onEose(rest.relayURL, rest.minCreatedAt);\n }\n }\n } else if (type === \"subscribed\") {\n // Do nothing\n } else if (type === \"metadata\") {\n // Need better handling\n } else if (type === \"contactList\") {\n // Need better handling\n } else {\n console.warn(\"Unhandled message from worker:\", event.data);\n }\n }\n\n subscribe(\n filters: any,\n relays: string[] | undefined,\n onEvent: OnEvent,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ): () => void {\n const subscriptionId = Math.random().toString(36).slice(2, 9);\n\n this.subscriptionCallbacks.set(subscriptionId, {onEvent, onEose});\n\n this.worker.postMessage({\n action: \"subscribe\",\n data: {\n filters,\n relays,\n maxDelayms,\n onEose: !!onEose,\n options,\n subscriptionId,\n },\n });\n\n return () => {\n this.subscriptionCallbacks.delete(subscriptionId);\n this.worker.postMessage({action: \"unsubscribe\", data: {subscriptionId}});\n };\n }\n\n publish(event: Event, relays: string[]) {\n this.worker.postMessage({action: \"publish\", data: {event, relays}});\n }\n\n setWriteRelaysForPubKey(pubkey: string, writeRelays: string[]) {\n this.worker.postMessage({\n action: \"set_write_relays_for_pub_key\",\n data: {pubkey, writeRelays},\n });\n }\n\n subscribeReferencedEvents(\n event: Event,\n onEvent: OnEvent,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ): () => void {\n const subscriptionId = Math.random().toString(36).slice(2, 9);\n\n this.subscriptionCallbacks.set(subscriptionId, {onEvent, onEose});\n\n this.worker.postMessage({\n action: \"subscribe_referenced_events\",\n data: {event, maxDelayms, onEose: !!onEose, options, subscriptionId},\n });\n\n return () => {\n this.subscriptionCallbacks.delete(subscriptionId);\n this.worker.postMessage({action: \"unsubscribe\", data: {subscriptionId}});\n };\n }\n\n fetchAndCacheMetadata(pubkey: string): Promise<Event> {\n return new Promise((resolve) => {\n const listener = (event: MessageEvent) => {\n if (event.data.type === \"metadata\" && event.data.pubkey === pubkey) {\n this.worker.removeEventListener(\"message\", listener);\n resolve(event.data.metadata);\n }\n };\n\n this.worker.addEventListener(\"message\", listener);\n this.worker.postMessage({\n action: \"fetch_and_cache_metadata\",\n data: {pubkey},\n });\n });\n }\n\n fetchAndCacheContactList(pubkey: string): Promise<Event> {\n return new Promise((resolve) => {\n const listener = (event: MessageEvent) => {\n if (event.data.type === \"contactList\" && event.data.pubkey === pubkey) {\n this.worker.removeEventListener(\"message\", listener);\n resolve(event.data.contactList);\n }\n };\n\n this.worker.addEventListener(\"message\", listener);\n this.worker.postMessage({\n action: \"fetch_and_cache_contact_list\",\n data: {pubkey},\n });\n });\n }\n\n subscribeReferencedEventsAndPrefetchMetadata(\n event: Event,\n onEvent: OnEvent,\n maxDelayms?: number,\n onEose?: OnEose,\n options: SubscriptionOptions = {}\n ): () => void {\n const subscriptionId = Math.random().toString(36).slice(2, 9);\n\n this.subscriptionCallbacks.set(subscriptionId, {onEvent, onEose});\n\n this.worker.postMessage({\n action: \"subscribe_referenced_events_and_prefetch_metadata\",\n data: {event, maxDelayms, onEose: !!onEose, options, subscriptionId},\n });\n\n return () => {\n this.subscriptionCallbacks.delete(subscriptionId);\n this.worker.postMessage({action: \"unsubscribe\", data: {subscriptionId}});\n };\n }\n\n setCachedMetadata(pubkey: string, metadata: Event) {\n this.worker.postMessage({\n action: \"set_cached_metadata\",\n data: {pubkey, metadata},\n });\n }\n\n close() {\n this.worker.postMessage({action: \"close\"});\n }\n}\n"],
"mappings": "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",
"names": ["import_nostr_tools", "event", "id", "WebSocket", "type", "import_nostr_tools", "import_nostr_tools", "pubkey", "import_nostr_tools", "filters", "onEvent", "unique", "a"]
}