This repository has been archived by the owner on Jan 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.ts
102 lines (81 loc) · 2.46 KB
/
client.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
import { Client, QueryFetcher } from "gqless";
import { useCallback, useMemo, useState } from "react";
import { Mutation, Query, schema } from "./generated";
const endpoint = "http://localhost:3000/api/graphql";
const fetchQuery: QueryFetcher = async (query, variables) => {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
query,
variables
}),
mode: "cors"
});
if (!response.ok) {
throw new Error(`Network error, received status code ${response.status}`);
}
const json = await response.json();
return json;
};
export const clientQuery = new Client<Query>(schema.Query, fetchQuery);
export const query = clientQuery.query;
type MutationState = "waiting" | "loading" | "error" | "done";
export const useMutation = <TData extends any>(
mutationFn: (schema: Client<Mutation>["query"]) => TData
): [
() => Promise<TData>,
{ state: MutationState; data: TData | undefined }
] => {
const [n, setN] = useState(0);
const [state, setState] = useState<MutationState>("waiting");
const [data, setData] = useState<TData | undefined>(undefined);
const fetchMutation = useCallback<QueryFetcher>(
async (query, variables) => {
setState("loading");
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
query: "mutation" + query,
variables
}),
mode: "cors"
});
if (!response.ok) {
setState("error");
throw new Error(
`Network error, received status code ${response.status}`
);
}
const json = await response.json();
setState("done");
return json;
},
[setState]
);
const mutationClient = useMemo<Client<Mutation>>(() => {
return new Client<Mutation>(schema.Mutation, fetchMutation);
}, [fetchMutation, n]);
const mutationCallback = useCallback<() => Promise<TData>>(async () => {
mutationFn(mutationClient.query);
await new Promise(resolve => {
mutationClient.scheduler.commit.onFetched(() => {
resolve();
});
});
const val = mutationFn(mutationClient.query);
setData(val);
setN(n => ++n);
return val;
}, [mutationClient, setData, setN]);
return useMemo(() => [mutationCallback, { state, data }], [
mutationCallback,
state,
data
]);
};