Skip to content

Instantly share code, notes, and snippets.

@simme
Created September 8, 2021 12:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simme/36ca2bcece92ae595f27b3e23376b988 to your computer and use it in GitHub Desktop.
Save simme/36ca2bcece92ae595f27b3e23376b988 to your computer and use it in GitHub Desktop.
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