From 7ff97b5488a20620b403256f31c822a2f1a2e214 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Wed, 8 Feb 2023 16:37:53 -0300 Subject: [PATCH] list() and get() methods. --- README.md | 12 +++++++++- package.json | 2 +- pool.ts | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ relay.ts | 32 +++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2d7aa4a..e4c9457 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,11 @@ pub.on('failed', reason => { console.log(`failed to publish to ${relay.url}: ${reason}`) }) +let events = await relay.list([{kinds: [0, 1]}]) +let event = await relay.get({ + ids: ['44e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'] +}) + await relay.close() ``` @@ -147,12 +152,17 @@ subs.forEach(sub => }) ) -let pubs = pool.publish(newEvent) +let pubs = pool.publish(relays, newEvent) pubs.forEach(pub => pub.on('ok', () => { // ... }) ) + +let events = await pool.list(relays, [{kinds: [0, 1]}]) +let event = await pool.get(relays, { + ids: ['44e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'] +}) ``` ### Querying profile data from a NIP-05 address diff --git a/package.json b/package.json index b68ac38..ab9280c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nostr-tools", - "version": "1.2.4", + "version": "1.3.0", "description": "Tools for making a Nostr client.", "repository": { "type": "git", diff --git a/pool.ts b/pool.ts index c6e8668..3ed55ac 100644 --- a/pool.ts +++ b/pool.ts @@ -37,6 +37,68 @@ export class SimplePool { }) } + get( + relays: string[], + filter: Filter, + opts?: SubscriptionOptions + ): Promise { + return new Promise(resolve => { + let subs = this.sub(relays, [filter], opts) + let timeout = setTimeout(() => { + subs.forEach(sub => sub.unsub(), 1500) + resolve(null) + }) + subs.forEach(sub => { + sub.on('event', (event: Event) => { + resolve(event) + clearTimeout(timeout) + subs.forEach(sub => { + sub.unsub() + }) + }) + }) + }) + } + + list( + relays: string[], + filters: Filter[], + opts?: SubscriptionOptions + ): Promise { + return new Promise(resolve => { + let _knownIds: Set = new Set() + let modifiedOpts = opts || {} + modifiedOpts.alreadyHaveEvent = id => _knownIds.has(id) + + let events: Event[] = [] + + let subs = this.sub(relays, filters, modifiedOpts) + let timeout = setTimeout(() => { + subs.forEach(sub => sub.unsub(), 1500) + resolve(events) + }) + + let pendingEoses = relays.length + + subs.forEach(sub => { + sub.on('event', (event: Event) => { + events.push(event) + }) + + sub.on('eose', () => { + pendingEoses-- + if (pendingEoses === 0) { + resolve(events) + clearTimeout(timeout) + subs.forEach(sub => { + sub.unsub() + }) + } + }) + }) + }) + } + publish(relays: string[], event: Event): Pub[] { return relays.map(relay => { let r = this._conn[relay] diff --git a/relay.ts b/relay.ts index f29ef4a..6cecd28 100644 --- a/relay.ts +++ b/relay.ts @@ -12,6 +12,8 @@ export type Relay = { connect: () => Promise close: () => Promise sub: (filters: Filter[], opts?: SubscriptionOptions) => Sub + list: (filters: Filter[], opts?: SubscriptionOptions) => Promise + get: (filter: Filter, opts?: SubscriptionOptions) => Promise publish: (event: Event) => Pub on: (type: RelayEvent, cb: any) => void off: (type: RelayEvent, cb: any) => void @@ -231,6 +233,36 @@ export function relayInit(url: string): Relay { let index = listeners[type].indexOf(cb) if (index !== -1) listeners[type].splice(index, 1) }, + list: (filters: Filter[], opts?: SubscriptionOptions): Promise => + new Promise(resolve => { + let s = sub(filters, opts) + let events: Event[] = [] + let timeout = setTimeout(() => { + s.unsub() + resolve(events) + }, 1500) + s.on('eose', () => { + s.unsub() + clearTimeout(timeout) + resolve(events) + }) + s.on('event', (event: Event) => { + events.push(event) + }) + }), + get: (filter: Filter, opts?: SubscriptionOptions): Promise => + new Promise(resolve => { + let s = sub([filter], opts) + let timeout = setTimeout(() => { + s.unsub() + resolve(null) + }, 1500) + s.on('event', (event: Event) => { + s.unsub() + clearTimeout(timeout) + resolve(event) + }) + }), publish(event: Event): Pub { if (!event.id) throw new Error(`event ${event} has no id`) let id = event.id