Created
September 8, 2021 12:01
-
-
Save simme/36ca2bcece92ae595f27b3e23376b988 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension Reducer { | |
/// Wraps a reducer to inject a debounced action back into the reducer. | |
/// | |
/// Use this higher order reducer when you want to schedule some work to happen after any other action is recieved by | |
/// the reducer. | |
/// | |
/// **Usage:** | |
/// ``` | |
/// otherReducer.debounceReactiveAction( | |
/// id: DebounceID(), | |
/// for: .seconds(1), | |
/// scheduler: \.mainQueue, | |
/// options: nil, | |
/// send: .debouncedAction, | |
/// filter: { action in | |
/// switch action { | |
/// case .someActionTriggeredByDebouncedAction: return false | |
/// default: return true | |
/// } | |
/// } | |
/// ) | |
/// ``` | |
/// | |
/// - Parameters: | |
/// - id: The effect’s identifier. | |
/// - dueTime: The duration you want to debounce for. | |
/// - scheduler: A keypath on the environment to the scheduler you want to deliver the debounced output to. | |
/// - options: Scheduler options that customize the effect’s delivery of elements. | |
/// - action: The action to inject back into the reducer. | |
/// - filter: A closure that determines if an action should trigger the scheduled action. Use this to filter out | |
/// actions that would otherwise create an infinite loop of debouncing. | |
/// | |
/// - Returns: A new reducer wrapping the reciever. | |
public func debounceReactiveAction<S: Scheduler>( | |
id: AnyHashable, | |
for dueTime: S.SchedulerTimeType.Stride, | |
scheduler: KeyPath<Environment, S>, | |
options: S.SchedulerOptions? = nil, | |
send action: Action, | |
filter: @escaping (Action) -> Bool | |
) -> Self where Action: Equatable { | |
.init { state, localAction, environment in | |
.merge( | |
self.run(&state, localAction, environment), | |
localAction != action && filter(localAction) | |
? Effect(value: action) | |
.debounce(id: id, for: dueTime, scheduler: environment[keyPath: scheduler], options: options) | |
: .none | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment