UNPKG

@zkochan/pnpm

Version:

Fast, disk space efficient package manager

140 lines (114 loc) 3.39 kB
/** @license MIT License (c) copyright 2010-2016 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ import Stream from '../Stream' import Pipe from '../sink/Pipe' import Map from '../fusion/Map' /** * Limit the rate of events by suppressing events that occur too often * @param {Number} period time to suppress events * @param {Stream} stream * @returns {Stream} */ export function throttle (period, stream) { return new Stream(throttleSource(period, stream.source)) } function throttleSource (period, source) { return source instanceof Map ? commuteMapThrottle(period, source) : source instanceof Throttle ? fuseThrottle(period, source) : new Throttle(period, source) } function commuteMapThrottle (period, source) { return Map.create(source.f, throttleSource(period, source.source)) } function fuseThrottle (period, source) { return new Throttle(Math.max(period, source.period), source.source) } function Throttle (period, source) { this.period = period this.source = source } Throttle.prototype.run = function (sink, scheduler) { return this.source.run(new ThrottleSink(this.period, sink), scheduler) } function ThrottleSink (period, sink) { this.time = 0 this.period = period this.sink = sink } ThrottleSink.prototype.event = function (t, x) { if (t >= this.time) { this.time = t + this.period this.sink.event(t, x) } } ThrottleSink.prototype.end = Pipe.prototype.end ThrottleSink.prototype.error = Pipe.prototype.error /** * Wait for a burst of events to subside and emit only the last event in the burst * @param {Number} period events occuring more frequently than this * will be suppressed * @param {Stream} stream stream to debounce * @returns {Stream} new debounced stream */ export function debounce (period, stream) { return new Stream(new Debounce(period, stream.source)) } function Debounce (dt, source) { this.dt = dt this.source = source } Debounce.prototype.run = function (sink, scheduler) { return new DebounceSink(this.dt, this.source, sink, scheduler) } function DebounceSink (dt, source, sink, scheduler) { this.dt = dt this.sink = sink this.scheduler = scheduler this.value = void 0 this.timer = null this.disposable = source.run(this, scheduler) } DebounceSink.prototype.event = function (t, x) { this._clearTimer() this.value = x this.timer = this.scheduler.delay(this.dt, new DebounceTask(this, x)) } DebounceSink.prototype._event = function (t, x) { this._clearTimer() this.sink.event(t, x) } DebounceSink.prototype.end = function (t, x) { if (this._clearTimer()) { this.sink.event(t, this.value) this.value = void 0 } this.sink.end(t, x) } DebounceSink.prototype.error = function (t, x) { this._clearTimer() this.sink.error(t, x) } DebounceSink.prototype.dispose = function () { this._clearTimer() return this.disposable.dispose() } DebounceSink.prototype._clearTimer = function () { if (this.timer === null) { return false } this.timer.dispose() this.timer = null return true } function DebounceTask (debounce, value) { this.debounce = debounce this.value = value } DebounceTask.prototype.run = function (t) { this.debounce._event(t, this.value) } DebounceTask.prototype.error = function (t, e) { this.debounce.error(t, e) } DebounceTask.prototype.dispose = function () {}