UNPKG

@equinor/fusion-observable

Version:
71 lines (65 loc) 2.82 kB
import { from, of } from 'rxjs'; import type { ObservableInput, Observable } from 'rxjs'; import { isObservableInput } from './is-observable-input'; /** * Represents a value that can be: * - a direct value of type T, * - a function returning T (optionally accepting arguments), * - or any ObservableInput<T> (Observable, Promise, Iterable, etc). * * @template T The value type. * @template TArgs The argument type(s) for the function variant. */ // biome-ignore lint/suspicious/noExplicitAny: must be any to allow any type of input export type DynamicInputValue<T, TArgs extends any[] = []> = | T | ObservableInput<T> | ((...args: TArgs) => T | ObservableInput<T>); /** * Converts a dynamic input (value, function, or ObservableInput) to an RxJS Observable. * * Handles the following cases: * - If the input is an ObservableInput (Observable, Promise, Iterable, etc), it is converted using `from()`. * - If the input is a function, it is called with the provided arguments and the result is wrapped with `of()`. * - If the input is a plain object or primitive, it is wrapped with `of()`. * * @template T The value type to be emitted by the Observable. * @template TArgs The argument type(s) for the function variant. * @param input The dynamic input value to convert. Can be a value, function, or ObservableInput. * @param args Arguments to pass if the input is a function. * @returns An Observable emitting the value(s) from the input. * @throws If the input is not a supported type. * * @example * // ObservableInput * toObservable([1, 2, 3]).subscribe(x => console.log(x)); // 1, 2, 3 * toObservable(Promise.resolve(42)).subscribe(x => console.log(x)); // 42 * * // Object * toObservable({ key: 'value' }).subscribe(x => console.log(x)); // { key: 'value' } * * // Function * const fn = (x: number) => x * 2; * toObservable(fn, 5).subscribe(x => console.log(x)); // 10 * * // Primitive * toObservable(42).subscribe(x => console.log(x)); // 42 */ // biome-ignore lint/suspicious/noExplicitAny: must be any to allow any type of input export function toObservable<T, TArgs extends any[]>( input: DynamicInputValue<T, TArgs>, ...args: TArgs ): Observable<T> { // If input is already an ObservableInput (Observable, Promise, Iterable, etc), use RxJS 'from' to convert it if (isObservableInput(input)) { return from(input as ObservableInput<T>); } // If input is a function, call it with the provided arguments and wrap the result with 'of' if (typeof input === 'function') { const fn = input as (...args: TArgs[]) => T; const result = fn(...args); return isObservableInput(result) ? from(result as ObservableInput<T>) : of(result); } // Otherwise, treat input as a plain value or object and wrap it with 'of' return of(input as T); }