Elmish.WPF icon indicating copy to clipboard operation
Elmish.WPF copied to clipboard

Throttling particular message type

Open xperiandri opened this issue 1 year ago • 5 comments

High-level description I've created such throttling function

[<AutoOpen>]
module Dispatching =

    open System
    open Elmish
    open R3

    let asDispatchWrapper<'msg>
        (configure: Observable<'msg> -> Observable<'msg>)
        (dispatch: Dispatch<'msg>)
        : Dispatch<'msg> =
        let subject = new Subject<_>()
        (subject |> configure).Subscribe dispatch |> ignore
        fun msg -> async.Return(subject.OnNext msg) |> Async.Start

    let throttle<'msg> =
        /// Ignores elements from an observable sequence which are followed by another element within a specified relative time duration.
        let throttle  (dueTime:TimeSpan) (source:Observable<'Source>): Observable<'Source> =
            source.ThrottleLast(dueTime)
        throttle (TimeSpan.FromMilliseconds 500)
        |> asDispatchWrapper<'msg>

But it throttles all the messages which causes input data to be missed. How would you suggest to fix that?

Expected or desired behavior All messages are throttled

Actual behavior Only a particular message type is throttled

xperiandri avatar Apr 18 '24 15:04 xperiandri

But it throttles all the messages [...]

Expected or desired behavior All messages are throttled

Actual behavior Only a particular message type is throttled

Did you enter the expected/desired behavior and actual behavior incorrectly?

TysonMN avatar Apr 20 '24 11:04 TysonMN

@xperiandri the core dispatch loop of Elmish is single-threaded, so you would want to avoid generating messages in the first place that you don't want immediately applied to the model.

However, if what you're looking for is a way to avoid UI updates every time Elmish updates the model, look at the Threading and Threading.Core example. If you call startElmishLoop from a separate thread from the WPF main window thread (and then call Dispatcher.Run() on that thread), Elmish will use that thread to dispatch model updates independently of the main thread. This allows Elmish to save up multiple model updates in between calculating the full View Model update and sending NotifyPropertyChanged events to WPF (note how the example freezes the UI, but the Elmish model continues executing in the background).

Saying that out loud, I should probably wrap that in a separate top-level function that does all of the threaded housekeeping for you.

marner2 avatar Apr 22 '24 22:04 marner2

I need a way to wait 0.5 sec for messages to stop till I send a request to a server

xperiandri avatar Apr 22 '24 23:04 xperiandri

This should easily be possible using Reactive and Binding.alterMsgStream.

https://fsprojects.github.io/FSharp.Control.Reactive/reference/fsharp-control-reactive-observablemodule.html

TysonMN avatar Apr 23 '24 05:04 TysonMN

I use R3 instead. This is what I implemented

namespace eCierge.Elmish

open System

[<AutoOpen>]
module Dispatching =

    open Elmish
    open R3

    let asDispatchWrapper<'msg> (configure : Observable<'msg> -> Observable<'msg>) (dispatch : Dispatch<'msg>) : Dispatch<'msg> =
        let subject = new Subject<_> ()
        (subject |> configure).Subscribe dispatch |> ignore
        fun msg -> async.Return (subject.OnNext msg) |> Async.Start

    let throttle<'msg> timespan =
        /// Ignores elements from an observable sequence which are followed by another element within a specified relative time duration.
        let throttle (dueTime : TimeSpan) (source : Observable<'Source>) : Observable<'Source> = source.ThrottleLast (dueTime)
        throttle timespan |> asDispatchWrapper<'msg>

    [<Literal>]
    let DefaultThrottleTimeout = 500.0

    [<Literal>]
    let HalfThrottleTimeout = 250.0

open Elmish.Uno
open System.Runtime.InteropServices

[<AbstractClass; Sealed>]
type BindingT private () =

    static member twoWayThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWay (get, setWithModel = setWithModel)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayThrottle
        (
            get : 'model -> 'a,
            setWithModel : 'a -> 'model -> 'msg,
            [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float
        )
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayThrottle (get, setWithModel, (TimeSpan.FromMilliseconds timeout))

    static member twoWayThrottle (get : 'model -> 'a, set : 'a -> 'msg, timespan) : string -> Binding<'model, 'msg, 'a> =
        BindingT.twoWay (get, set)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayThrottle (get, set, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptThrottle
        (getOpt : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOpt (getOpt, setWithModel = setWithModel)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptThrottle
        (
            getOpt : 'model -> 'a option,
            setWithModel : 'a option -> 'model -> 'msg,
            [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float
        )
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptThrottle (getOpt, setWithModel, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOpt (get, set)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptThrottle
        (
            get : 'model -> 'a option,
            set : 'a option -> 'msg,
            [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float
        )
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptThrottle (get, set, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptThrottle
        (getVOpt : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOpt (getVOpt = getVOpt, setWithModel = setWithModel)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptThrottle
        (
            getVOpt : 'model -> 'a voption,
            setWithModel : 'a voption -> 'model -> 'msg,
            [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float
        )
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptThrottle (getVOpt, setWithModel, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptThrottle (get : 'model -> 'a voption, set : 'a voption -> 'msg, timespan) : string -> Binding<'model, 'msg, 'a> =
        BindingT.twoWayOpt (get, set)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptThrottle (get : 'model -> 'a voption, set : 'a voption -> 'msg, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float) : string -> Binding<'model, 'msg, 'a> =
        BindingT.twoWayOptThrottle (get, set, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> string list, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get = get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> string list, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> string list, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> string list, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> string voption, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> string voption, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> string voption, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> string voption, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> string option, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> string option, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> string option, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> string option, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> Result<'ignored, string>, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, setWithModel : 'a -> 'model -> 'msg, validate : 'model -> Result<'ignored, string>, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> Result<'ignored, string>, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayValidateThrottle
        (get : 'model -> 'a, set : 'a -> 'msg, validate : 'model -> Result<'ignored, string>, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (getVOpt : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> string list, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (getVOpt = getVOpt, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (getVOpt : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> string list, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (getVOpt, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> string list, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> string list, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> string voption, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> string voption, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> string voption, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> string voption, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> string option, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> string option, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> string option, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> string option, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> Result<'ignored, string>, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, setWithModel : 'a voption -> 'model -> 'msg, validate : 'model -> Result<'ignored, string>, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> Result<'ignored, string>, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a voption, set : 'a voption -> 'msg, validate : 'model -> Result<'ignored, string>, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> string list, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> string list, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> string list, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> string list, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> string voption, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> string voption, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> string voption, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> string voption, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
       (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> string option, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> string option, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> string option, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> string option, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> Result<'ignored, string>, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, setWithModel = setWithModel, validate = validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, setWithModel : 'a option -> 'model -> 'msg, validate : 'model -> Result<'ignored, string>, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, setWithModel, validate, (TimeSpan.FromMilliseconds timeout))

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> Result<'ignored, string>, timespan)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidate (get, set, validate)
        >> Binding.alterMsgStream (throttle timespan)

    static member twoWayOptValidateThrottle
        (get : 'model -> 'a option, set : 'a option -> 'msg, validate : 'model -> Result<'ignored, string>, [<Optional; DefaultParameterValue(DefaultThrottleTimeout)>] timeout : float)
        : string -> Binding<'model, 'msg, 'a>
        =
        BindingT.twoWayOptValidateThrottle (get, set, validate, (TimeSpan.FromMilliseconds timeout))

xperiandri avatar Apr 23 '24 19:04 xperiandri