Add add/remove relay commands, thunk status utilities, raw on parsed

This commit is contained in:
Jon Staab
2025-06-04 13:47:02 -07:00
parent a6886d9734
commit e7bf416ae6
7 changed files with 225 additions and 35 deletions
+60 -2
View File
@@ -1,20 +1,78 @@
import {get} from "svelte/store"
import {uniq} from "@welshman/lib"
import {uniq, nthNe, removeNil, nthEq} from "@welshman/lib"
import {
addToListPublicly,
EventTemplate,
removeFromList,
getListTags,
getRelayTags,
makeList,
RelayMode,
INBOX_RELAYS,
FOLLOWS,
RELAYS,
MUTES,
PINS,
} from "@welshman/util"
import {Nip59, stamp} from "@welshman/signer"
import {Router, addMaximalFallbacks} from "@welshman/router"
import {userFollows, userMutes, userPins} from "./user.js"
import {
userRelaySelections,
userInboxRelaySelections,
userFollows,
userMutes,
userPins,
} from "./user.js"
import {nip44EncryptToSelf, signer} from "./session.js"
import {ThunkOptions, MergedThunk, publishThunk} from "./thunk.js"
export const removeRelay = async (url: string, mode: RelayMode) => {
const list = get(userRelaySelections) || makeList({kind: RELAYS})
const dup = getRelayTags(getListTags(list)).find(nthEq(1, url))
const alt = mode === RelayMode.Read ? RelayMode.Write : RelayMode.Read
const tags = list.publicTags.filter(nthNe(1, url))
// If we had a duplicate that was used as the alt mode, keep the alt
if (dup && (!dup[2] || dup[2] === alt)) {
tags.push(["r", url, alt])
}
const event = {kind: list.kind, content: list.event?.content || "", tags}
const relays = Router.get().FromUser().policy(addMaximalFallbacks).getUrls()
// Make sure to notify the old relay too
relays.push(url)
return publishThunk({event, relays})
}
export const addRelay = async (url: string, mode: RelayMode) => {
const list = get(userRelaySelections) || makeList({kind: RELAYS})
const dup = getRelayTags(getListTags(list)).find(nthEq(1, url))
const tag = removeNil(["r", url, dup && dup[2] !== mode ? undefined : mode])
const tags = [...list.publicTags.filter(nthNe(1, url)), tag]
const event = {kind: list.kind, content: list.event?.content || "", tags}
const relays = Router.get().FromUser().policy(addMaximalFallbacks).getUrls()
return publishThunk({event, relays})
}
export const removeInboxRelay = async (url: string) => {
const list = get(userInboxRelaySelections) || makeList({kind: INBOX_RELAYS})
const event = await removeFromList(list, url).reconcile(nip44EncryptToSelf)
const relays = Router.get().FromUser().policy(addMaximalFallbacks).getUrls()
return publishThunk({event, relays})
}
export const addInboxRelay = async (url: string) => {
const list = get(userInboxRelaySelections) || makeList({kind: INBOX_RELAYS})
const event = await addToListPublicly(list, ["relay", url]).reconcile(nip44EncryptToSelf)
const relays = Router.get().FromUser().policy(addMaximalFallbacks).getUrls()
return publishThunk({event, relays})
}
export const unfollow = async (value: string) => {
const list = get(userFollows) || makeList({kind: FOLLOWS})
const event = await removeFromList(list, value).reconcile(nip44EncryptToSelf)
+39
View File
@@ -270,6 +270,45 @@ export const thunkIncompleteUrls = (thunk: AbstractThunk) => {
export const thunkIsComplete = (thunk: AbstractThunk) => thunkCompleteUrls(thunk).length > 0
export const getThunkError = (thunk: Thunk) =>
new Promise<string>(resolve => {
thunk.subscribe($thunk => {
for (const [relay, status] of Object.entries($thunk.status)) {
if (status === PublishStatus.Failure) {
resolve($thunk.details[relay])
}
}
if (thunkIsComplete($thunk)) {
resolve("")
}
})
})
export const waitForThunkStatus = (thunk: Thunk, status: PublishStatus) =>
new Promise<boolean>(resolve => {
thunk.subscribe($thunk => {
for (const [_, s] of Object.entries($thunk.status)) {
if (s === status) {
resolve(true)
}
}
if (thunkIsComplete($thunk)) {
resolve(false)
}
})
})
export const waitForThunkCompletion = (thunk: Thunk) =>
new Promise<void>(resolve => {
thunk.subscribe($thunk => {
if (thunkIsComplete($thunk)) {
resolve()
}
})
})
export function* walkThunks(thunks: AbstractThunk[]): Iterable<Thunk> {
for (const thunk of thunks) {
if (thunk instanceof MergedThunk) {
+17 -26
View File
@@ -53,22 +53,23 @@ export enum ParsedType {
Topic = "topic",
}
export type ParsedCashu = {
export type ParsedBase = {
raw: string
}
export type ParsedCashu = ParsedBase & {
type: ParsedType.Cashu
value: string
raw: string
}
export type ParsedCode = {
export type ParsedCode = ParsedBase & {
type: ParsedType.Code
value: string
raw: string
}
export type ParsedEllipsis = {
export type ParsedEllipsis = ParsedBase & {
type: ParsedType.Ellipsis
value: string
raw: string
}
export type ParsedEmojiValue = {
@@ -76,16 +77,14 @@ export type ParsedEmojiValue = {
url?: string
}
export type ParsedEmoji = {
export type ParsedEmoji = ParsedBase & {
type: ParsedType.Emoji
value: ParsedEmojiValue
raw: string
}
export type ParsedInvoice = {
export type ParsedInvoice = ParsedBase & {
type: ParsedType.Invoice
value: string
raw: string
}
export type ParsedLinkValue = {
@@ -97,52 +96,44 @@ export type ParsedLinkGridValue = {
links: ParsedLinkValue[]
}
export type ParsedLink = {
export type ParsedLink = ParsedBase & {
type: ParsedType.Link
value: ParsedLinkValue
raw: string
}
export type ParsedLinkGrid = {
export type ParsedLinkGrid = ParsedBase & {
type: ParsedType.LinkGrid
value: ParsedLinkGridValue
raw: string
}
export type ParsedNewline = {
export type ParsedNewline = ParsedBase & {
type: ParsedType.Newline
value: string
raw: string
}
export type ParsedText = {
export type ParsedText = ParsedBase & {
type: ParsedType.Text
value: string
raw: string
}
export type ParsedTopic = {
export type ParsedTopic = ParsedBase & {
type: ParsedType.Topic
value: string
raw: string
}
export type ParsedEvent = {
export type ParsedEvent = ParsedBase & {
type: ParsedType.Event
value: EventPointer
raw: string
}
export type ParsedProfile = {
export type ParsedProfile = ParsedBase & {
type: ParsedType.Profile
value: ProfilePointer
raw: string
}
export type ParsedAddress = {
export type ParsedAddress = ParsedBase & {
type: ParsedType.Address
value: AddressPointer
raw: string
}
export type Parsed =
+1 -1
View File
@@ -41,7 +41,7 @@
"@tiptap/suggestion": "^2.11.5",
"@welshman/lib": "workspace:*",
"@welshman/util": "workspace:*",
"nostr-editor": "^0.0.4-pre.17",
"nostr-editor": "github:cesardeazevedo/nostr-editor#a1babb361e081dd9548b852e15837525a2fc82bc",
"nostr-tools": "^2.7.2",
"tippy.js": "^6.3.7"
},
+1 -1
View File
@@ -2,4 +2,4 @@ export * from "./nodeviews/index.js"
export * from "./extensions/index.js"
export * from "./plugins/index.js"
export {Editor, NodeViewProps} from "@tiptap/core"
export {UploadTask, BlossomOptions, uploadBlossom} from "nostr-editor"
export {UploadTask, BlossomOptions, uploadBlossom, encryptFile, decryptFile} from "nostr-editor"