@hyper-fetch/react
Version:
React hooks and utils for the hyper-fetch
84 lines (69 loc) • 2.44 kB
text/typescript
import type { EmitterInstance, EmitterCallbackErrorType, EmitType } from "@hyper-fetch/sockets";
import { useDidUpdate } from "@better-hooks/lifecycle";
import { useRef } from "react";
import type { UseEmitterOptionsType } from "hooks/use-emitter";
import { useSocketState } from "helpers";
import { useProvider } from "provider";
import { createTrackedProxy } from "utils";
/** Send messages through a socket emitter with tracked connection state and lifecycle callbacks. */
export const useEmitter = <EmitterType extends EmitterInstance>(
emitter: EmitterType,
options?: UseEmitterOptionsType,
) => {
const { config: globalConfig } = useProvider();
const { dependencyTracking } = { ...globalConfig.useEmitter, ...options };
const [state, actions, callbacks, { setRenderKey }] = useSocketState(emitter.socket, { dependencyTracking });
/**
* Callbacks
*/
const onEventStartCallback = useRef<null | ((emitter: EmitterType) => void)>(null);
const onEventErrorCallback = useRef<null | EmitterCallbackErrorType>(null);
useDidUpdate(
() => {
const onEventStart = () => {
return emitter.socket.events.onEmitterStartEventByTopic(emitter, () => {
onEventStartCallback.current?.(emitter);
});
};
const onEventError = () => {
return emitter.socket.events.onEmitterErrorByTopic(emitter, ({ error }) => {
onEventErrorCallback.current?.({ error });
});
};
const unmountEventStart = onEventStart();
const unmountEventError = onEventError();
return () => {
unmountEventStart();
unmountEventError();
};
},
[emitter.topic, onEventStartCallback.current, onEventErrorCallback.current],
true,
);
/**
* Emitter
*/
const emit: EmitType<EmitterType> = (emitOptions: Parameters<EmitType<EmitterType>>[0]) => {
return emitter.emit(emitOptions as any);
};
const onEmit = (callback: (emitter: EmitterType) => void) => {
onEventStartCallback.current = callback;
};
const onEmitError = (callback: EmitterCallbackErrorType) => {
onEventErrorCallback.current = callback;
};
const trackedKeys = ["connected", "connecting"] as const;
return createTrackedProxy(
{
connected: state.connected,
connecting: state.connecting,
...actions,
...callbacks,
onEmit,
onEmitError,
emit,
},
trackedKeys,
setRenderKey,
);
};