forked from coracle/flotilla
176 lines
4.2 KiB
TypeScript
176 lines
4.2 KiB
TypeScript
import {get} from 'svelte/store'
|
|
import type {SignedEvent} from '@welshman/util'
|
|
import {batcher, uniq, now, postJson, assoc} from "@welshman/lib"
|
|
import {normalizeRelayUrl, PROFILE, FOLLOWS, MUTES, GROUP_META} from "@welshman/util"
|
|
import {subscribe} from "@welshman/net"
|
|
import type {RelayInfo, HandleInfo, Session} from "@app/types"
|
|
import {splitGroupId} from "@app/domain"
|
|
import {DUFFLEPUD_URL, INDEXER_RELAYS, repository, pk, sessions} from "@app/base"
|
|
import {relayInfo, handleInfo, groupsById, profilesByPubkey, mutesByPubkey} from "@app/state"
|
|
|
|
// Session
|
|
|
|
export const addSession = (session: Session) => {
|
|
sessions.update(assoc(session.pubkey, session))
|
|
pk.set(session.pubkey)
|
|
}
|
|
|
|
// Handle info
|
|
|
|
export const loadHandleInfo = batcher(800, async (handles: string[]) => {
|
|
const res = await postJson(`${DUFFLEPUD_URL}/handle/info`, {handles: uniq(handles)})
|
|
const data: {handle: string, info: HandleInfo}[] = res?.data || []
|
|
|
|
handleInfo.update($handleInfo => {
|
|
for (const {handle, info} of data) {
|
|
$handleInfo.set(handle, {...info, fetched_at: now()})
|
|
}
|
|
|
|
return $handleInfo
|
|
})
|
|
|
|
return data.map(item => item.info)
|
|
})
|
|
|
|
export const getHandleInfo = (handle: string) => {
|
|
const info = get(handleInfo).get(handle)
|
|
|
|
if (info?.fetched_at > now() - 3600) {
|
|
return info
|
|
}
|
|
|
|
return loadHandleInfo(handle)
|
|
}
|
|
|
|
// Relay info
|
|
|
|
export const loadRelayInfo = batcher(800, async (urls: string[]) => {
|
|
const res = await postJson(`${DUFFLEPUD_URL}/relay/info`, {urls: uniq(urls)})
|
|
const data: {url: string, info: RelayInfo}[] = res?.data || []
|
|
|
|
relayInfo.update($relayInfo => {
|
|
for (const {url, info} of data) {
|
|
$relayInfo.set(normalizeRelayUrl(url), {...info, fetched_at: now()})
|
|
}
|
|
|
|
return $relayInfo
|
|
})
|
|
|
|
return data.map(item => item.info)
|
|
})
|
|
|
|
export const getRelayInfo = (url: string) => {
|
|
const info = get(relayInfo).get(url)
|
|
|
|
if (info?.fetched_at > now() - 3600) {
|
|
return info
|
|
}
|
|
|
|
return loadRelayInfo(url)
|
|
}
|
|
|
|
// Group meta
|
|
|
|
export const getGroup = (groupId: string) => {
|
|
const group = get(groupsById).get(groupId)
|
|
|
|
if (group?.event.fetched_at > now() - 3600) {
|
|
return group
|
|
}
|
|
|
|
const [url, nom] = splitGroupId(groupId)
|
|
|
|
const sub = subscribe({
|
|
relays: [url],
|
|
filters: [{kinds: [GROUP_META], '#d': [groupId]}],
|
|
closeOnEose: true,
|
|
})
|
|
|
|
sub.emitter.on('event', (url: string, e: SignedEvent) => {
|
|
e.fetched_at = now()
|
|
repository.publish(e)
|
|
console.log(e)
|
|
})
|
|
}
|
|
|
|
// Profile
|
|
|
|
export const getProfile = (pubkey: string, relays = []) => {
|
|
const profile = get(profilesByPubkey).get(pubkey)
|
|
|
|
if (profile?.event.fetched_at > now() - 3600) {
|
|
return profile
|
|
}
|
|
|
|
return new Promise(resolve => {
|
|
const sub = subscribe({
|
|
relays: [...relays, ...INDEXER_RELAYS],
|
|
filters: [{kinds: [PROFILE], authors: [pubkey]}],
|
|
closeOnEose: true,
|
|
})
|
|
|
|
sub.emitter.on('event', (url: string, e: SignedEvent) => {
|
|
e.fetched_at = now()
|
|
repository.publish(e)
|
|
console.log(e)
|
|
resolve(e)
|
|
})
|
|
|
|
sub.emitter.on('close', () => resolve(null))
|
|
})
|
|
}
|
|
|
|
// Follows
|
|
|
|
export const getFollows = (pubkey: string, relays = []) => {
|
|
const follows = get(followsByPubkey).get(pubkey)
|
|
|
|
if (follows?.event.fetched_at > now() - 3600) {
|
|
return follows
|
|
}
|
|
|
|
return new Promise(resolve => {
|
|
const sub = subscribe({
|
|
relays: [...relays, ...INDEXER_RELAYS],
|
|
filters: [{kinds: [FOLLOWS], authors: [pubkey]}],
|
|
closeOnEose: true,
|
|
})
|
|
|
|
sub.emitter.on('event', (url: string, e: SignedEvent) => {
|
|
e.fetched_at = now()
|
|
repository.publish(e)
|
|
console.log(e)
|
|
resolve(e)
|
|
})
|
|
|
|
sub.emitter.on('close', () => resolve(null))
|
|
})
|
|
}
|
|
|
|
// Mutes
|
|
|
|
export const getMutes = (pubkey: string, relays = []) => {
|
|
const mutes = get(mutesByPubkey).get(pubkey)
|
|
|
|
if (mutes?.event.fetched_at > now() - 3600) {
|
|
return mutes
|
|
}
|
|
|
|
return new Promise(resolve => {
|
|
const sub = subscribe({
|
|
relays: [...relays, ...INDEXER_RELAYS],
|
|
filters: [{kinds: [MUTES], authors: [pubkey]}],
|
|
closeOnEose: true,
|
|
})
|
|
|
|
sub.emitter.on('event', (url: string, e: SignedEvent) => {
|
|
e.fetched_at = now()
|
|
repository.publish(e)
|
|
console.log(e)
|
|
resolve(e)
|
|
})
|
|
|
|
sub.emitter.on('close', () => resolve(null))
|
|
})
|
|
}
|