common-ui/src/lib/utils/operators.ts
2022-04-21 14:27:43 +03:00

48 lines
1.8 KiB
TypeScript

import { distinctUntilChanged, map, shareReplay, tap } from 'rxjs/operators';
import { MonoTypeOperatorFunction, Observable, OperatorFunction, pipe, UnaryFunction } from 'rxjs';
import { _log } from './functions';
export function get<T>(predicate: (value: T, index: number) => boolean): OperatorFunction<readonly T[], T | undefined> {
return map(entities => entities.find(predicate));
}
export function any<T>(predicate: (value: T, index: number) => boolean): OperatorFunction<readonly T[], boolean> {
return map(entities => entities.some(predicate));
}
export function mapEach<T, R>(predicate: (value: T, index: number) => R): OperatorFunction<readonly T[], R[]> {
return map(entities => entities.map(predicate));
}
export function filterEach<T>(predicate: (value: T, index: number) => boolean): OperatorFunction<readonly T[], T[]> {
return map(entities => entities.filter(predicate));
}
export function shareLast<T>(values = 1): MonoTypeOperatorFunction<T> {
return shareReplay<T>({ bufferSize: values, refCount: true });
}
export function shareDistinctLast<T>(values = 1): UnaryFunction<Observable<T>, Observable<T>> {
return pipe(distinctUntilChanged(), shareLast(values));
}
export const toLengthValue = (entities: unknown[]): number => entities?.length ?? 0;
export const getLength = pipe(map(toLengthValue), distinctUntilChanged());
export function boolFactory<T = boolean>(
obs: Observable<T>,
project: (value: T) => boolean = value => !!value,
): readonly [Observable<boolean>, Observable<boolean>] {
const result = obs.pipe(map(project), shareDistinctLast());
const inverse = result.pipe(
map(value => !value),
shareDistinctLast(),
);
return [result, inverse];
}
export function log<T>(message = ''): MonoTypeOperatorFunction<T> {
return tap<T>(res => _log(res, message));
}