UNPKG

react-rx

Version:
1 lines 8.13 kB
{"version":3,"file":"index.cjs","sources":["../src/useObservable.ts","../src/useObservableEvent.ts"],"sourcesContent":["import {useCallback, useMemo, useSyncExternalStore} from 'react'\nimport {\n asapScheduler,\n catchError,\n finalize,\n type Observable,\n type ObservedValueOf,\n of,\n share,\n timer,\n} from 'rxjs'\nimport {map, tap} from 'rxjs/operators'\n\nfunction getValue<T>(value: T): T extends () => infer U ? U : T {\n return (typeof value === 'function' ? (value as () => any)() : value) as T extends () => infer U\n ? U\n : T\n}\n\ninterface ObservableState<T> {\n didEmit: boolean\n snapshot?: T\n error?: unknown\n}\n\ninterface CacheRecord<T> {\n observable: Observable<void>\n state: {\n didEmit: boolean\n snapshot?: T\n error?: unknown\n }\n getSnapshot: (initialValue: unknown) => T\n}\n\nconst cache = new WeakMap<Observable<any>, CacheRecord<any>>()\n\n/** @public */\nexport function useObservable<ObservableType extends Observable<any>>(\n observable: ObservableType,\n initialValue: ObservedValueOf<ObservableType> | (() => ObservedValueOf<ObservableType>),\n): ObservedValueOf<ObservableType>\n/** @public */\nexport function useObservable<ObservableType extends Observable<any>>(\n observable: ObservableType,\n): undefined | ObservedValueOf<ObservableType>\n/** @public */\nexport function useObservable<ObservableType extends Observable<any>, InitialValue>(\n observable: ObservableType,\n initialValue: InitialValue | (() => InitialValue),\n): InitialValue | ObservedValueOf<ObservableType>\n/** @public */\nexport function useObservable<ObservableType extends Observable<any>, InitialValue>(\n observable: ObservableType,\n initialValue?: InitialValue | (() => InitialValue),\n): InitialValue | ObservedValueOf<ObservableType> {\n const instance = useMemo(() => {\n if (!cache.has(observable)) {\n // This separate object is used as a stable reference to the cache entry's snapshot and error.\n // It's used by the `getSnapshot` closure.\n const state: ObservableState<ObservedValueOf<ObservableType>> = {\n didEmit: false,\n }\n const entry: CacheRecord<ObservedValueOf<ObservableType>> = {\n state,\n observable: observable.pipe(\n map((value) => ({snapshot: value, error: undefined})),\n catchError((error) => of({snapshot: undefined, error})),\n tap(({snapshot, error}) => {\n state.didEmit = true\n state.snapshot = snapshot\n state.error = error\n }),\n // Note: any value or error emitted by the provided observable will be mapped to the cache entry's mutable state\n // and the observable is thereafter only used as a notifier to call `onStoreChange`, hence the `void` return type.\n map((value) => void value),\n // Ensure that the cache entry is deleted when the observable completes or errors.\n finalize(() => cache.delete(observable)),\n share({resetOnRefCountZero: () => timer(0, asapScheduler)}),\n ),\n getSnapshot: (initialValue) => {\n if (state.error) {\n throw state.error\n }\n return (\n state.didEmit ? state.snapshot : getValue(initialValue)\n ) as ObservedValueOf<ObservableType>\n },\n }\n\n // Eagerly subscribe to sync set `state.snapshot` to what the observable returns, and keep the observable alive until the component unmounts.\n const subscription = entry.observable.subscribe()\n subscription.unsubscribe()\n\n cache.set(observable, entry)\n }\n return cache.get(observable)!\n }, [observable])\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n const subscription = instance.observable.subscribe(onStoreChange)\n return () => {\n subscription.unsubscribe()\n }\n },\n [instance.observable],\n )\n\n return useSyncExternalStore<ObservedValueOf<ObservableType>>(\n subscribe,\n () => {\n return instance.getSnapshot(initialValue)\n },\n typeof initialValue === 'undefined'\n ? undefined\n : () => getValue(initialValue) as ObservedValueOf<ObservableType>,\n )\n}\n","import {observableCallback} from 'observable-callback'\nimport {useEffect, useState} from 'react'\nimport {type Observable} from 'rxjs'\nimport {useEffectEvent} from 'use-effect-event'\n\n/** @public */\nexport function useObservableEvent<T, U>(\n handleEvent: (arg: Observable<T>) => Observable<U>,\n): (arg: T) => void {\n const [[calls$, call]] = useState(() => observableCallback<T>())\n\n const onEvent = useEffectEvent((observable: Observable<T>) => handleEvent(observable))\n\n useEffect(() => {\n const subscription = calls$.pipe((observable) => onEvent(observable)).subscribe()\n return () => subscription.unsubscribe()\n }, [calls$])\n\n return call\n}\n"],"names":["getValue","value","cache","WeakMap","useObservable","observable","initialValue","$","_c","t0","has","state","didEmit","entry","pipe","map","_temp","catchError","_temp2","tap","t1","snapshot","error","error_0","_temp3","finalize","delete","share","resetOnRefCountZero","_temp4","getSnapshot","initialValue_0","subscribe","unsubscribe","set","get","instance","t2","onStoreChange","subscription_0","subscription","t3","t4","undefined","useSyncExternalStore","timer","asapScheduler","value_0","of","useObservableEvent","handleEvent","useState","calls$","call","onEvent","useEffectEvent","observable_0","useEffect","observableCallback"],"mappings":"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"}