diff --git a/lib/tunnelbroker/tunnelbroker-context.js b/lib/tunnelbroker/tunnelbroker-context.js new file mode 100644 --- /dev/null +++ b/lib/tunnelbroker/tunnelbroker-context.js @@ -0,0 +1,80 @@ +// @flow + +import invariant from 'invariant'; +import * as React from 'react'; + +import { type TunnelbrokerMessage } from '../types/tunnelbroker/messages.js'; +import type { ConnectionInitializationMessage } from '../types/tunnelbroker/session-types.js'; + +export type ClientMessageToDevice = { + +deviceID: string, + +payload: string, +}; + +export type TunnelbrokerSocketListener = ( + message: TunnelbrokerMessage, +) => mixed; + +type TunnelbrokerContextType = { + +sendMessage: (message: ClientMessageToDevice) => Promise, + +addListener: (listener: TunnelbrokerSocketListener) => void, + +removeListener: (listener: TunnelbrokerSocketListener) => void, + +connected: boolean, +}; + +const TunnelbrokerContext: React.Context = + React.createContext(); + +type Props = { + +children: React.Node, + +initMessage: ?ConnectionInitializationMessage, +}; + +function TunnelbrokerProvider(props: Props): React.Node { + const { children } = props; + const [connected] = React.useState(false); + const listeners = React.useRef>(new Set()); + + const sendMessage: () => Promise = React.useCallback(() => { + return new Promise(() => {}); + }, []); + + const addListener = React.useCallback( + (listener: TunnelbrokerSocketListener) => { + listeners.current.add(listener); + }, + [], + ); + + const removeListener = React.useCallback( + (listener: TunnelbrokerSocketListener) => { + listeners.current.delete(listener); + }, + [], + ); + + const value: TunnelbrokerContextType = React.useMemo( + () => ({ + sendMessage, + connected, + addListener, + removeListener, + }), + [addListener, connected, removeListener, sendMessage], + ); + + return ( + + {children} + + ); +} + +function useTunnelbroker(): TunnelbrokerContextType { + const context = React.useContext(TunnelbrokerContext); + invariant(context, 'TunnelbrokerContext not found'); + + return context; +} + +export { TunnelbrokerProvider, useTunnelbroker };