import { checkFunction } from "../_check" import { Source } from "../_core" import { In, Out } from "../_interfaces" import { makeObservable } from "../_obs" import { Transaction } from "../_tx" import { curry2 } from "../_util" import { dispatcherOf } from "../Observable" import { Sliding } from "./slidingWindow" export type Eq = (a: T, b: T) => boolean export const skipDuplicates: CurriedSkipDuplicates = curry2(_skipDuplicates) export interface CurriedSkipDuplicates { (isEqual: Eq, observable: In): Out< ObsType, ValueType > (isEqual: Eq): ( observable: In, ) => Out } export function skipEquals( observable: In, ): Out { return _skipDuplicates((a, b) => a === b, observable) } function _skipDuplicates( isEqual: Eq, observable: In, ): Out { checkFunction(isEqual) return makeObservable(observable, new SkipDuplicates(dispatcherOf(observable), isEqual)) } class SkipDuplicates extends Sliding { constructor(source: Source, private eq: Eq) { super(source, 1, 2, []) } protected nextWin(tx: Transaction, win: T[]): void { if (win.length === 2) { const { eq } = this const [a, b] = win if (!eq(a, b)) { this.sink.next(tx, b) } } else { this.sink.next(tx, win[0]) } } }