diff --git a/packages/core/src/internal/useObservable.ts b/packages/core/src/internal/useObservable.ts index 0cbdeac..985eae7 100644 --- a/packages/core/src/internal/useObservable.ts +++ b/packages/core/src/internal/useObservable.ts @@ -1,10 +1,10 @@ import { useEffect, useReducer } from "react" import { BehaviorObservable } from "./BehaviorObservable" import { SUSPENSE } from "../SUSPENSE" +import { Observable } from "rxjs" const ERROR: "e" = "e" const VALUE: "v" = "v" -const SUSP: "s" = "s" type Action = "e" | "v" | "s" const reducer = ( @@ -17,15 +17,31 @@ const reducer = ( const init = (source$: BehaviorObservable) => source$.getValue() +const defaultSUSPENSE = (source$: Observable) => + new Observable((observer) => { + let isEmpty = true + const subscription = source$.subscribe( + (x) => { + isEmpty = false + observer.next(x) + }, + (e) => observer.error(e), + ) + + if (isEmpty) { + observer.next(SUSPENSE) + } + + return subscription + }) + export const useObservable = ( source$: BehaviorObservable, ): Exclude => { const [state, dispatch] = useReducer(reducer, source$, init) - if (state.type === ERROR) throw state.payload useEffect(() => { - dispatch(source$.getValue()) - const subscription = source$.subscribe( + const subscription = defaultSUSPENSE(source$).subscribe( (value) => { if ((value as any) === SUSPENSE) { dispatch(source$.getValue()) @@ -45,8 +61,7 @@ export const useObservable = ( return () => subscription.unsubscribe() }, [source$]) - if (state.type === SUSP) { - throw state.payload - } - return state.payload + const { type, payload } = state + if (type === VALUE) return payload + throw payload }