@idiosync/react-observable
Version:
State management control layer for React projects
64 lines (63 loc) • 2.44 kB
JavaScript
;
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;