@@ -7,19 +7,18 @@ import OpenCombine
7
7
import OpenCombineDispatch
8
8
#endif
9
9
10
-
11
10
/// An action represent an operation on the store.
12
11
public protocol Action : Identifiable {
13
12
14
- associatedtype AssociatedStoreType : ReducibleStore
13
+ associatedtype AssociatedStoreType : MutableStore
15
14
16
15
/// Unique action identifier.
17
16
/// An high level description of the action (e.g. `FETCH_USER` or `DELETE_COMMENT`)
18
17
var id : String { get }
19
18
20
19
/// The execution body for this action.
21
20
/// - note: Invoke `context.operation.finish` to signal task completion.
22
- func reduce ( context: TransactionContext < AssociatedStoreType , Self > )
21
+ func mutate ( context: TransactionContext < AssociatedStoreType , Self > )
23
22
24
23
/// Used to implement custom cancellation logic for this action.
25
24
/// E.g. Stop network transfer.
@@ -55,81 +54,121 @@ extension Action {
55
54
///
56
55
/// ```
57
56
@propertyWrapper public final class CancellableStorage {
57
+
58
58
public var wrappedValue : AnyCancellable ?
59
59
60
60
public init ( wrappedValue: AnyCancellable ? = nil ) {
61
61
self . wrappedValue = wrappedValue
62
62
}
63
63
}
64
64
65
- /// Reduce the model by using the closure passed as argument.
66
- public struct Reduce < M> : Action {
65
+ // MARK: - Mutate
66
+
67
+ extension Store {
68
+
69
+ /// Mutate the model with the closure passed as argument.
70
+ public func mutate(
71
+ id: String = _ID. mutate,
72
+ mode: Executor . Mode = . sync,
73
+ mutate: @escaping ( inout M ) -> Void
74
+ ) {
75
+ let action = Mutate ( id: id, mutate: mutate)
76
+ run ( action: action, mode: mode)
77
+ }
78
+ }
79
+
80
+ /// Mutate the model by using the closure passed as argument.
81
+ public struct Mutate < M> : Action {
82
+
67
83
public let id : String
68
- public let reduce : ( inout M ) -> Void
84
+ public let mutate : ( inout M ) -> Void
69
85
70
- public init ( id: String = _ID. reduce , reduce : @escaping ( inout M ) -> Void ) {
86
+ public init ( id: String = _ID. mutate , mutate : @escaping ( inout M ) -> Void ) {
71
87
self . id = id
72
- self . reduce = reduce
88
+ self . mutate = mutate
73
89
}
74
90
75
- public func reduce ( context: TransactionContext < Store < M > , Self > ) {
91
+ public func mutate ( context: TransactionContext < Store < M > , Self > ) {
76
92
defer {
77
93
context. fulfill ( )
78
94
}
79
- context. reduceModel ( closure: reduce )
95
+ context. update ( closure: mutate )
80
96
}
81
97
82
98
public func cancel( context: TransactionContext < Store < M > , Self < M , V > > ) { }
83
99
}
84
100
101
+ // MARK: - Assign
102
+
103
+ extension Store {
104
+
105
+ /// Mutate the model at the target key path passed as argument.
106
+ public func mutate< V> (
107
+ keyPath: WritableKeyPath < M , V > ,
108
+ value: V ,
109
+ mode: Executor . Mode = . sync
110
+ ) {
111
+ let action = Assign ( keyPath, value)
112
+ run ( action: action, mode: mode)
113
+ }
114
+
115
+ /// Synchronously mutate the model at the target key path passed as argument.
116
+ public func mutateSynchronous< V> ( keyPath: WritableKeyPath < M , V ? > , value: V ? ) {
117
+ let action = Assign ( keyPath, value)
118
+ run ( action: action, mode: . sync)
119
+ }
120
+ }
121
+
85
122
/// Assigns the value passed as argument to the model's keyPath.
86
123
public struct Assign < M, V> : Action {
124
+
87
125
public let id : String
88
- public let keyPath : KeyPathArg < M , V >
89
- public let value : V ?
90
126
91
- public init ( id: String = _ID. assign, _ keyPath: KeyPathArg < M , V > , _ value: V ) {
92
- self . id = id
127
+ private let value : V ?
128
+ private let keyPath : KeyPathTarget < M , V >
129
+
130
+ private init ( _ keyPath: KeyPathTarget < M , V > , _ value: V ) {
131
+ self . id = _ID. assign
93
132
self . keyPath = keyPath
94
133
self . value = value
95
134
}
96
135
97
- public init ( id : String = _ID . assign , _ keyPath: WritableKeyPath < M , V > , _ value: V ) {
98
- self . id = " \( id ) [ \( keyPath. readableFormat ?? " unknown " ) ] "
136
+ public init ( _ keyPath: WritableKeyPath < M , V > , _ value: V ) {
137
+ self . id = " \( _ID . assign ) [ \( keyPath. readableFormat ?? " unknown " ) ] "
99
138
self . keyPath = . value( keyPath: keyPath)
100
139
self . value = value
101
140
}
102
141
103
- public init ( id : String = _ID . assign , _ keyPath: WritableKeyPath < M , V ? > , _ value: V ? ) {
104
- self . id = " \( id ) [ \( keyPath. readableFormat ?? " unknown " ) ] "
142
+ public init ( _ keyPath: WritableKeyPath < M , V ? > , _ value: V ? ) {
143
+ self . id = " \( _ID . assign ) [ \( keyPath. readableFormat ?? " unknown " ) ] "
105
144
self . keyPath = . optional( keyPath: keyPath)
106
145
self . value = value
107
146
}
108
147
109
- public func reduce ( context: TransactionContext < Store < M > , Self > ) {
148
+ public func mutate ( context: TransactionContext < Store < M > , Self > ) {
110
149
defer {
111
150
context. fulfill ( )
112
151
}
113
- context. reduceModel { model in
152
+ context. update { model in
114
153
_assignKeyPath ( object: & model, keyPath: keyPath, value: value)
115
154
}
116
155
}
117
156
118
157
public func cancel( context: TransactionContext < Store < M > , Self < M , V > > ) { }
119
158
}
120
159
121
- // MARK: - Internal
160
+ // MARK: - Private
161
+
162
+ private enum KeyPathTarget < M, V> {
122
163
123
- public enum KeyPathArg < M, V> {
124
164
/// A non-optional writeable keyPath.
125
165
case value( keyPath: WritableKeyPath < M , V > )
166
+
126
167
/// A optional writeable keyPath.
127
168
case optional( keyPath: WritableKeyPath < M , V ? > )
128
169
}
129
170
130
- // MARK: - Private
131
-
132
- private func _assignKeyPath< M, V> ( object: inout M , keyPath: KeyPathArg < M , V > , value: V ? ) {
171
+ private func _assignKeyPath< M, V> ( object: inout M , keyPath: KeyPathTarget < M , V > , value: V ? ) {
133
172
switch keyPath {
134
173
case . value( let keyPath) :
135
174
guard let value = value else { return }
@@ -142,6 +181,6 @@ private func _assignKeyPath<M, V>(object: inout M, keyPath: KeyPathArg<M, V>, va
142
181
// MARK: - IDs
143
182
144
183
public struct _ID {
145
- public static let reduce = " _REDUCE "
146
- public static let assign = " _BINDING_ASSIGN "
184
+ public static let mutate = " MUTATE "
185
+ public static let assign = " BINDING_ASSIGN "
147
186
}
0 commit comments