feat: replace user search service
This commit is contained in:
parent
400da44543
commit
b6cb701ff1
5 changed files with 86 additions and 84 deletions
|
|
@ -1031,18 +1031,6 @@ class ClientService extends EventTarget {
|
|||
|
||||
/** =========== Profile =========== */
|
||||
|
||||
async searchProfiles(relayUrls: string[], filter: Filter): Promise<TProfile[]> {
|
||||
const events = await this.query(relayUrls, {
|
||||
...filter,
|
||||
kinds: [kinds.Metadata]
|
||||
})
|
||||
|
||||
const profileEvents = events.sort((a, b) => b.created_at - a.created_at)
|
||||
await Promise.allSettled(profileEvents.map((profile) => this.addUsernameToIndex(profile)))
|
||||
profileEvents.forEach((profile) => this.updateProfileEventCache(profile))
|
||||
return profileEvents.map((profileEvent) => getProfileFromEvent(profileEvent))
|
||||
}
|
||||
|
||||
async searchNpubsFromLocal(query: string, limit: number = 100) {
|
||||
const result = await this.userIndex.searchAsync(query, { limit })
|
||||
return result.map((pubkey) => pubkeyToNpub(pubkey as string)).filter(Boolean) as string[]
|
||||
|
|
@ -1170,7 +1158,10 @@ class ClientService extends EventTarget {
|
|||
}
|
||||
|
||||
async updateProfileEventCache(event: NEvent) {
|
||||
await this.updateReplaceableEventFromBigRelaysCache(event)
|
||||
await Promise.allSettled([
|
||||
this.updateReplaceableEventFromBigRelaysCache(event),
|
||||
this.addUsernameToIndex(event)
|
||||
])
|
||||
}
|
||||
|
||||
/** =========== Relay list =========== */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { getProfileFromEvent } from '@/lib/event-metadata'
|
||||
import { userIdToPubkey } from '@/lib/pubkey'
|
||||
import { TProfile } from '@/types'
|
||||
import DataLoader from 'dataloader'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import client from './client.service'
|
||||
|
||||
const SERVICE_URL = 'https://fayan.jumble.social'
|
||||
|
||||
class FayanService {
|
||||
static instance: FayanService
|
||||
|
|
@ -7,7 +13,7 @@ class FayanService {
|
|||
private userPercentileDataLoader = new DataLoader<string, number | null>(
|
||||
async (pubkeys) => {
|
||||
try {
|
||||
const res = await fetch(`https://fayan.jumble.social/users`, {
|
||||
const res = await fetch(`${SERVICE_URL}/users`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
|
|
@ -30,6 +36,7 @@ class FayanService {
|
|||
}
|
||||
}
|
||||
)
|
||||
private searchResultCache: Map<string, TProfile[]> = new Map()
|
||||
|
||||
constructor() {
|
||||
if (!FayanService.instance) {
|
||||
|
|
@ -42,6 +49,50 @@ class FayanService {
|
|||
async fetchUserPercentile(userId: string): Promise<number | null> {
|
||||
return await this.userPercentileDataLoader.load(userId)
|
||||
}
|
||||
|
||||
async searchUsers(query: string, limit = 20, offset = 0) {
|
||||
const cache = this.searchResultCache.get(query)
|
||||
if (cache) {
|
||||
if (offset + limit <= cache.length) {
|
||||
console.log('FayanService searchUsers returning from cache')
|
||||
return cache.slice(offset, offset + limit)
|
||||
}
|
||||
}
|
||||
try {
|
||||
const url = new URL('/search', SERVICE_URL)
|
||||
url.searchParams.append('q', query)
|
||||
url.searchParams.append('limit', limit.toString())
|
||||
if (offset > 0) {
|
||||
url.searchParams.append('offset', offset.toString())
|
||||
}
|
||||
|
||||
const res = await fetch(url.toString())
|
||||
if (!res.ok) {
|
||||
return []
|
||||
}
|
||||
const data = (await res.json()) as { event: NostrEvent; percentile: number }[]
|
||||
const profiles: TProfile[] = []
|
||||
data.forEach(({ event, percentile }) => {
|
||||
const profile = getProfileFromEvent(event)
|
||||
profiles.push(profile)
|
||||
this.userPercentileDataLoader.prime(profile.pubkey, percentile)
|
||||
client.updateProfileEventCache(event)
|
||||
})
|
||||
|
||||
// Cache the results
|
||||
const existingCache = this.searchResultCache.get(query) || []
|
||||
if (offset === 0) {
|
||||
this.searchResultCache.set(query, profiles)
|
||||
} else if (offset <= existingCache.length) {
|
||||
const newCache = existingCache.slice(0, offset).concat(profiles)
|
||||
this.searchResultCache.set(query, newCache)
|
||||
}
|
||||
|
||||
return profiles
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new FayanService()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue