mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-09 00:28:51 +00:00
Infer relay event types from filter
This commit is contained in:
26
pool.ts
26
pool.ts
@@ -2,7 +2,7 @@ import {Relay, relayInit} from './relay'
|
|||||||
import {normalizeURL} from './utils'
|
import {normalizeURL} from './utils'
|
||||||
import {Filter} from './filter'
|
import {Filter} from './filter'
|
||||||
import {Event} from './event'
|
import {Event} from './event'
|
||||||
import {SubscriptionOptions, Sub, Pub, CountPayload} from './relay'
|
import {SubscriptionOptions, Sub, Pub} from './relay'
|
||||||
|
|
||||||
export class SimplePool {
|
export class SimplePool {
|
||||||
private _conn: {[url: string]: Relay}
|
private _conn: {[url: string]: Relay}
|
||||||
@@ -39,7 +39,7 @@ export class SimplePool {
|
|||||||
return relay
|
return relay
|
||||||
}
|
}
|
||||||
|
|
||||||
sub(relays: string[], filters: Filter[], opts?: SubscriptionOptions): Sub {
|
sub<K extends number = number>(relays: string[], filters: Filter<K>[], opts?: SubscriptionOptions): Sub<K> {
|
||||||
let _knownIds: Set<string> = new Set()
|
let _knownIds: Set<string> = new Set()
|
||||||
let modifiedOpts = {...(opts || {})}
|
let modifiedOpts = {...(opts || {})}
|
||||||
modifiedOpts.alreadyHaveEvent = (id, url) => {
|
modifiedOpts.alreadyHaveEvent = (id, url) => {
|
||||||
@@ -73,7 +73,7 @@ export class SimplePool {
|
|||||||
}
|
}
|
||||||
if (!r) return
|
if (!r) return
|
||||||
let s = r.sub(filters, modifiedOpts)
|
let s = r.sub(filters, modifiedOpts)
|
||||||
s.on('event', (event: Event) => {
|
s.on('event', (event) => {
|
||||||
_knownIds.add(event.id as string)
|
_knownIds.add(event.id as string)
|
||||||
for (let cb of eventListeners.values()) cb(event)
|
for (let cb of eventListeners.values()) cb(event)
|
||||||
})
|
})
|
||||||
@@ -118,18 +118,18 @@ export class SimplePool {
|
|||||||
return greaterSub
|
return greaterSub
|
||||||
}
|
}
|
||||||
|
|
||||||
get(
|
get<K extends number = number>(
|
||||||
relays: string[],
|
relays: string[],
|
||||||
filter: Filter,
|
filter: Filter<K>,
|
||||||
opts?: SubscriptionOptions
|
opts?: SubscriptionOptions
|
||||||
): Promise<Event | null> {
|
): Promise<Event<K> | null> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
let sub = this.sub(relays, [filter], opts)
|
let sub = this.sub(relays, [filter], opts)
|
||||||
let timeout = setTimeout(() => {
|
let timeout = setTimeout(() => {
|
||||||
sub.unsub()
|
sub.unsub()
|
||||||
resolve(null)
|
resolve(null)
|
||||||
}, this.getTimeout)
|
}, this.getTimeout)
|
||||||
sub.on('event', (event: Event) => {
|
sub.on('event', (event) => {
|
||||||
resolve(event)
|
resolve(event)
|
||||||
clearTimeout(timeout)
|
clearTimeout(timeout)
|
||||||
sub.unsub()
|
sub.unsub()
|
||||||
@@ -137,16 +137,16 @@ export class SimplePool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
list(
|
list<K extends number = number>(
|
||||||
relays: string[],
|
relays: string[],
|
||||||
filters: Filter[],
|
filters: Filter<K>[],
|
||||||
opts?: SubscriptionOptions
|
opts?: SubscriptionOptions
|
||||||
): Promise<Event[]> {
|
): Promise<Event<K>[]> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
let events: Event[] = []
|
let events: Event<K>[] = []
|
||||||
let sub = this.sub(relays, filters, opts)
|
let sub = this.sub(relays, filters, opts)
|
||||||
|
|
||||||
sub.on('event', (event: Event) => {
|
sub.on('event', (event) => {
|
||||||
events.push(event)
|
events.push(event)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ export class SimplePool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
publish(relays: string[], event: Event): Pub {
|
publish(relays: string[], event: Event<number>): Pub {
|
||||||
const pubPromises: Promise<Pub>[] = relays.map(async relay => {
|
const pubPromises: Promise<Pub>[] = relays.map(async relay => {
|
||||||
let r
|
let r
|
||||||
try {
|
try {
|
||||||
|
|||||||
52
relay.ts
52
relay.ts
@@ -14,8 +14,8 @@ type RelayEvent = {
|
|||||||
export type CountPayload = {
|
export type CountPayload = {
|
||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
type SubEvent = {
|
type SubEvent<K extends number> = {
|
||||||
event: (event: Event) => void | Promise<void>
|
event: (event: Event<K>) => void | Promise<void>
|
||||||
count: (payload: CountPayload) => void | Promise<void>
|
count: (payload: CountPayload) => void | Promise<void>
|
||||||
eose: () => void | Promise<void>
|
eose: () => void | Promise<void>
|
||||||
}
|
}
|
||||||
@@ -24,15 +24,15 @@ export type Relay = {
|
|||||||
status: number
|
status: number
|
||||||
connect: () => Promise<void>
|
connect: () => Promise<void>
|
||||||
close: () => void
|
close: () => void
|
||||||
sub: (filters: Filter[], opts?: SubscriptionOptions) => Sub
|
sub: <K extends number = number>(filters: Filter<K>[], opts?: SubscriptionOptions) => Sub<K>
|
||||||
list: (filters: Filter[], opts?: SubscriptionOptions) => Promise<Event[]>
|
list: <K extends number = number>(filters: Filter<K>[], opts?: SubscriptionOptions) => Promise<Event<K>[]>
|
||||||
get: (filter: Filter, opts?: SubscriptionOptions) => Promise<Event | null>
|
get: <K extends number = number>(filter: Filter<K>, opts?: SubscriptionOptions) => Promise<Event<K> | null>
|
||||||
count: (
|
count: (
|
||||||
filters: Filter[],
|
filters: Filter[],
|
||||||
opts?: SubscriptionOptions
|
opts?: SubscriptionOptions
|
||||||
) => Promise<CountPayload | null>
|
) => Promise<CountPayload | null>
|
||||||
publish: (event: Event) => Pub
|
publish: (event: Event<number>) => Pub
|
||||||
auth: (event: Event) => Pub
|
auth: (event: Event<number>) => Pub
|
||||||
off: <T extends keyof RelayEvent, U extends RelayEvent[T]>(
|
off: <T extends keyof RelayEvent, U extends RelayEvent[T]>(
|
||||||
event: T,
|
event: T,
|
||||||
listener: U
|
listener: U
|
||||||
@@ -46,14 +46,14 @@ export type Pub = {
|
|||||||
on: (type: 'ok' | 'failed', cb: any) => void
|
on: (type: 'ok' | 'failed', cb: any) => void
|
||||||
off: (type: 'ok' | 'failed', cb: any) => void
|
off: (type: 'ok' | 'failed', cb: any) => void
|
||||||
}
|
}
|
||||||
export type Sub = {
|
export type Sub<K extends number = number> = {
|
||||||
sub: (filters: Filter[], opts: SubscriptionOptions) => Sub
|
sub: <K extends number = number>(filters: Filter<K>[], opts: SubscriptionOptions) => Sub<K>
|
||||||
unsub: () => void
|
unsub: () => void
|
||||||
on: <T extends keyof SubEvent, U extends SubEvent[T]>(
|
on: <T extends keyof SubEvent<K>, U extends SubEvent<K>[T]>(
|
||||||
event: T,
|
event: T,
|
||||||
listener: U
|
listener: U
|
||||||
) => void
|
) => void
|
||||||
off: <T extends keyof SubEvent, U extends SubEvent[T]>(
|
off: <T extends keyof SubEvent<K>, U extends SubEvent<K>[T]>(
|
||||||
event: T,
|
event: T,
|
||||||
listener: U
|
listener: U
|
||||||
) => void
|
) => void
|
||||||
@@ -88,7 +88,7 @@ export function relayInit(
|
|||||||
var openSubs: {[id: string]: {filters: Filter[]} & SubscriptionOptions} = {}
|
var openSubs: {[id: string]: {filters: Filter[]} & SubscriptionOptions} = {}
|
||||||
var listeners = newListeners()
|
var listeners = newListeners()
|
||||||
var subListeners: {
|
var subListeners: {
|
||||||
[subid: string]: {[TK in keyof SubEvent]: SubEvent[TK][]}
|
[subid: string]: {[TK in keyof SubEvent<any>]: SubEvent<any>[TK][]}
|
||||||
} = {}
|
} = {}
|
||||||
var pubListeners: {
|
var pubListeners: {
|
||||||
[eventid: string]: {
|
[eventid: string]: {
|
||||||
@@ -245,15 +245,15 @@ export function relayInit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sub = (
|
const sub = <K extends number = number>(
|
||||||
filters: Filter[],
|
filters: Filter<K>[],
|
||||||
{
|
{
|
||||||
verb = 'REQ',
|
verb = 'REQ',
|
||||||
skipVerification = false,
|
skipVerification = false,
|
||||||
alreadyHaveEvent = null,
|
alreadyHaveEvent = null,
|
||||||
id = Math.random().toString().slice(2)
|
id = Math.random().toString().slice(2)
|
||||||
}: SubscriptionOptions = {}
|
}: SubscriptionOptions = {}
|
||||||
): Sub => {
|
): Sub<K> => {
|
||||||
let subid = id
|
let subid = id
|
||||||
|
|
||||||
openSubs[subid] = {
|
openSubs[subid] = {
|
||||||
@@ -276,10 +276,7 @@ export function relayInit(
|
|||||||
delete subListeners[subid]
|
delete subListeners[subid]
|
||||||
trySend(['CLOSE', subid])
|
trySend(['CLOSE', subid])
|
||||||
},
|
},
|
||||||
on: <T extends keyof SubEvent, U extends SubEvent[T]>(
|
on: (type, cb) => {
|
||||||
type: T,
|
|
||||||
cb: U
|
|
||||||
): void => {
|
|
||||||
subListeners[subid] = subListeners[subid] || {
|
subListeners[subid] = subListeners[subid] || {
|
||||||
event: [],
|
event: [],
|
||||||
count: [],
|
count: [],
|
||||||
@@ -287,10 +284,7 @@ export function relayInit(
|
|||||||
}
|
}
|
||||||
subListeners[subid][type].push(cb)
|
subListeners[subid][type].push(cb)
|
||||||
},
|
},
|
||||||
off: <T extends keyof SubEvent, U extends SubEvent[T]>(
|
off: (type, cb): void => {
|
||||||
type: T,
|
|
||||||
cb: U
|
|
||||||
): void => {
|
|
||||||
let listeners = subListeners[subid]
|
let listeners = subListeners[subid]
|
||||||
let idx = listeners[type].indexOf(cb)
|
let idx = listeners[type].indexOf(cb)
|
||||||
if (idx >= 0) listeners[type].splice(idx, 1)
|
if (idx >= 0) listeners[type].splice(idx, 1)
|
||||||
@@ -298,7 +292,7 @@ export function relayInit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _publishEvent(event: Event, type: string) {
|
function _publishEvent(event: Event<number>, type: string) {
|
||||||
if (!event.id) throw new Error(`event ${event} has no id`)
|
if (!event.id) throw new Error(`event ${event} has no id`)
|
||||||
let id = event.id
|
let id = event.id
|
||||||
|
|
||||||
@@ -341,10 +335,10 @@ export function relayInit(
|
|||||||
let index = listeners[type].indexOf(cb)
|
let index = listeners[type].indexOf(cb)
|
||||||
if (index !== -1) listeners[type].splice(index, 1)
|
if (index !== -1) listeners[type].splice(index, 1)
|
||||||
},
|
},
|
||||||
list: (filters: Filter[], opts?: SubscriptionOptions): Promise<Event[]> =>
|
list: (filters, opts?: SubscriptionOptions) =>
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
let s = sub(filters, opts)
|
let s = sub(filters, opts)
|
||||||
let events: Event[] = []
|
let events: Event<any>[] = []
|
||||||
let timeout = setTimeout(() => {
|
let timeout = setTimeout(() => {
|
||||||
s.unsub()
|
s.unsub()
|
||||||
resolve(events)
|
resolve(events)
|
||||||
@@ -354,18 +348,18 @@ export function relayInit(
|
|||||||
clearTimeout(timeout)
|
clearTimeout(timeout)
|
||||||
resolve(events)
|
resolve(events)
|
||||||
})
|
})
|
||||||
s.on('event', (event: Event) => {
|
s.on('event', (event) => {
|
||||||
events.push(event)
|
events.push(event)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
get: (filter: Filter, opts?: SubscriptionOptions): Promise<Event | null> =>
|
get: (filter, opts?: SubscriptionOptions) =>
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
let s = sub([filter], opts)
|
let s = sub([filter], opts)
|
||||||
let timeout = setTimeout(() => {
|
let timeout = setTimeout(() => {
|
||||||
s.unsub()
|
s.unsub()
|
||||||
resolve(null)
|
resolve(null)
|
||||||
}, getTimeout)
|
}, getTimeout)
|
||||||
s.on('event', (event: Event) => {
|
s.on('event', (event) => {
|
||||||
s.unsub()
|
s.unsub()
|
||||||
clearTimeout(timeout)
|
clearTimeout(timeout)
|
||||||
resolve(event)
|
resolve(event)
|
||||||
|
|||||||
Reference in New Issue
Block a user