-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate rx-utils #180
Comments
Can you please give an example of
|
@igoralekseev Assuming we're using const withEffect = <A>(source: Observable<A>, f: (a: A) => Observable<unknown>): Observable<A> =>
merge(
source,
pipe(
source,
switchMap(f),
ignoreElements(),
),
);
declare function save(data: string): Observable<void>;
declare const source: Observable<string>;
const data = withEffect(source, save); |
@igoralekseev Or if we're creating an instance of effectful viewmodel (typical usage): interface ViewModel {
a: Observable<string>;
b: Observable<string>;
remove(): void;
}
declare function remove(id: string): Observable<void>;
const createViewModel = (id: string): Observable<ViewModel> => {
const removeHandler = createHandler<void>();
const vm = {
a: of('123'),
b: of('456'),
remove: removeHandler.handle,
};
const removeEffect = pipe(
removeHandler.value$,
switchMap(() => remove(id)),
share(),
);
return withEffect(of(vm), () => removeEffect);
}; |
We could go even shorter with using Proxy for creating handlers: const withEffect = <A>(source: Observable<A>, effect: Observable<unknown>): Observable<A> =>
merge(
source,
pipe(
source,
switchMapTo(effect),
ignoreElements(),
share(),
),
);
interface Handler<A> extends Observable<A> {
(a: A): void;
}
interface VoidHandler<A> extends Observable<A> {
(): void;
}
const functionKeys: PropertyKey[] = Object.getOwnPropertyNames(Object.getPrototypeOf(constVoid));
const createHandler = <A = never>(): A extends void ? VoidHandler<A> : Handler<A> => {
const s = new Subject<A>();
const shared = pipe(
s,
share(),
);
const next = (a: A) => s.next(a);
return new Proxy(next, {
get(target, key) {
return (functionKeys.includes(key) ? next : shared)[key];
},
}) as any;
};
interface ViewModel {
a: Observable<string>;
b: Observable<string>;
remove(): void;
}
declare function remoteRemove(id: string): Observable<void>;
const createViewModel = (id: string): Observable<ViewModel> => {
const remove = createHandler<void>();
const vm: ViewModel = {
a: of('123'),
b: of('456'),
remove,
};
const removeEffect = pipe(
remove,
switchMap(() => remoteRemove(id)),
);
return withEffect(of(vm), removeEffect);
}; |
Wow, |
Why not, it's just an object that implements both |
Historically
Sink
andContext
were a wrong abstraction and we should consider removing them in future versions of platform.Sink
exposes unsafe access to inner value when you can forget about subscribing to effect. On the other hand we could replacetype Sink<A> = { value: A, effect: Observable<unknown>> }
with just atype Sink<A> = Observable<A>
where effect is bundled into the stream and you don't have direct unsafe access to sink's value, only in subscriber.Keeping that in mind,
type Context<E, A>
becomes just aReader<E, Observable<A>>
and can be dropped as well.Still we have to deliver
LiveData
and operators and that's why we should think about #171The text was updated successfully, but these errors were encountered: