import { checkNaturalInt } from "../_check" import { In, Out } from "../_interfaces" import { makeObservable } from "../_obs" import { Transaction } from "../_tx" import { curry2 } from "../_util" import { dispatcherOf, Observable } from "../Observable" import { Throttle, ThrottleBase } from "./throttle" export const debounce: CurriedDebounce = curry2(_debounce) export interface CurriedDebounce { (delay: number, observable: In): Out (delay: number): ( observable: In, ) => Out } export const debounceImmediate: CurriedDebounceImmediate = curry2(_debounceImmediate) export interface CurriedDebounceImmediate { (delay: number, observable: In): Out (delay: number): ( observable: In, ) => Out } function _debounce(delay: number, observable: Observable): Observable { checkNaturalInt(delay) return makeObservable(observable, new Debounce(dispatcherOf(observable), delay)) } function _debounceImmediate(delay: number, observable: Observable): Observable { checkNaturalInt(delay) return makeObservable(observable, new DebounceImmediate(dispatcherOf(observable), delay)) } class Debounce extends Throttle { public nextChange(tx: Transaction, val: T): void { this.memo = val this.resetTimeout() this.ensureTimeout() } } class DebounceImmediate extends ThrottleBase { private skip: boolean = false public dispose(): void { this.skip = false super.dispose() } public nextChange(tx: Transaction, val: T): void { if (!this.skip) { this.skip = true this.sink.next(tx, val) } if (this.active) { this.ensureTimeout() } } public due(): void { this.to = null this.skip = false } }