55 lines
1.3 KiB
TypeScript
55 lines
1.3 KiB
TypeScript
import { merge, Observable } from "kefir";
|
|
import Bus from "kefir-bus";
|
|
|
|
export type ValueWithin<O extends Observable<any, any>> = Parameters<
|
|
Parameters<O["map"]>[0]
|
|
>[0];
|
|
|
|
type Mutation<A, O extends Observable<any, any>> = [
|
|
O,
|
|
(prev: A, value: ValueWithin<O>) => A
|
|
];
|
|
|
|
export const multiScan = <A, M extends Mutation<A, any>[]>(
|
|
initValue: A,
|
|
...mutations: M
|
|
): Observable<A, any> =>
|
|
merge(
|
|
mutations.map(([source, mutation]) =>
|
|
source.map((event) => ({ event, mutation }))
|
|
)
|
|
).scan((prev, { event, mutation }) => mutation(prev, event), initValue);
|
|
|
|
export const partition = <
|
|
C extends readonly [...string[]],
|
|
T extends { [key: string]: any },
|
|
E
|
|
>(
|
|
classes: C,
|
|
obs: Observable<T, E>
|
|
) => {
|
|
const classBuses = Object.fromEntries(classes.map((c) => [c, Bus()]));
|
|
obs.onValue((v) => {
|
|
for (const _class of classes) {
|
|
if (_class in v) {
|
|
classBuses[_class].emit(v);
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
return classBuses;
|
|
};
|
|
|
|
export const isEmpty = (container: { length: number }) => container.length == 0;
|
|
|
|
export const setDiff = <T>(
|
|
sets: [Set<T>, s2: Set<T>]
|
|
): { added: T[]; removed: T[] } => ({
|
|
added: [...sets[1].difference(sets[0])],
|
|
removed: [...sets[0].difference(sets[1])],
|
|
});
|
|
|
|
export const set = <T>(arr: T[]) => new Set<T>(arr);
|
|
|
|
export const invert = <E>(obs: Observable<boolean, E>) => obs.map((o) => !o);
|