@@ -92,14 +92,13 @@ extension Gate {
9292/// trigger inner middleware before and after the reducer, and after the reducer that value will be already set to `bypass`, so you can stop timers
9393/// and async tasks. An action that changes the state from `bypass` to `active`, will not trigger the inner middleware before the reducer nor after
9494/// it, so you may want to send a second action to start the middleware timers again, because the gated middleware can't do that for you.
95- public final class GatedMiddleware < M: Middleware > : Middleware {
95+ public final class GatedMiddleware < M: MiddlewareProtocol > : MiddlewareProtocol {
9696 public typealias InputActionType = M . InputActionType
9797 public typealias OutputActionType = M . OutputActionType
9898 public typealias StateType = M . StateType
9999
100100 private let middleware : M
101101 private let gate : Gate < InputActionType , OutputActionType , StateType >
102- private var getState : GetState < StateType > ?
103102
104103 /// GatedMiddleware by action init with Closure variant
105104 /// - Parameters:
@@ -170,27 +169,6 @@ public final class GatedMiddleware<M: Middleware>: Middleware {
170169 self . init ( middleware: middleware, stateMap: { $0 [ keyPath: state] } )
171170 }
172171
173- /// Middleware setup. This function will be called before actions are handled to the middleware, so you can configure your middleware with the
174- /// given parameters. You can hold any of them if you plan to read the state or dispatch new actions.
175- /// You can initialize and start timers or async tasks in here or in the `handle(action:next)` function, but never before this function is called,
176- /// otherwise the middleware would not yet be running from a store.
177- /// Because no actions are delivered to this middleware before the `receiveContext(getState:output:)` is called, you can safely keep implicit
178- /// unwrapped versions of `getState` and `output` as properties of your concrete middleware, and set them from the arguments of this function.
179- ///
180- /// This will be always forwarded to the inner middleware regardless of its gate state, another reason for you to never start side-effects on this
181- /// event. However, this is proxied by the gated middleware, and output will only be forwarded to the store in case the gate state is active.
182- ///
183- /// - Parameters:
184- /// - getState: a closure that allows the middleware to read the current state at any point in time
185- /// - output: an action handler that allows the middleware to dispatch new actions at any point in time
186- public func receiveContext( getState: @escaping GetState < M . StateType > , output: AnyActionHandler < M . OutputActionType > ) {
187- self . getState = getState
188- middleware. receiveContext ( getState: getState, output: . init { [ weak self] outputAction, source in
189- guard let self = self , self . gate. shouldDispatchAction ( outputAction, getState ( ) ) else { return }
190- output. dispatch ( outputAction, from: source)
191- } )
192- }
193-
194172 /// Handles the incoming actions and may or not start async tasks, check the latest state at any point or dispatch additional actions.
195173 /// This is also a good place for analytics, tracking, logging and telemetry. You can schedule tasks to run after the reducer changed the global
196174 /// state if you want, and/or execute things before the reducer.
@@ -215,17 +193,30 @@ public final class GatedMiddleware<M: Middleware>: Middleware {
215193 /// - Parameters:
216194 /// - action: the action to be handled
217195 /// - dispatcher: information about the action source, representing the entity that created and dispatched the action
218- /// - afterReducer: it can be set to perform any operation after the reducer has changed the global state. If the function ends before you set
219- /// this in/out parameter, `afterReducer` will default to `.doNothing()`.
220- public func handle( action: M . InputActionType , from dispatcher: ActionSource , afterReducer: inout AfterReducer ) {
221- guard let state = self . getState ? ( ) ,
222- gate. shouldHandleAction ( action, state) else { return }
196+ /// - state: read the most up-to-date state at any point
197+ /// - Returns: IO closure, where side-effects should be put, and from where actions can be dispatched. In the Gated Middleware this will not
198+ /// do anything in case the predicate is not satisfied, or it will forward the action to the inner middleware in case the predicate
199+ /// is true.
200+ public func handle( action: M . InputActionType , from dispatcher: ActionSource , state: @escaping GetState < M . StateType > ) -> IO < M . OutputActionType > {
201+ print ( action)
202+ dump ( state ( ) )
203+ guard gate. shouldHandleAction ( action, state ( ) ) else { return . pure( ) }
204+
205+ return middleware. handle ( action: action, from: dispatcher, state: state)
206+ . flatMap { [ weak self] actionFromInnerMiddlewareAsResponse in
207+ guard let self = self ,
208+ self . gate. shouldHandleAction ( action, state ( ) ) ,
209+ self . gate. shouldDispatchAction ( actionFromInnerMiddlewareAsResponse. action, state ( ) )
210+ else { return . pure( ) }
223211
224- middleware. handle ( action: action, from: dispatcher, afterReducer: & afterReducer)
212+ return IO { output in
213+ output. dispatch ( actionFromInnerMiddlewareAsResponse)
214+ }
215+ }
225216 }
226217}
227218
228- extension Middleware {
219+ extension MiddlewareProtocol {
229220 /// Gated middleware is a middleware that holds an inner middleware that could be either active or not.
230221 ///
231222 /// This creates a GatedMiddleware by action:
@@ -441,7 +432,7 @@ extension Middleware {
441432 }
442433}
443434
444- extension Middleware {
435+ extension MiddlewareProtocol {
445436 /// Gated middleware is a middleware that holds an inner middleware that could be either active or not.
446437 ///
447438 /// This creates a GatedMiddleware by state:
0 commit comments