Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/lib/hooks/api.ts
1453 views
1
import { useEffect, useRef, useState } from "react";
2
import apiPost from "lib/api/post";
3
import useIsMounted from "./mounted";
4
import { delay } from "awaiting";
5
6
interface Options {
7
endpoint: string;
8
params?: object;
9
cache_s?: number;
10
}
11
12
export default function useAPI(
13
endpoint?: string,
14
params?: object,
15
cache_s?: number,
16
) {
17
const [counter, setCounter] = useState<number>(0);
18
const [error, setError] = useState<string>("");
19
const [result, setResult] = useState<any>(undefined);
20
const [calling, setCalling] = useState<boolean>(false);
21
const queue = useRef<Options[]>([]);
22
const isMounted = useIsMounted();
23
24
async function call(
25
endpoint1: string | undefined = endpoint,
26
params1: object | undefined = params,
27
cache_s1: number | undefined = cache_s,
28
): Promise<any> {
29
if (endpoint1 == undefined) return;
30
if (calling) {
31
queue.current.push({
32
endpoint: endpoint1,
33
params: params1,
34
cache_s: cache_s1,
35
});
36
return;
37
}
38
setCalling(true);
39
let result;
40
try {
41
setError("");
42
result = await apiPost(endpoint1, params1, cache_s);
43
} catch (err) {
44
if (!isMounted.current) return;
45
setCalling(false);
46
setError(`${err}`);
47
setResult({ error: err });
48
queue.current = [];
49
return;
50
}
51
if (!isMounted.current) return;
52
setCalling(false);
53
setResult(result);
54
if (queue.current.length > 0) {
55
const next = queue.current.shift();
56
if (next == null) return;
57
const { endpoint, params, cache_s } = next;
58
if (!isMounted.current) return;
59
await delay(1);
60
call(endpoint, params, cache_s);
61
}
62
}
63
64
useEffect(() => {
65
if (endpoint) {
66
call(endpoint, params, cache_s);
67
}
68
}, [counter, endpoint + JSON.stringify(params)]);
69
70
return {
71
error,
72
result,
73
calling,
74
call,
75
refresh: () => {
76
setCounter(counter + 1);
77
},
78
};
79
}
80
81