mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-10 09:08:50 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
472a01af6a | ||
|
|
bb5acfc197 | ||
|
|
5b15237b95 | ||
|
|
4184609a00 | ||
|
|
97287cad74 | ||
|
|
fa21f71ab5 |
7
nip19.ts
7
nip19.ts
@@ -69,9 +69,7 @@ export function decode(nip19: string): DecodeResult {
|
|||||||
data: {
|
data: {
|
||||||
id: bytesToHex(tlv[0][0]),
|
id: bytesToHex(tlv[0][0]),
|
||||||
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : [],
|
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : [],
|
||||||
author: tlv[2]?.[0]
|
author: tlv[2]?.[0] ? bytesToHex(tlv[2][0]) : undefined
|
||||||
? bytesToHex(tlv[2][0])
|
|
||||||
: undefined
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,9 +121,10 @@ function parseTLV(data: Uint8Array): TLV {
|
|||||||
while (rest.length > 0) {
|
while (rest.length > 0) {
|
||||||
let t = rest[0]
|
let t = rest[0]
|
||||||
let l = rest[1]
|
let l = rest[1]
|
||||||
|
if (!l) throw new Error(`malformed TLV ${t}`)
|
||||||
let v = rest.slice(2, 2 + l)
|
let v = rest.slice(2, 2 + l)
|
||||||
rest = rest.slice(2 + l)
|
rest = rest.slice(2 + l)
|
||||||
if (v.length < l) continue
|
if (v.length < l) throw new Error(`not enough data to read on TLV ${t}`)
|
||||||
result[t] = result[t] || []
|
result[t] = result[t] || []
|
||||||
result[t].push(v)
|
result[t].push(v)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nostr-tools",
|
"name": "nostr-tools",
|
||||||
"version": "1.11.1",
|
"version": "1.11.2",
|
||||||
"description": "Tools for making a Nostr client.",
|
"description": "Tools for making a Nostr client.",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
9
relay.ts
9
relay.ts
@@ -3,6 +3,7 @@
|
|||||||
import {verifySignature, validateEvent, type Event} from './event.ts'
|
import {verifySignature, validateEvent, type Event} from './event.ts'
|
||||||
import {matchFilters, type Filter} from './filter.ts'
|
import {matchFilters, type Filter} from './filter.ts'
|
||||||
import {getHex64, getSubscriptionId} from './fakejson.ts'
|
import {getHex64, getSubscriptionId} from './fakejson.ts'
|
||||||
|
import { MessageQueue } from './utils.ts'
|
||||||
|
|
||||||
type RelayEvent = {
|
type RelayEvent = {
|
||||||
connect: () => void | Promise<void>
|
connect: () => void | Promise<void>
|
||||||
@@ -122,24 +123,24 @@ export function relayInit(
|
|||||||
listeners.disconnect.forEach(cb => cb())
|
listeners.disconnect.forEach(cb => cb())
|
||||||
}
|
}
|
||||||
|
|
||||||
let incomingMessageQueue: string[] = []
|
let incomingMessageQueue: MessageQueue = new MessageQueue()
|
||||||
let handleNextInterval: any
|
let handleNextInterval: any
|
||||||
|
|
||||||
ws.onmessage = e => {
|
ws.onmessage = e => {
|
||||||
incomingMessageQueue.push(e.data)
|
incomingMessageQueue.enqueue(e.data)
|
||||||
if (!handleNextInterval) {
|
if (!handleNextInterval) {
|
||||||
handleNextInterval = setInterval(handleNext, 0)
|
handleNextInterval = setInterval(handleNext, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNext() {
|
function handleNext() {
|
||||||
if (incomingMessageQueue.length === 0) {
|
if (incomingMessageQueue.size === 0) {
|
||||||
clearInterval(handleNextInterval)
|
clearInterval(handleNextInterval)
|
||||||
handleNextInterval = null
|
handleNextInterval = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var json = incomingMessageQueue.shift()
|
var json = incomingMessageQueue.dequeue()
|
||||||
if (!json) return
|
if (!json) return
|
||||||
|
|
||||||
let subid = getSubscriptionId(json)
|
let subid = getSubscriptionId(json)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {buildEvent} from './test-helpers.ts'
|
import {buildEvent} from './test-helpers.ts'
|
||||||
import {
|
import {
|
||||||
|
MessageQueue,
|
||||||
insertEventIntoAscendingList,
|
insertEventIntoAscendingList,
|
||||||
insertEventIntoDescendingList,
|
insertEventIntoDescendingList,
|
||||||
} from './utils.ts'
|
} from './utils.ts'
|
||||||
@@ -191,3 +192,48 @@ describe('inserting into a asc sorted list of events', () => {
|
|||||||
expect(list1).toHaveLength(3)
|
expect(list1).toHaveLength(3)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('enque a message into MessageQueue', () => {
|
||||||
|
test('enque into an empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
expect(queue.first!.value).toBe('node1')
|
||||||
|
})
|
||||||
|
test('enque into a non-empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
queue.enqueue('node3')
|
||||||
|
queue.enqueue('node2')
|
||||||
|
expect(queue.first!.value).toBe('node1')
|
||||||
|
expect(queue.last!.value).toBe('node2')
|
||||||
|
expect(queue.size).toBe(3)
|
||||||
|
})
|
||||||
|
test('dequeue from an empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
const item1 = queue.dequeue()
|
||||||
|
expect(item1).toBe(null)
|
||||||
|
expect(queue.size).toBe(0)
|
||||||
|
})
|
||||||
|
test('dequeue from a non-empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
queue.enqueue('node3')
|
||||||
|
queue.enqueue('node2')
|
||||||
|
const item1 = queue.dequeue()
|
||||||
|
expect(item1).toBe('node1')
|
||||||
|
const item2 = queue.dequeue()
|
||||||
|
expect(item2).toBe('node3')
|
||||||
|
})
|
||||||
|
test('dequeue more than in queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
queue.enqueue('node3')
|
||||||
|
const item1 = queue.dequeue()
|
||||||
|
expect(item1).toBe('node1')
|
||||||
|
const item2 = queue.dequeue()
|
||||||
|
expect(item2).toBe('node3')
|
||||||
|
expect(queue.size).toBe(0)
|
||||||
|
const item3 = queue.dequeue()
|
||||||
|
expect(item3).toBe(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
76
utils.ts
76
utils.ts
@@ -109,3 +109,79 @@ export function insertEventIntoAscendingList(
|
|||||||
|
|
||||||
return sortedArray
|
return sortedArray
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class MessageNode {
|
||||||
|
private _value: string
|
||||||
|
private _next: MessageNode | null
|
||||||
|
|
||||||
|
public get value(): string {
|
||||||
|
return this._value
|
||||||
|
}
|
||||||
|
public set value(message: string) {
|
||||||
|
this._value = message
|
||||||
|
}
|
||||||
|
public get next(): MessageNode | null {
|
||||||
|
return this._next
|
||||||
|
}
|
||||||
|
public set next(node: MessageNode | null) {
|
||||||
|
this._next = node
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(message: string) {
|
||||||
|
this._value = message
|
||||||
|
this._next = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MessageQueue {
|
||||||
|
private _first: MessageNode | null
|
||||||
|
private _last: MessageNode | null
|
||||||
|
|
||||||
|
public get first(): MessageNode | null {
|
||||||
|
return this._first
|
||||||
|
}
|
||||||
|
public set first(messageNode: MessageNode | null) {
|
||||||
|
this._first = messageNode
|
||||||
|
}
|
||||||
|
public get last(): MessageNode | null {
|
||||||
|
return this._last
|
||||||
|
}
|
||||||
|
public set last(messageNode: MessageNode | null) {
|
||||||
|
this._last = messageNode
|
||||||
|
}
|
||||||
|
private _size: number
|
||||||
|
public get size(): number {
|
||||||
|
return this._size
|
||||||
|
}
|
||||||
|
public set size(v: number) {
|
||||||
|
this._size = v
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._first = null
|
||||||
|
this._last = null
|
||||||
|
this._size = 0
|
||||||
|
}
|
||||||
|
enqueue(message: string): boolean {
|
||||||
|
const newNode = new MessageNode(message)
|
||||||
|
if (this._size === 0 || !this._last) {
|
||||||
|
this._first = newNode
|
||||||
|
this._last = newNode
|
||||||
|
} else {
|
||||||
|
this._last.next = newNode
|
||||||
|
this._last = newNode
|
||||||
|
}
|
||||||
|
this._size++
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
dequeue(): string | null {
|
||||||
|
if (this._size === 0 || !this._first) return null
|
||||||
|
|
||||||
|
let prev = this._first
|
||||||
|
this._first = prev.next
|
||||||
|
prev.next = null
|
||||||
|
|
||||||
|
this._size--
|
||||||
|
return prev.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user