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 { import {type AppBskyActorDefs} from '@atproto/api'
type AppBskyActorDefs,
type AppBskyGraphGetKnownFollowers,
} from '@atproto/api'
import { import {
type InfiniteData, type InfiniteData,
type QueryClient, type QueryClient,
@@ -9,7 +6,8 @@ import {
useInfiniteQuery, useInfiniteQuery,
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {useAgent} from '#/state/session' import {useAppviewClient} from '#/state/session'
import {app} from '#/lexicons'
const PAGE_SIZE = 50 const PAGE_SIZE = 50
type RQPageParam = string | undefined type RQPageParam = string | undefined
@@ -18,22 +16,22 @@ const RQKEY_ROOT = 'profile-known-followers'
export const RQKEY = (did: string) => [RQKEY_ROOT, did] export const RQKEY = (did: string) => [RQKEY_ROOT, did]
export function useProfileKnownFollowersQuery(did: string | undefined) { export function useProfileKnownFollowersQuery(did: string | undefined) {
const agent = useAgent() const client = useAppviewClient()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetKnownFollowers.OutputSchema, app.bsky.graph.getKnownFollowers.$OutputBody,
Error, Error,
InfiniteData<AppBskyGraphGetKnownFollowers.OutputSchema>, InfiniteData<app.bsky.graph.getKnownFollowers.$OutputBody>,
QueryKey, QueryKey,
RQPageParam RQPageParam
>({ >({
queryKey: RQKEY(did || ''), queryKey: RQKEY(did || ''),
async queryFn({pageParam}: {pageParam: RQPageParam}) { async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await agent.app.bsky.graph.getKnownFollowers({ return await client.call(app.bsky.graph.getKnownFollowers, {
actor: did!, // the enabled flag prevents this from running until did is set
actor: did! as app.bsky.graph.getKnownFollowers.$Params['actor'],
limit: PAGE_SIZE, limit: PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
}) })
return res.data
}, },
initialPageParam: undefined, initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor, getNextPageParam: lastPage => lastPage.cursor,
@@ -46,7 +44,7 @@ export function* findAllProfilesInQueryData(
did: string, did: string,
): Generator<AppBskyActorDefs.ProfileView, void> { ): Generator<AppBskyActorDefs.ProfileView, void> {
const queryDatas = queryClient.getQueriesData< const queryDatas = queryClient.getQueriesData<
InfiniteData<AppBskyGraphGetKnownFollowers.OutputSchema> InfiniteData<app.bsky.graph.getKnownFollowers.$OutputBody>
>({ >({
queryKey: [RQKEY_ROOT], queryKey: [RQKEY_ROOT],
}) })
+17 -14
View File
@@ -1,7 +1,4 @@
import { import {type AppBskyActorDefs} from '@atproto/api'
type AppBskyActorDefs,
type AppBskyGraphGetFollowers,
} from '@atproto/api'
import { import {
type InfiniteData, type InfiniteData,
type QueryClient, type QueryClient,
@@ -9,8 +6,9 @@ import {
useInfiniteQuery, useInfiniteQuery,
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {useAgent} from '#/state/session' import {useAppviewClient} from '#/state/session'
import {useAnalytics} from '#/analytics' import {useAnalytics} from '#/analytics'
import {app} from '#/lexicons'
const DEFAULT_SORT = 'latest' const DEFAULT_SORT = 'latest'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@@ -33,26 +31,31 @@ export function useProfileFollowersQuery(
) { ) {
const ax = useAnalytics() const ax = useAnalytics()
const isSortEnabled = ax.features.enabled(ax.features.FollowSortEnable) const isSortEnabled = ax.features.enabled(ax.features.FollowSortEnable)
const agent = useAgent() const client = useAppviewClient()
const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetFollowers.OutputSchema, app.bsky.graph.getFollowers.$OutputBody,
Error, Error,
InfiniteData<AppBskyGraphGetFollowers.OutputSchema>, InfiniteData<app.bsky.graph.getFollowers.$OutputBody>,
QueryKey, QueryKey,
RQPageParam RQPageParam
>({ >({
queryKey: RQKEY(did || '', sortParam), queryKey: RQKEY(did || '', sortParam),
async queryFn({pageParam}: {pageParam: RQPageParam}) { 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, limit: PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
sort: sortParam, ...(sortParam ? {sort: sortParam} : {}),
}) } as app.bsky.graph.getFollowers.$Params)
return res.data
}, },
initialPageParam: undefined, initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor, getNextPageParam: lastPage => lastPage.cursor,
@@ -65,7 +68,7 @@ export function* findAllProfilesInQueryData(
did: string, did: string,
): Generator<AppBskyActorDefs.ProfileView, void> { ): Generator<AppBskyActorDefs.ProfileView, void> {
const queryDatas = queryClient.getQueriesData< const queryDatas = queryClient.getQueriesData<
InfiniteData<AppBskyGraphGetFollowers.OutputSchema> InfiniteData<app.bsky.graph.getFollowers.$OutputBody>
>({ >({
queryKey: [RQKEY_ROOT], 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 { import {
type InfiniteData, type InfiniteData,
type QueryClient, type QueryClient,
@@ -7,8 +7,9 @@ import {
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {useAgent} from '#/state/session' import {useAppviewClient} from '#/state/session'
import {useAnalytics} from '#/analytics' import {useAnalytics} from '#/analytics'
import {app} from '#/lexicons'
const DEFAULT_SORT = 'latest' const DEFAULT_SORT = 'latest'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@@ -34,27 +35,32 @@ export function useProfileFollowsQuery(
) { ) {
const ax = useAnalytics() const ax = useAnalytics()
const isSortEnabled = ax.features.enabled(ax.features.FollowSortEnable) const isSortEnabled = ax.features.enabled(ax.features.FollowSortEnable)
const agent = useAgent() const client = useAppviewClient()
const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetFollows.OutputSchema, app.bsky.graph.getFollows.$OutputBody,
Error, Error,
InfiniteData<AppBskyGraphGetFollows.OutputSchema>, InfiniteData<app.bsky.graph.getFollows.$OutputBody>,
QueryKey, QueryKey,
RQPageParam RQPageParam
>({ >({
staleTime: STALE.MINUTES.ONE, staleTime: STALE.MINUTES.ONE,
queryKey: RQKEY(did || '', sortParam), queryKey: RQKEY(did || '', sortParam),
async queryFn({pageParam}: {pageParam: RQPageParam}) { 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, limit: limit || PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
sort: sortParam, ...(sortParam ? {sort: sortParam} : {}),
}) } as app.bsky.graph.getFollows.$Params)
return res.data
}, },
initialPageParam: undefined, initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor, getNextPageParam: lastPage => lastPage.cursor,
@@ -67,7 +73,7 @@ export function* findAllProfilesInQueryData(
did: string, did: string,
): Generator<AppBskyActorDefs.ProfileView, void> { ): Generator<AppBskyActorDefs.ProfileView, void> {
const queryDatas = queryClient.getQueriesData< const queryDatas = queryClient.getQueriesData<
InfiniteData<AppBskyGraphGetFollows.OutputSchema> InfiniteData<app.bsky.graph.getFollows.$OutputBody>
>({ >({
queryKey: [RQKEY_ROOT], queryKey: [RQKEY_ROOT],
}) })