openpanel/packages/devtools-shared/src/context.tsx
Stefan Pejcic 8595a9f4e5 back
2024-05-08 19:58:53 +02:00

90 lines
2.1 KiB
TypeScript

import React from "react";
import { DevtoolsEvent } from "./event-types";
import { send } from "./send";
import { receive } from "./receive";
type DevToolsContextValue = {
__devtools: boolean;
port: number;
url: string;
secure: boolean;
ws: WebSocket | null;
devtoolsUrl?: string;
};
export const DevToolsContext = React.createContext<DevToolsContextValue>({
__devtools: false,
port: 5002,
url: "localhost",
secure: false,
ws: null,
});
type Props = React.PropsWithChildren<
Partial<Pick<DevToolsContextValue, "port" | "__devtools">>
>;
export const DevToolsContextProvider: React.FC<Props> = ({
__devtools,
port,
children,
}) => {
const [values, setValues] = React.useState<DevToolsContextValue>({
__devtools: __devtools ?? false,
port: port ?? 5002,
url: "localhost",
secure: false,
ws: null,
});
const [ws, setWs] = React.useState<WebSocket | null>(null);
React.useEffect(() => {
const wsInstance = new WebSocket(
`${values.secure ? "wss" : "ws"}://localhost:${values.port}`,
);
const unsubscribe = receive(
wsInstance,
DevtoolsEvent.DEVTOOLS_HANDSHAKE,
(data) => {
setValues((v) => ({
...v,
devtoolsUrl: data.url,
}));
unsubscribe();
},
);
wsInstance.addEventListener("open", () => {
if (!values.__devtools) {
send(wsInstance, DevtoolsEvent.DEVTOOLS_INIT, {
url: window.location.origin,
});
}
});
setWs(wsInstance);
return () => {
unsubscribe();
wsInstance.close(1000, window.location.origin);
};
}, []);
const contextValues = React.useMemo<DevToolsContextValue>(
() => ({
...values,
ws,
}),
[values, ws],
);
return (
<DevToolsContext.Provider value={contextValues}>
{children}
</DevToolsContext.Provider>
);
};