import { type InfiniteData, keepPreviousData, type QueryClient, type QueryKey, useInfiniteQuery, } from '@tanstack/react-query' import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' import {app} from '#/lexicons' export const RQKEY_ROOT = 'actor-search' export const RQKEY = (query: string, limit?: number) => [ RQKEY_ROOT, query, limit, ] export function useActorSearch({ query, enabled, maintainData, limit = 25, }: { query: string enabled?: boolean maintainData?: boolean limit?: number }) { const client = useAppviewClient() return useInfiniteQuery< app.bsky.actor.searchActors.$OutputBody, Error, InfiniteData, QueryKey, string | undefined >({ staleTime: STALE.MINUTES.FIVE, queryKey: RQKEY(query, limit), queryFn: async ({pageParam}) => { return await client.call(app.bsky.actor.searchActors, { q: query, limit, cursor: pageParam, }) }, enabled: enabled && !!query, initialPageParam: undefined, getNextPageParam: lastPage => lastPage.cursor, placeholderData: maintainData ? keepPreviousData : undefined, select, }) } function select(data: InfiniteData) { // enforce uniqueness const dids = new Set() return { ...data, pages: data.pages.map(page => ({ actors: page.actors.filter(actor => { if (dids.has(actor.did)) { return false } dids.add(actor.did) return true }), })), } } export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, ) { const queryDatas = queryClient.getQueriesData< InfiniteData >({ queryKey: [RQKEY_ROOT], }) for (const [_queryKey, queryData] of queryDatas) { if (!queryData) { continue } for (const actor of queryData.pages.flatMap(page => page.actors)) { if (actor.did === did) { yield actor } } } }