export const intoObservable = (value: T | Promise | Observable): Observable => { if (isObservable(value)) { return Observable.from(value) } else if (isPromise(value)) { return new Observable(observer => { value.then( value => { if (observer.closed) return observer.next(value) observer.complete() }, (error: Error) => { if (observer.closed) return observer.error(error) observer.complete() } ) return () => {} }) } else { return new Observable(observer => { observer.next(value) observer.complete() return () => {} }) } } const isObservable = (value: any): value is Observable => value != null && typeof value === 'object' && value[Symbol['observable']] const isPromise = (value: any): value is Promise => value != null && typeof value === 'object' && typeof value.then === 'function' export const debounce = (observable: Observable, timeout: number = 0): Observable => new Observable(observer => { let timeoutID: any let lastValue: T const subscription = observable.subscribe( nextValue => { lastValue = nextValue clearTimeout(timeoutID) timeoutID = setTimeout(() => observer.next(lastValue), timeout) }, error => observer.error(error), () => { clearTimeout(timeoutID) observer.next(lastValue) observer.complete() } ) return () => { clearTimeout(timeoutID) subscription.unsubscribe() } })