-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinject-if.ts
47 lines (43 loc) · 2.12 KB
/
inject-if.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import {IterationState, Operation, map, spread, wait, concurrencyFork, toIterable} from 'iter-ops';
/**
* Conditionally injects value(s) after the current value.
*/
export function appendIf<T, R>(value: R | Iterable<R>, predicate: (value: T, index: number, state: IterationState) => boolean | Promise<boolean>): Operation<T, T | R> {
const i = toIterable(value as R);
return injectIf(predicate, current => [current, ...i]);
}
/**
* Conditionally injects value(s) before the current value.
*/
export function prependIf<T, R>(value: R | Iterable<R>, predicate: (value: T, index: number, state: IterationState) => boolean | Promise<boolean>): Operation<T, T | R> {
const i = toIterable(value as R);
return injectIf(predicate, current => [...i, current]);
}
/**
* Conditionally injects value(s) in place of the current value.
*/
export function replaceIf<T, R>(value: R | Iterable<R>, predicate: (value: T, index: number, state: IterationState) => boolean | Promise<boolean>): Operation<T, T | R> {
const i = toIterable(value as R);
return injectIf(predicate, () => i);
}
/**
* Conditional injector of synchronous values, with support for asynchronous predicate result.
*/
function injectIf<T, R>(predicate: (value: T, index: number, state: IterationState) => boolean | Promise<boolean>, cb: (current: T) => Iterable<R>): Operation<T, T | R> {
return source => concurrencyFork({
onSync(i: Iterable<T>) {
const m = map((a: T, index, state) => predicate(a, index, state) ? cb(a) : [a])(i);
return spread()(m) as Iterable<T | R>;
},
onAsync(i: AsyncIterable<T>) {
const m = map((a: T, index, state) => {
const r = predicate(a, index, state) as any;
const isPromise = r && typeof r.then === 'function';
const out = (pass: boolean) => pass ? cb(a) : [a];
return isPromise ? r.then(out) : out(r);
})(i) as AsyncIterable<Array<T | R> | Promise<Array<T | R>>>;
const w = wait()(m) as AsyncIterable<Array<T | R>>;
return spread()(w) as AsyncIterable<T | R>;
}
})(source);
}