Fix some bugs with message delivery

This commit is contained in:
Jonathan Staab
2023-03-28 14:23:31 -05:00
parent 9b6a779397
commit 5a1a72491e
20 changed files with 275 additions and 224 deletions
+91
View File
@@ -0,0 +1,91 @@
import type {EventBus} from './util/EventBus.ts'
const createFilterId = filters =>
[Math.random().toString().slice(2, 6), filters.map(describeFilter).join(":")].join("-")
const describeFilter = ({kinds = [], ...filter}) => {
const parts = []
parts.push(kinds.join(","))
for (const [key, value] of Object.entries(filter)) {
if (value instanceof Array) {
parts.push(`${key}[${value.length}]`)
} else {
parts.push(key)
}
}
return "(" + parts.join(",") + ")"
}
type Executable = {
bus: EventBus
send: (verb: string, ...args) => void
}
export class Executor {
target: Executable
constructor(target) {
this.target = target
}
subscribe(filters, {onEvent, onEose}) {
const id = createFilterId(filters)
const unsubscribe = this.target.bus.addListeners({
EVENT: (url, subid, e) => subid === id && onEvent?.(url, e),
EOSE: (url, subid) => subid === id && onEose?.(url),
})
this.target.send("REQ", id, ...filters)
return {
unsubscribe: () => {
this.target.send("CLOSE", id)
unsubscribe()
},
}
}
publish(event, {onOk, onError}) {
const unsubscribe = this.target.bus.addListeners({
OK: (url, id, ...payload) => id === event.id && onOk(url, ...payload),
ERROR: (url, id, ...payload) => id === event.id && onError(url, ...payload),
})
this.target.send("EVENT", event)
return {unsubscribe}
}
count(filters, {onCount}) {
const id = createFilterId(filters)
const unsubscribe = this.target.bus.addListeners({
COUNT: (url, subid, ...payload) => {
if (subid === id) {
onCount(url, ...payload)
unsubscribe()
}
}
})
this.target.send("COUNT", id, ...filters)
return {unsubscribe}
}
handleAuth({onAuth, onOk}) {
let event
const unsubscribe = this.target.bus.addListeners({
AUTH: async (url, challenge) => {
event = await onAuth(url, challenge)
},
OK: (url, id, ok, message) => {
if (id === event?.id) {
event = null
onOk(url, id, ok, message)
}
}
})
return {unsubscribe}
}
}