This repository has been archived by the owner on Apr 13, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
source.ts
115 lines (102 loc) · 2.86 KB
/
source.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import xs, {Stream} from 'xstream';
import {adapt} from '@cycle/run/lib/adapt';
import {Action, ActionResult, SelectedResults} from './interfaces';
/**
* Check both array are equal.
* @param a1 the first array
* @param a2 the second array
* @returns true when equal otherwise false
* @private
*/
export function arrayEqual(a1: Array<string>, a2: Array<string>): boolean {
for (let i = 0; i < a2.length; i++) {
if (a1[i] !== a2[i]) {
return false;
}
}
return true;
}
/**
* The source of provided by the driver.
*/
export class ActionsSource<I, O> {
constructor(
public result$: Stream<ActionResult<I, O>>,
public readonly name?: string,
public readonly namespace: Array<string> = []
) {
}
/**
* Used by `@cycle/isolate` to isolate the source.
* @param actionSource the source
* @param scope the scope
*/
public isolateSource(
actionSource: ActionsSource<I, O>,
scope: string | null
) {
if (scope === null) {
return actionSource;
}
return actionSource.filter((action) =>
Array.isArray(action.namespace) &&
arrayEqual(
action.namespace,
(actionSource).namespace.concat(scope)
), scope
);
}
/**
* Used by `@cycle/isolate` to isolate the sink.
* @param action$ the stream of actions
* @param scope the scope
*/
public isolateSink(
action$: Stream<Action<I>>,
scope: string | null
): Stream<Action<any>> {
if (scope === null) {
return action$;
}
return adapt(
xs.fromObservable<Action<any>>(action$).map(action => {
action.namespace = action.namespace || [];
action.namespace.unshift(scope);
return action;
})
);
}
/**
* Filter results according to a predicate on the {@link Action}.
* @param predicate the predicate
* @param scope the scope
* @return a new {@link ActionsSource}
*/
public filter(
predicate: (action: Action<I>) => boolean,
scope?: string
): ActionsSource<I, O> {
const filteredResponse$$ = this.result$.filter(result => predicate(result.request));
return new ActionsSource(
filteredResponse$$,
this.name,
scope === undefined ? this.namespace : this.namespace.concat(scope)
);
}
/**
* Extract from the streams of result streams flatten streams.
* @param category an optional category ({@link Action.category})
* @returns the selected results
*/
public select(category?: string): SelectedResults<I, O> {
let result$ = category
? this.result$.filter(result => result && result.request.category === category)
: this.result$;
result$ = adapt(result$);
const response$ = result$.filter(result => !!result.response)
.map(result => result.response);
const error$ = result$.filter(result => !!result.error)
.map(result => result.error);
return {result$, response$, error$};
}
}