Created
June 25, 2025 12:43
-
-
Save dralletje/e8f1fc622ae2b4d4965bd4d56abffa04 to your computer and use it in GitHub Desktop.
`useFragment` composable for Vue & Apollo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Reference, StoreObject, TypedDocumentNode } from '@apollo/client'; | |
/** | |
* Returns an always-up-to-date view of whatever data the cache currently contains for a given fragment and useFragment | |
* never triggers network requests of its own. | |
* | |
* Based on https://www.apollographql.com/docs/react/api/react/hooks#usefragment code at https://github.com/apollographql/apollo-client/blob/a8fe0a1217d9784d3165e0ec2e88a2caca0f82d7/src/react/hooks/useFragment.ts#L1-L108 | |
* | |
* I've taken this from https://github.com/vuejs/apollo/issues/1510 with a bit more tweaks from the apollo react codebase. | |
* | |
* @param fragment | |
* @param from | |
* @param fragmentName | |
*/ | |
export function useFragment<TResult = unknown, TVariables = unknown>( | |
fragment: TypedDocumentNode<TResult, TVariables>, | |
from: MaybeRefOrGetter<StoreObject | Reference | string | null | undefined>, | |
fragmentName?: string, | |
) { | |
const { client } = useApolloClient(); | |
const data = shallowRef<TResult | undefined>(undefined); | |
const complete = shallowRef<boolean>(false); | |
let unsubscribe: (() => void) | undefined = undefined; | |
watchEffect(() => { | |
const unwrappedFrom = toValue(from); | |
// Remove our previous subscription | |
if (unsubscribe !== undefined) { | |
unsubscribe(); | |
} | |
// If we have a from that is not "empty" we good! | |
if (unwrappedFrom !== undefined && unwrappedFrom !== null) { | |
unsubscribe = client.cache.watch<TResult, TVariables>({ | |
returnPartialData: true, | |
immediate: true, | |
id: typeof unwrappedFrom === 'string' ? unwrappedFrom : client.cache.identify(unwrappedFrom), | |
// eslint-disable-next-line @typescript-eslint/dot-notation | |
query: client.cache['getFragmentDoc'](fragment, fragmentName), // This is private, lol! | |
optimistic: false, | |
callback(diff) { | |
// TODO: There is more to this I think: https://github.com/apollographql/apollo-client/blob/a8fe0a1217d9784d3165e0ec2e88a2caca0f82d7/src/react/hooks/useFragment.ts#L77-L82 | |
data.value = diff.result; | |
complete.value = diff.complete ?? false; | |
}, | |
}); | |
} | |
}); | |
return { data: data, complete: complete }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment