@@ -315,10 +315,10 @@ public final class Store<State, Action> {
315
315
self . threadCheck ( status: . scope)
316
316
317
317
#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 ) } )
319
319
#else
320
320
return ( self . scope ?? StoreScope ( root: self ) )
321
- . rescope ( self , state: toChildState, action: fromChildAction)
321
+ . rescope ( self , state: toChildState, action: { fromChildAction ( $1 ) } )
322
322
#endif
323
323
}
324
324
@@ -334,6 +334,19 @@ public final class Store<State, Action> {
334
334
self . scope ( state: toChildState, action: { $0 } )
335
335
}
336
336
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
+
337
350
@_spi ( Internals) public func send(
338
351
_ action: Action ,
339
352
originatingFrom originatingAction: Action ? = nil
@@ -386,24 +399,24 @@ public final class Store<State, Action> {
386
399
}
387
400
} ,
388
401
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
392
405
self ? . effectDisposables. removeValue ( forKey: uuid) ? . dispose ( )
393
- } ,
406
+ } ,
394
407
interrupted: { [ weak self] in
395
408
boxedTask. wrappedValue? . cancel ( )
396
409
didComplete = true
397
410
self ? . effectDisposables. removeValue ( forKey: uuid) ? . dispose ( )
398
- }
411
+ }
399
412
)
400
413
401
414
let effectDisposable = CompositeDisposable ( )
402
415
effectDisposable += producer. start ( observer)
403
416
effectDisposable += AnyDisposable { [ weak self] in
404
417
self ? . threadCheck ( status: . effectCompletion( action) )
405
418
self ? . effectDisposables. removeValue ( forKey: uuid) ? . dispose ( )
406
- }
419
+ }
407
420
408
421
if !didComplete {
409
422
let task = Task < Void , Never > { @MainActor in
@@ -590,7 +603,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
590
603
fileprivate func rescope< ChildState, ChildAction> (
591
604
_ store: Store < State , Action > ,
592
605
state toChildState: @escaping ( State ) -> ChildState ,
593
- action fromChildAction: @escaping ( ChildAction ) -> Action
606
+ action fromChildAction: @escaping ( ChildState , ChildAction ) -> Action ?
594
607
) -> Store < ChildState , ChildAction > {
595
608
( self as? any AnyScopedReducer ?? ScopedReducer ( rootStore: store) )
596
609
. rescope ( store, state: toChildState, action: fromChildAction)
@@ -603,7 +616,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
603
616
let rootStore : Store < RootState , RootAction >
604
617
let toScopedState : ( RootState ) -> ScopedState
605
618
private let parentStores : [ Any ]
606
- let fromScopedAction : ( ScopedAction ) -> RootAction
619
+ let fromScopedAction : ( ScopedState , ScopedAction ) -> RootAction ?
607
620
private( set) var isSending = false
608
621
609
622
@inlinable
@@ -612,14 +625,14 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
612
625
self . rootStore = rootStore
613
626
self . toScopedState = { $0 }
614
627
self . parentStores = [ ]
615
- self . fromScopedAction = { $0 }
628
+ self . fromScopedAction = { $1 }
616
629
}
617
630
618
631
@inlinable
619
632
init (
620
633
rootStore: Store < RootState , RootAction > ,
621
634
state toScopedState: @escaping ( RootState ) -> ScopedState ,
622
- action fromScopedAction: @escaping ( ScopedAction ) -> RootAction ,
635
+ action fromScopedAction: @escaping ( ScopedState , ScopedAction ) -> RootAction ? ,
623
636
parentStores: [ Any ]
624
637
) {
625
638
self . rootStore = rootStore
@@ -637,7 +650,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
637
650
state = self . toScopedState ( self . rootStore. state)
638
651
self . isSending = false
639
652
}
640
- if let task = self . rootStore. send ( self . fromScopedAction ( action) ) {
653
+ if let action = self . fromScopedAction ( state , action ) , let task = self . rootStore. send ( action) {
641
654
return . fireAndForget { await task. cancellableValue }
642
655
} else {
643
656
return . none
@@ -649,7 +662,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
649
662
func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
650
663
_ store: Store < ScopedState , ScopedAction > ,
651
664
state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
652
- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
665
+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
653
666
) -> Store < RescopedState , RescopedAction >
654
667
}
655
668
@@ -658,13 +671,13 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
658
671
func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
659
672
_ store: Store < ScopedState , ScopedAction > ,
660
673
state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
661
- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
674
+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
662
675
) -> Store < RescopedState , RescopedAction > {
663
- let fromScopedAction = self . fromScopedAction as! ( ScopedAction ) -> RootAction
676
+ let fromScopedAction = self . fromScopedAction as! ( ScopedState , ScopedAction ) -> RootAction ?
664
677
let reducer = ScopedReducer < RootState , RootAction , RescopedState , RescopedAction > (
665
678
rootStore: self . rootStore,
666
679
state: { _ in toRescopedState ( store. state) } ,
667
- action: { fromScopedAction ( fromRescopedAction ( $0) ) } ,
680
+ action: { fromRescopedAction ( $0, $1 ) . flatMap { fromScopedAction ( store . state . value , $0 ) } } ,
668
681
parentStores: self . parentStores + [ store]
669
682
)
670
683
let childStore = Store < RescopedState , RescopedAction > (
@@ -685,7 +698,7 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
685
698
func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
686
699
_ store: Store < ScopedState , ScopedAction > ,
687
700
state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
688
- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
701
+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
689
702
) -> Store < RescopedState , RescopedAction >
690
703
}
691
704
@@ -694,12 +707,15 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
694
707
let fromScopedAction : Any
695
708
696
709
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
+ )
698
714
}
699
715
700
- private init < ScopedAction> (
716
+ private init < ScopedState , ScopedAction> (
701
717
root: Store < RootState , RootAction > ,
702
- fromScopedAction: @escaping ( ScopedAction ) -> RootAction
718
+ fromScopedAction: @escaping ( ScopedState , ScopedAction ) -> RootAction ?
703
719
) {
704
720
self . root = root
705
721
self . fromScopedAction = fromScopedAction
@@ -708,17 +724,21 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
708
724
func rescope< ScopedState, ScopedAction, RescopedState, RescopedAction> (
709
725
_ scopedStore: Store < ScopedState , ScopedAction > ,
710
726
state toRescopedState: @escaping ( ScopedState ) -> RescopedState ,
711
- action fromRescopedAction: @escaping ( RescopedAction ) -> ScopedAction
727
+ action fromRescopedAction: @escaping ( RescopedState , RescopedAction ) -> ScopedAction ?
712
728
) -> Store < RescopedState , RescopedAction > {
713
- let fromScopedAction = self . fromScopedAction as! ( ScopedAction ) -> RootAction
729
+ let fromScopedAction = self . fromScopedAction as! ( ScopedState , ScopedAction ) -> RootAction ?
714
730
715
731
var isSending = false
716
732
let rescopedStore = Store < RescopedState , RescopedAction > (
717
733
initialState: toRescopedState ( scopedStore. state) ,
718
734
reducer: . init { rescopedState, rescopedAction, _ in
719
735
isSending = true
720
736
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)
722
742
rescopedState = toRescopedState ( scopedStore. state)
723
743
if let task = task {
724
744
return . fireAndForget { await task. cancellableValue }
@@ -736,7 +756,9 @@ public typealias StoreOf<R: ReducerProtocol> = Store<R.State, R.Action>
736
756
}
737
757
rescopedStore. scope = StoreScope < RootState , RootAction > (
738
758
root: self . root,
739
- fromScopedAction: { fromScopedAction ( fromRescopedAction ( $0) ) }
759
+ fromScopedAction: {
760
+ fromRescopedAction ( $0, $1) . flatMap { fromScopedAction ( scopedStore. state. value, $0) }
761
+ }
740
762
)
741
763
return rescopedStore
742
764
}
0 commit comments