migrate the follows and followers queries to the appview client

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-08-03 15:13:11 +03:00
parent 6ef3628155
commit 8d738b891f
3 changed files with 44 additions and 37 deletions
+10 -12
View File
@@ -1,7 +1,4 @@
import {
type AppBskyActorDefs,
type AppBskyGraphGetKnownFollowers,
} from '@atproto/api'
import {type AppBskyActorDefs} from '@atproto/api'
import {
type InfiniteData,
type QueryClient,
@@ -9,7 +6,8 @@ import {
useInfiniteQuery,
} from '@tanstack/react-query'
import {useAgent} from '#/state/session'
import {useAppviewClient} from '#/state/session'
import {app} from '#/lexicons'
const PAGE_SIZE = 50
type RQPageParam = string | undefined
@@ -18,22 +16,22 @@ const RQKEY_ROOT = 'profile-known-followers'
export const RQKEY = (did: string) => [RQKEY_ROOT, did]
export function useProfileKnownFollowersQuery(did: string | undefined) {
const agent = useAgent()
const client = useAppviewClient()
return useInfiniteQuery<
AppBskyGraphGetKnownFollowers.OutputSchema,
app.bsky.graph.getKnownFollowers.$OutputBody,
Error,
InfiniteData<AppBskyGraphGetKnownFollowers.OutputSchema>,
InfiniteData<app.bsky.graph.getKnownFollowers.$OutputBody>,
QueryKey,
RQPageParam
>({
queryKey: RQKEY(did || ''),
async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await agent.app.bsky.graph.getKnownFollowers({
actor: did!,
return await client.call(app.bsky.graph.getKnownFollowers, {
// the enabled flag prevents this from running until did is set
actor: did! as app.bsky.graph.getKnownFollowers.$Params['actor'],
limit: PAGE_SIZE,
cursor: pageParam,
})
return res.data
},
initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor,
@@ -46,7 +44,7 @@ export function* findAllProfilesInQueryData(
did: string,
): Generator<AppBskyActorDefs.ProfileView, void> {
const queryDatas = queryClient.getQueriesData<
InfiniteData<AppBskyGraphGetKnownFollowers.OutputSchema>
InfiniteData<app.bsky.graph.getKnownFollowers.$OutputBody>
>({
queryKey: [RQKEY_ROOT],
})
+17 -14
View File
@@ -1,7 +1,4 @@
import {
type AppBskyActorDefs,
type AppBskyGraphGetFollowers,
} from '@atproto/api'
import {type AppBskyActorDefs} from '@atproto/api'
import {
type InfiniteData,
type QueryClient,
@@ -9,8 +6,9 @@ import {
useInfiniteQuery,
} from '@tanstack/react-query'
import {useAgent} from '#/state/session'
import {useAppviewClient} from '#/state/session'
import {useAnalytics} from '#/analytics'
import {app} from '#/lexicons'
const DEFAULT_SORT = 'latest'
const PAGE_SIZE = 30
@@ -33,26 +31,31 @@ export function useProfileFollowersQuery(
) {
const ax = useAnalytics()
const isSortEnabled = ax.features.enabled(ax.features.FollowSortEnable)
const agent = useAgent()
const client = useAppviewClient()
const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined
return useInfiniteQuery<
AppBskyGraphGetFollowers.OutputSchema,
app.bsky.graph.getFollowers.$OutputBody,
Error,
InfiniteData<AppBskyGraphGetFollowers.OutputSchema>,
InfiniteData<app.bsky.graph.getFollowers.$OutputBody>,
QueryKey,
RQPageParam
>({
queryKey: RQKEY(did || '', sortParam),
async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await agent.app.bsky.graph.getFollowers({
actor: did || '',
/*
* The vendored lexicon does not declare `sort`, so it is spread in only
* when set and the whole params object is asserted. lex forwards
* undeclared params verbatim but rejects an undeclared key whose value
* is `undefined`, hence the conditional spread.
*/
return await client.call(app.bsky.graph.getFollowers, {
actor: (did || '') as app.bsky.graph.getFollowers.$Params['actor'],
limit: PAGE_SIZE,
cursor: pageParam,
sort: sortParam,
})
return res.data
...(sortParam ? {sort: sortParam} : {}),
} as app.bsky.graph.getFollowers.$Params)
},
initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor,
@@ -65,7 +68,7 @@ export function* findAllProfilesInQueryData(
did: string,
): Generator<AppBskyActorDefs.ProfileView, void> {
const queryDatas = queryClient.getQueriesData<
InfiniteData<AppBskyGraphGetFollowers.OutputSchema>
InfiniteData<app.bsky.graph.getFollowers.$OutputBody>
>({
queryKey: [RQKEY_ROOT],
})
+17 -11
View File
@@ -1,4 +1,4 @@
import {type AppBskyActorDefs, type AppBskyGraphGetFollows} from '@atproto/api'
import {type AppBskyActorDefs} from '@atproto/api'
import {
type InfiniteData,
type QueryClient,
@@ -7,8 +7,9 @@ import {
} from '@tanstack/react-query'
import {STALE} from '#/state/queries'
import {useAgent} from '#/state/session'
import {useAppviewClient} from '#/state/session'
import {useAnalytics} from '#/analytics'
import {app} from '#/lexicons'
const DEFAULT_SORT = 'latest'
const PAGE_SIZE = 30
@@ -34,27 +35,32 @@ export function useProfileFollowsQuery(
) {
const ax = useAnalytics()
const isSortEnabled = ax.features.enabled(ax.features.FollowSortEnable)
const agent = useAgent()
const client = useAppviewClient()
const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined
return useInfiniteQuery<
AppBskyGraphGetFollows.OutputSchema,
app.bsky.graph.getFollows.$OutputBody,
Error,
InfiniteData<AppBskyGraphGetFollows.OutputSchema>,
InfiniteData<app.bsky.graph.getFollows.$OutputBody>,
QueryKey,
RQPageParam
>({
staleTime: STALE.MINUTES.ONE,
queryKey: RQKEY(did || '', sortParam),
async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await agent.app.bsky.graph.getFollows({
actor: did || '',
/*
* The vendored lexicon does not declare `sort`, so it is spread in only
* when set and the whole params object is asserted. lex forwards
* undeclared params verbatim but rejects an undeclared key whose value
* is `undefined`, hence the conditional spread.
*/
return await client.call(app.bsky.graph.getFollows, {
actor: (did || '') as app.bsky.graph.getFollows.$Params['actor'],
limit: limit || PAGE_SIZE,
cursor: pageParam,
sort: sortParam,
})
return res.data
...(sortParam ? {sort: sortParam} : {}),
} as app.bsky.graph.getFollows.$Params)
},
initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor,
@@ -67,7 +73,7 @@ export function* findAllProfilesInQueryData(
did: string,
): Generator<AppBskyActorDefs.ProfileView, void> {
const queryDatas = queryClient.getQueriesData<
InfiniteData<AppBskyGraphGetFollows.OutputSchema>
InfiniteData<app.bsky.graph.getFollows.$OutputBody>
>({
queryKey: [RQKEY_ROOT],
})