Refactor relay list a bit
tests / tests (push) Failing after 5m10s

This commit is contained in:
Jon Staab
2026-06-22 13:49:35 -07:00
parent 22a666d497
commit f97215de47
3 changed files with 63 additions and 71 deletions
+7 -7
View File
@@ -60,10 +60,10 @@ describe("RelayList", () => {
it("adds modeless and single-mode relays via a fresh builder", async () => {
const tmpl = await new RelayListBuilder()
.addUrl(read, RelayMode.Read)
.addUrl(write, RelayMode.Write)
.addUrl(both, RelayMode.Read)
.addUrl(both, RelayMode.Write)
.addReadUrl(read)
.addWriteUrl(write)
.addReadUrl(both)
.addWriteUrl(both)
.toTemplate(signer)
expect(tmpl.kind).toBe(RELAYS)
@@ -75,9 +75,9 @@ describe("RelayList", () => {
it("downgrades a modeless relay when one mode is removed", async () => {
const tmpl = await new RelayListBuilder()
.addUrl(both, RelayMode.Read)
.addUrl(both, RelayMode.Write)
.removeUrl(both, RelayMode.Read)
.addReadUrl(both)
.addWriteUrl(both)
.removeReadUrl(both)
.toTemplate(signer)
expect(tmpl.tags).toContainEqual(["r", both, RelayMode.Write])
+49 -62
View File
@@ -1,32 +1,30 @@
import {uniq, uniqBy} from "@welshman/lib"
import {RELAYS, RelayMode, getRelayTags, getRelayTagValues, normalizeRelayUrl} from "@welshman/util"
import {nth, uniq, uniqBy, remove} from "@welshman/lib"
import {RELAYS, getRelayTags, normalizeRelayUrl} from "@welshman/util"
import {ListReader} from "../ListReader.js"
import {ListBuilder} from "../ListBuilder.js"
const getUrls = (tags: string[][], mode?: string) =>
uniqBy(
normalizeRelayUrl,
getRelayTags(tags)
.filter(t => !mode || !t[2] || t[2] === mode)
.map(nth(1)),
)
// NIP-65 kind-10002 relay list.
export class RelayList extends ListReader {
readonly kind = RELAYS
urls() {
return uniqBy(normalizeRelayUrl, getRelayTagValues(this.tags()))
return getUrls(this.tags())
}
readUrls() {
return uniqBy(
normalizeRelayUrl,
getRelayTags(this.tags())
.filter(t => !t[2] || t[2] === RelayMode.Read)
.map(t => t[1]),
)
return getUrls(this.tags(), "read")
}
writeUrls() {
return uniqBy(
normalizeRelayUrl,
getRelayTags(this.tags())
.filter(t => !t[2] || t[2] === RelayMode.Write)
.map(t => t[1]),
)
return getUrls(this.tags(), "write")
}
builder() {
@@ -37,73 +35,62 @@ export class RelayList extends ListReader {
export class RelayListBuilder extends ListBuilder<RelayList> {
readonly kind = RELAYS
readUrls() {
return uniqBy(
normalizeRelayUrl,
getRelayTags(this.publicTags)
.filter(t => !t[2] || t[2] === RelayMode.Read)
.map(t => t[1]),
)
addReadUrl(url: string) {
return this.addUrlForMode(url, "read")
}
writeUrls() {
return uniqBy(
normalizeRelayUrl,
getRelayTags(this.publicTags)
.filter(t => !t[2] || t[2] === RelayMode.Write)
.map(t => t[1]),
)
addWriteUrl(url: string) {
return this.addUrlForMode(url, "write")
}
addUrl(url: string, mode: RelayMode) {
removeReadUrl(url: string) {
return this.removeUrlForMode(url, "read")
}
removeWriteUrl(url: string) {
return this.removeUrlForMode(url, "write")
}
private findUrlTag(url: string) {
const normalized = normalizeRelayUrl(url)
const existing = getRelayTags(this.publicTags).filter(
t => normalizeRelayUrl(t[1]) === normalized,
)
const priorModes = new Set<RelayMode | undefined>(
existing.map(t => t[2] as RelayMode | undefined),
)
return this.publicTags.find(t => t[0] === "r" && normalizeRelayUrl(t[1]) === normalized)
}
const alt = mode === RelayMode.Read ? RelayMode.Write : RelayMode.Read
const coversAlt = priorModes.has(undefined) || priorModes.has(alt)
private addUrlForMode(url: string, mode: "read" | "write") {
const existing = this.findUrlTag(url)
const alt = mode === "read" ? "write" : "read"
this.publicTags = this.publicTags.filter(
t => !(t[0] === "r" && normalizeRelayUrl(t[1]) === normalized),
)
this.publicTags.push(coversAlt ? ["r", url] : ["r", url, mode])
if (!existing) {
this.publicTags.push(["r", normalizeRelayUrl(url), mode])
} else if (existing[2] === alt) {
existing.splice(2)
}
return this
}
removeUrl(url: string, mode: RelayMode) {
const normalized = normalizeRelayUrl(url)
const existing = getRelayTags(this.publicTags).filter(
t => normalizeRelayUrl(t[1]) === normalized,
)
private removeUrlForMode(url: string, mode: "read" | "write") {
const existing = this.findUrlTag(url)
const alt = mode === "read" ? "write" : "read"
const alt = mode === RelayMode.Read ? RelayMode.Write : RelayMode.Read
const keepAlt = existing.some(t => !t[2] || t[2] === alt)
this.publicTags = this.publicTags.filter(
t => !(t[0] === "r" && normalizeRelayUrl(t[1]) === normalized),
)
if (keepAlt) {
this.publicTags.push(["r", url, alt])
if (existing) {
if (!existing[2]) {
existing[2] = alt
} else if (existing[2] === mode) {
this.publicTags = remove(existing, this.publicTags)
}
}
return this
}
setReadUrls(urls: string[]) {
return this.setUrlsForModes(urls, this.writeUrls())
return this.setUrlsForModes(urls, getUrls(this.publicTags, "write"))
}
setWriteUrls(urls: string[]) {
return this.setUrlsForModes(this.readUrls(), urls)
return this.setUrlsForModes(getUrls(this.publicTags, "read"), urls)
}
private setUrlsForModes(readUrls: string[], writeUrls: string[]) {
@@ -114,8 +101,8 @@ export class RelayListBuilder extends ListBuilder<RelayList> {
read.has(url) && write.has(url)
? ["r", url]
: read.has(url)
? ["r", url, RelayMode.Read]
: ["r", url, RelayMode.Write],
? ["r", url, "read"]
: ["r", url, "write"],
)
this.publicTags = [...otherTags, ...relayTags]