diff options
Diffstat (limited to 'src/hooks')
| -rw-r--r-- | src/hooks/useRequests.tsx | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/hooks/useRequests.tsx b/src/hooks/useRequests.tsx new file mode 100644 index 0000000..3ad5cc7 --- /dev/null +++ b/src/hooks/useRequests.tsx | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | import {useCallback, useEffect, useMemo, useState} from "react"; | ||
| 2 | import {getHost} from "../utils"; | ||
| 3 | |||
| 4 | type Dict = { | ||
| 5 | [key: string]: string | ||
| 6 | } | ||
| 7 | |||
| 8 | export interface RequestPayload { | ||
| 9 | id: string | ||
| 10 | body: string | ||
| 11 | cookies: Dict | ||
| 12 | headers: Dict | ||
| 13 | method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | ||
| 14 | path: string | ||
| 15 | } | ||
| 16 | |||
| 17 | interface Request { | ||
| 18 | type: 'request', | ||
| 19 | payload: RequestPayload, | ||
| 20 | } | ||
| 21 | |||
| 22 | export interface ResponsePayload { | ||
| 23 | id: string | ||
| 24 | timing: number | ||
| 25 | body: string | ||
| 26 | cookies: Dict | ||
| 27 | headers: Dict | ||
| 28 | status: number | ||
| 29 | } | ||
| 30 | |||
| 31 | interface Response { | ||
| 32 | type: 'response', | ||
| 33 | payload: ResponsePayload, | ||
| 34 | } | ||
| 35 | |||
| 36 | export interface RequestResponse { | ||
| 37 | request: RequestPayload | ||
| 38 | response?: ResponsePayload | ||
| 39 | } | ||
| 40 | |||
| 41 | export default function useRequests(): RequestResponse[] { | ||
| 42 | const wsHost = useMemo(getHost, []); | ||
| 43 | const connect = useCallback(() => new WebSocket(`ws://${wsHost}/inspect/`), [wsHost]) | ||
| 44 | |||
| 45 | const [requests, setRequests] = useState<RequestPayload[]>([]); | ||
| 46 | const [responses, setResponses] = useState<ResponsePayload[]>([]); | ||
| 47 | const [ws, setWs] = useState(() => connect()); | ||
| 48 | |||
| 49 | useEffect(() => { | ||
| 50 | const reconnect = () => setWs(() => connect()) | ||
| 51 | const onMessage = ({ data }) => { | ||
| 52 | const { type, payload } = JSON.parse(data) as Request | Response | ||
| 53 | |||
| 54 | switch (type) { | ||
| 55 | case 'request': | ||
| 56 | setRequests((rqs) => [...rqs, payload as RequestPayload]) | ||
| 57 | break | ||
| 58 | case 'response': | ||
| 59 | setResponses((rps) => [...rps, payload as ResponsePayload]) | ||
| 60 | break | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | ws.addEventListener('message', onMessage) | ||
| 65 | ws.addEventListener('close', reconnect) | ||
| 66 | |||
| 67 | return () => { | ||
| 68 | ws.removeEventListener('message', onMessage); | ||
| 69 | ws.removeEventListener('close', reconnect); | ||
| 70 | } | ||
| 71 | }, [ws]) | ||
| 72 | |||
| 73 | return useMemo<RequestResponse[]>(() => requests.map((request) => ({ | ||
| 74 | request: request, | ||
| 75 | response: responses.find(({ id }) => id === request.id) | ||
| 76 | })), [requests, responses]) | ||
| 77 | } | ||
