UNPKG

@leancodepl/hook-pipe-client

Version:

React hooks for real-time data streaming and subscriptions using @leancodepl/pipe

50 lines (47 loc) 1.85 kB
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 };