diff --git a/src/useQuery.ts b/src/useQuery.ts index ed37f5f..4b9d896 100644 --- a/src/useQuery.ts +++ b/src/useQuery.ts @@ -1,6 +1,6 @@ import stringify from 'fast-json-stable-stringify'; import { inject, isReactive, isRef, onMounted, Ref, ref, watch } from 'vue-demi'; -import { CachePolicy, MaybeReactive, Operation, QueryVariables } from './types'; +import { CachePolicy, MaybeReactive, Operation, OperationResult, QueryVariables } from './types'; import { Client } from './client'; import { hash, CombinedError, toWatchableSource } from './utils'; @@ -11,18 +11,37 @@ interface QueryCompositeOptions { lazy?: boolean; } -function _useQuery({ query, variables, cachePolicy }: QueryCompositeOptions) { +interface QueryExecutionOpts { + cachePolicy?: CachePolicy; +} + +interface QueryComposable { + data: Ref; + error: Ref; + fetching: Ref; + done: Ref; + execute: (opts?: QueryExecutionOpts) => Promise>; + pause: () => void; + paused: Ref; + resume: () => void; +} + +function _useQuery({ + query, + variables, + cachePolicy, +}: QueryCompositeOptions): QueryComposable { const client = inject('$villus') as Client; if (!client) { throw new Error('Cannot detect villus Client, did you forget to call `useClient`?'); } - const data = ref(null); + const data: Ref = ref(null); const fetching = ref(false); const done = ref(false); const error: Ref = ref(null); - async function execute(overrideOpts: { cachePolicy?: CachePolicy } = {}) { + async function execute(overrideOpts: QueryExecutionOpts = {}) { fetching.value = true; const vars = (isRef(variables) ? variables.value : variables) || {}; const res = await client.executeQuery({ @@ -31,7 +50,7 @@ function _useQuery({ query, variables, cachePolicy }: QueryComposi cachePolicy: overrideOpts?.cachePolicy || cachePolicy, }); - data.value = res.data; + data.value = res.data as TData; error.value = res.error; done.value = true; fetching.value = false; @@ -88,12 +107,17 @@ function _useQuery({ query, variables, cachePolicy }: QueryComposi return { data, fetching, done, error, execute, pause, paused, resume }; } -type QueryComposable = ReturnType; +function useQuery( + query: QueryCompositeOptions['query'], + variables?: QueryCompositeOptions['variables'] +): QueryComposable; + +function useQuery(query: QueryCompositeOptions): QueryComposable; function useQuery( opts: QueryCompositeOptions | QueryCompositeOptions['query'], variables?: QueryCompositeOptions['variables'] -): QueryComposable { +): QueryComposable { const normalizedOpts = normalizeOptions(opts, variables); const api = _useQuery(normalizedOpts); // Fetch on mounted if lazy is disabled. @@ -109,11 +133,11 @@ function useQuery( function useQueryAsync( query: QueryCompositeOptions['query'], variables?: QueryCompositeOptions['variables'] -): Promise; +): Promise>; function useQueryAsync( query: QueryCompositeOptions -): Promise; +): Promise>; async function useQueryAsync( opts: QueryCompositeOptions | QueryCompositeOptions['query'], diff --git a/test/useQuery.spec.ts b/test/useQuery.spec.ts index 46231f8..1938176 100644 --- a/test/useQuery.spec.ts +++ b/test/useQuery.spec.ts @@ -13,7 +13,7 @@ test('executes hook queries on mounted', async () => { url: 'https://test.com/graphql', }); - const { data, error } = useQuery<{ posts: Post[] }>({ query: '{ posts { id title } }' }); + const { data, error } = useQuery<{ posts: Post[] }>('{ posts { id title } }'); return { data, error }; },