CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/lib/hooks/api.ts
Views: 687
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 [error, setError] = useState<string>("");
18
const [result, setResult] = useState<any>(undefined);
19
const [calling, setCalling] = useState<boolean>(false);
20
const queue = useRef<Options[]>([]);
21
const isMounted = useIsMounted();
22
23
async function call(
24
endpoint1: string | undefined = endpoint,
25
params1: object | undefined = params,
26
cache_s1: number | undefined = cache_s
27
): Promise<any> {
28
if (endpoint1 == undefined) return;
29
if (calling) {
30
queue.current.push({
31
endpoint: endpoint1,
32
params: params1,
33
cache_s: cache_s1,
34
});
35
return;
36
}
37
setCalling(true);
38
let result;
39
try {
40
result = await apiPost(endpoint1, params1, cache_s);
41
} catch (err) {
42
if (!isMounted.current) return;
43
setCalling(false);
44
setError(`${err}`);
45
setResult({ error: err });
46
queue.current = [];
47
return;
48
}
49
if (!isMounted.current) return;
50
setCalling(false);
51
setResult(result);
52
if (queue.current.length > 0) {
53
const next = queue.current.shift();
54
if (next == null) return;
55
const { endpoint, params, cache_s } = next;
56
if (!isMounted.current) return;
57
await delay(1);
58
call(endpoint, params, cache_s);
59
}
60
}
61
62
useEffect(() => {
63
if (endpoint) {
64
call(endpoint, params, cache_s);
65
}
66
}, [endpoint + JSON.stringify(params)]);
67
68
return { error, result, calling, call };
69
}
70
71