-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuse-lazy-query.ts
129 lines (116 loc) · 3.62 KB
/
use-lazy-query.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { useCallback, useState } from "react";
import {
useQuery,
Variables,
QueryOptions,
QueryResult,
QueryOptionsWithVariables,
BaseQueryResult,
} from "./use-query";
export type LazyQueryOptions<TData> = Omit<QueryOptions<TData>, "skip">;
export type LazyQueryOptionsWithVariables<
TData,
TVariables extends Variables
> = Omit<QueryOptionsWithVariables<TData, TVariables>, "skip">;
export interface QueryOptionsWithMaybeVariables<
TData,
TVariables extends Variables
> extends QueryOptions<TData> {
variables?: TVariables;
}
export type LazyQueryOptionsWithPartialVariables<
TData,
TPartialVariables extends Variables
> = Omit<QueryOptionsWithMaybeVariables<TData, TPartialVariables>, "skip">;
export type LazyQueryResult<TData, TVariables extends Variables> = [
(
options?:
| {
variables: TVariables;
}
| undefined
) => Promise<QueryResult<TData, TVariables> & { called?: boolean }>,
QueryResult<TData, TVariables> & { called?: boolean }
];
export interface QueryResultVariablesRequiredInRefetch<
TData,
TVariables extends Variables = Variables
> extends BaseQueryResult<TData> {
refetch: (
variables: TVariables
) => Promise<QueryResultVariablesRequiredInRefetch<TData, TVariables>>;
}
export type LazyQueryResultVariablesRequiredInRefetch<
TData,
TVariables extends Variables
> = [
(
options?:
| {
variables: TVariables;
}
| undefined
) => Promise<QueryResult<TData, TVariables> & { called?: boolean }>,
QueryResultVariablesRequiredInRefetch<TData, TVariables> & {
called?: boolean;
}
];
// Query has no variables
export function useLazyQuery<TData>(
query: () => Promise<TData>,
options?: LazyQueryOptions<TData>
): LazyQueryResult<TData, never>;
// Query has variables and they are all supplied in options
export function useLazyQuery<TData, TVariables extends Variables>(
query: (variables: TVariables) => Promise<TData>,
options: LazyQueryOptionsWithVariables<TData, TVariables>
): LazyQueryResult<TData, TVariables>;
// Query has variables variables, they are not all supplied in initial options
export function useLazyQuery<
TData,
TVariables extends Variables,
TPartialVariables extends Partial<TVariables> = TVariables
>(
query: (variables: TVariables) => Promise<TData>,
options?: LazyQueryOptionsWithPartialVariables<TData, TPartialVariables>
): LazyQueryResultVariablesRequiredInRefetch<TData, TVariables>;
export function useLazyQuery<TData, TVariables extends Variables>(
query: (variables?: TVariables) => Promise<TData>,
options?:
| LazyQueryOptionsWithVariables<TData, TVariables>
| LazyQueryOptions<TData>
| LazyQueryOptionsWithPartialVariables<TData, TVariables>
):
| LazyQueryResult<TData, TVariables>
| LazyQueryResultVariablesRequiredInRefetch<TData, TVariables> {
const [execution, setExecution] = useState<{
called: boolean;
options?: { variables: TVariables };
}>({
called: false,
});
let result: QueryResult<TData, TVariables> & { called?: boolean } = useQuery<
TData,
TVariables
>(query, Object.assign({}, options, execution.options, { skip: true }));
if (!execution.called) {
result = {
...result,
called: false,
};
}
const execute = useCallback(
(executeOptions?: { variables: TVariables }) => {
setExecution({ called: true, options: executeOptions });
return result.refetch(executeOptions?.variables).then((newResult) => ({
...result,
data: newResult.data,
error: newResult.error,
called: true,
loading: false,
}));
},
[result]
);
return [execute, result];
}