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
+1
View File
@@ -24,6 +24,7 @@
"globals": "~16.0.0",
"happy-dom": "^17.4.4",
"husky": "^9.1.7",
"onchange": "^7.1.0",
"prettier": "~3.5.3",
"ts-node": "^10.9.2",
"typedoc": "^0.28.2",
+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"
+106 -5
View File
@@ -32,6 +32,9 @@ importers:
husky:
specifier: ^9.1.7
version: 9.1.7
onchange:
specifier: ^7.1.0
version: 7.1.0
prettier:
specifier: ~3.5.3
version: 3.5.3
@@ -201,8 +204,8 @@ importers:
specifier: workspace:*
version: link:../util
nostr-editor:
specifier: ^0.0.4-pre.17
version: 0.0.4-pre.17(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/extension-image@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7)))(@tiptap/extension-link@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7)(linkifyjs@4.2.0)(nostr-tools@2.12.0(typescript@5.8.2))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.0)(prosemirror-state@1.4.3)(tiptap-markdown@0.8.10(@tiptap/core@2.11.7(@tiptap/pm@2.11.7)))
specifier: github:cesardeazevedo/nostr-editor#a1babb361e081dd9548b852e15837525a2fc82bc
version: https://codeload.github.com/cesardeazevedo/nostr-editor/tar.gz/a1babb361e081dd9548b852e15837525a2fc82bc(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/extension-image@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7)))(@tiptap/extension-link@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7)(linkifyjs@4.2.0)(nostr-tools@2.12.0(typescript@5.8.2))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.0)(prosemirror-state@1.4.3)(tiptap-markdown@0.8.10(@tiptap/core@2.11.7(@tiptap/pm@2.11.7)))
nostr-tools:
specifier: ^2.7.2
version: 2.12.0(typescript@5.8.2)
@@ -503,6 +506,12 @@ packages:
resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
engines: {node: '>=6.9.0'}
'@blakeembrey/deque@1.0.5':
resolution: {integrity: sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==}
'@blakeembrey/template@1.2.0':
resolution: {integrity: sha512-w/63nURdkRPpg3AXbNr7lPv6HgOuVDyefTumiXsbXxtIwcuk5EXayWR5OpSwDjsQPgaYsfUSedMduaNOjAYY8A==}
'@braintree/sanitize-url@7.1.1':
resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==}
@@ -923,6 +932,10 @@ packages:
'@noble/ciphers@0.5.3':
resolution: {integrity: sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==}
'@noble/ciphers@1.3.0':
resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==}
engines: {node: ^14.21.3 || >=16}
'@noble/curves@1.1.0':
resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==}
@@ -945,6 +958,10 @@ packages:
resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==}
engines: {node: ^14.21.3 || >=16}
'@noble/hashes@1.8.0':
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
engines: {node: ^14.21.3 || >=16}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -1469,6 +1486,10 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -1490,6 +1511,10 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
birpc@0.2.19:
resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
@@ -1532,6 +1557,10 @@ packages:
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
engines: {node: '>= 16'}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
code-red@1.0.4:
resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==}
@@ -1827,6 +1856,10 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -1994,8 +2027,13 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
nostr-editor@0.0.4-pre.17:
resolution: {integrity: sha512-A3e/SdEUHZhsr+lAMefKahUGx0vqGEfu4NSg6QuEHBL9RCk+p49JV48onS+KlhcYcdLTyB3xE4GgHQtcvClexg==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
nostr-editor@https://codeload.github.com/cesardeazevedo/nostr-editor/tar.gz/a1babb361e081dd9548b852e15837525a2fc82bc:
resolution: {tarball: https://codeload.github.com/cesardeazevedo/nostr-editor/tar.gz/a1babb361e081dd9548b852e15837525a2fc82bc}
version: 0.0.4-pre.17
engines: {node: '>=18.16.1'}
peerDependencies:
'@tiptap/core': ^2.6.6
@@ -2025,6 +2063,10 @@ packages:
nostr-wasm@0.1.0:
resolution: {integrity: sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==}
onchange@7.1.0:
resolution: {integrity: sha512-ZJcqsPiWUAUpvmnJri5TPBooqJOPmC0ttN65juhN15Q8xA+Nbg3BaxBHXQ45EistKKlKElb0edmbPWnKSBkvMg==}
hasBin: true
oniguruma-to-es@3.1.1:
resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==}
@@ -2174,6 +2216,10 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
regex-recursion@6.0.2:
resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
@@ -2333,6 +2379,10 @@ packages:
resolution: {integrity: sha512-2dt4qJEVtYIwCoihoO+HfVLN+uid7ibtKnZ4pjLF4YqyDOwGuP0uTGLTUnvNkAp92qh3YmgRv4wojxnj5yBPAQ==}
engines: {node: '>=6.0.0', npm: '>=4.0.0'}
tree-kill@1.2.2:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
trim-lines@3.0.1:
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
@@ -2736,6 +2786,10 @@ snapshots:
'@babel/helper-string-parser': 7.25.9
'@babel/helper-validator-identifier': 7.25.9
'@blakeembrey/deque@1.0.5': {}
'@blakeembrey/template@1.2.0': {}
'@braintree/sanitize-url@7.1.1': {}
'@capacitor/core@7.2.0':
@@ -3022,6 +3076,8 @@ snapshots:
'@noble/ciphers@0.5.3': {}
'@noble/ciphers@1.3.0': {}
'@noble/curves@1.1.0':
dependencies:
'@noble/hashes': 1.3.1
@@ -3040,6 +3096,8 @@ snapshots:
'@noble/hashes@1.7.1': {}
'@noble/hashes@1.8.0': {}
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -3599,6 +3657,11 @@ snapshots:
ansi-styles@6.2.1: {}
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
arg@4.1.3: {}
argparse@2.0.1: {}
@@ -3611,6 +3674,8 @@ snapshots:
balanced-match@1.0.2: {}
binary-extensions@2.3.0: {}
birpc@0.2.19: {}
brace-expansion@1.1.11:
@@ -3651,6 +3716,18 @@ snapshots:
check-error@2.1.1: {}
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.3
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
code-red@1.0.4:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
@@ -3985,6 +4062,10 @@ snapshots:
imurmurhash@0.1.4: {}
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
@@ -4139,8 +4220,12 @@ snapshots:
natural-compare@1.4.0: {}
nostr-editor@0.0.4-pre.17(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/extension-image@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7)))(@tiptap/extension-link@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7)(linkifyjs@4.2.0)(nostr-tools@2.12.0(typescript@5.8.2))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.0)(prosemirror-state@1.4.3)(tiptap-markdown@0.8.10(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))):
normalize-path@3.0.0: {}
nostr-editor@https://codeload.github.com/cesardeazevedo/nostr-editor/tar.gz/a1babb361e081dd9548b852e15837525a2fc82bc(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/extension-image@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7)))(@tiptap/extension-link@2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7)(linkifyjs@4.2.0)(nostr-tools@2.12.0(typescript@5.8.2))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.0)(prosemirror-state@1.4.3)(tiptap-markdown@0.8.10(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))):
dependencies:
'@noble/ciphers': 1.3.0
'@noble/hashes': 1.8.0
'@tiptap/core': 2.11.7(@tiptap/pm@2.11.7)
'@tiptap/extension-image': 2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))
'@tiptap/extension-link': 2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7)
@@ -4172,6 +4257,16 @@ snapshots:
nostr-wasm@0.1.0: {}
onchange@7.1.0:
dependencies:
'@blakeembrey/deque': 1.0.5
'@blakeembrey/template': 1.2.0
arg: 4.1.3
chokidar: 3.6.0
cross-spawn: 7.0.6
ignore: 5.3.2
tree-kill: 1.2.2
oniguruma-to-es@3.1.1:
dependencies:
emoji-regex-xs: 1.0.0
@@ -4355,6 +4450,10 @@ snapshots:
queue-microtask@1.2.3: {}
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
regex-recursion@6.0.2:
dependencies:
regex-utilities: 2.3.0
@@ -4532,6 +4631,8 @@ snapshots:
trava@1.2.1: {}
tree-kill@1.2.2: {}
trim-lines@3.0.1: {}
ts-api-utils@2.1.0(typescript@5.8.2):