@leancodepl/hook-pipe-client
Version:
React hooks for real-time data streaming and subscriptions using @leancodepl/pipe
50 lines (47 loc) • 1.85 kB
JavaScript
import { useState, useRef, useEffect } from 'react';
import deepEqual from 'deep-equal';
import { share } from 'rxjs';
/**
* Creates React hooks for real-time data subscriptions using "@leancodepl/pipe".
*
* @param pipe - Pipe instance from "@leancodepl/pipe"
* @returns Object containing `createTopic` method for creating typed hooks
* @example
* ```typescript
* const pipe = createPipe({ url: 'wss://api.example.com/pipe' });
* const pipeClient = mkPipeClient({ pipe });
*
* const useChatTopic = pipeClient.createTopic('chat');
* ```
*/ function mkPipeClient({ pipe }) {
return {
createTopic (topicType) {
function useTopic(topic, { onData }) {
const [data, setData] = useState();
const onDataRef = useRef(onData);
onDataRef.current = onData;
const memoizedTopic = useRef();
if (memoizedTopic.current === undefined || !deepEqual(memoizedTopic.current, topic)) {
memoizedTopic.current = topic;
}
useEffect(()=>{
const topic$ = pipe.topic(topicType, memoizedTopic.current).pipe(share());
const subscription = topic$.subscribe((data)=>{
setData(data);
onDataRef.current == null ? void 0 : onDataRef.current.call(onDataRef, data);
});
return ()=>subscription.unsubscribe();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
memoizedTopic.current
]);
return {
data
};
}
useTopic.topic = (topic)=>pipe.topic(topicType, topic);
return useTopic;
}
};
}
export { mkPipeClient };