1
1
import xs , { Stream } from 'xstream' ;
2
- import { Instances } from 'cycle-onionify' ;
2
+ import { Instances , Lens } from 'cycle-onionify' ;
3
3
4
4
export type Sinks = any ;
5
5
export type Sources = any ;
@@ -15,29 +15,35 @@ export interface MergeExceptions {
15
15
* @param {MergeExceptions } exceptions a dictionary of special channels, e.g. DOM
16
16
* @return {Sinks } the new unified sink
17
17
*/
18
- export function mergeSinks ( sinks : Sinks [ ] , exceptions : MergeExceptions = { } ) : Sinks
19
- {
20
- const drivers : string [ ] = sinks
18
+ export function mergeSinks (
19
+ sinks : Sinks [ ] ,
20
+ exceptions : MergeExceptions = { }
21
+ ) : Sinks {
22
+ const drivers : string [ ] = sinks
21
23
. map ( Object . keys )
22
24
. reduce ( ( acc , curr ) => acc . concat ( curr ) , [ ] )
23
- . reduce ( ( acc , curr ) => acc . indexOf ( curr ) === - 1 ? [ ...acc , curr ] : acc , [ ] ) ;
24
-
25
- const emptySinks : any = drivers
26
- . map ( s => ( { [ s ] : [ ] } ) as any )
27
- . reduce ( ( acc , curr ) => Object . assign ( acc , curr ) , { } ) ;
28
-
29
- const combinedSinks = sinks
30
- . reduce ( ( acc , curr ) => {
31
- return Object . keys ( acc )
32
- . map ( s => ( { [ s ] : acc [ s ] } ) )
33
- . map ( o => {
34
- const name : string = Object . keys ( o ) [ 0 ] ;
35
- return ! curr [ name ] ? o : {
36
- [ name ] : [ ...o [ name ] , curr [ name ] ]
37
- } ;
38
- } )
39
- . reduce ( ( a , c ) => Object . assign ( a , c ) , { } ) ;
40
- } , emptySinks ) ;
25
+ . reduce (
26
+ ( acc , curr ) => ( acc . indexOf ( curr ) === - 1 ? [ ...acc , curr ] : acc ) ,
27
+ [ ]
28
+ ) ;
29
+
30
+ const emptySinks : any = drivers
31
+ . map ( s => ( { [ s ] : [ ] } as any ) )
32
+ . reduce ( ( acc , curr ) => Object . assign ( acc , curr ) , { } ) ;
33
+
34
+ const combinedSinks = sinks . reduce ( ( acc , curr ) => {
35
+ return Object . keys ( acc )
36
+ . map ( s => ( { [ s ] : acc [ s ] } ) )
37
+ . map ( o => {
38
+ const name : string = Object . keys ( o ) [ 0 ] ;
39
+ return ! curr [ name ]
40
+ ? o
41
+ : {
42
+ [ name ] : [ ...o [ name ] , curr [ name ] ]
43
+ } ;
44
+ } )
45
+ . reduce ( ( a , c ) => Object . assign ( a , c ) , { } ) ;
46
+ } , emptySinks ) ;
41
47
42
48
const merged = Object . keys ( combinedSinks )
43
49
. filter ( name => Object . keys ( exceptions ) . indexOf ( name ) === - 1 )
@@ -49,7 +55,8 @@ export function mergeSinks(sinks: Sinks[], exceptions: MergeExceptions = {}): Si
49
55
. filter ( ( [ _ , arr ] ) => arr !== undefined )
50
56
. map ( ( [ key , arr ] ) => ( { [ key ] : exceptions [ key ] ( arr ) } ) ) ;
51
57
52
- return merged . concat ( special )
58
+ return merged
59
+ . concat ( special )
53
60
. reduce ( ( acc , curr ) => Object . assign ( acc , curr ) , { } ) ;
54
61
}
55
62
@@ -61,18 +68,23 @@ export interface PickMergeExceptions {
61
68
* Just like mergeSinks, but for onionify collections
62
69
* @see mergeSinks
63
70
*/
64
- export function pickMergeSinks ( driverNames : string [ ] , exceptions : PickMergeExceptions = { } ) : ( ins : Instances < any > ) => Sinks {
71
+ export function pickMergeSinks (
72
+ driverNames : string [ ] ,
73
+ exceptions : PickMergeExceptions = { }
74
+ ) : ( ins : Instances < any > ) => Sinks {
65
75
return instances => {
66
76
const merged : Sinks = driverNames
67
77
. filter ( name => Object . keys ( exceptions ) . indexOf ( name ) === - 1 )
68
78
. map ( name => ( { [ name ] : instances . pickMerge ( name ) } ) ) ;
69
79
70
- const special = Object . keys ( exceptions )
71
- . map ( key => ( { [ key ] : exceptions [ key ] ( instances ) } ) ) ;
80
+ const special = Object . keys ( exceptions ) . map ( key => ( {
81
+ [ key ] : exceptions [ key ] ( instances )
82
+ } ) ) ;
72
83
73
- return merged . concat ( special )
74
- . reduce ( ( acc , curr ) => Object . assign ( acc , curr ) , { } ) ;
75
- }
84
+ return merged
85
+ . concat ( special )
86
+ . reduce ( ( acc , curr ) => Object . assign ( acc , curr ) , { } ) ;
87
+ } ;
76
88
}
77
89
78
90
/**
@@ -81,14 +93,16 @@ export function pickMergeSinks(driverNames: string[], exceptions: PickMergeExcep
81
93
* @param {string[] } driverNames the names of all drivers that are possibly in the stream, it's best to use Object.keys() on your driver object
82
94
* @return {Sinks } A sinks containing the streams of the last emission in the sinks$
83
95
*/
84
- export function extractSinks ( sinks$ : Stream < Sinks > , driverNames : string [ ] ) : Sinks
85
- {
96
+ export function extractSinks (
97
+ sinks$ : Stream < Sinks > ,
98
+ driverNames : string [ ]
99
+ ) : Sinks {
86
100
return driverNames
87
101
. map ( d => ( {
88
- [ d ] : sinks$
89
- . map < Stream < any > | undefined > ( s => s [ d ] )
90
- . filter ( b => ! ! b )
91
- . flatten ( )
102
+ [ d ] : sinks$
103
+ . map < Stream < any > | undefined > ( s => s [ d ] )
104
+ . filter ( b => ! ! b )
105
+ . flatten ( )
92
106
} ) )
93
107
. reduce ( ( acc , curr ) => Object . assign ( acc , curr ) , { } ) ;
94
108
}
@@ -100,12 +114,34 @@ export function extractSinks(sinks$ : Stream<Sinks>, driverNames : string[]) : S
100
114
* @param {string } name The name of the export. For loading a default export simply ignore
101
115
* @return {Component } A dummy that loads the actual component
102
116
*/
103
- export function loadAsync ( moduleLoader : ( ) => any , driverNames : string [ ] , name : string = 'default' ) : Component {
117
+ export function loadAsync (
118
+ moduleLoader : ( ) => any ,
119
+ driverNames : string [ ] ,
120
+ name : string = 'default'
121
+ ) : Component {
104
122
return sources => {
105
- const lazyComponent$ : Stream < Sinks > = xs . fromPromise ( moduleLoader ( ) )
123
+ const lazyComponent$ : Stream < Sinks > = xs
124
+ . fromPromise ( moduleLoader ( ) )
106
125
. map ( m => m [ name ] )
107
126
. map ( m => m ( sources ) ) ;
108
127
109
128
return extractSinks ( lazyComponent$ , driverNames ) ;
110
129
} ;
111
130
}
131
+
132
+ /**
133
+ * Composes two lenses to one
134
+ * @param {Lens<A, B> } outer
135
+ * @param {Lens<B, C> } inner
136
+ * @return {Lens<A, C> } composed lens
137
+ */
138
+ export function composeLenses < A , B , C > (
139
+ outer : Lens < A , B > ,
140
+ inner : Lens < B , C >
141
+ ) : Lens < A , C > {
142
+ return {
143
+ get : parent => inner . get ( outer . get ( parent ) ) ,
144
+ set : ( parent , child ) =>
145
+ outer . set ( parent , inner . set ( outer . get ( parent ) , child ) )
146
+ } ;
147
+ }
0 commit comments