@@ -20,23 +20,45 @@ import RxCocoa
20
20
/// A Store is dedicated to a State Type
21
21
public final class Store < State: Equatable > {
22
22
23
- public typealias ReducerFunction = ( State , Action ) -> State
23
+ private typealias ReducerFunction = ( State , Action ) -> State
24
24
25
25
private var state : State
26
- private var reducers = [ ReducerFunction] ( )
27
- // private let reducers: ContiguousArray<Reducer<StateType>>
26
+ private var reducers = [ String: ReducerFunction] ( )
27
+
28
+ private var subStateTypes = [ String] ( )
28
29
// private let middlewares: ContiguousArray<Middleware<StateType>>?
29
30
30
31
public init ( withState state: State ) {
31
32
self . state = state
33
+
34
+ let stateMirror = Mirror ( reflecting: self . state)
35
+ for child in stateMirror. children {
36
+ let childMirror = Mirror ( reflecting: child. value)
37
+ subStateTypes. append ( " \( type ( of: childMirror. subjectType) ) " )
38
+ }
39
+
32
40
// self.middlewares = middlewares
33
41
}
34
42
35
- public func register< SubState: Equatable > ( reducer: Reducer < State , SubState > ) {
36
- self . reducers. append ( reducer. apply)
43
+ public func register< SubState: Equatable > ( reducer: Reducer < State , SubState > ) throws {
44
+ let key = " \( type ( of: SubState . self) ) "
45
+
46
+ if let index = self . subStateTypes. index ( of: key) {
47
+ self . subStateTypes. remove ( at: index)
48
+ }
49
+
50
+ guard self . reducers [ key] == nil else {
51
+ throw NSError ( domain: " ReducerAlreadyExists " , code: - 1 )
52
+ }
53
+ self . reducers [ key] = reducer. apply
37
54
}
38
55
39
56
public func dispatch( action: Action ) -> Observable < State > {
57
+
58
+ guard self . subStateTypes. isEmpty else {
59
+ fatalError ( " All substate must be handled " )
60
+ }
61
+
40
62
// every received action is converted to an async action
41
63
return action
42
64
. toAsync ( )
@@ -47,7 +69,7 @@ public final class Store<State: Equatable> {
47
69
// })
48
70
. map { ( action) -> State in
49
71
50
- return self . reducers. reduce ( self . state, { ( currentState, reducer) -> State in
72
+ return self . reducers. values . reduce ( self . state, { ( currentState, reducer) -> State in
51
73
return reducer ( currentState, action)
52
74
} )
53
75
} . do ( onNext: { [ unowned self] ( newState) in
0 commit comments