mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-08 16:28:49 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3368e8c00e | ||
|
|
e5a3ad9855 | ||
|
|
03185c654b | ||
|
|
9d690814ca | ||
|
|
17590cce91 | ||
|
|
ee9f37e192 |
@@ -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({
|
||||
|
||||
1
index.ts
1
index.ts
@@ -16,6 +16,7 @@ export * as nip21 from './nip21.ts'
|
||||
export * as nip25 from './nip25.ts'
|
||||
export * as nip26 from './nip26.ts'
|
||||
export * as nip27 from './nip27.ts'
|
||||
export * as nip28 from './nip28.ts'
|
||||
export * as nip39 from './nip39.ts'
|
||||
export * as nip42 from './nip42.ts'
|
||||
export * as nip57 from './nip57.ts'
|
||||
|
||||
134
nip28.test.ts
Normal file
134
nip28.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import {Kind} from './event.ts'
|
||||
import {getPublicKey} from './keys.ts'
|
||||
import {
|
||||
channelCreateEvent,
|
||||
channelMetadataEvent,
|
||||
channelMessageEvent,
|
||||
channelHideMessageEvent,
|
||||
channelMuteUserEvent,
|
||||
ChannelMetadata,
|
||||
ChannelMessageEventTemplate
|
||||
} from './nip28.ts'
|
||||
|
||||
const privateKey =
|
||||
'd217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf'
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
describe('NIP-28 Functions', () => {
|
||||
const channelMetadata: ChannelMetadata = {
|
||||
name: 'Test Channel',
|
||||
about: 'This is a test channel',
|
||||
picture: 'https://example.com/picture.jpg'
|
||||
}
|
||||
|
||||
it('channelCreateEvent should create an event with given template', () => {
|
||||
const template = {
|
||||
content: channelMetadata,
|
||||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = channelCreateEvent(template, privateKey)
|
||||
expect(event!.kind).toEqual(Kind.ChannelCreation)
|
||||
expect(event!.content).toEqual(JSON.stringify(template.content))
|
||||
expect(event!.pubkey).toEqual(publicKey)
|
||||
})
|
||||
|
||||
it('channelMetadataEvent should create a signed event with given template', () => {
|
||||
const template = {
|
||||
channel_create_event_id: 'channel creation event id',
|
||||
content: channelMetadata,
|
||||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = channelMetadataEvent(template, privateKey)
|
||||
expect(event!.kind).toEqual(Kind.ChannelMetadata)
|
||||
expect(event!.tags).toEqual([['e', template.channel_create_event_id]])
|
||||
expect(event!.content).toEqual(JSON.stringify(template.content))
|
||||
expect(event!.pubkey).toEqual(publicKey)
|
||||
expect(typeof event!.id).toEqual('string')
|
||||
expect(typeof event!.sig).toEqual('string')
|
||||
})
|
||||
|
||||
it('channelMessageEvent should create a signed message event with given template', () => {
|
||||
const template = {
|
||||
channel_create_event_id: 'channel creation event id',
|
||||
relay_url: 'https://relay.example.com',
|
||||
content: 'Hello, world!',
|
||||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = channelMessageEvent(template, privateKey)
|
||||
expect(event.kind).toEqual(Kind.ChannelMessage)
|
||||
expect(event.tags[0]).toEqual([
|
||||
'e',
|
||||
template.channel_create_event_id,
|
||||
template.relay_url,
|
||||
'root'
|
||||
])
|
||||
expect(event.content).toEqual(template.content)
|
||||
expect(event.pubkey).toEqual(publicKey)
|
||||
expect(typeof event.id).toEqual('string')
|
||||
expect(typeof event.sig).toEqual('string')
|
||||
})
|
||||
|
||||
it('channelMessageEvent should create a signed message reply event with given template', () => {
|
||||
const template: ChannelMessageEventTemplate = {
|
||||
channel_create_event_id: 'channel creation event id',
|
||||
reply_to_channel_message_event_id: 'channel message event id',
|
||||
relay_url: 'https://relay.example.com',
|
||||
content: 'Hello, world!',
|
||||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = channelMessageEvent(template, privateKey)
|
||||
expect(event.kind).toEqual(Kind.ChannelMessage)
|
||||
expect(event.tags).toContainEqual([
|
||||
'e',
|
||||
template.channel_create_event_id,
|
||||
template.relay_url,
|
||||
'root'
|
||||
])
|
||||
expect(event.tags).toContainEqual([
|
||||
'e',
|
||||
template.reply_to_channel_message_event_id,
|
||||
template.relay_url,
|
||||
'reply'
|
||||
])
|
||||
expect(event.content).toEqual(template.content)
|
||||
expect(event.pubkey).toEqual(publicKey)
|
||||
expect(typeof event.id).toEqual('string')
|
||||
expect(typeof event.sig).toEqual('string')
|
||||
})
|
||||
|
||||
it('channelHideMessageEvent should create a signed event with given template', () => {
|
||||
const template = {
|
||||
channel_message_event_id: 'channel message event id',
|
||||
content: {reason: 'Inappropriate content'},
|
||||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = channelHideMessageEvent(template, privateKey)
|
||||
expect(event!.kind).toEqual(Kind.ChannelHideMessage)
|
||||
expect(event!.tags).toEqual([['e', template.channel_message_event_id]])
|
||||
expect(event!.content).toEqual(JSON.stringify(template.content))
|
||||
expect(event!.pubkey).toEqual(publicKey)
|
||||
expect(typeof event!.id).toEqual('string')
|
||||
expect(typeof event!.sig).toEqual('string')
|
||||
})
|
||||
|
||||
it('channelMuteUserEvent should create a signed event with given template', () => {
|
||||
const template = {
|
||||
content: {reason: 'Spamming'},
|
||||
created_at: 1617932115,
|
||||
pubkey_to_mute: 'pubkey to mute'
|
||||
}
|
||||
|
||||
const event = channelMuteUserEvent(template, privateKey)
|
||||
expect(event!.kind).toEqual(Kind.ChannelMuteUser)
|
||||
expect(event!.tags).toEqual([['p', template.pubkey_to_mute]])
|
||||
expect(event!.content).toEqual(JSON.stringify(template.content))
|
||||
expect(event!.pubkey).toEqual(publicKey)
|
||||
expect(typeof event!.id).toEqual('string')
|
||||
expect(typeof event!.sig).toEqual('string')
|
||||
})
|
||||
})
|
||||
163
nip28.ts
Normal file
163
nip28.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
import {Event, finishEvent, Kind} from './event.ts'
|
||||
|
||||
export interface ChannelMetadata {
|
||||
name: string
|
||||
about: string
|
||||
picture: string
|
||||
}
|
||||
|
||||
export interface ChannelCreateEventTemplate {
|
||||
/* JSON string containing ChannelMetadata as defined for Kind 40 and 41 in nip-28. */
|
||||
content: string | ChannelMetadata
|
||||
created_at: number
|
||||
tags?: string[][]
|
||||
}
|
||||
|
||||
export interface ChannelMetadataEventTemplate {
|
||||
channel_create_event_id: string
|
||||
/* JSON string containing ChannelMetadata as defined for Kind 40 and 41 in nip-28. */
|
||||
content: string | ChannelMetadata
|
||||
created_at: number
|
||||
tags?: string[][]
|
||||
}
|
||||
|
||||
export interface ChannelMessageEventTemplate {
|
||||
channel_create_event_id: string
|
||||
reply_to_channel_message_event_id?: string
|
||||
relay_url: string
|
||||
content: string
|
||||
created_at: number
|
||||
tags?: string[][]
|
||||
}
|
||||
|
||||
export interface ChannelHideMessageEventTemplate {
|
||||
channel_message_event_id: string
|
||||
content: string | {reason: string}
|
||||
created_at: number
|
||||
tags?: string[][]
|
||||
}
|
||||
|
||||
export interface ChannelMuteUserEventTemplate {
|
||||
content: string | {reason: string}
|
||||
created_at: number
|
||||
pubkey_to_mute: string
|
||||
tags?: string[][]
|
||||
}
|
||||
|
||||
export const channelCreateEvent = (
|
||||
t: ChannelCreateEventTemplate,
|
||||
privateKey: string
|
||||
): Event<Kind.ChannelCreation> | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
} else if (typeof t.content === 'string') {
|
||||
content = t.content
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
{
|
||||
kind: Kind.ChannelCreation,
|
||||
tags: [...(t.tags ?? [])],
|
||||
content: content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
)
|
||||
}
|
||||
|
||||
export const channelMetadataEvent = (
|
||||
t: ChannelMetadataEventTemplate,
|
||||
privateKey: string
|
||||
): Event<Kind.ChannelMetadata> | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
} else if (typeof t.content === 'string') {
|
||||
content = t.content
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
{
|
||||
kind: Kind.ChannelMetadata,
|
||||
tags: [['e', t.channel_create_event_id], ...(t.tags ?? [])],
|
||||
content: content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
)
|
||||
}
|
||||
|
||||
export const channelMessageEvent = (
|
||||
t: ChannelMessageEventTemplate,
|
||||
privateKey: string
|
||||
): Event<Kind.ChannelMessage> => {
|
||||
const tags = [['e', t.channel_create_event_id, t.relay_url, 'root']]
|
||||
|
||||
if (t.reply_to_channel_message_event_id) {
|
||||
tags.push(['e', t.reply_to_channel_message_event_id, t.relay_url, 'reply'])
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
{
|
||||
kind: Kind.ChannelMessage,
|
||||
tags: [...tags, ...(t.tags ?? [])],
|
||||
content: t.content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
)
|
||||
}
|
||||
|
||||
/* "e" tag should be the kind 42 event to hide */
|
||||
export const channelHideMessageEvent = (
|
||||
t: ChannelHideMessageEventTemplate,
|
||||
privateKey: string
|
||||
): Event<Kind.ChannelHideMessage> | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
} else if (typeof t.content === 'string') {
|
||||
content = t.content
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
{
|
||||
kind: Kind.ChannelHideMessage,
|
||||
tags: [['e', t.channel_message_event_id], ...(t.tags ?? [])],
|
||||
content: content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
)
|
||||
}
|
||||
|
||||
export const channelMuteUserEvent = (
|
||||
t: ChannelMuteUserEventTemplate,
|
||||
privateKey: string
|
||||
): Event<Kind.ChannelMuteUser> | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
} else if (typeof t.content === 'string') {
|
||||
content = t.content
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
{
|
||||
kind: Kind.ChannelMuteUser,
|
||||
tags: [['p', t.pubkey_to_mute], ...(t.tags ?? [])],
|
||||
content: content,
|
||||
created_at: t.created_at
|
||||
},
|
||||
privateKey
|
||||
)
|
||||
}
|
||||
16
nip42.ts
16
nip42.ts
@@ -17,7 +17,9 @@ export const authenticate = async ({
|
||||
}: {
|
||||
challenge: string
|
||||
relay: Relay
|
||||
sign: <K extends number = number>(e: EventTemplate<K>) => Promise<Event<K>> | Event<K>
|
||||
sign: <K extends number = number>(
|
||||
e: EventTemplate<K>
|
||||
) => Promise<Event<K>> | Event<K>
|
||||
}): Promise<void> => {
|
||||
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))
|
||||
}
|
||||
|
||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nostr-tools",
|
||||
"version": "1.13.0",
|
||||
"version": "1.14.0",
|
||||
"description": "Tools for making a Nostr client.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -19,11 +19,11 @@
|
||||
},
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@noble/curves": "1.0.0",
|
||||
"@noble/hashes": "1.3.0",
|
||||
"@noble/curves": "1.1.0",
|
||||
"@noble/hashes": "1.3.1",
|
||||
"@scure/base": "1.1.1",
|
||||
"@scure/bip32": "1.3.0",
|
||||
"@scure/bip39": "1.2.0"
|
||||
"@scure/bip32": "1.3.1",
|
||||
"@scure/bip39": "1.2.1"
|
||||
},
|
||||
"keywords": [
|
||||
"decentralization",
|
||||
|
||||
59
pool.ts
59
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<K extends number = number>(relays: string[], filters: Filter<K>[], opts?: SubscriptionOptions): Sub<K> {
|
||||
sub<K extends number = number>(
|
||||
relays: string[],
|
||||
filters: Filter<K>[],
|
||||
opts?: SubscriptionOptions
|
||||
): Sub<K> {
|
||||
let _knownIds: Set<string> = 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<K>[] = []
|
||||
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<number>): Pub {
|
||||
const pubPromises: Promise<Pub>[] = 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<number>): Promise<void>[] {
|
||||
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[] {
|
||||
|
||||
82
relay.ts
82
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<void>
|
||||
@@ -25,15 +25,24 @@ export type Relay = {
|
||||
status: number
|
||||
connect: () => Promise<void>
|
||||
close: () => void
|
||||
sub: <K extends number = number>(filters: Filter<K>[], opts?: SubscriptionOptions) => Sub<K>
|
||||
list: <K extends number = number>(filters: Filter<K>[], opts?: SubscriptionOptions) => Promise<Event<K>[]>
|
||||
get: <K extends number = number>(filter: Filter<K>, opts?: SubscriptionOptions) => Promise<Event<K> | null>
|
||||
sub: <K extends number = number>(
|
||||
filters: Filter<K>[],
|
||||
opts?: SubscriptionOptions
|
||||
) => Sub<K>
|
||||
list: <K extends number = number>(
|
||||
filters: Filter<K>[],
|
||||
opts?: SubscriptionOptions
|
||||
) => Promise<Event<K>[]>
|
||||
get: <K extends number = number>(
|
||||
filter: Filter<K>,
|
||||
opts?: SubscriptionOptions
|
||||
) => Promise<Event<K> | null>
|
||||
count: (
|
||||
filters: Filter[],
|
||||
opts?: SubscriptionOptions
|
||||
) => Promise<CountPayload | null>
|
||||
publish: (event: Event<number>) => Pub
|
||||
auth: (event: Event<number>) => Pub
|
||||
publish: (event: Event<number>) => Promise<void>
|
||||
auth: (event: Event<number>) => Promise<void>
|
||||
off: <T extends keyof RelayEvent, U extends RelayEvent[T]>(
|
||||
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<K extends number = number> = {
|
||||
sub: <K extends number = number>(filters: Filter<K>[], opts: SubscriptionOptions) => Sub<K>
|
||||
sub: <K extends number = number>(
|
||||
filters: Filter<K>[],
|
||||
opts: SubscriptionOptions
|
||||
) => Sub<K>
|
||||
unsub: () => void
|
||||
on: <T extends keyof SubEvent<K>, U extends SubEvent<K>[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<number>, 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<void> {
|
||||
await _publishEvent(event, 'EVENT')
|
||||
},
|
||||
auth(event): Pub {
|
||||
return _publishEvent(event, 'AUTH')
|
||||
async auth(event): Promise<void> {
|
||||
await _publishEvent(event, 'AUTH')
|
||||
},
|
||||
connect,
|
||||
close(): void {
|
||||
|
||||
Reference in New Issue
Block a user