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
|
import { useCallback, useEffect, useMemo, useState } from "react";
import { getHost } from "~/utils";
import {
Historic,
ReadyState,
Request,
RequestPayload,
RequestResponse,
Response,
ResponsePayload,
WebsocketType,
} from "~/types";
export interface useRequestsProps {
onConnect: () => Promise<void>;
}
export interface UseRequests {
calls: RequestResponse[];
readyState: ReadyState;
clear: () => void;
}
export default function useRequests({
onConnect,
}: useRequestsProps): UseRequests {
const wsHost = useMemo(getHost, []);
const [initialConnection, setInitialConnection] = useState(true);
const [requests, setRequests] = useState<RequestPayload[]>([]);
const [responses, setResponses] = useState<ResponsePayload[]>([]);
const [websocketFrames, setWebsocketFrames] =
useState<WebsocketType["payload"]>();
const connect = useCallback(
() => new WebSocket(`ws://${wsHost}/inspect/`),
[wsHost]
);
const [ws, setWs] = useState<WebSocket>(() => connect());
const [readyState, setReadyState] = useState<ReadyState>(ws.readyState);
useEffect(() => {
setReadyState(ws.readyState);
const onClose = () => {
setReadyState(ws.readyState);
setWs(connect());
};
const onOpen = () => {
onConnect();
setInitialConnection(false);
setReadyState(ws.readyState);
};
const onMessage = ({ data }) => {
const { type, payload } = JSON.parse(data) as
| Historic
| Request
| Response;
console.debug(type, payload);
switch (type) {
case "historic":
if (initialConnection) {
const requests = (payload as (Request | Response)[]).filter(
({ type }) => type === "request"
);
const responses = (payload as (Request | Response)[]).filter(
({ type }) => type === "response"
);
setRequests((rqs) => [
...rqs,
...requests.map(({ payload }) => payload as RequestPayload),
]);
setResponses((rps) => [
...rps,
...responses.map(({ payload }) => payload as ResponsePayload),
]);
}
break;
case "request":
setRequests((rqs) => [...rqs, payload as RequestPayload]);
break;
case "response":
setResponses((rps) => [...rps, payload as ResponsePayload]);
break;
}
};
ws.addEventListener("message", onMessage);
ws.addEventListener("close", onClose);
ws.addEventListener("open", onOpen);
return () => {
ws.removeEventListener("message", onMessage);
ws.removeEventListener("close", onClose);
ws.removeEventListener("open", onOpen);
};
}, [ws]);
return {
calls: useMemo<RequestResponse[]>(
() =>
requests.map((request) => ({
request: request,
response: responses.find(({ id }) => id === request.id),
})),
[requests, responses]
),
readyState,
clear: () => {
setRequests([]);
setResponses([]);
},
};
}
|