@towns-protocol/react-sdk
Version:
React Hooks for Towns Protocol SDK
56 lines • 1.93 kB
JavaScript
'use client';
import { useCallback, useEffect, useMemo, useSyncExternalStore } from 'react';
import { isPersistedModel } from './internals/utils';
/**
* This hook subscribes to an observable and returns the value of the observable.
* @param observable - The observable to subscribe to.
* @param config - Configuration options for the observable.
* @returns The value of the observable.
*/
export function useObservable(observable, config) {
const opts = useMemo(() => ({ fireImmediately: true, ...config }), [config]);
const subscribeFn = useCallback((subFn) => {
return observable.subscribe(subFn, {
fireImediately: opts?.fireImmediately,
});
}, [observable, opts?.fireImmediately]);
const value = useSyncExternalStore(subscribeFn, () => observable.value);
useEffect(() => {
if (isPersistedModel(value)) {
if (value.status === 'loaded') {
opts.onUpdate?.(value.data);
}
if (value.status === 'error') {
opts.onError?.(value.error);
}
}
else {
opts.onUpdate?.(value);
}
}, [opts, value]);
const data = useMemo(() => {
if (isPersistedModel(value)) {
const { data, status } = value;
return {
data: data,
error: status === 'error' ? value.error : undefined,
status,
isLoading: status === 'loading',
isError: status === 'error',
isLoaded: status === 'loaded',
};
}
else {
return {
data: value,
error: undefined,
status: 'loaded',
isLoading: false,
isError: false,
isLoaded: true,
};
}
}, [value]);
return data;
}
//# sourceMappingURL=useObservable.js.map