tc39 proposal compatible fromObservable for better ecosystem interop.
jessekelly881 opened this issue · comments
What is the problem this feature would solve?
It would be nice to add a Stream.fromObservable fn to better interop. w/ rxjs and other libs which use Observables.
https://github.com/tc39/proposal-observable
What is the feature you are proposing to solve the problem?
import { range, Observable } from "rxjs";
import { Effect, Stream } from "effect";
/**
* Creates a `Stream` from an `Observable` instance.
* @since 3.2.0
* @see https://tc39.es/proposal-observable/
*/
export const fromObservable = <T>(observable: Observable<T>) =>
Stream.async((emit) => {
const subscription = observable.subscribe((value) =>
emit.single(value)
);
return Effect.sync(() => subscription.unsubscribe());
});
fromObservable(range(0, 10)).pipe(
Stream.runForEach((s) => Effect.log(s)),
Effect.runPromise
);
Observable type could be simplified to a compatible ObservableLike
.
interface ObservableLike<T> {
subscribe: (_: (_: T) => any) => { unsubscribe: () => void };
}
I think we should wait until it reaches stage 3 and is officially supported by TypeScript.
The spec might never make it into typescript but there are still quite a few libraries that adhere to the proposed type: rxjs, xstate, redux, facebook's relay being a few of them. A simplified interface ObservableLike { subscribe: (_: (_: T) => void) => { unsubscribe: () => void }; }
should be enough to be compatible w/ them w/o having to use the full type.
The spec might never make it into typescript but there are still quite a few libraries that adhere to the proposed type: rxjs, xstate, redux, facebook's relay being a few of them. A simplified
interface ObservableLike { subscribe: (_: (_: T) => void) => { unsubscribe: () => void }; }
should be enough to be compatible w/ them w/o having to use the full type.
Unless we introduce an Observable module I would avoid using the name, there is also the risk that the tc39 spec ends up in a different direction. I'd wait and see