mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-29 08:21:20 +00:00
Use welshman relays
This commit is contained in:
parent
cf06ab1788
commit
e554acc79d
@ -8,11 +8,11 @@
|
||||
import * as lib from "@welshman/lib"
|
||||
import * as util from "@welshman/util"
|
||||
import * as network from "@welshman/net"
|
||||
import {session, pubkey} from "@welshman/app"
|
||||
import {session, pubkey, relays} from "@welshman/app"
|
||||
import logger from "src/util/logger"
|
||||
import * as misc from "src/util/misc"
|
||||
import * as nostr from "src/util/nostr"
|
||||
import {storage, relays, getSetting} from "src/engine"
|
||||
import {storage, getSetting} from "src/engine"
|
||||
import * as engine from "src/engine"
|
||||
import * as domain from "src/domain"
|
||||
import {loadAppData, slowConnections, loadUserData} from "src/app/state"
|
||||
@ -459,39 +459,14 @@
|
||||
const {lastOpen, lastPublish, lastRequest, lastFault} = connection.meta
|
||||
const lastActivity = lib.max([lastOpen, lastPublish, lastRequest, lastFault])
|
||||
|
||||
if (lastFault) {
|
||||
relays.key(url).update($r => ({
|
||||
...$r,
|
||||
faults: lib.uniq(($r.faults || []).concat(lastFault)).slice(-10),
|
||||
}))
|
||||
}
|
||||
|
||||
if (lastActivity < Date.now() - 60_000) {
|
||||
connection.disconnect()
|
||||
}
|
||||
}
|
||||
}, 5_000)
|
||||
|
||||
const interval2 = setInterval(async () => {
|
||||
if (!getSetting("dufflepud_url")) {
|
||||
return
|
||||
}
|
||||
|
||||
// Find relays with old/missing metadata and refresh them. Only pick a
|
||||
// few so we're not asking for too much data at once
|
||||
const staleRelays = relays
|
||||
.get()
|
||||
.filter(r => (r.last_checked || 0) < lib.now() - seconds(7, "day"))
|
||||
.slice(0, 20)
|
||||
|
||||
for (const relay of staleRelays) {
|
||||
engine.loadRelay(relay.url)
|
||||
}
|
||||
}, 30_000)
|
||||
|
||||
return () => {
|
||||
clearInterval(interval1)
|
||||
clearInterval(interval2)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<script lang="ts">
|
||||
import {FeedType} from "@welshman/feeds"
|
||||
import {relaySearch} from "@welshman/app"
|
||||
import SearchSelect from "src/partials/SearchSelect.svelte"
|
||||
import {relaySearch} from "src/engine"
|
||||
import {displayRelayUrl} from 'src/domain'
|
||||
|
||||
export let feed
|
||||
export let onChange
|
||||
@ -13,5 +14,5 @@
|
||||
value={feed.slice(1)}
|
||||
search={$relaySearch.searchValues}
|
||||
onChange={urls => onChange([FeedType.Relay, ...urls])}>
|
||||
<span slot="item" let:item>{$relaySearch.displayValue(item)}</span>
|
||||
<span slot="item" let:item>{displayRelayUrl(item)}</span>
|
||||
</SearchSelect>
|
||||
|
@ -2,6 +2,7 @@
|
||||
import {join, uniqBy} from "ramda"
|
||||
import {ucFirst} from "hurdak"
|
||||
import {Address, GROUP, COMMUNITY} from "@welshman/util"
|
||||
import {relaySearch} from "@welshman/app"
|
||||
import {toSpliced} from "src/util/misc"
|
||||
import {fly} from "src/util/transition"
|
||||
import {formCtrl} from "src/partials/utils"
|
||||
@ -20,7 +21,7 @@
|
||||
import PersonSelect from "src/app/shared/PersonSelect.svelte"
|
||||
import type {GroupMeta} from "src/domain"
|
||||
import {normalizeRelayUrl, displayRelayUrl} from "src/domain"
|
||||
import {env, hints, relaySearch, feedSearch} from "src/engine"
|
||||
import {env, hints, feedSearch} from "src/engine"
|
||||
|
||||
export let onSubmit
|
||||
export let values: GroupMeta & {members: string[]}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import {identity} from "@welshman/lib"
|
||||
import {Tags, NAMED_PEOPLE, NAMED_RELAYS, NAMED_TOPICS} from "@welshman/util"
|
||||
import {topicSearch} from "@welshman/app"
|
||||
import {topicSearch, relaySearch} from "@welshman/app"
|
||||
import {showInfo} from "src/partials/Toast.svelte"
|
||||
import Field from "src/partials/Field.svelte"
|
||||
import Modal from "src/partials/Modal.svelte"
|
||||
@ -11,8 +11,15 @@
|
||||
import Input from "src/partials/Input.svelte"
|
||||
import SearchSelect from "src/partials/SearchSelect.svelte"
|
||||
import PersonSelect from "src/app/shared/PersonSelect.svelte"
|
||||
import {hints, mention, relaySearch, createAndPublish, deleteEvent} from "src/engine"
|
||||
import {KindSearch, normalizeRelayUrl, createList, displayList, editList} from "src/domain"
|
||||
import {hints, mention, createAndPublish, deleteEvent} from "src/engine"
|
||||
import {
|
||||
KindSearch,
|
||||
normalizeRelayUrl,
|
||||
createList,
|
||||
displayList,
|
||||
editList,
|
||||
displayRelayUrl,
|
||||
} from "src/domain"
|
||||
|
||||
export let list
|
||||
export let exit
|
||||
@ -98,7 +105,7 @@
|
||||
search={$relaySearch.searchValues}
|
||||
termToItem={normalizeRelayUrl}
|
||||
onChange={onRelaysChange}>
|
||||
<span slot="item" let:item>{$relaySearch.displayValue(item)}</span>
|
||||
<span slot="item" let:item>{displayRelayUrl(item)}</span>
|
||||
</SearchSelect>
|
||||
{:else if list.kind === NAMED_TOPICS}
|
||||
<SearchSelect
|
||||
|
@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import {last} from "ramda"
|
||||
import {derived} from "svelte/store"
|
||||
import {signer} from "@welshman/app"
|
||||
import {signer, deriveRelay} from "@welshman/app"
|
||||
import OverflowMenu from "src/partials/OverflowMenu.svelte"
|
||||
import {relays, userRelayPolicies, joinRelay, leaveRelay} from "src/engine"
|
||||
import {userRelayPolicies, joinRelay, leaveRelay} from "src/engine"
|
||||
import {router} from "src/app/util/router"
|
||||
|
||||
export let url
|
||||
|
||||
const relay = relays.key(url)
|
||||
const relay = deriveRelay(url)
|
||||
const joined = derived(userRelayPolicies, $policies =>
|
||||
Boolean($policies.find(p => p.url === url)),
|
||||
)
|
||||
@ -46,9 +46,9 @@
|
||||
})
|
||||
}
|
||||
|
||||
if ($relay?.contact) {
|
||||
if ($relay?.profile?.contact) {
|
||||
actions.push({
|
||||
onClick: () => window.open("mailto:" + last($relay.contact.split(":"))),
|
||||
onClick: () => window.open("mailto:" + last($relay.profile?.contact.split(":"))),
|
||||
label: "Contact",
|
||||
icon: "envelope",
|
||||
})
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import cx from "classnames"
|
||||
import {isNil} from "@welshman/lib"
|
||||
import {signer} from "@welshman/app"
|
||||
import {signer, deriveRelay} from "@welshman/app"
|
||||
import {onMount} from "svelte"
|
||||
import {quantify} from "hurdak"
|
||||
import {stringToHue, displayUrl, hsl} from "src/util/misc"
|
||||
@ -14,14 +14,7 @@
|
||||
import RelayCardActions from "src/app/shared/RelayCardActions.svelte"
|
||||
import {router} from "src/app/util/router"
|
||||
import {displayRelayUrl, RelayMode} from "src/domain"
|
||||
import {
|
||||
deriveRelay,
|
||||
getSetting,
|
||||
setInboxPolicy,
|
||||
setOutboxPolicy,
|
||||
deriveUserRelayPolicy,
|
||||
loadRelay,
|
||||
} from "src/engine"
|
||||
import {getSetting, setInboxPolicy, setOutboxPolicy, deriveUserRelayPolicy} from "src/engine"
|
||||
|
||||
export let url
|
||||
export let claim = null
|
||||
@ -45,10 +38,6 @@
|
||||
setOutboxPolicy(newPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
loadRelay(url)
|
||||
})
|
||||
</script>
|
||||
|
||||
<div
|
||||
@ -88,28 +77,29 @@
|
||||
</div>
|
||||
{#if !hideDescription}
|
||||
<slot name="description">
|
||||
{#if $relay.description}
|
||||
<p>{$relay.description}</p>
|
||||
{#if $relay.profile?.description}
|
||||
<p>{$relay.profile.description}</p>
|
||||
{/if}
|
||||
</slot>
|
||||
{#if !isNil($relay.count)}
|
||||
{#if !$relay.stats}
|
||||
<span class="flex items-center gap-1 text-sm text-neutral-400">
|
||||
{#if $relay.contact}
|
||||
<Anchor external underline href={$relay.contact}>{displayUrl($relay.contact)}</Anchor>
|
||||
{#if $relay.profile?.contact}
|
||||
<Anchor external underline href={$relay.profile.contact}
|
||||
>{displayUrl($relay.profile.contact)}</Anchor>
|
||||
•
|
||||
{/if}
|
||||
{#if $relay.supported_nips}
|
||||
{#if $relay.profile?.supported_nips}
|
||||
<Popover>
|
||||
<span slot="trigger" class="cursor-pointer underline">
|
||||
{$relay.supported_nips.length} NIPs
|
||||
{$relay.profile.supported_nips.length} NIPs
|
||||
</span>
|
||||
<span slot="tooltip">
|
||||
NIPs supported: {$relay.supported_nips.join(", ")}
|
||||
NIPs supported: {$relay.profile.supported_nips.join(", ")}
|
||||
</span>
|
||||
</Popover>
|
||||
•
|
||||
{/if}
|
||||
Seen {quantify($relay.count || 0, "time")}
|
||||
Connected {quantify($relay.stats.connect_count, "time")}
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import {without, identity} from "@welshman/lib"
|
||||
import {getAddress} from "@welshman/util"
|
||||
import {relaySearch} from "@welshman/app"
|
||||
import {onMount} from "svelte"
|
||||
import {pickVals, toSpliced} from "src/util/misc"
|
||||
import Card from "src/partials/Card.svelte"
|
||||
@ -16,7 +17,7 @@
|
||||
import PersonSelect from "src/app/shared/PersonSelect.svelte"
|
||||
import {router} from "src/app/util/router"
|
||||
import {displayRelayUrl} from "src/domain"
|
||||
import {hints, relaySearch, groupMetaSearch, displayGroupByAddress} from "src/engine"
|
||||
import {hints, groupMetaSearch, displayGroupByAddress} from "src/engine"
|
||||
|
||||
export let initialPubkey = null
|
||||
export let initialGroupAddress = null
|
||||
|
@ -3,6 +3,7 @@
|
||||
import {quantify} from "hurdak"
|
||||
import {fromPairs, uniq, without, remove, append, nth, nthEq} from "@welshman/lib"
|
||||
import {getPubkeyTagValues, getAddress} from "@welshman/util"
|
||||
import {relaySearch} from "@welshman/app"
|
||||
import Card from "src/partials/Card.svelte"
|
||||
import Input from "src/partials/Input.svelte"
|
||||
import Modal from "src/partials/Modal.svelte"
|
||||
@ -11,7 +12,7 @@
|
||||
import Subheading from "src/partials/Subheading.svelte"
|
||||
import PersonSummary from "src/app/shared/PersonSummary.svelte"
|
||||
import RelayCard from "src/app/shared/RelayCard.svelte"
|
||||
import {createPeopleLoader, profileSearch, relaySearch} from "src/engine"
|
||||
import {createPeopleLoader, profileSearch} from "src/engine"
|
||||
|
||||
export let relays
|
||||
export let follows
|
||||
|
@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import {batch} from "hurdak"
|
||||
import {makeRelayFeed, feedFromFilter} from "@welshman/feeds"
|
||||
import {deriveRelay} from "@welshman/app"
|
||||
import {getAvgRating} from "src/util/nostr"
|
||||
import Feed from "src/app/shared/Feed.svelte"
|
||||
import Tabs from "src/partials/Tabs.svelte"
|
||||
import Rating from "src/partials/Rating.svelte"
|
||||
import RelayTitle from "src/app/shared/RelayTitle.svelte"
|
||||
import RelayActions from "src/app/shared/RelayActions.svelte"
|
||||
import {deriveRelay} from "src/engine"
|
||||
import {makeFeed, normalizeRelayUrl, displayRelayUrl} from "src/domain"
|
||||
|
||||
export let url
|
||||
@ -54,8 +54,8 @@
|
||||
<Rating inert value={rating} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $relay.description}
|
||||
<p>{$relay.description}</p>
|
||||
{#if $relay.profile?.description}
|
||||
<p>{$relay.profile.description}</p>
|
||||
{/if}
|
||||
<Tabs {tabs} {activeTab} {setActiveTab} />
|
||||
{#if activeTab === "reviews"}
|
||||
|
@ -4,7 +4,7 @@
|
||||
import {groupBy, sortBy, uniqBy, prop} from "ramda"
|
||||
import {displayList} from "hurdak"
|
||||
import {pushToMapKey} from "@welshman/lib"
|
||||
import {pubkey} from "@welshman/app"
|
||||
import {pubkey, relays, relaySearch, type Relay} from "@welshman/app"
|
||||
import {Tags, isShareableRelayUrl, normalizeRelayUrl} from "@welshman/util"
|
||||
import {createScroller} from "src/util/misc"
|
||||
import {showWarning} from "src/partials/Toast.svelte"
|
||||
@ -17,16 +17,13 @@
|
||||
import RelayCard from "src/app/shared/RelayCard.svelte"
|
||||
import Note from "src/app/shared/Note.svelte"
|
||||
import {profileHasName, RelayMode} from "src/domain"
|
||||
import type {RelayInfo} from "src/engine"
|
||||
import {
|
||||
load,
|
||||
hints,
|
||||
relays,
|
||||
userFollows,
|
||||
getProfile,
|
||||
displayProfileByPubkey,
|
||||
userRelayPolicies,
|
||||
relaySearch,
|
||||
getPubkeyRelayPolicies,
|
||||
sortEventsDesc,
|
||||
joinRelay,
|
||||
@ -58,14 +55,14 @@
|
||||
(term
|
||||
? $relaySearch.searchOptions(term)
|
||||
: sortBy(p => -(pubkeysByUrl.get(p.url)?.length || 0), $relaySearch.options)
|
||||
).map((profile: RelayInfo) => {
|
||||
const pubkeys = pubkeysByUrl.get(profile.url) || []
|
||||
).map((relay: Relay) => {
|
||||
const pubkeys = pubkeysByUrl.get(relay.url) || []
|
||||
const description =
|
||||
pubkeys.length > 0
|
||||
? "Used by " + displayList(pubkeys.map(displayProfileByPubkey))
|
||||
: profile.description
|
||||
: relay.profile?.description
|
||||
|
||||
return {...profile, description}
|
||||
return {...relay, description}
|
||||
}),
|
||||
)
|
||||
|
||||
@ -189,9 +186,9 @@
|
||||
placeholder="Search relays or add a custom url">
|
||||
<i slot="before" class="fa-solid fa-search" />
|
||||
</Input>
|
||||
{#each $searchRelays(q).slice(0, limit) as { url, description } (url)}
|
||||
{#each $searchRelays(q).slice(0, limit) as { url, profile } (url)}
|
||||
<RelayCard {url} ratings={ratings[url]}>
|
||||
<p slot="description">{description || ""}</p>
|
||||
<p slot="description">{profile?.description || ""}</p>
|
||||
</RelayCard>
|
||||
{/each}
|
||||
{/if}
|
||||
|
@ -5,7 +5,7 @@
|
||||
import {getAddress, WRAP, GROUP} from "@welshman/util"
|
||||
import type {SignedEvent} from "@welshman/util"
|
||||
import {Nip59, Nip01Signer, getPubkey} from "@welshman/signer"
|
||||
import {session} from "@welshman/app"
|
||||
import {session, relaySearch} from "@welshman/app"
|
||||
import {toHex, nsecEncode, isKeyValid} from "src/util/nostr"
|
||||
import {showInfo, showWarning} from "src/partials/Toast.svelte"
|
||||
import CopyValue from "src/partials/CopyValue.svelte"
|
||||
@ -21,7 +21,6 @@
|
||||
import {
|
||||
hints,
|
||||
groupSharedKeys,
|
||||
relaySearch,
|
||||
userIsGroupMember,
|
||||
groupAdminKeys,
|
||||
subscribe,
|
||||
@ -204,9 +203,8 @@
|
||||
<Field label="Relays to search">
|
||||
<SearchSelect
|
||||
multiple
|
||||
getKey={$relaySearch.displayValue}
|
||||
search={$relaySearch.searchValues}
|
||||
bind:value={relays}
|
||||
search={$relaySearch.searchValues}
|
||||
placeholder="wss://..." />
|
||||
</Field>
|
||||
<Anchor button accent loading={importing} on:click={finishImport}>Import key</Anchor>
|
||||
|
@ -3,14 +3,6 @@ import type {Nip46Handler} from "@welshman/signer"
|
||||
import type {TrustedEvent, Zapper as WelshmanZapper} from "@welshman/util"
|
||||
import type {Session} from "@welshman/app"
|
||||
import {isTrustedEvent} from "@welshman/util"
|
||||
import type {RelayProfile} from "src/domain"
|
||||
|
||||
export type RelayInfo = RelayProfile & {
|
||||
count?: number
|
||||
faults?: number[]
|
||||
first_seen?: number
|
||||
last_checked?: number
|
||||
}
|
||||
|
||||
export enum GroupAccess {
|
||||
None = null,
|
||||
|
@ -22,7 +22,6 @@ import {parseJson} from "src/util/misc"
|
||||
import {normalizeRelayUrl} from "src/domain"
|
||||
import {GroupAccess, type SessionWithMeta} from "src/engine/model"
|
||||
import {
|
||||
relays,
|
||||
deriveAdminKeyForGroup,
|
||||
getGroupStatus,
|
||||
groupAdminKeys,
|
||||
@ -181,21 +180,6 @@ projections.addHandler(0, e => {
|
||||
updateZapper(e, content)
|
||||
})
|
||||
|
||||
// Relays
|
||||
|
||||
projections.addHandler(RELAYS, (e: TrustedEvent) => {
|
||||
for (const [key, value] of e.tags) {
|
||||
if (["r", "relay"].includes(key) && isShareableRelayUrl(value)) {
|
||||
relays.key(normalizeRelayUrl(value)).update($relay => ({
|
||||
url: value,
|
||||
last_checked: 0,
|
||||
count: inc($relay?.count || 0),
|
||||
first_seen: $relay?.first_seen || e.created_at,
|
||||
}))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Decrypt encrypted events eagerly
|
||||
|
||||
projections.addHandler(SEEN_GENERAL, ensurePlaintext)
|
||||
|
@ -48,12 +48,12 @@ import {
|
||||
DEPRECATED_DIRECT_MESSAGE,
|
||||
} from "@welshman/util"
|
||||
import {makeDvmRequest} from "@welshman/dvm"
|
||||
import {pubkey, repository, signer, updateSession} from "@welshman/app"
|
||||
import {pubkey, relays, repository, signer, updateSession} from "@welshman/app"
|
||||
import {updateIn} from "src/util/misc"
|
||||
import {noteKinds, reactionKinds, repostKinds} from "src/util/nostr"
|
||||
import {always, partition, pluck, uniq, without} from "ramda"
|
||||
import {LIST_KINDS} from "src/domain"
|
||||
import type {Zapper, RelayInfo, SessionWithMeta} from "src/engine/model"
|
||||
import {LIST_KINDS, filterRelaysByNip} from "src/domain"
|
||||
import type {Zapper, SessionWithMeta} from "src/engine/model"
|
||||
import {
|
||||
getUserCircles,
|
||||
getGroupReqInfo,
|
||||
@ -72,11 +72,9 @@ import {
|
||||
getNetwork,
|
||||
primeWotCaches,
|
||||
publish,
|
||||
getNip50Relays,
|
||||
subscribe,
|
||||
subscribePersistent,
|
||||
dufflepud,
|
||||
relays,
|
||||
getFreshness,
|
||||
setFreshness,
|
||||
sessionWithMeta,
|
||||
@ -247,6 +245,10 @@ export const createPeopleLoader = ({
|
||||
onEvent = noop,
|
||||
}: PeopleLoaderOpts = {}) => {
|
||||
const loading = writable(false)
|
||||
const nip50Relays = uniq([
|
||||
...env.SEARCH_RELAYS,
|
||||
...filterRelaysByNip(50, relays.get()).map(r => r.url),
|
||||
])
|
||||
|
||||
return {
|
||||
loading,
|
||||
@ -260,7 +262,7 @@ export const createPeopleLoader = ({
|
||||
onEvent,
|
||||
skipCache: true,
|
||||
forcePlatform: false,
|
||||
relays: getNip50Relays().slice(0, 8),
|
||||
relays: nip50Relays.slice(0, 8),
|
||||
filters: [{kinds: [0], search: term, limit: 100}],
|
||||
onComplete: async () => {
|
||||
await sleep(Math.min(1000, Date.now() - now))
|
||||
@ -557,34 +559,3 @@ export const loadHandlers = () =>
|
||||
addSinceToFilter({kinds: [HANDLER_INFORMATION]}),
|
||||
],
|
||||
})
|
||||
|
||||
export const loadRelay = batcher(800, async (urls: string[]) => {
|
||||
const urlSet = new Set(
|
||||
urls
|
||||
.map(url => normalizeRelayUrl(url))
|
||||
.filter(url => getFreshness("relay", url) < now() - 3600),
|
||||
)
|
||||
|
||||
for (const url of urlSet) {
|
||||
setFreshness("relay", url, now())
|
||||
}
|
||||
|
||||
const res = urlSet.size && (await postJson(dufflepud("relay/info"), {urls: Array.from(urlSet)}))
|
||||
const index = indexBy((item: any) => item.url, res?.data || [])
|
||||
const items: RelayInfo[] = urls.map(url => {
|
||||
const normalizedUrl = normalizeRelayUrl(url)
|
||||
const {info = {}} = index.get(normalizedUrl) || {}
|
||||
|
||||
return {...info, url: normalizedUrl, last_checked: now()}
|
||||
})
|
||||
|
||||
relays.mapStore.update($relays => {
|
||||
for (const relay of items) {
|
||||
$relays.set(relay.url, {...($relays.get(relay.url) || {}), ...relay})
|
||||
}
|
||||
|
||||
return $relays
|
||||
})
|
||||
|
||||
return items
|
||||
})
|
||||
|
@ -112,6 +112,7 @@ import {
|
||||
tracker,
|
||||
pubkey,
|
||||
sessions,
|
||||
relaysByUrl,
|
||||
} from "@welshman/app"
|
||||
import {fuzzy, synced, parseJson, fromCsv, SearchHelper} from "src/util/misc"
|
||||
import {Collection as CollectionStore} from "src/util/store"
|
||||
@ -150,7 +151,6 @@ import {
|
||||
asDecryptedEvent,
|
||||
normalizeRelayUrl,
|
||||
makeRelayPolicy,
|
||||
filterRelaysByNip,
|
||||
displayRelayUrl,
|
||||
readGroupMeta,
|
||||
displayGroupMeta,
|
||||
@ -167,7 +167,6 @@ import type {
|
||||
Topic,
|
||||
Zapper,
|
||||
AnonymousUserState,
|
||||
RelayInfo,
|
||||
} from "src/engine/model"
|
||||
import {sortEventsAsc} from "src/engine/utils"
|
||||
import {GroupAccess, OnboardingTask} from "src/engine/model"
|
||||
@ -219,7 +218,6 @@ export const groupHints = withGetter(writable<Record<string, string[]>>({}))
|
||||
export const publishes = withGetter(writable<Record<string, PublishInfo>>({}))
|
||||
|
||||
export const groups = new CollectionStore<Group>("address")
|
||||
export const relays = new CollectionStore<RelayInfo>("url")
|
||||
export const groupAdminKeys = new CollectionStore<GroupKey>("pubkey")
|
||||
export const groupSharedKeys = new CollectionStore<GroupKey>("pubkey")
|
||||
export const groupRequests = new CollectionStore<GroupRequest>("id")
|
||||
@ -1145,31 +1143,6 @@ export const channelHasNewMessages = (channel: Channel) =>
|
||||
|
||||
export const hasNewMessages = derived(channels, $channels => $channels.some(channelHasNewMessages))
|
||||
|
||||
// Relays
|
||||
|
||||
export const getRelay = url => defaultTo({url}, relays.key(url).get())
|
||||
|
||||
export const deriveRelay = url => derived(relays.key(url), defaultTo({url}))
|
||||
|
||||
export const getNip50Relays = () =>
|
||||
uniq([...env.SEARCH_RELAYS, ...filterRelaysByNip(50, relays.get()).map(r => r.url)])
|
||||
|
||||
export class RelaySearch extends SearchHelper<RelayInfo, string> {
|
||||
config = {keys: ["url", "name", "description"]}
|
||||
|
||||
getSearch = () => {
|
||||
const search = fuzzy(this.options, this.config)
|
||||
|
||||
return term => (term ? search(term) : sortBy(r => -r.count || 0, this.options))
|
||||
}
|
||||
|
||||
getValue = (option: RelayInfo) => option.url
|
||||
|
||||
displayValue = displayRelayUrl
|
||||
}
|
||||
|
||||
export const relaySearch = derived(relays, $relays => new RelaySearch($relays))
|
||||
|
||||
// Relay policies
|
||||
|
||||
export const relayListEvents = deriveEvents(repository, {filters: [{kinds: [RELAYS]}]})
|
||||
@ -1349,24 +1322,26 @@ export const hints = new Router({
|
||||
const oneHour = 60 * oneMinute
|
||||
const oneDay = 24 * oneHour
|
||||
const oneWeek = 7 * oneDay
|
||||
const {count = 0, faults = []} = relays.key(url).get() || {}
|
||||
const relay = relaysByUrl.get().get(url)
|
||||
const connect_count = relay?.stats?.connect_count || 0
|
||||
const recent_errors = relay?.stats?.recent_errors || []
|
||||
const connection = NetworkContext.pool.get(url, {autoConnect: false})
|
||||
|
||||
// If we haven't connected, consult our relay record and see if there has
|
||||
// been a recent fault. If there has been, penalize the relay. If there have been several,
|
||||
// don't use the relay.
|
||||
if (!connection) {
|
||||
const lastFault = last(faults) || 0
|
||||
const lastFault = last(recent_errors) || 0
|
||||
|
||||
if (faults.filter(n => n > Date.now() - oneHour).length > 10) {
|
||||
if (recent_errors.filter(n => n > Date.now() - oneHour).length > 10) {
|
||||
return 0
|
||||
}
|
||||
|
||||
if (faults.filter(n => n > Date.now() - oneDay).length > 50) {
|
||||
if (recent_errors.filter(n => n > Date.now() - oneDay).length > 50) {
|
||||
return 0
|
||||
}
|
||||
|
||||
if (faults.filter(n => n > Date.now() - oneWeek).length > 100) {
|
||||
if (recent_errors.filter(n => n > Date.now() - oneWeek).length > 100) {
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -1380,7 +1355,7 @@ export const hints = new Router({
|
||||
[ConnectionStatus.Closed]: 0.6,
|
||||
[ConnectionStatus.Slow]: 0.5,
|
||||
[ConnectionStatus.Ok]: 1,
|
||||
default: clamp([0.5, 1], count / 1000),
|
||||
default: clamp([0.5, 1], connect_count / 1000),
|
||||
})
|
||||
},
|
||||
})
|
||||
@ -2323,7 +2298,6 @@ export const storage = new Storage(16, [
|
||||
objectAdapter("zappers", "key", zappers, {limit: 10000}),
|
||||
objectAdapter("plaintext", "key", plaintext, {limit: 100000}),
|
||||
objectAdapter("publishes2", "id", publishes, {sort: sortBy(prop("created_at"))}),
|
||||
collectionAdapter("relays", "url", relays, {limit: 1000, sort: sortBy(prop("count"))}),
|
||||
collectionAdapter("groups", "address", groups, {limit: 1000, sort: sortBy(prop("count"))}),
|
||||
collectionAdapter("groupAlerts", "id", groupAlerts, {sort: sortBy(prop("created_at"))}),
|
||||
collectionAdapter("groupRequests", "id", groupRequests, {sort: sortBy(prop("created_at"))}),
|
||||
|
Loading…
Reference in New Issue
Block a user