UNPKG

@towns-protocol/react-sdk

Version:

React Hooks for Towns Protocol SDK

56 lines 1.93 kB
'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