Update welshman stuff, fix bug in makeFeed

This commit is contained in:
Jon Staab
2025-04-24 10:02:27 -07:00
parent 3a954201ce
commit c18b29e7d6
19 changed files with 60 additions and 47 deletions
+2
View File
@@ -59,6 +59,7 @@
"@welshman/lib": "^0.1.2", "@welshman/lib": "^0.1.2",
"@welshman/net": "^0.1.2", "@welshman/net": "^0.1.2",
"@welshman/relay": "^0.1.2", "@welshman/relay": "^0.1.2",
"@welshman/router": "^0.1.0",
"@welshman/signer": "^0.1.4", "@welshman/signer": "^0.1.4",
"@welshman/store": "^0.1.3", "@welshman/store": "^0.1.3",
"@welshman/util": "^0.1.3", "@welshman/util": "^0.1.3",
@@ -84,6 +85,7 @@
"@welshman/feeds": "link:../welshman/packages/feeds", "@welshman/feeds": "link:../welshman/packages/feeds",
"@welshman/net": "link:../welshman/packages/net", "@welshman/net": "link:../welshman/packages/net",
"@welshman/relay": "link:../welshman/packages/relay", "@welshman/relay": "link:../welshman/packages/relay",
"@welshman/router": "link:../welshman/packages/router",
"@welshman/signer": "link:../welshman/packages/signer", "@welshman/signer": "link:../welshman/packages/signer",
"@welshman/store": "link:../welshman/packages/store", "@welshman/store": "link:../welshman/packages/store",
"@welshman/editor": "link:../welshman/packages/editor" "@welshman/editor": "link:../welshman/packages/editor"
+4
View File
@@ -13,6 +13,7 @@ overrides:
'@welshman/feeds': link:../welshman/packages/feeds '@welshman/feeds': link:../welshman/packages/feeds
'@welshman/net': link:../welshman/packages/net '@welshman/net': link:../welshman/packages/net
'@welshman/relay': link:../welshman/packages/relay '@welshman/relay': link:../welshman/packages/relay
'@welshman/router': link:../welshman/packages/router
'@welshman/signer': link:../welshman/packages/signer '@welshman/signer': link:../welshman/packages/signer
'@welshman/store': link:../welshman/packages/store '@welshman/store': link:../welshman/packages/store
'@welshman/editor': link:../welshman/packages/editor '@welshman/editor': link:../welshman/packages/editor
@@ -87,6 +88,9 @@ importers:
'@welshman/relay': '@welshman/relay':
specifier: link:../welshman/packages/relay specifier: link:../welshman/packages/relay
version: link:../welshman/packages/relay version: link:../welshman/packages/relay
'@welshman/router':
specifier: link:../welshman/packages/router
version: link:../welshman/packages/router
'@welshman/signer': '@welshman/signer':
specifier: link:../welshman/packages/signer specifier: link:../welshman/packages/signer
version: link:../welshman/packages/signer version: link:../welshman/packages/signer
+4 -4
View File
@@ -33,6 +33,7 @@ import {
import type {TrustedEvent, Filter, EventContent, EventTemplate} from "@welshman/util" import type {TrustedEvent, Filter, EventContent, EventTemplate} from "@welshman/util"
import {Pool, PublishStatus, AuthStatus, SocketStatus} from "@welshman/net" import {Pool, PublishStatus, AuthStatus, SocketStatus} from "@welshman/net"
import {Nip59, stamp} from "@welshman/signer" import {Nip59, stamp} from "@welshman/signer"
import {Router} from "@welshman/router"
import { import {
pubkey, pubkey,
signer, signer,
@@ -53,7 +54,6 @@ import {
dropSession, dropSession,
tagEventForComment, tagEventForComment,
tagEventForQuote, tagEventForQuote,
Router,
thunkIsComplete, thunkIsComplete,
} from "@welshman/app" } from "@welshman/app"
import type {Thunk} from "@welshman/app" import type {Thunk} from "@welshman/app"
@@ -259,7 +259,7 @@ export const setInboxRelayPolicy = (url: string, enabled: boolean) => {
// Relay access // Relay access
export const checkRelayAccess = async (url: string, claim = "") => { export const checkRelayAccess = async (url: string, claim = "") => {
const socket = Pool.getSingleton().get(url) const socket = Pool.get().get(url)
await socket.auth.attemptAuth(signer.get().sign) await socket.auth.attemptAuth(signer.get().sign)
@@ -291,7 +291,7 @@ export const checkRelayProfile = async (url: string) => {
} }
export const checkRelayConnection = async (url: string) => { export const checkRelayConnection = async (url: string) => {
const socket = Pool.getSingleton().get(url) const socket = Pool.get().get(url)
socket.attemptToOpen() socket.attemptToOpen()
@@ -306,7 +306,7 @@ export const checkRelayConnection = async (url: string) => {
} }
export const checkRelayAuth = async (url: string, timeout = 3000) => { export const checkRelayAuth = async (url: string, timeout = 3000) => {
const socket = Pool.getSingleton().get(url) const socket = Pool.get().get(url)
const okStatuses = [AuthStatus.None, AuthStatus.Ok] const okStatuses = [AuthStatus.None, AuthStatus.Ok]
await socket.auth.attemptAuth(signer.get().sign) await socket.auth.attemptAuth(signer.get().sign)
+1 -2
View File
@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import {parseJson, nthEq} from "@welshman/lib" import {parseJson, displayList, nthEq} from "@welshman/lib"
import { import {
getAddress, getAddress,
getTagValue, getTagValue,
@@ -9,7 +9,6 @@
MESSAGE, MESSAGE,
THREAD, THREAD,
} from "@welshman/util" } from "@welshman/util"
import {displayList} from "@lib/util"
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
+2 -1
View File
@@ -2,7 +2,8 @@
import * as nip19 from "nostr-tools/nip19" import * as nip19 from "nostr-tools/nip19"
import {goto} from "$app/navigation" import {goto} from "$app/navigation"
import {nthEq} from "@welshman/lib" import {nthEq} from "@welshman/lib"
import {Router, tracker, repository} from "@welshman/app" import {Router} from "@welshman/router"
import {tracker, repository} from "@welshman/app"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import {Address, DIRECT_MESSAGE, MESSAGE, THREAD, EVENT_TIME} from "@welshman/util" import {Address, DIRECT_MESSAGE, MESSAGE, THREAD, EVENT_TIME} from "@welshman/util"
import {scrollToEvent} from "@lib/html" import {scrollToEvent} from "@lib/html"
+1 -1
View File
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import * as nip19 from "nostr-tools/nip19" import * as nip19 from "nostr-tools/nip19"
import {Router} from "@welshman/app" import {Router} from "@welshman/router"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import FieldInline from "@lib/components/FieldInline.svelte" import FieldInline from "@lib/components/FieldInline.svelte"
+2 -1
View File
@@ -4,7 +4,8 @@
import * as nip19 from "nostr-tools/nip19" import * as nip19 from "nostr-tools/nip19"
import {getListTags, getPubkeyTagValues} from "@welshman/util" import {getListTags, getPubkeyTagValues} from "@welshman/util"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import {formatTimestamp, Router, userMutes} from "@welshman/app" import {Router} from "@welshman/router"
import {formatTimestamp, userMutes} from "@welshman/app"
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
+2 -1
View File
@@ -3,7 +3,8 @@
import type {Filter} from "@welshman/util" import type {Filter} from "@welshman/util"
import {deriveEvents} from "@welshman/store" import {deriveEvents} from "@welshman/store"
import {load} from "@welshman/net" import {load} from "@welshman/net"
import {Router, repository, loadRelaySelections, formatTimestampRelative} from "@welshman/app" import {Router} from "@welshman/router"
import {repository, loadRelaySelections, formatTimestampRelative} from "@welshman/app"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import Profile from "@app/components/Profile.svelte" import Profile from "@app/components/Profile.svelte"
+2 -1
View File
@@ -9,7 +9,8 @@
isPublishedProfile, isPublishedProfile,
uniqTags, uniqTags,
} from "@welshman/util" } from "@welshman/util"
import {Router, pubkey, profilesByPubkey, publishThunk} from "@welshman/app" import {Router} from "@welshman/router"
import {pubkey, profilesByPubkey, publishThunk} from "@welshman/app"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import ProfileEditForm from "@app/components/ProfileEditForm.svelte" import ProfileEditForm from "@app/components/ProfileEditForm.svelte"
import {clearModals} from "@app/modal" import {clearModals} from "@app/modal"
+2 -2
View File
@@ -4,7 +4,7 @@
import {feedFromFilter, makeIntersectionFeed, makeRelayFeed} from "@welshman/feeds" import {feedFromFilter, makeIntersectionFeed, makeRelayFeed} from "@welshman/feeds"
import {NOTE, getReplyTags} from "@welshman/util" import {NOTE, getReplyTags} from "@welshman/util"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import {createFeedController} from "@welshman/app" import {makeFeedController} from "@welshman/app"
import {createScroller} from "@lib/html" import {createScroller} from "@lib/html"
import {fly} from "@lib/transition" import {fly} from "@lib/transition"
import Spinner from "@lib/components/Spinner.svelte" import Spinner from "@lib/components/Spinner.svelte"
@@ -19,7 +19,7 @@
let {url, pubkey, events = $bindable([]), hideLoading = false}: Props = $props() let {url, pubkey, events = $bindable([]), hideLoading = false}: Props = $props()
const ctrl = createFeedController({ const ctrl = makeFeedController({
useWindowing: true, useWindowing: true,
feed: makeIntersectionFeed( feed: makeIntersectionFeed(
makeRelayFeed(url), makeRelayFeed(url),
+1 -2
View File
@@ -1,13 +1,12 @@
<script lang="ts"> <script lang="ts">
import {onMount} from "svelte" import {onMount} from "svelte"
import type {Snippet} from "svelte" import type {Snippet} from "svelte"
import {groupBy, uniq, uniqBy, batch} from "@welshman/lib" import {groupBy, uniq, uniqBy, batch, displayList} from "@welshman/lib"
import {REACTION, getReplyFilters, getTag, REPORT, DELETE} from "@welshman/util" import {REACTION, getReplyFilters, getTag, REPORT, DELETE} from "@welshman/util"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import {deriveEvents} from "@welshman/store" import {deriveEvents} from "@welshman/store"
import {load} from "@welshman/net" import {load} from "@welshman/net"
import {pubkey, repository, displayProfileByPubkey} from "@welshman/app" import {pubkey, repository, displayProfileByPubkey} from "@welshman/app"
import {displayList} from "@lib/util"
import {isMobile, preventDefault, stopPropagation} from "@lib/html" import {isMobile, preventDefault, stopPropagation} from "@lib/html"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import EventReportDetails from "@app/components/EventReportDetails.svelte" import EventReportDetails from "@app/components/EventReportDetails.svelte"
+1 -1
View File
@@ -18,7 +18,7 @@
const back = () => history.back() const back = () => history.back()
const next = () => { const next = () => {
if (!error && Pool.getSingleton().get(url).auth.status === AuthStatus.None) { if (!error && Pool.get().get(url).auth.status === AuthStatus.None) {
pushModal(SpaceVisitConfirm, {url}, {replaceState: true}) pushModal(SpaceVisitConfirm, {url}, {replaceState: true})
} else { } else {
confirmSpaceVisit(url) confirmSpaceVisit(url)
+1 -1
View File
@@ -26,7 +26,7 @@
return pushToast({theme: "error", message: error}) return pushToast({theme: "error", message: error})
} }
const socket = Pool.getSingleton().get(url) const socket = Pool.get().get(url)
if (socket.auth.status === AuthStatus.None) { if (socket.auth.status === AuthStatus.None) {
pushModal(SpaceJoinConfirm, {url}, {replaceState: true}) pushModal(SpaceJoinConfirm, {url}, {replaceState: true})
+2 -1
View File
@@ -2,7 +2,8 @@ import {mount} from "svelte"
import type {Writable} from "svelte/store" import type {Writable} from "svelte/store"
import {get} from "svelte/store" import {get} from "svelte/store"
import type {StampedEvent} from "@welshman/util" import type {StampedEvent} from "@welshman/util"
import {Router, signer, profileSearch} from "@welshman/app" import {Router} from "@welshman/router"
import {signer, profileSearch} from "@welshman/app"
import {Editor, MentionSuggestion, WelshmanExtension} from "@welshman/editor" import {Editor, MentionSuggestion, WelshmanExtension} from "@welshman/editor"
import {getSetting, userSettingValues} from "@app/state" import {getSetting, userSettingValues} from "@app/state"
import {makeMentionNodeView} from "./MentionNodeView" import {makeMentionNodeView} from "./MentionNodeView"
+28 -11
View File
@@ -35,7 +35,7 @@ import {
pull, pull,
hasNegentropy, hasNegentropy,
thunkQueue, thunkQueue,
createFeedController, makeFeedController,
loadRelay, loadRelay,
loadMutes, loadMutes,
loadFollows, loadFollows,
@@ -102,7 +102,7 @@ export const makeFeed = ({
const events = writable(initialEvents) const events = writable(initialEvents)
const controller = new AbortController() const controller = new AbortController()
for (const event of initialEvents) { const markEvent = (event: TrustedEvent) => {
if (!seen.has(event.id)) { if (!seen.has(event.id)) {
seen.add(event.id) seen.add(event.id)
onEvent?.(event) onEvent?.(event)
@@ -110,19 +110,32 @@ export const makeFeed = ({
} }
const insertEvent = (event: TrustedEvent) => { const insertEvent = (event: TrustedEvent) => {
buffer.update($buffer => { let handled = false
for (let i = 0; i < $buffer.length; i++) {
if ($buffer[i].id === event.id) return $buffer events.update($events => {
if ($buffer[i].created_at < event.created_at) return insertAt(i, event, $buffer) for (let i = 0; i < $events.length; i++) {
if ($events[i].id === event.id) return $events
if ($events[i].created_at < event.created_at) {
handled = true
return insertAt(i, event, $events)
}
} }
return [...$buffer, event] return $events
}) })
if (!seen.has(event.id)) { if (!handled) {
seen.add(event.id) buffer.update($buffer => {
onEvent?.(event) for (let i = 0; i < $buffer.length; i++) {
if ($buffer[i].id === event.id) return $buffer
if ($buffer[i].created_at < event.created_at) return insertAt(i, event, $buffer)
}
return [...$buffer, event]
})
} }
markEvent(event)
} }
const removeEvents = (ids: string[]) => { const removeEvents = (ids: string[]) => {
@@ -144,13 +157,17 @@ export const makeFeed = ({
} }
} }
const ctrl = createFeedController({ const ctrl = makeFeedController({
useWindowing: true, useWindowing: true,
feed: makeIntersectionFeed(makeRelayFeed(...relays), feedFromFilters(feedFilters)), feed: makeIntersectionFeed(makeRelayFeed(...relays), feedFromFilters(feedFilters)),
onEvent: insertEvent, onEvent: insertEvent,
onExhausted, onExhausted,
}) })
for (const event of initialEvents) {
markEvent(event)
}
request({ request({
relays, relays,
signal: controller.signal, signal: controller.signal,
+1 -2
View File
@@ -43,6 +43,7 @@ import {
} from "@welshman/util" } from "@welshman/util"
import type {TrustedEvent, SignedEvent, PublishedList, List, Filter} from "@welshman/util" import type {TrustedEvent, SignedEvent, PublishedList, List, Filter} from "@welshman/util"
import {Nip59, decrypt} from "@welshman/signer" import {Nip59, decrypt} from "@welshman/signer"
import {routerContext, Router} from "@welshman/router"
import { import {
pubkey, pubkey,
repository, repository,
@@ -60,9 +61,7 @@ import {
thunks, thunks,
walkThunks, walkThunks,
signer, signer,
Router,
makeOutboxLoader, makeOutboxLoader,
routerContext,
appContext, appContext,
} from "@welshman/app" } from "@welshman/app"
import type {Thunk, Relay} from "@welshman/app" import type {Thunk, Relay} from "@welshman/app"
-14
View File
@@ -2,20 +2,6 @@ import {hexToBytes, bytesToHex} from "@noble/hashes/utils"
import * as nip19 from "nostr-tools/nip19" import * as nip19 from "nostr-tools/nip19"
import {range, DAY} from "@welshman/lib" import {range, DAY} from "@welshman/lib"
export const displayList = <T>(xs: T[], conj = "and", n = 6, locale = "en-US") => {
const stringItems = xs.map(String)
if (xs.length > n + 2) {
const formattedList = new Intl.ListFormat(locale, {style: "long", type: "unit"}).format(
stringItems.slice(0, n),
)
return `${formattedList}, ${conj} ${xs.length - n} others`
}
return new Intl.ListFormat(locale, {style: "long", type: "conjunction"}).format(stringItems)
}
export const nsecEncode = (secret: string) => nip19.nsecEncode(hexToBytes(secret)) export const nsecEncode = (secret: string) => nip19.nsecEncode(hexToBytes(secret))
export const nsecDecode = (nsec: string) => { export const nsecDecode = (nsec: string) => {
+2 -1
View File
@@ -1,7 +1,8 @@
<script lang="ts"> <script lang="ts">
import {page} from "$app/stores" import {page} from "$app/stores"
import {WRAP} from "@welshman/util" import {WRAP} from "@welshman/util"
import {pubkey, Router} from "@welshman/app" import {Router} from "@welshman/router"
import {pubkey} from "@welshman/app"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Page from "@lib/components/Page.svelte" import Page from "@lib/components/Page.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
+2 -1
View File
@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import {getListTags, createEvent, getPubkeyTagValues, MUTES} from "@welshman/util" import {getListTags, createEvent, getPubkeyTagValues, MUTES} from "@welshman/util"
import {pubkey, Router, signer, userMutes, tagPubkey, publishThunk} from "@welshman/app" import {Router} from "@welshman/router"
import {pubkey, signer, userMutes, tagPubkey, publishThunk} from "@welshman/app"
import {preventDefault} from "@lib/html" import {preventDefault} from "@lib/html"
import Field from "@lib/components/Field.svelte" import Field from "@lib/components/Field.svelte"
import FieldInline from "@lib/components/FieldInline.svelte" import FieldInline from "@lib/components/FieldInline.svelte"