Remove Fluent, Tags

This commit is contained in:
Jon Staab
2024-12-13 15:18:33 -08:00
parent 6235c3f6bb
commit 760d6d07cd
7 changed files with 14 additions and 258 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
import {verifiedSymbol, getEventHash, verifyEvent} from 'nostr-tools'
import {cached, pick, now} from '@welshman/lib'
import {Tags} from './Tags'
import {getAncestorTagValues} from './Tags'
import {getAddress} from './Address'
import {isEphemeralKind, isReplaceableKind, isPlainReplaceableKind, isParameterizedReplaceableKind} from './Kinds'
@@ -128,8 +128,8 @@ export const isPlainReplaceable = (e: EventTemplate) => isPlainReplaceableKind(e
export const isParameterizedReplaceable = (e: EventTemplate) => isParameterizedReplaceableKind(e.kind)
export const isChildOf = (child: EventContent, parent: HashedEvent) => {
const {roots, replies} = Tags.fromEvent(child).ancestors()
const parentIds = (replies.exists() ? replies : roots).values().valueOf()
const {roots, replies} = getAncestorTagValues(child.tags)
const parentIds = replies.length > 0 ? replies : roots
return getIdAndAddress(parent).some(x => parentIds.includes(x))
}
+2 -165
View File
@@ -1,170 +1,7 @@
import type {OmitStatics} from "@welshman/lib"
import {Fluent, uniq, uniqBy, mapVals, nth, nthEq, ensurePlural} from "@welshman/lib"
import {isRelayUrl, isShareableRelayUrl, normalizeRelayUrl} from "./Relay"
import {uniq, uniqBy, mapVals, nth, nthEq, ensurePlural} from "@welshman/lib"
import {isRelayUrl, isShareableRelayUrl} from "./Relay"
import {Address} from "./Address"
export class Tag extends (Fluent<string> as OmitStatics<typeof Fluent<string>, "from">) {
static from = (xs: Iterable<string>) => new Tag(Array.from(xs))
static fromId = (id: string) => new Tag(["e", id])
static fromIdentifier = (identifier: string) => new Tag(["d", identifier])
static fromTopic = (topic: string) => new Tag(["t", topic])
static fromPubkey = (pubkey: string) => new Tag(["p", pubkey])
static fromAddress = (address: string, relay = "") => new Tag(["a", address, relay])
key = () => this.xs[0]
value = () => this.xs[1]
entry = () => this.xs.slice(0, 2)
setKey = (k: string) => this.set(0, k)
setValue = (v: string) => this.set(1, v)
isAddress = (kind?: number) => this.key() === "a" && this.value()?.startsWith(`${kind}:`)
}
export class Tags extends (Fluent<Tag> as OmitStatics<typeof Fluent<Tag>, "from">) {
static from = (p: Iterable<Tag>) => new Tags(Array.from(p))
static wrap = (p: Iterable<string[]>) => new Tags(Array.from(p).map(Tag.from))
static fromEvent = (event: {tags: string[][]}) => Tags.wrap(event?.tags || [])
static fromEvents = (events: {tags: string[][]}[]) => Tags.wrap(events.flatMap(e => e.tags || []))
static fromIMeta = (imeta: string[]) => Tags.wrap(imeta.map((m: string) => m.split(" ")))
unwrap = () => this.xs.map(tag => tag.valueOf())
whereKey = (key: string) => this.filter(t => t.key() === key)
whereValue = (value: string) => this.filter(t => t.value() === value)
filterByKey = (keys: string[]) => this.filter(t => keys.includes(t.key()))
filterByValue = (values: string[]) => this.filter(t => values.includes(t.value()))
rejectByKey = (keys: string[]) => this.reject(t => keys.includes(t.key()))
rejectByValue = (values: string[]) => this.reject(t => values.includes(t.value()))
get = (key: string) => this.whereKey(key).first()
keys = () => this.mapTo(t => t.key())
values = (key?: string | string[]) =>
(key ? this.filterByKey(ensurePlural(key)) : this).mapTo(t => t.value())
entries = () => this.mapTo(t => t.entry())
relays = () =>
this.flatMap((t: Tag) =>
t
.valueOf()
.filter(isRelayUrl)
.map(url => normalizeRelayUrl(url))
).uniq()
topics = () =>
this.whereKey("t")
.values()
.map((t: string) => t.replace(/^#/, ""))
ancestors = (x?: boolean) => {
const {roots, replies, mentions} = getAncestorTags(this.unwrap())
return {
roots: Tags.wrap(roots),
replies: Tags.wrap(replies),
mentions: Tags.wrap(mentions),
}
}
roots = () => this.ancestors().roots
replies = () => this.ancestors().replies
mentions = () => this.ancestors().mentions
root = () => {
const roots = this.roots()
return roots.get("e") || roots.get("a")
}
reply = () => {
const replies = this.replies()
return replies.get("e") || replies.get("a")
}
parents = () => {
const {roots, replies} = this.ancestors()
return replies.exists() ? replies : roots
}
parent = () => {
const parents = this.parents()
return parents.get("e") || parents.get("a")
}
asObject = () => {
const result: Record<string, string> = {}
for (const t of this.xs) {
result[t.key()] = t.value()
}
return result
}
imeta = (url: string) => {
for (const tag of this.whereKey("imeta").xs) {
const tags = Tags.fromIMeta(tag.drop(1).valueOf())
if (tags.get("url")?.value() === url) {
return tags
}
}
return null
}
// Generic setters
addTag = (...args: string[]) => this.append(Tag.from(args))
setTag = (k: string, ...args: string[]) => this.rejectByKey([k]).addTag(k, ...args)
// Images
addImages = (imeta: Tags[]) =>
this.concat(imeta.map(tags => Tag.from(["image", tags.get("url").value()])))
removeImages = () => this.rejectByKey(["image"])
setImages = (imeta: Tags[]) => this.removeImages().addImages(imeta)
// IMeta
addIMeta = (imeta: Tags[]) =>
this.concat(imeta.map(tags => Tag.from(["imeta", ...tags.valueOf().map(xs => xs.join(" "))])))
removeIMeta = () => this.rejectByKey(["imeta"])
setIMeta = (imeta: Tags[]) => this.removeIMeta().addIMeta(imeta)
}
// New, simpler version
export const getTags = (types: string | string[], tags: string[][]) => {
types = ensurePlural(types)