mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-09 16:48:50 +00:00
Add support for count
This commit is contained in:
33
relay.ts
33
relay.ts
@@ -10,8 +10,12 @@ type RelayEvent = {
|
|||||||
error: () => void | Promise<void>
|
error: () => void | Promise<void>
|
||||||
notice: (msg: string) => void | Promise<void>
|
notice: (msg: string) => void | Promise<void>
|
||||||
}
|
}
|
||||||
|
type CountPayload = {
|
||||||
|
count: number
|
||||||
|
}
|
||||||
type SubEvent = {
|
type SubEvent = {
|
||||||
event: (event: Event) => void | Promise<void>
|
event: (event: Event) => void | Promise<void>
|
||||||
|
count: (payload: CountPayload) => void | Promise<void>
|
||||||
eose: () => void | Promise<void>
|
eose: () => void | Promise<void>
|
||||||
}
|
}
|
||||||
export type Relay = {
|
export type Relay = {
|
||||||
@@ -22,6 +26,7 @@ export type Relay = {
|
|||||||
sub: (filters: Filter[], opts?: SubscriptionOptions) => Sub
|
sub: (filters: Filter[], opts?: SubscriptionOptions) => Sub
|
||||||
list: (filters: Filter[], opts?: SubscriptionOptions) => Promise<Event[]>
|
list: (filters: Filter[], opts?: SubscriptionOptions) => Promise<Event[]>
|
||||||
get: (filter: Filter, opts?: SubscriptionOptions) => Promise<Event | null>
|
get: (filter: Filter, opts?: SubscriptionOptions) => Promise<Event | null>
|
||||||
|
count: (filters: Filter[], opts?: SubscriptionOptions) => Promise<CountPayload | null>
|
||||||
publish: (event: Event) => Pub
|
publish: (event: Event) => Pub
|
||||||
off: <T extends keyof RelayEvent, U extends RelayEvent[T]>(
|
off: <T extends keyof RelayEvent, U extends RelayEvent[T]>(
|
||||||
event: T,
|
event: T,
|
||||||
@@ -51,6 +56,7 @@ export type Sub = {
|
|||||||
|
|
||||||
export type SubscriptionOptions = {
|
export type SubscriptionOptions = {
|
||||||
id?: string
|
id?: string
|
||||||
|
verb?: 'REQ' | 'COUNT',
|
||||||
skipVerification?: boolean
|
skipVerification?: boolean
|
||||||
alreadyHaveEvent?: null | ((id: string, relay: string) => boolean)
|
alreadyHaveEvent?: null | ((id: string, relay: string) => boolean)
|
||||||
}
|
}
|
||||||
@@ -60,9 +66,10 @@ export function relayInit(
|
|||||||
options: {
|
options: {
|
||||||
getTimeout?: number
|
getTimeout?: number
|
||||||
listTimeout?: number
|
listTimeout?: number
|
||||||
|
countTimeout?: number
|
||||||
} = {}
|
} = {}
|
||||||
): Relay {
|
): Relay {
|
||||||
let {listTimeout = 3000, getTimeout = 3000} = options
|
let {listTimeout = 3000, getTimeout = 3000, countTimeout = 3000} = options
|
||||||
|
|
||||||
var ws: WebSocket
|
var ws: WebSocket
|
||||||
var openSubs: {[id: string]: {filters: Filter[]} & SubscriptionOptions} = {}
|
var openSubs: {[id: string]: {filters: Filter[]} & SubscriptionOptions} = {}
|
||||||
@@ -159,6 +166,13 @@ export function relayInit(
|
|||||||
;(subListeners[id]?.event || []).forEach(cb => cb(event))
|
;(subListeners[id]?.event || []).forEach(cb => cb(event))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
case 'COUNT':
|
||||||
|
let id = data[1]
|
||||||
|
let payload = data[2]
|
||||||
|
if (openSubs[id]) {
|
||||||
|
(subListeners[id]?.count || []).forEach(cb => cb(payload))
|
||||||
|
}
|
||||||
|
return
|
||||||
case 'EOSE': {
|
case 'EOSE': {
|
||||||
let id = data[1]
|
let id = data[1]
|
||||||
if (id in subListeners) {
|
if (id in subListeners) {
|
||||||
@@ -220,6 +234,7 @@ export function relayInit(
|
|||||||
const sub = (
|
const sub = (
|
||||||
filters: Filter[],
|
filters: Filter[],
|
||||||
{
|
{
|
||||||
|
verb = 'REQ',
|
||||||
skipVerification = false,
|
skipVerification = false,
|
||||||
alreadyHaveEvent = null,
|
alreadyHaveEvent = null,
|
||||||
id = Math.random().toString().slice(2)
|
id = Math.random().toString().slice(2)
|
||||||
@@ -233,7 +248,7 @@ export function relayInit(
|
|||||||
skipVerification,
|
skipVerification,
|
||||||
alreadyHaveEvent
|
alreadyHaveEvent
|
||||||
}
|
}
|
||||||
trySend(['REQ', subid, ...filters])
|
trySend([verb, subid, ...filters])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sub: (newFilters, newOpts = {}) =>
|
sub: (newFilters, newOpts = {}) =>
|
||||||
@@ -253,6 +268,7 @@ export function relayInit(
|
|||||||
): void => {
|
): void => {
|
||||||
subListeners[subid] = subListeners[subid] || {
|
subListeners[subid] = subListeners[subid] || {
|
||||||
event: [],
|
event: [],
|
||||||
|
count: [],
|
||||||
eose: []
|
eose: []
|
||||||
}
|
}
|
||||||
subListeners[subid][type].push(cb)
|
subListeners[subid][type].push(cb)
|
||||||
@@ -318,6 +334,19 @@ export function relayInit(
|
|||||||
resolve(event)
|
resolve(event)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
count: (filters: Filter[], opts?: SubscriptionOptions): Promise<CountPayload | null> =>
|
||||||
|
new Promise(resolve => {
|
||||||
|
let s = sub(filters, {...sub, verb: 'COUNT'})
|
||||||
|
let timeout = setTimeout(() => {
|
||||||
|
s.unsub()
|
||||||
|
resolve(null)
|
||||||
|
}, countTimeout)
|
||||||
|
s.on('count', (event: Event) => {
|
||||||
|
s.unsub()
|
||||||
|
clearTimeout(timeout)
|
||||||
|
resolve(event)
|
||||||
|
})
|
||||||
|
}),
|
||||||
publish(event: Event): Pub {
|
publish(event: Event): Pub {
|
||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user