@@ -315,10 +315,10 @@ public final class Store<State, Action> {
315315 self . threadCheck ( status: . scope)
316316
317317 #if swift(>=5.7)
318- return self . reducer. rescope ( self , state: toChildState, action: fromChildAction)
318+ return self . reducer. rescope ( self , state: toChildState, action: { fromChildAction ( $1 ) } )
319319 #else
320320 return ( self . scope ?? StoreScope ( root: self ) )
321- . rescope ( self , state: toChildState, action: fromChildAction)
321+ . rescope ( self , state: toChildState, action: { fromChildAction ( $1 ) } )
322322 #endif
323323 }
324324
@@ -334,6 +334,19 @@ public final class Store<State, Action> {
334334 self . scope ( state: toChildState, action: { $0 } )
335335 }
336336
337+ @_spi ( Internals) public func filter(
338+ _ isSent: @escaping ( State , Action ) -> Bool
339+ ) -> Store < State , Action > {
340+ self . threadCheck ( status: . scope)
341+
342+ #if swift(>=5.7)
343+ return self . reducer. rescope ( self , state: { $0 } , action: { isSent ( $0, $1) ? $1 : nil } )
344+ #else
345+ return ( self . scope ?? StoreScope ( root: self ) )
346+ . rescope ( self , state: { $0 } , action: { isSent ( $0, $1) ? $1 : nil } )
347+ #endif
348+ }
349+
337350 @_spi ( Internals) public func send(
338351 _ action: Action ,
339352 originatingFrom originatingAction: Action ? = nil
@@ -386,24 +399,24 @@ public final class Store<State, Action> {
386399 }
387400 } ,
388401 completed: { [ weak self] in
389- self ? . threadCheck ( status: . effectCompletion( action) )
390- boxedTask. wrappedValue? . cancel ( )
391- didComplete = true
402+ self ? . threadCheck ( status: . effectCompletion( action) )
403+ boxedTask. wrappedValue? . cancel ( )
404+ didComplete = true
392405 self ? . effectDisposables. removeValue ( forKey: uuid) ? . dispose ( )
393- } ,
406+ } ,
394407 interrupted: { [ weak self] in
395408 boxedTask. wrappedValue? . cancel ( )
396409 didComplete = true
397410 self ? . effectDisposables. removeValue ( forKey: uuid) ? . dispose ( )
398- }
411+ }
399412 )
400413
401414 let effectDisposable = CompositeDisposable ( )
402415 effectDisposable += producer. start ( observer)
403416 effectDisposable += AnyDisposable { [ weak self] in
404417 self ? . threadCheck ( status: . effectCompletion( action) )
405418 self ? . effectDisposables. removeValue ( forKey: uuid) ? . dispose ( )
406- }
419+ }
407420
408421 if !didComplete {
409422 let task = Task < Void , Never > { @MainActor in
@@ -590,7 +603,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
590603 fileprivate func rescope< ChildState, ChildAction> (
591604 _ store: Store < State , Action > ,
592605 state toChildState: @escaping ( State ) -> ChildState ,
593- action fromChildAction: @escaping ( ChildAction ) -> Action
606+ action fromChildAction: @escaping ( ChildState , ChildAction ) -> Action ?
594607 ) -> Store < ChildState , ChildAction > {
595608 ( self as? any AnyScopedReducer ?? ScopedReducer ( rootStore: store) )
596609 . rescope ( store, state: toChildState, action: fromChildAction)
@@ -603,7 +616,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
603616 let rootStore : Store < RootState , RootAction >
604617 let toScopedState : ( RootState ) -> ScopedState
605618 private let parentStores : [ Any ]
606- let fromScopedAction : ( ScopedAction ) -> RootAction
619+ let fromScopedAction : ( ScopedState , ScopedAction ) -> RootAction ?
607620 private( set) var isSending = false
608621
609622 @inlinable
@@ -612,14 +625,14 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
612625 self . rootStore = rootStore
613626 self . toScopedState = { $0 }
614627 self . parentStores = [ ]
615- self . fromScopedAction = { $0 }
628+ self . fromScopedAction = { $1 }
616629 }
617630
618631 @inlinable
619632 init (
620633 rootStore: Store < RootState , RootAction > ,
621634 state toScopedState: @escaping ( RootState ) -> ScopedState ,
622- action fromScopedAction: @escaping ( ScopedAction ) -> RootAction ,
635+ action fromScopedAction: @escaping ( ScopedState , ScopedAction ) -> RootAction ? ,
623636 parentStores: [ Any ]
624637 ) {
625638 self . rootStore = rootStore
@@ -637,7 +650,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
637650 state = self . toScopedState ( self . rootStore. state)
638651 self . isSending = false
639652 }
640- if let task = self . rootStore. send ( self . fromScopedAction ( action) ) {
653+ if let action = self . fromScopedAction ( state , action ) , let task = self . rootStore. send ( action) {
641654 return . fireAndForget { await task. cancellableValue }
642655 } else {
643656 return . none
@@ -649,7 +662,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
649662 func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
650663 _ store: Store < ScopedState , ScopedAction > ,
651664 state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
652- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
665+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
653666 ) -> Store < RescopedState , RescopedAction >
654667 }
655668
@@ -658,13 +671,13 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
658671 func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
659672 _ store: Store < ScopedState , ScopedAction > ,
660673 state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
661- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
674+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
662675 ) -> Store < RescopedState , RescopedAction > {
663- let fromScopedAction = self . fromScopedAction as! ( ScopedAction ) -> RootAction
676+ let fromScopedAction = self . fromScopedAction as! ( ScopedState , ScopedAction ) -> RootAction ?
664677 let reducer = ScopedReducer < RootState , RootAction , RescopedState , RescopedAction > (
665678 rootStore: self . rootStore,
666679 state: { _ in toRescopedState ( store. state) } ,
667- action: { fromScopedAction ( fromRescopedAction ( $0) ) } ,
680+ action: { fromRescopedAction ( $0, $1 ) . flatMap { fromScopedAction ( store . state . value , $0 ) } } ,
668681 parentStores: self . parentStores + [ store]
669682 )
670683 let childStore = Store < RescopedState , RescopedAction > (
@@ -685,7 +698,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
685698 func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
686699 _ store: Store < ScopedState , ScopedAction > ,
687700 state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
688- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
701+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
689702 ) -> Store < RescopedState , RescopedAction >
690703 }
691704
@@ -694,12 +707,15 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
694707 let fromScopedAction : Any
695708
696709 init ( root: Store < RootState , RootAction > ) {
697- self . init ( root: root, fromScopedAction: { $0 } )
710+ self . init (
711+ root: root,
712+ fromScopedAction: { ( state: RootState , action: RootAction ) -> RootAction ? in action }
713+ )
698714 }
699715
700- private init < ScopedAction> (
716+ private init < ScopedState , ScopedAction> (
701717 root: Store < RootState , RootAction > ,
702- fromScopedAction: @escaping ( ScopedAction ) -> RootAction
718+ fromScopedAction: @escaping ( ScopedState , ScopedAction ) -> RootAction ?
703719 ) {
704720 self . root = root
705721 self . fromScopedAction = fromScopedAction
@@ -708,17 +724,21 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
708724 func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
709725 _ scopedStore: Store < ScopedState , ScopedAction > ,
710726 state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
711- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
727+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
712728 ) -> Store < RescopedState , RescopedAction > {
713- let fromScopedAction = self . fromScopedAction as! ( ScopedAction ) -> RootAction
729+ let fromScopedAction = self . fromScopedAction as! ( ScopedState , ScopedAction ) -> RootAction ?
714730
715731 var isSending = false
716732 let rescopedStore = Store < RescopedState , RescopedAction > (
717733 initialState: toRescopedState ( scopedStore. state) ,
718734 reducer: . init { rescopedState, rescopedAction, _ in
719735 isSending = true
720736 defer { isSending = false }
721- let task = self . root. send ( fromScopedAction ( fromRescopedAction ( rescopedAction) ) )
737+ guard
738+ let scopedAction = fromRescopedAction ( rescopedState, rescopedAction) ,
739+ let rootAction = fromScopedAction ( scopedStore. state. value, scopedAction)
740+ else { return . none }
741+ let task = self . root. send ( rootAction)
722742 rescopedState = toRescopedState ( scopedStore. state)
723743 if let task = task {
724744 return . fireAndForget { await task. cancellableValue }
@@ -736,7 +756,9 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
736756 }
737757 rescopedStore. scope = StoreScope < RootState , RootAction > (
738758 root: self . root,
739- fromScopedAction: { fromScopedAction ( fromRescopedAction ( $0) ) }
759+ fromScopedAction: {
760+ fromRescopedAction ( $0, $1) . flatMap { fromScopedAction ( scopedStore. state. value, $0) }
761+ }
740762 )
741763 return rescopedStore
742764 }
0 commit comments