UNPKG

@idiosync/react-observable

Version:

State management control layer for React projects

64 lines (63 loc) 2.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useEffectStream = void 0; const react_1 = require("react"); const use_equality_checker_1 = require("./use-equality-checker"); const observable_1 = require("../factories/observable"); const use_store_proxy_1 = require("./use-store-proxy"); const general_1 = require("../utils/general"); const useEffectStream = (initialise, inputs) => { const ref = (0, react_1.useRef)(undefined); const subscriptionsRef = (0, react_1.useRef)([]); const entry$ = (0, react_1.useRef)(undefined); if (!entry$.current) { const name = (0, general_1.getCallsiteName)(); entry$.current = (0, observable_1.createObservable)({ name, emitWhenValuesAreEqual: true, initialValue: inputs, }); } const handleSubscription = (0, react_1.useCallback)((unsubscribe) => { subscriptionsRef.current.push(unsubscribe); }, []); // Get store proxy - this will throw if no provider is available const observableStoreProxy = (0, use_store_proxy_1.useStoreProxy)(handleSubscription); if (!ref.current) { ref.current = initialise({ $: entry$.current, store: observableStoreProxy, }); } const isEqual = (0, use_equality_checker_1.useEqualityChecker)(inputs); if (!isEqual) { entry$.current.set(inputs); } const [data, setData] = (0, react_1.useState)(ref.current.get); (0, react_1.useEffect)(() => { if (!ref.current) throw new Error('No observable found'); const isDev = (0, general_1.isDevEnv)(); const sub = ref.current.subscribeWithValue((newData) => { setData(newData); }, (error) => { if (isDev) { console.error('Error in useEffectStream', error); } }, (stack) => { if (isDev) { console.log('Stream halted', stack); } }); return () => { sub === null || sub === void 0 ? void 0 : sub(); subscriptionsRef.current.forEach((unsub) => unsub()); subscriptionsRef.current.length = 0; }; }, []); const execute = (0, react_1.useCallback)(() => { entry$.current.emit(); }, []); return (0, react_1.useMemo)(() => [data, execute], [data, execute]); }; exports.useEffectStream = useEffectStream;