@@ -31,24 +31,25 @@ import { useApolloClient } from './useApolloClient'
3131 */
3232export type UseFragmentOptions < TData = unknown , TVariables extends OperationVariables = OperationVariables > = {
3333 /**
34- * An object containing a `__typename` and primary key fields (such as `id`)
35- * identifying the entity object from which the fragment will be retrieved,
36- * or a `{ __ref: "..." }` reference, or a `string` ID (uncommon).
34+ * Entity identifier to read the fragment from.
35+ * Can be an object with __typename and id, a cache reference, or a string ID.
36+ *
37+ * @example
38+ * ```ts
39+ * from: { __typename: 'User', id: '123' }
40+ * from: computed(() => ({ __typename: 'User', id: userId.value }))
41+ * from: 'User:123'
42+ * ```
3743 */
3844 from : MaybeRefOrGetter < FragmentType < NoInfer < TData > > | Reference | StoreObject | string >
3945
4046 /**
41- * A GraphQL document created using the `gql` template string tag from
42- * `graphql-tag` with one or more fragments which will be used to determine
43- * the shape of data to read. If you provide more than one fragment in this
44- * document then you must also specify `fragmentName` to select a single.
47+ * GraphQL fragment document.
4548 */
4649 fragment : DocumentNode | TypedDocumentNode < TData , TVariables >
4750
4851 /**
49- * The name of the fragment in your GraphQL document to be used. If you do
50- * not provide a `fragmentName` and there is only one fragment in your
51- * `fragment` document, then that fragment will be used.
52+ * Fragment name (required if document has multiple fragments).
5253 */
5354 fragmentName ?: string
5455
@@ -61,12 +62,7 @@ export type UseFragmentOptions<TData = unknown, TVariables extends OperationVari
6162 *
6263 * @example
6364 * ```ts
64- * const shouldWatch = ref(false)
65- * useFragment({
66- * fragment: USER_FRAGMENT,
67- * from: { __typename: 'User', id: '123' },
68- * enabled: shouldWatch
69- * })
65+ * enabled: computed(() => isVisible.value)
7066 * ```
7167 */
7268 enabled ?: MaybeRefOrGetter < boolean >
@@ -81,156 +77,46 @@ export type UseFragmentOptions<TData = unknown, TVariables extends OperationVari
8177 prefetch ?: boolean
8278
8379 /**
84- * Any variables that the GraphQL fragment may depend on .
80+ * Fragment variables.
8581 */
8682 variables ?: MaybeRefOrGetter < NoInfer < TVariables > >
8783
8884 /**
8985 * Whether to read from optimistic or non-optimistic cache data.
9086 *
91- * @defaultValue true
87+ * @default true
9288 */
9389 optimistic ?: boolean
9490} & UseBaseOption
9591
96- /**
97- * Result type for useFragment composable
98- */
99- export type UseFragmentResult < TData , TCompleted extends boolean = boolean > = {
100- complete : TCompleted
101- missing ?: TCompleted extends true ? never : MissingTree
102- } & GetDataState < MaybeMasked < TData > , TCompleted extends true ? 'complete' : 'partial' >
92+ /** Fragment result with completion status and data */
93+ export type UseFragmentResult < TData >
94+ = | ( {
95+ complete : false
96+ missing ?: MissingTree
97+ } & GetDataState < MaybeMasked < TData > , 'partial' > )
98+ | ( {
99+ complete : true
100+ missing ?: never
101+ } & GetDataState < MaybeMasked < TData > , 'complete' > )
103102
104103/**
105104 * Composable for reading GraphQL fragments from Apollo Cache with Vue reactivity.
106- * Provides a lightweight live binding into the Apollo Client Cache and automatically
107- * updates when the fragment data changes.
105+ * Provides a lightweight live binding and automatically updates when fragment data changes.
108106 *
109107 * @template TData - Type of the fragment result data
110108 * @template TVariables - Type of the fragment variables
111109 *
112- * @param options - Fragment options including document, from identifier, and other settings
110+ * @param options - Fragment options including document, from identifier, and settings
113111 *
114112 * @returns Object containing fragment state and control methods
115113 *
116- * @remarks
117- * **Important Notes:**
118- * - This composable reads data synchronously from the cache (no network requests)
119- * - Uses internal Apollo Client APIs (`getFragmentDoc`, `transform`, `maskFragment`)
120- * - Automatically restarts when `from` or `variables` change
121- * - Must be called within a Vue component setup or effect scope
122- *
123- * **Performance Tips:**
124- * - Use `computed` for reactive `from` and `variables` instead of `ref` + watchers
125- * - Set `enabled: false` when fragment is not needed to avoid unnecessary subscriptions
126- * - Use `shallowRef` when storing fragment data in parent component
127- * - Fragment reads are cached by Apollo, so multiple reads are efficient
128- *
129- * @example
130- * Basic usage with type narrowing (recommended):
131- * ```ts
132- * const userId = ref('123')
133- * const { result } = useFragment({
134- * fragment: gql`
135- * fragment UserFields on User {
136- * id
137- * name
138- * email
139- * }
140- * `,
141- * from: computed(() => ({ __typename: 'User', id: userId.value })),
142- * fragmentName: 'UserFields'
143- * })
144- *
145- * // TypeScript type narrowing works correctly
146- * watchEffect(() => {
147- * if (result.value?.complete) {
148- * // data is non-optional, missing is never
149- * console.log(result.value.data.name) // ✅ Type-safe
150- * }
151- * })
152- * ```
153- *
154114 * @example
155- * Convenience usage (less type-safe but more ergonomic):
156115 * ```ts
157116 * const { data, complete } = useFragment({
158- * fragment: USER_FRAGMENT ,
117+ * fragment: gql`fragment UserFields on User { id name email }` ,
159118 * from: { __typename: 'User', id: '123' }
160119 * })
161- *
162- * // Still need optional chaining
163- * watchEffect(() => {
164- * if (complete.value) {
165- * console.log(data.value?.name) // ⚠️ Still optional
166- * }
167- * })
168- * ```
169- *
170- * @example
171- * Handling null/missing data:
172- * ```ts
173- * const userId = ref<string | null>(null)
174- * const { data, complete, missing } = useFragment({
175- * fragment: USER_FRAGMENT,
176- * from: computed(() =>
177- * userId.value ? { __typename: 'User', id: userId.value } : null
178- * )
179- * })
180- *
181- * // Check if data is available
182- * watchEffect(() => {
183- * if (data.value) {
184- * console.log('User data:', data.value)
185- * } else if (!complete.value && missing.value) {
186- * console.warn('Incomplete data:', missing.value)
187- * }
188- * })
189- * ```
190- *
191- * @example
192- * Error handling:
193- * ```ts
194- * const { data, error, onError } = useFragment({
195- * fragment: USER_FRAGMENT,
196- * from: { __typename: 'User', id: '123' }
197- * })
198- *
199- * onError((err, context) => {
200- * console.error('Fragment error:', err.message)
201- * // Handle error (show toast, log to service, etc.)
202- * })
203- * ```
204- *
205- * @example
206- * Conditional watching with enabled:
207- * ```ts
208- * const isVisible = ref(false)
209- * const { data, start, stop } = useFragment({
210- * fragment: USER_FRAGMENT,
211- * from: { __typename: 'User', id: '123' },
212- * enabled: isVisible
213- * })
214- *
215- * // Or manually control:
216- * // enabled: false
217- * // Then call start() when needed
218- * ```
219- *
220- * @example
221- * With variables:
222- * ```ts
223- * const locale = ref('en')
224- * const { data } = useFragment({
225- * fragment: gql`
226- * fragment UserWithLocale on User {
227- * id
228- * name(locale: $locale)
229- * }
230- * `,
231- * from: { __typename: 'User', id: '123' },
232- * variables: computed(() => ({ locale: locale.value }))
233- * })
234120 * ```
235121 */
236122export function useFragment < TData = unknown , TVariables extends OperationVariables = OperationVariables > (
@@ -436,25 +322,14 @@ export function useFragment<TData = unknown, TVariables extends OperationVariabl
436322
437323 return {
438324 /**
439- * Whether the fragment data is complete (all fields were found in cache).
440- *
441- * **Note: ** For better type narrowing, use `result.value?.complete` instead.
442- * @see result
325+ * Whether all fragment fields were found in cache.
443326 */
444327 complete : computed ( ( ) => result . value ?. complete ?? false ) ,
445328
446329 /**
447330 * The fragment result data.
448331 * Can be undefined if no data has been loaded yet or if `from` is null.
449- *
450- * **Note: ** For better type safety, use `result.value` with type narrowing:
451- * ```ts
452- * if (result.value?.complete) {
453- * // result.value.data is non-optional here
454- * console.log(result.value.data.name)
455- * }
456- * ```
457- * @see result
332+ * For better type safety, use `result` with type narrowing.
458333 */
459334 data : computed ( ( ) => result . value ?. data ) ,
460335
@@ -465,9 +340,6 @@ export function useFragment<TData = unknown, TVariables extends OperationVariabl
465340
466341 /**
467342 * A tree of all MissingFieldError messages reported during fragment reading.
468- *
469- * **Note: ** For better type narrowing, use `result.value?.missing` instead.
470- * @see result
471343 */
472344 missing : computed ( ( ) => result . value ?. missing ) ,
473345
@@ -485,6 +357,7 @@ export function useFragment<TData = unknown, TVariables extends OperationVariabl
485357
486358 /**
487359 * Event hook that fires when new fragment results are received.
360+ * Only fires when actual data is present (not undefined).
488361 *
489362 * @example
490363 * ```ts
@@ -497,39 +370,20 @@ export function useFragment<TData = unknown, TVariables extends OperationVariabl
497370
498371 /**
499372 * The full fragment result including data, complete status, and missing info.
500- *
501- * **Recommended: ** Use this for better TypeScript type narrowing.
373+ * Use this for better TypeScript type narrowing.
502374 *
503375 * @example
504- * Type-safe access with narrowing:
505376 * ```ts
506- * const { result } = useFragment<User>(...)
507- *
508- * // TypeScript knows data is complete and non-optional
509377 * if (result.value?.complete) {
510- * console.log(result.value.data.name) // ✅ No optional chaining needed
511- * // result.value.missing is never
512- * } else {
513- * console.log(result.value?.data?.name) // ⚠️ Partial data
514- * console.log(result.value?.missing) // ✅ Available
515- * }
516- * ```
517- *
518- * @example
519- * Convenience access (less type-safe):
520- * ```ts
521- * const { data, complete } = useFragment<User>(...)
522- *
523- * // Still need optional chaining even when complete is true
524- * if (complete.value) {
525- * console.log(data.value?.name) // ⚠️ Still optional
378+ * console.log(result.value.data.name) // No optional chaining needed
526379 * }
527380 * ```
528381 */
529382 result,
530383
531384 /**
532385 * Manually start watching the fragment.
386+ * Useful after stopping the fragment or when using enabled: false initially.
533387 *
534388 * @example
535389 * ```ts
@@ -546,6 +400,7 @@ export function useFragment<TData = unknown, TVariables extends OperationVariabl
546400
547401 /**
548402 * Stop watching the fragment and unsubscribe from updates.
403+ * Useful for pausing fragments or cleaning up manually.
549404 *
550405 * @example
551406 * ```ts
0 commit comments