Clean up unstable profile cache

This commit is contained in:
Eric Bailey
2025-01-07 15:50:29 -06:00
parent 283a647539
commit e0344434c9
3 changed files with 67 additions and 49 deletions
+12 -35
View File
@@ -23,6 +23,10 @@ import {logEvent, LogEvents, toClout} from '#/lib/statsig/statsig'
import {Shadow} from '#/state/cache/types'
import {STALE} from '#/state/queries'
import {resetProfilePostsQueries} from '#/state/queries/post-feed'
import {
unstableCacheProfileView,
useUnstableProfileViewCache,
} from '#/state/queries/unstable-profile-cache'
import * as userActionHistory from '#/state/userActionHistory'
import * as atp from '#/types/atproto'
import {updateProfileShadow} from '../cache/profile-shadow'
@@ -35,6 +39,12 @@ import {RQKEY as RQKEY_LIST_CONVOS} from './messages/list-conversations'
import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts'
import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts'
export * from '#/state/queries/unstable-profile-cache'
/**
* @deprecated use {@link unstableCacheProfileView} instead
*/
export const precacheProfile = unstableCacheProfileView
const RQKEY_ROOT = 'profile'
export const RQKEY = (did: string) => [RQKEY_ROOT, did]
@@ -44,16 +54,6 @@ export const profilesQueryKey = (handles: string[]) => [
handles,
]
const unstableProfileViewCacheQueryKeyRoot = 'unstableProfileViewCache'
/**
* We cache multiple profile view types by this query key. If object shapes are
* important, you should validate the type when accessing the data.
*/
export const unstableProfileViewCacheQueryKey = (didOrHandle: string) => [
unstableProfileViewCacheQueryKeyRoot,
didOrHandle,
]
export function useProfileQuery({
did,
staleTime = STALE.SECONDS.FIFTEEN,
@@ -61,8 +61,8 @@ export function useProfileQuery({
did: string | undefined
staleTime?: number
}) {
const queryClient = useQueryClient()
const agent = useAgent()
const {getUnstableProfile} = useUnstableProfileViewCache()
return useQuery<AppBskyActorDefs.ProfileViewDetailed>({
// WARNING
// this staleTime is load-bearing
@@ -77,11 +77,7 @@ export function useProfileQuery({
},
placeholderData: () => {
if (!did) return
// This can return any profile view type
return queryClient.getQueryData<atp.profile.AnyProfileView>(
unstableProfileViewCacheQueryKey(did),
) as AppBskyActorDefs.ProfileViewDetailed
return getUnstableProfile(did) as AppBskyActorDefs.ProfileViewDetailed
},
enabled: !!did,
})
@@ -512,25 +508,6 @@ function useProfileUnblockMutation() {
})
}
/**
* This function is used to precache a profile view in the query client. Any
* profile view type is accepted, so you should validate the type when
* accessing the data.
*/
export function precacheProfile(
queryClient: QueryClient,
profile: atp.profile.AnyProfileView,
) {
queryClient.setQueryData(
unstableProfileViewCacheQueryKey(profile.handle),
profile,
)
queryClient.setQueryData(
unstableProfileViewCacheQueryKey(profile.did),
profile,
)
}
async function whenAppViewReady(
agent: BskyAgent,
actor: string,
+4 -14
View File
@@ -1,15 +1,9 @@
import {AtUri} from '@atproto/api'
import {
QueryClient,
useQuery,
useQueryClient,
UseQueryResult,
} from '@tanstack/react-query'
import {QueryClient, useQuery, UseQueryResult} from '@tanstack/react-query'
import {STALE} from '#/state/queries'
import {useAgent} from '#/state/session'
import * as atp from '#/types/atproto'
import {unstableProfileViewCacheQueryKey} from './profile'
import {useUnstableProfileViewCache} from './profile'
const RQKEY_ROOT = 'resolved-did'
export const RQKEY = (didOrHandle: string) => [RQKEY_ROOT, didOrHandle]
@@ -29,8 +23,8 @@ export function useResolveUriQuery(uri: string | undefined): UriUseQueryResult {
}
export function useResolveDidQuery(didOrHandle: string | undefined) {
const queryClient = useQueryClient()
const agent = useAgent()
const {getUnstableProfile} = useUnstableProfileViewCache()
return useQuery<string, Error>({
staleTime: STALE.HOURS.ONE,
@@ -46,11 +40,7 @@ export function useResolveDidQuery(didOrHandle: string | undefined) {
initialData: () => {
// Return undefined if no did or handle
if (!didOrHandle) return
// This can return any profile view type
const profile = queryClient.getQueryData<atp.profile.AnyProfileView>(
unstableProfileViewCacheQueryKey(didOrHandle),
)
const profile = getUnstableProfile(didOrHandle)
return profile?.did
},
enabled: !!didOrHandle,
@@ -0,0 +1,51 @@
import {useCallback} from 'react'
import {QueryClient,useQueryClient} from '@tanstack/react-query'
import * as atp from '#/types/atproto'
const unstableProfileViewCacheQueryKeyRoot = 'unstableProfileViewCache'
export const unstableProfileViewCacheQueryKey = (didOrHandle: string) => [
unstableProfileViewCacheQueryKeyRoot,
didOrHandle,
]
/**
* Used as a rough cache of profile views to make loading snappier. This method
* accepts and stores any profile view type by both handle and DID.
*
* Access the cache via {@link useUnstableProfileViewCache}.
*/
export function unstableCacheProfileView(
queryClient: QueryClient,
profile: atp.profile.AnyProfileView,
) {
queryClient.setQueryData(
unstableProfileViewCacheQueryKey(profile.handle),
profile,
)
queryClient.setQueryData(
unstableProfileViewCacheQueryKey(profile.did),
profile,
)
}
/**
* Hook to access the unstable profile view cache. This cache can return ANY
* profile view type, so if the object shape is important, you need to use the
* identity validators shipped in the atproto SDK e.g.
* `AppBskyActorDefs.isValidProfileViewBasic` to confirm before using.
*
* To cache a profile, use {@link unstableCacheProfileView}.
*/
export function useUnstableProfileViewCache() {
const qc = useQueryClient()
const getUnstableProfile = useCallback(
(didOrHandle: string) => {
return qc.getQueryData<atp.profile.AnyProfileView>(
unstableProfileViewCacheQueryKey(didOrHandle),
)
},
[qc],
)
return {getUnstableProfile}
}