diff --git a/README.md b/README.md index b6996db..cb85fd4 100644 --- a/README.md +++ b/README.md @@ -108,13 +108,7 @@ let event = { event.id = getEventHash(event) event.sig = getSignature(event, sk) -let pub = relay.publish(event) -pub.on('ok', () => { - console.log(`${relay.url} has accepted our event`) -}) -pub.on('failed', reason => { - console.log(`failed to publish to ${relay.url}: ${reason}`) -}) +await relay.publish(event) let events = await relay.list([{kinds: [0, 1]}]) let event = await relay.get({ diff --git a/nip42.ts b/nip42.ts index 93c7cdc..369545b 100644 --- a/nip42.ts +++ b/nip42.ts @@ -17,7 +17,9 @@ export const authenticate = async ({ }: { challenge: string relay: Relay - sign: (e: EventTemplate) => Promise> | Event + sign: ( + e: EventTemplate + ) => Promise> | Event }): Promise => { const e: EventTemplate = { kind: Kind.ClientAuth, @@ -28,15 +30,5 @@ export const authenticate = async ({ ], content: '' } - const pub = relay.auth(await sign(e)) - return new Promise((resolve, reject) => { - pub.on('ok', function ok() { - pub.off('ok', ok) - resolve() - }) - pub.on('failed', function fail(reason: string) { - pub.off('failed', fail) - reject(reason) - }) - }) + return relay.auth(await sign(e)) } diff --git a/pool.ts b/pool.ts index f13d1ac..b881c36 100644 --- a/pool.ts +++ b/pool.ts @@ -1,9 +1,8 @@ import { relayInit, - type Pub, type Relay, type Sub, - type SubscriptionOptions, + type SubscriptionOptions } from './relay.ts' import {normalizeURL} from './utils.ts' @@ -17,7 +16,13 @@ export class SimplePool { private getTimeout: number private seenOnEnabled: boolean = true - constructor(options: {eoseSubTimeout?: number; getTimeout?: number; seenOnEnabled?: boolean} = {}) { + constructor( + options: { + eoseSubTimeout?: number + getTimeout?: number + seenOnEnabled?: boolean + } = {} + ) { this._conn = {} this.eoseSubTimeout = options.eoseSubTimeout || 3400 this.getTimeout = options.getTimeout || 3400 @@ -46,7 +51,11 @@ export class SimplePool { return relay } - sub(relays: string[], filters: Filter[], opts?: SubscriptionOptions): Sub { + sub( + relays: string[], + filters: Filter[], + opts?: SubscriptionOptions + ): Sub { let _knownIds: Set = new Set() let modifiedOpts = {...(opts || {})} modifiedOpts.alreadyHaveEvent = (id, url) => { @@ -82,7 +91,7 @@ export class SimplePool { } if (!r) return let s = r.sub(filters, modifiedOpts) - s.on('event', (event) => { + s.on('event', event => { _knownIds.add(event.id as string) for (let cb of eventListeners.values()) cb(event) }) @@ -138,7 +147,7 @@ export class SimplePool { sub.unsub() resolve(null) }, this.getTimeout) - sub.on('event', (event) => { + sub.on('event', event => { resolve(event) clearTimeout(timeout) sub.unsub() @@ -155,7 +164,7 @@ export class SimplePool { let events: Event[] = [] let sub = this.sub(relays, filters, opts) - sub.on('event', (event) => { + sub.on('event', event => { events.push(event) }) @@ -167,39 +176,11 @@ export class SimplePool { }) } - publish(relays: string[], event: Event): Pub { - const pubPromises: Promise[] = relays.map(async relay => { - let r - try { - r = await this.ensureRelay(relay) - return r.publish(event) - } catch (_) { - return {on() {}, off() {}} - } + publish(relays: string[], event: Event): Promise[] { + return relays.map(async relay => { + let r = await this.ensureRelay(relay) + return r.publish(event) }) - - const callbackMap = new Map() - - return { - on(type, cb) { - relays.forEach(async (relay, i) => { - let pub = await pubPromises[i] - let callback = () => cb(relay) - callbackMap.set(cb, callback) - pub.on(type, callback) - }) - }, - - off(type, cb) { - relays.forEach(async (_, i) => { - let callback = callbackMap.get(cb) - if (callback) { - let pub = await pubPromises[i] - pub.off(type, callback) - } - }) - } - } } seenOn(id: string): string[] { diff --git a/relay.ts b/relay.ts index cd7b39e..63e7e59 100644 --- a/relay.ts +++ b/relay.ts @@ -3,7 +3,7 @@ import {verifySignature, validateEvent, type Event} from './event.ts' import {matchFilters, type Filter} from './filter.ts' import {getHex64, getSubscriptionId} from './fakejson.ts' -import { MessageQueue } from './utils.ts' +import {MessageQueue} from './utils.ts' type RelayEvent = { connect: () => void | Promise @@ -25,15 +25,24 @@ export type Relay = { status: number connect: () => Promise close: () => void - sub: (filters: Filter[], opts?: SubscriptionOptions) => Sub - list: (filters: Filter[], opts?: SubscriptionOptions) => Promise[]> - get: (filter: Filter, opts?: SubscriptionOptions) => Promise | null> + sub: ( + filters: Filter[], + opts?: SubscriptionOptions + ) => Sub + list: ( + filters: Filter[], + opts?: SubscriptionOptions + ) => Promise[]> + get: ( + filter: Filter, + opts?: SubscriptionOptions + ) => Promise | null> count: ( filters: Filter[], opts?: SubscriptionOptions ) => Promise - publish: (event: Event) => Pub - auth: (event: Event) => Pub + publish: (event: Event) => Promise + auth: (event: Event) => Promise off: ( event: T, listener: U @@ -43,12 +52,11 @@ export type Relay = { listener: U ) => void } -export type Pub = { - on: (type: 'ok' | 'failed', cb: any) => void - off: (type: 'ok' | 'failed', cb: any) => void -} export type Sub = { - sub: (filters: Filter[], opts: SubscriptionOptions) => Sub + sub: ( + filters: Filter[], + opts: SubscriptionOptions + ) => Sub unsub: () => void on: , U extends SubEvent[T]>( event: T, @@ -93,9 +101,8 @@ export function relayInit( } = {} var pubListeners: { [eventid: string]: { - ok: Array<() => void> - seen: Array<() => void> - failed: Array<(reason: string) => void> + resolve: (_: unknown) => void + reject: (err: Error) => void } } = {} @@ -196,10 +203,9 @@ export function relayInit( let ok: boolean = data[2] let reason: string = data[3] || '' if (id in pubListeners) { - if (ok) pubListeners[id].ok.forEach(cb => cb()) - else pubListeners[id].failed.forEach(cb => cb(reason)) - pubListeners[id].ok = [] // 'ok' only happens once per pub, so stop listeners here - pubListeners[id].failed = [] + let {resolve, reject} = pubListeners[id] + if (ok) resolve(null) + else reject(new Error(reason)) } return } @@ -294,26 +300,16 @@ export function relayInit( } function _publishEvent(event: Event, type: string) { - if (!event.id) throw new Error(`event ${event} has no id`) - let id = event.id - - trySend([type, event]) - - return { - on: (type: 'ok' | 'failed', cb: any) => { - pubListeners[id] = pubListeners[id] || { - ok: [], - failed: [] - } - pubListeners[id][type].push(cb) - }, - off: (type: 'ok' | 'failed', cb: any) => { - let listeners = pubListeners[id] - if (!listeners) return - let idx = listeners[type].indexOf(cb) - if (idx >= 0) listeners[type].splice(idx, 1) + return new Promise((resolve, reject) => { + if (!event.id) { + reject(new Error(`event ${event} has no id`)) + return } - } + + let id = event.id + trySend([type, event]) + pubListeners[id] = {resolve, reject} + }) } return { @@ -349,7 +345,7 @@ export function relayInit( clearTimeout(timeout) resolve(events) }) - s.on('event', (event) => { + s.on('event', event => { events.push(event) }) }), @@ -360,7 +356,7 @@ export function relayInit( s.unsub() resolve(null) }, getTimeout) - s.on('event', (event) => { + s.on('event', event => { s.unsub() clearTimeout(timeout) resolve(event) @@ -379,11 +375,11 @@ export function relayInit( resolve(event) }) }), - publish(event): Pub { - return _publishEvent(event, 'EVENT') + async publish(event): Promise { + await _publishEvent(event, 'EVENT') }, - auth(event): Pub { - return _publishEvent(event, 'AUTH') + async auth(event): Promise { + await _publishEvent(event, 'AUTH') }, connect, close(): void {