@@ -0,0 +1,1244 @@
1+var ControlStreamScheduler = require('../Control.Stream.Scheduler')
2+var ControlStreamStream = require('../Control.Stream.Stream')
3+
4+exports.drain = function (stream) { return function () { return runSource(stream, ControlStreamScheduler.scheduler) } }
5+
6+exports.subscribe = function (event) {
7+ return function (end) {
8+ return function (stream) {
9+ return function () {
10+ var disposable = new SettableDisposable()
11+
12+ var observer = { event: event, end: end }
13+
14+ var d = stream.run(observer)(ControlStreamScheduler.scheduler)
15+
16+ disposable.setDisposable(d)
17+
18+ return {}
19+ }
20+ }
21+ }
22+}
23+
24+function runSource (source, scheduler) {
25+ var disposable = new SettableDisposable()
26+
27+ function event (t) {
28+ return function (x) {
29+ return {}
30+ }
31+ }
32+
33+ function end (t) {
34+ disposable.dispose()
35+ return {}
36+ }
37+
38+ var observer = { event: event, end: end }
39+
40+ var d = source.run(observer)(scheduler)
41+
42+ disposable.setDisposable(d)
43+
44+ return {}
45+}
46+
47+var SettableDisposable = function SettableDisposable () {
48+ this.disposable = void 0
49+ this.disposed = false
50+ this.result = void 0
51+}
52+
53+SettableDisposable.prototype.setDisposable = function setDisposable (disposable) {
54+ this.disposable = disposable
55+
56+ if (this.disposed) {
57+ this.result = disposable.dispose()
58+ }
59+}
60+
61+SettableDisposable.prototype.dispose = function dispose () {
62+ if (this.disposed) {
63+ return this.result
64+ }
65+
66+ this.disposed = true
67+
68+ if (this.disposable !== void 0) {
69+ this.result = this.disposable.dispose()
70+ }
71+
72+ return this.result
73+}
74+
75+exports.fromArray = function (array) {
76+ return function (stream) {
77+ return new FromArray(array, stream)
78+ }
79+}
80+
81+function FromArray (array, stream) {
82+ this.array = array
83+ this.stream = stream
84+}
85+
86+FromArray.prototype.run = function (sink) {
87+ var that = this
88+
89+ return function (scheduler) {
90+ return that.stream.run(new FromArraySink(sink, that.array))(scheduler)
91+ }
92+}
93+
94+function FromArraySink (sink, array) {
95+ this.sink = sink
96+ this.array = array
97+}
98+
99+FromArraySink.prototype.event = function (time) {
100+ var array = this.array
101+ var sink = this.sink
102+ return function (x) {
103+ var value = array.shift()
104+
105+ if (value) {
106+ sink.event(time)(value)
107+ } else {
108+ sink.end(time)
109+ }
110+ }
111+}
112+
113+FromArraySink.prototype.end = function (time) {
114+ this.sink.end(time)
115+}
116+
117+var LinkedList = function LinkedList () {
118+ this.head = null
119+ this.length = 0
120+}
121+
122+LinkedList.prototype.add = function add (x) {
123+ if (this.head !== null) {
124+ this.head.prev = x
125+ x.next = this.head
126+ }
127+ this.head = x
128+ ++this.length
129+}
130+
131+LinkedList.prototype.remove = function remove (x) { // eslint-disable-line complexity
132+ --this.length
133+ if (x === this.head) {
134+ this.head = this.head.next
135+ }
136+ if (x.next !== null) {
137+ x.next.prev = x.prev
138+ x.next = null
139+ }
140+ if (x.prev !== null) {
141+ x.prev.next = x.next
142+ x.prev = null
143+ }
144+}
145+
146+LinkedList.prototype.isEmpty = function isEmpty () {
147+ return this.length === 0
148+}
149+
150+LinkedList.prototype.dispose = function dispose () {
151+ if (this.isEmpty()) { return }
152+
153+ var x = this.head
154+ this.head = null
155+ this.length = 0
156+
157+ while (x !== null) {
158+ x.dispose()
159+ x = x.next
160+ }
161+}
162+
163+exports.chain = function (f) {
164+ return function (stream) {
165+ return mergeMapConcurrently(f)(Infinity)(stream)
166+ }
167+}
168+
169+exports.mergeConcurrently = mergeConcurrently
170+
171+function mergeConcurrently (concurrency) {
172+ return function (stream) {
173+ return mergeMapConcurrently(function (x) { return x })(concurrency)(stream)
174+ }
175+}
176+
177+exports.join = mergeConcurrently(Infinity)
178+
179+exports.mergeMapConcurrently = mergeMapConcurrently
180+
181+function mergeMapConcurrently (f) {
182+ return function (concurrency) {
183+ return function (stream) {
184+ var mstream = new MergeConcurrently(f, concurrency, stream)
185+
186+ mstream.run.bind(mstream)
187+
188+ return mstream
189+ }
190+ }
191+}
192+
193+function MergeConcurrently (f, concurrency, source) {
194+ this.f = f
195+ this.concurrency = concurrency
196+ this.source = source
197+}
198+
199+MergeConcurrently.prototype.run = function run (sink) {
200+ var this$1 = this
201+
202+ return function (scheduler) { return new Outer(this$1.f, this$1.concurrency, this$1.source, sink, scheduler) }
203+}
204+
205+var Outer = function Outer (f, concurrency, source, sink, scheduler) {
206+ this.f = f
207+ this.concurrency = concurrency
208+ this.sink = sink
209+ this.scheduler = scheduler
210+ this.pending = []
211+ this.current = new LinkedList()
212+
213+ var disposed = false
214+ var disposable = source.run(this)(scheduler)
215+
216+ this.disposable = {
217+ dispose: function () {
218+ if (disposed) return
219+
220+ disposed = true
221+ disposable.dispose()
222+ }
223+ }
224+
225+ this.active = true
226+}
227+
228+Outer.prototype.event = function event (t) {
229+ var this$1 = this
230+
231+ return function (x) { return this$1._addInner(t, x) }
232+}
233+
234+Outer.prototype._addInner = function _addInner (t, x) {
235+ if (this.current.length < this.concurrency) {
236+ this._startInner(t, x)
237+ } else {
238+ this.pending.push(x)
239+ }
240+}
241+
242+Outer.prototype._startInner = function _startInner (t, x) {
243+ this._initInner(t, x)
244+}
245+
246+Outer.prototype._initInner = function _initInner (t, x) {
247+ var innerSink = new Inner(t, this, this.sink)
248+ innerSink.disposable = mapAndRun(this.f, x, innerSink, this.scheduler)
249+ this.current.add(innerSink)
250+}
251+
252+Outer.prototype.end = function end (t) {
253+ this.active = false
254+ this.disposable.dispose()
255+ this._checkEnd(t)
256+}
257+
258+Outer.prototype.dispose = function dispose () {
259+ this.active = false
260+ this.pending.length = 0
261+ this.disposable.dispose()
262+ this.current.dispose()
263+}
264+
265+Outer.prototype._endInner = function _endInner (t, inner) {
266+ this.current.remove(inner)
267+ inner.dispose()
268+
269+ if (this.pending.length === 0) {
270+ this._checkEnd(t)
271+ } else {
272+ this._startInner(t, this.pending.shift())
273+ }
274+}
275+
276+Outer.prototype._checkEnd = function _checkEnd (t) {
277+ if (!this.active && this.current.isEmpty()) {
278+ this.sink.end(t)
279+ }
280+}
281+
282+var mapAndRun = function (f, x, sink, scheduler) { return f(x).run(sink)(scheduler) }
283+
284+var Inner = function Inner (time, outer, sink) {
285+ this.prev = this.next = null
286+ this.time = time
287+ this.outer = outer
288+ this.sink = sink
289+ this.disposable = void 0
290+}
291+
292+Inner.prototype.event = function event (t) {
293+ var this$1 = this
294+
295+ return function (x) { return this$1.sink.event(Math.max(t, this$1.time))(x) }
296+}
297+
298+Inner.prototype.end = function end (t) {
299+ this.outer._endInner(Math.max(t, this.time), this)
300+}
301+
302+Inner.prototype.dispose = function dispose () {
303+ return this.disposable.dispose()
304+}
305+
306+exports.switch = function switchLatest (stream) {
307+ return new Switch(stream)
308+}
309+
310+function Switch (source) {
311+ this.source = source
312+}
313+
314+Switch.prototype.run = function (sink) {
315+ var this$1 = this
316+
317+ return function (scheduler) {
318+ var switchSink = new SwitchSink(sink, scheduler)
319+ var disposable = this$1.source.run(switchSink)(scheduler)
320+
321+ return {
322+ dispose: function () {
323+ switchSink.dispose()
324+ disposable.dispose()
325+ }
326+ }
327+ }
328+}
329+
330+function SwitchSink (sink, scheduler) {
331+ this.sink = sink
332+ this.scheduler = scheduler
333+ this.current = null
334+ this.ended = false
335+}
336+
337+SwitchSink.prototype.event = function (t) {
338+ var this$1 = this
339+
340+ return function (stream) {
341+ this$1._disposeCurrent(t) // TODO: capture the result of this dispose
342+ this$1.current = new Segment(t, Infinity, this$1, this$1.sink)
343+ this$1.current.disposable = stream.run(this$1.current)(this$1.scheduler)
344+ }
345+}
346+
347+SwitchSink.prototype.end = function (t, x) {
348+ this.ended = true
349+ this._checkEnd(t, x)
350+}
351+
352+SwitchSink.prototype.dispose = function () {
353+ return this._disposeCurrent(this.scheduler.now())
354+}
355+
356+SwitchSink.prototype._disposeCurrent = function (t) {
357+ if (this.current !== null) {
358+ return this.current._dispose(t)
359+ }
360+}
361+
362+SwitchSink.prototype._disposeInner = function (t, inner) {
363+ inner._dispose(t) // TODO: capture the result of this dispose
364+ if (inner === this.current) {
365+ this.current = null
366+ }
367+}
368+
369+SwitchSink.prototype._checkEnd = function (t, x) {
370+ if (this.ended && this.current === null) {
371+ this.sink.end(t, x)
372+ }
373+}
374+
375+SwitchSink.prototype._endInner = function (t, x, inner) {
376+ this._disposeInner(t, inner)
377+ this._checkEnd(t, x)
378+}
379+
380+function Segment (min, max, outer, sink) {
381+ this.min = min
382+ this.max = max
383+ this.outer = outer
384+ this.sink = sink
385+ this.disposable = { dispose: Function.prototype }
386+}
387+
388+Segment.prototype.event = function (t) {
389+ var this$1 = this
390+
391+ return function (x) {
392+ if (t < this$1.max) {
393+ this$1.sink.event(Math.max(t, this$1.min))(x)
394+ }
395+ }
396+}
397+
398+Segment.prototype.end = function (t, x) {
399+ this.outer._endInner(Math.max(t, this.min), x, this)
400+}
401+
402+Segment.prototype._dispose = function (t) {
403+ this.max = t
404+ this.disposable.dispose()
405+}
406+
407+exports.continueWith = function continueWith (f) {
408+ return function (stream) {
409+ return new ContinueWith(f, stream)
410+ }
411+}
412+
413+function ContinueWith (f, source) {
414+ this.f = f
415+ this.source = source
416+}
417+
418+ContinueWith.prototype.run = function (sink) {
419+ var that = this
420+ return function (scheduler) {
421+ return new ContinueWithSink(that.f, that.source, sink, scheduler)
422+ }
423+}
424+
425+function ContinueWithSink (f, source, sink, scheduler) {
426+ this.f = f
427+ this.sink = sink
428+ this.scheduler = scheduler
429+ this.active = true
430+ this.disposable = source.run(this)(scheduler)
431+}
432+
433+ContinueWithSink.prototype.event = function (t) {
434+ var that = this
435+
436+ return function (x) {
437+ if (!that.active) {
438+ return
439+ }
440+ that.sink.event(t)(x)
441+ }
442+}
443+
444+ContinueWithSink.prototype.end = function (t, x) {
445+ if (!this.active) {
446+ return
447+ }
448+
449+ this.disposable.dispose()
450+
451+ this._startNext(t, x, this.sink)
452+}
453+
454+ContinueWithSink.prototype._startNext = function (t, x, sink) {
455+ try {
456+ this.disposable = this._continue(this.f, x, sink)
457+ } catch (e) {
458+ sink.error(t, e)
459+ }
460+}
461+
462+ContinueWithSink.prototype._continue = function (f, x, sink) {
463+ return f(x).run(sink)(this.scheduler)
464+}
465+
466+ContinueWithSink.prototype.dispose = function () {
467+ this.active = false
468+ return this.disposable.dispose()
469+}
470+
471+exports.combine2 = function (f) { return function (s1) { return function (s2) { return combineArray(f, [s1, s2]) } } }
472+exports.combine3 = function (f) { return function (s1) { return function (s2) { return function (s3) { return combineArray(f, [s1, s2, s3]) } } } }
473+exports.combine4 = function (f) { return function (s1) { return function (s2) { return function (s3) { return function (s4) { return combineArray(f, [s1, s2, s3, s4]) } } } } }
474+exports.combine5 = function (f) { return function (s1) { return function (s2) { return function (s3) { return function (s4) { return function (s5) { return combineArray(f, [s1, s2, s3, s4, s5]) } } } } } }
475+
476+exports.combineArray = function (streams) {
477+ return combineArray(Array, streams)
478+}
479+
480+function combineArray (f, streams) {
481+ return new Combine(f, streams)
482+}
483+
484+function Combine (f, sources) {
485+ this.f = f
486+ this.sources = sources
487+}
488+
489+Combine.prototype.run = function (sink) {
490+ var this$1 = this
491+
492+ return function (scheduler) {
493+ var l = this$1.sources.length
494+ var disposables = new Array(l)
495+ var sinks = new Array(l)
496+
497+ var mergeSink = new CombineSink(disposables, sinks, sink, this$1.f)
498+
499+ for (var indexSink, i = 0; i < l; ++i) {
500+ indexSink = sinks[i] = new IndexSink(i, mergeSink)
501+ disposables[i] = this$1.sources[i].run(indexSink)(scheduler)
502+ }
503+
504+ return {
505+ dispose: function () {
506+ disposables.forEach(function (d) {
507+ d.dispose()
508+ })
509+ }
510+ }
511+ }
512+}
513+
514+function CombineSink (disposables, sinks, sink, f) {
515+ var this$1 = this
516+
517+ this.sink = sink
518+ this.disposables = disposables
519+ this.sinks = sinks
520+ this.f = f
521+
522+ var l = sinks.length
523+ this.awaiting = l
524+ this.values = new Array(l)
525+ this.hasValue = new Array(l)
526+
527+ for (var i = 0; i < l; ++i) {
528+ this$1.hasValue[i] = false
529+ }
530+
531+ this.activeCount = sinks.length
532+}
533+
534+CombineSink.prototype.event = function (t) {
535+ var this$1 = this
536+
537+ return function (indexedValue) {
538+ var i = indexedValue.index
539+ var awaiting = this$1._updateReady(i)
540+
541+ this$1.values[i] = indexedValue.value
542+ if (awaiting === 0) {
543+ var value = tail(this$1.values).reduce(function (f, x) { return f(x) }, this$1.f(this$1.values[0]))
544+ this$1.sink.event(t)(value)
545+ }
546+ }
547+}
548+
549+CombineSink.prototype._updateReady = function (index) {
550+ if (this.awaiting > 0) {
551+ if (!this.hasValue[index]) {
552+ this.hasValue[index] = true
553+ this.awaiting -= 1
554+ }
555+ }
556+ return this.awaiting
557+}
558+
559+CombineSink.prototype.end = function (t, indexedValue) {
560+ this.disposables[indexedValue.index].dispose()
561+
562+ if (--this.activeCount === 0) {
563+ this.sink.end(t)
564+ }
565+}
566+
567+var IndexSink = function IndexSink (i, sink) {
568+ this.sink = sink
569+ this.index = i
570+ this.active = true
571+ this.value = void 0
572+}
573+
574+IndexSink.prototype.event = function event (t) {
575+ var this$1 = this
576+
577+ return function (x) {
578+ if (!this$1.active) { return }
579+
580+ this$1.value = x
581+ this$1.sink.event(t)(this$1)
582+ }
583+}
584+
585+IndexSink.prototype.end = function end (t) {
586+ if (!this.active) { return }
587+
588+ this.active = false
589+ this.sink.end(t, { index: this.index })
590+}
591+
592+function drop (n, a) { // eslint-disable-line complexity
593+ if (n < 0) {
594+ throw new TypeError('n must be >= 0')
595+ }
596+
597+ var l = a.length
598+ if (n === 0 || l === 0) {
599+ return a
600+ }
601+
602+ if (n >= l) {
603+ return []
604+ }
605+
606+ return unsafeDrop(n, a, l - n)
607+}
608+
609+// unsafeDrop :: Int -> [a] -> Int -> [a]
610+// Internal helper for drop
611+function unsafeDrop (n, a, l) {
612+ var b = new Array(l)
613+ for (var i = 0; i < l; ++i) {
614+ b[i] = a[n + i]
615+ }
616+ return b
617+}
618+
619+// tail :: [a] -> [a]
620+// drop head element
621+function tail (a) {
622+ return drop(1, a)
623+}
624+
625+exports.merge = function merge (streams) {
626+ return mergeSources(streams)
627+}
628+
629+/**
630+ * This implements fusion/flattening for merge. It will
631+ * fuse adjacent merge operations. For example:
632+ * - a.merge(b).merge(c) effectively becomes merge(a, b, c)
633+ * - merge(a, merge(b, c)) effectively becomes merge(a, b, c)
634+ * It does this by concatenating the sources arrays of
635+ * any nested Merge sources, in effect "flattening" nested
636+ * merge operations into a single merge.
637+ */
638+function mergeSources (streams) {
639+ return new Merge(reduce(appendSources, [], streams))
640+}
641+
642+function appendSources (sources, stream) {
643+ return stream instanceof Merge
644+ ? sources.concat(stream.sources)
645+ : sources.concat(stream)
646+}
647+
648+function Merge (sources) {
649+ this.sources = sources
650+}
651+
652+Merge.prototype.run = function (sink) {
653+ var this$1 = this
654+
655+ return function (scheduler) {
656+ var l = this.sources.length
657+ var disposables = new Array(l)
658+ var sinks = new Array(l)
659+
660+ var mergeSink = new MergeSink(disposables, sinks, sink)
661+
662+ for (var indexSink, i = 0; i < l; ++i) {
663+ indexSink = sinks[i] = new IndexSink(i, mergeSink)
664+ disposables[i] = this$1.sources[i].run(indexSink, scheduler)
665+ }
666+
667+ return all(disposables)
668+ }
669+}
670+
671+function all (disposables) {
672+ return {
673+ dispose: function () {
674+ disposables.forEach(function (d) {
675+ d.dispose()
676+ })
677+ }
678+ }
679+}
680+
681+function MergeSink (disposables, sinks, sink) {
682+ this.sink = sink
683+ this.disposables = disposables
684+ this.activeCount = sinks.length
685+}
686+
687+MergeSink.prototype.event = function (t) {
688+ var that = this
689+ return function (indexValue) {
690+ that.sink.event(t)(indexValue.value)
691+ }
692+}
693+
694+MergeSink.prototype.end = function (t, indexedValue) {
695+ this.disposables[indexedValue.index].dispose()
696+ if (--this.activeCount === 0) {
697+ this.sink.end(t, indexedValue.value)
698+ }
699+}
700+
701+function reduce (f, z, a) {
702+ var r = z
703+ for (var i = 0, l = a.length; i < l; ++i) {
704+ r = f(r, a[i], i)
705+ }
706+ return r
707+}
708+
709+exports.until = function takeUntil (signal) {
710+ return function (stream) {
711+ return new Until(signal, stream)
712+ }
713+}
714+
715+exports.since = function skipUntil (signal) {
716+ return function (stream) {
717+ return new Since(signal, stream)
718+ }
719+}
720+
721+function Until (maxSignal, source) {
722+ this.maxSignal = maxSignal
723+ this.source = source
724+}
725+
726+Until.prototype.run = function (sink) {
727+ var that = this
728+ return function (scheduler) {
729+ var min = new Bound(-Infinity, sink)
730+ var max = new UpperBound(that.maxSignal, sink, scheduler)
731+ var disposable = that.source.run(new TimeWindowSink(min, max, sink), scheduler)
732+
733+ return all([min, max, disposable])
734+ }
735+}
736+
737+function Since (minSignal, source) {
738+ this.minSignal = minSignal
739+ this.source = source
740+}
741+
742+Since.prototype.run = function (sink) {
743+ var that = this
744+ return function (scheduler) {
745+ var min = new LowerBound(that.minSignal, sink, scheduler)
746+ var max = new Bound(Infinity, sink)
747+ var disposable = that.source.run(new TimeWindowSink(min, max, sink))(scheduler)
748+
749+ return all([min, max, disposable])
750+ }
751+}
752+
753+function Bound (value, sink) {
754+ this.value = value
755+ this.sink = sink
756+}
757+
758+Bound.prototype.event = noop
759+Bound.prototype.end = noop
760+Bound.prototype.dispose = noop
761+
762+function TimeWindowSink (min, max, sink) {
763+ this.min = min
764+ this.max = max
765+ this.sink = sink
766+}
767+
768+TimeWindowSink.prototype.event = function (t, x) {
769+ var that = this
770+ return function (x) {
771+ if (t >= that.min.value && t < that.max.value) {
772+ that.sink.event(t)(x)
773+ }
774+ }
775+}
776+
777+TimeWindowSink.prototype.end = function (time) {
778+ this.sink.end(time)
779+}
780+
781+function LowerBound (signal, sink, scheduler) {
782+ this.value = Infinity
783+ this.sink = sink
784+ this.disposable = signal.run(this)(scheduler)
785+}
786+
787+LowerBound.prototype.event = function (t /*, x */) {
788+ return function () {
789+ if (t < this.value) {
790+ this.value = t
791+ }
792+ }
793+}
794+
795+LowerBound.prototype.end = noop
796+
797+LowerBound.prototype.dispose = function () {
798+ return this.disposable.dispose()
799+}
800+
801+function UpperBound (signal, sink, scheduler) {
802+ this.value = Infinity
803+ this.sink = sink
804+ this.disposable = signal.run(this)(scheduler)
805+}
806+
807+UpperBound.prototype.event = function (t) {
808+ var that = this
809+
810+ return function (x) {
811+ if (t < this.value) {
812+ that.value = t
813+ that.sink.end(t)
814+ }
815+ }
816+}
817+
818+UpperBound.prototype.end = noop
819+
820+UpperBound.prototype.dispose = function () {
821+ return this.disposable.dispose()
822+}
823+
824+function noop () { }
825+
826+exports.throttle = function throttle (period) {
827+ return function (stream) {
828+ return throttleSource(period, stream)
829+ }
830+}
831+
832+function throttleSource (period, source) {
833+ return source instanceof Throttle
834+ ? fuseThrottle(period, source)
835+ : new Throttle(period, source)
836+}
837+
838+function fuseThrottle (period, source) {
839+ return new Throttle(Math.max(period, source.period), source.source)
840+}
841+
842+function Throttle (period, source) {
843+ this.period = period
844+ this.source = source
845+}
846+
847+Throttle.prototype.run = function (sink) {
848+ var that = this
849+ return function (scheduler) {
850+ return that.source.run(new ThrottleSink(that.period, sink), scheduler)
851+ }
852+}
853+
854+function ThrottleSink (period, sink) {
855+ this.time = 0
856+ this.period = period
857+ this.sink = sink
858+}
859+
860+ThrottleSink.prototype.event = function (t) {
861+ var that = this
862+ return function (x) {
863+ if (t >= this.time) {
864+ that.time = t + this.period
865+ that.sink.event(t)(x)
866+ }
867+ }
868+}
869+
870+ThrottleSink.prototype.end = function (t) { this.sink.end(t) }
871+
872+exports.debounce = function debounce (period) {
873+ return function (stream) {
874+ return new Debounce(period, stream)
875+ }
876+}
877+
878+function Debounce (dt, source) {
879+ this.dt = dt
880+ this.source = source
881+}
882+
883+Debounce.prototype.run = function (sink) {
884+ var that = this
885+ return function (scheduler) {
886+ return new DebounceSink(that.dt, that.source, sink, scheduler)
887+ }
888+}
889+
890+function DebounceSink (dt, source, sink, scheduler) {
891+ this.dt = dt
892+ this.sink = sink
893+ this.scheduler = scheduler
894+ this.value = void 0
895+ this.timer = null
896+
897+ var sourceDisposable = source.run(this)(scheduler)
898+ this.disposable = all([this, sourceDisposable])
899+}
900+
901+DebounceSink.prototype.event = function (t) {
902+ var that = this
903+ return function (x) {
904+ that._clearTimer()
905+ that.value = x
906+ var task = ControlStreamScheduler.eventTask(that.sink)(x)
907+ that.timer = this.scheduler.delay(this.dt, task)
908+ }
909+}
910+
911+DebounceSink.prototype.end = function (t, x) {
912+ if (this._clearTimer()) {
913+ this.sink.event(t, this.value)
914+ this.value = void 0
915+ }
916+ this.sink.end(t, x)
917+}
918+
919+DebounceSink.prototype.dispose = function () {
920+ this._clearTimer()
921+}
922+
923+DebounceSink.prototype._clearTimer = function () {
924+ if (this.timer === null) {
925+ return false
926+ }
927+ this.timer.dispose()
928+ this.timer = null
929+ return true
930+}
931+
932+exports.delay = function delay (delayTime) {
933+ return function (stream) {
934+ return delayTime <= 0 ? stream : new Delay(delayTime, stream)
935+ }
936+}
937+
938+function Delay (dt, source) {
939+ this.dt = dt
940+ this.source = source
941+}
942+
943+Delay.prototype.run = function (sink) {
944+ var that = this
945+
946+ return function (scheduler) {
947+ var delaySink = new DelaySink(that.dt, sink, scheduler)
948+ return all([delaySink, that.source.run(delaySink)(scheduler)])
949+ }
950+}
951+
952+function DelaySink (dt, sink, scheduler) {
953+ this.dt = dt
954+ this.sink = sink
955+ this.scheduler = scheduler
956+}
957+
958+DelaySink.prototype.dispose = function () {
959+ var self = this
960+ this.scheduler.cancelAll(function (task) {
961+ return task.sink === self.sink
962+ })
963+}
964+
965+DelaySink.prototype.event = function (t) {
966+ var that = this
967+ return function (x) {
968+ that.scheduler.delay(that.dt)(ControlStreamScheduler.eventTask(that.sink)(x))
969+ }
970+}
971+
972+DelaySink.prototype.end = function (t, x) {
973+ this.scheduler.delay(this.dt)(ControlStreamScheduler.endTask(this.sink))
974+}
975+
976+var MulticastDisposable = function MulticastDisposable (source, sink) {
977+ this.source = source
978+ this.sink = sink
979+ this.disposed = false
980+}
981+
982+MulticastDisposable.prototype.dispose = function dispose () {
983+ if (this.disposed) {
984+ return
985+ }
986+ this.disposed = true
987+ var remaining = this.source.remove(this.sink)
988+ return remaining === 0 && this.source._dispose()
989+}
990+
991+var dispose = function (disposable) { return disposable.dispose() }
992+
993+var emptyDisposable = {
994+ dispose: function dispose$1 () { }
995+}
996+
997+function MulticastSource (source) {
998+ this.source = source
999+ this.sinks = []
1000+ this._disposable = emptyDisposable
1001+}
1002+
1003+MulticastSource.prototype.run = function run (sink) {
1004+ var that = this
1005+ return function (scheduler) {
1006+ var n = that.add(sink)
1007+ if (n === 1) {
1008+ that._disposable = that.source.run(that)(scheduler)
1009+ }
1010+ return new MulticastDisposable(that, sink)
1011+ }
1012+}
1013+
1014+MulticastSource.prototype._dispose = function _dispose () {
1015+ var disposable = this._disposable
1016+ this._disposable = emptyDisposable
1017+ return Promise.resolve(disposable).then(dispose)
1018+}
1019+
1020+MulticastSource.prototype.add = function add (sink) {
1021+ this.sinks = append(sink, this.sinks)
1022+ return this.sinks.length
1023+}
1024+
1025+function append (x, a) {
1026+ var l = a.length
1027+ var b = new Array(l + 1)
1028+ for (var i = 0; i < l; ++i) {
1029+ b[i] = a[i]
1030+ }
1031+
1032+ b[l] = x
1033+ return b
1034+}
1035+
1036+MulticastSource.prototype.remove = function remove$1 (sink) {
1037+ var i = findIndex(sink, this.sinks)
1038+ // istanbul ignore next
1039+ if (i >= 0) {
1040+ this.sinks = remove(i, this.sinks)
1041+ }
1042+
1043+ return this.sinks.length
1044+}
1045+
1046+function findIndex (x, a) {
1047+ for (var i = 0, l = a.length; i < l; ++i) {
1048+ if (x === a[i]) {
1049+ return i
1050+ }
1051+ }
1052+ return -1
1053+}
1054+
1055+function remove (i, a) { // eslint-disable-line complexity
1056+ if (i < 0) {
1057+ throw new TypeError('i must be >= 0')
1058+ }
1059+
1060+ var l = a.length
1061+ if (l === 0 || i >= l) { // exit early if index beyond end of array
1062+ return a
1063+ }
1064+
1065+ if (l === 1) { // exit early if index in bounds and length === 1
1066+ return []
1067+ }
1068+
1069+ return unsafeRemove(i, a, l - 1)
1070+}
1071+
1072+// unsafeRemove :: Int -> [a] -> Int -> [a]
1073+// Internal helper to remove element at index
1074+function unsafeRemove (i, a, l) {
1075+ var b = new Array(l)
1076+ var j
1077+ for (j = 0; j < i; ++j) {
1078+ b[j] = a[j]
1079+ }
1080+ for (j = i; j < l; ++j) {
1081+ b[j] = a[j + 1]
1082+ }
1083+
1084+ return b
1085+}
1086+
1087+MulticastSource.prototype.event = function event (time) {
1088+ var that = this
1089+ return function (value) {
1090+ var s = that.sinks
1091+ if (s.length === 1) {
1092+ return s[0].event(time)(value)
1093+ }
1094+ for (var i = 0; i < s.length; ++i) {
1095+ s[i].event(time)(value)
1096+ }
1097+ }
1098+}
1099+
1100+MulticastSource.prototype.end = function end (time) {
1101+ var s = this.sinks
1102+ for (var i = 0; i < s.length; ++i) {
1103+ s[i].end(time)
1104+ }
1105+}
1106+
1107+MulticastSource.prototype.until = function (signal) {
1108+ return exports.until(signal)(this)
1109+}
1110+
1111+exports.multicast = function multicast (stream) {
1112+ return new MulticastSource(stream)
1113+}
1114+
1115+function __extends (d, b) { // eslint-disable-line complexity
1116+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]
1117+ function __ () { this.constructor = d }
1118+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __())
1119+}
1120+
1121+var HoldSubjectSource = (function (_super) {
1122+ __extends(HoldSubjectSource, _super)
1123+ function HoldSubjectSource (source, bufferSize) {
1124+ var _this = _super.call(this, source) || this
1125+ _this.has = false
1126+ _this.buffer = []
1127+ _this.bufferSize = bufferSize
1128+ return _this
1129+ }
1130+ HoldSubjectSource.prototype.add = function (sink) {
1131+ if (this.has) {
1132+ pushEvents(this.buffer, sink)
1133+ }
1134+ return _super.prototype.add.call(this, sink)
1135+ }
1136+ HoldSubjectSource.prototype.event = function (time) {
1137+ var that = this
1138+ return function (value) {
1139+ that.has = true
1140+ that.buffer = dropAndAppend(value, that.buffer, that.bufferSize)
1141+ return _super.prototype.event.call(that, time)(value)
1142+ }
1143+ }
1144+ return HoldSubjectSource
1145+}(MulticastSource))
1146+
1147+function pushEvents (buffer, sink) {
1148+ var length = buffer.length
1149+ for (var i = 0; i < length; ++i) {
1150+ sink.event(ControlStreamScheduler.scheduler.now(), buffer[i])
1151+ }
1152+}
1153+
1154+function dropAndAppend (value, buffer, bufferSize) {
1155+ if (buffer.length === bufferSize) {
1156+ return append(value, drop(1, buffer))
1157+ }
1158+ return append(value, buffer)
1159+}
1160+
1161+exports.hold = function hold (bufferSize) {
1162+ return function (stream) {
1163+ return new HoldSubjectSource(stream, bufferSize)
1164+ }
1165+}
1166+
1167+exports.toSubject = function (stream) {
1168+ return exports.multicast(stream)
1169+}
1170+
1171+exports.toHoldSubject = exports.hold
1172+
1173+exports.fromSubject = function (subject) {
1174+ return subject
1175+}
1176+
1177+exports.subjectEvent = function (value) {
1178+ return function (subject) {
1179+ ControlStreamScheduler.eventTask(subject)(value)
1180+ return subject
1181+ }
1182+}
1183+
1184+exports.subjectEnd = function (value) {
1185+ return function (subject) {
1186+ subject.end(Date.now())
1187+ return subject
1188+ }
1189+}
1190+
1191+exports.proxy = function (value) {
1192+ var stream = new ProxyStream(value)
1193+
1194+ function attach (original) {
1195+ stream.attach(original)
1196+ return original
1197+ }
1198+
1199+ return { attach: attach, stream: stream }
1200+}
1201+
1202+var ProxyStream = (function (_super) {
1203+ __extends(ProxyStream, _super)
1204+ function ProxyStream (value) {
1205+ var _this = _super.call(this, ControlStreamStream.never, 1) || this
1206+ _this.attached = false
1207+ _this.running = false
1208+ _this.buffer.push(value)
1209+ return _this
1210+ }
1211+ ProxyStream.prototype.run = function (sink) {
1212+ var that = this
1213+
1214+ that.add(sink)
1215+
1216+ return function (scheduler) {
1217+ if (that.attached && !that.running) {
1218+ that.running = true
1219+ that._disposable = that.source.run(that)(scheduler)
1220+ return that._disposable
1221+ }
1222+
1223+ return new MulticastDisposable(that, sink)
1224+ }
1225+ }
1226+
1227+ ProxyStream.prototype.attach = function (source) {
1228+ if (this.attached) throw new Error('Can only proxy 1 stream')
1229+ this.attached = true
1230+
1231+ this.source = source
1232+
1233+ if (this.sinks.length) { this._disposable = source.run(this)(ControlStreamScheduler.scheduler) }
1234+ }
1235+
1236+ ProxyStream.prototype.end = function end (time) {
1237+ this.attached = false
1238+ this.running = false
1239+
1240+ return _super.prototype.end.call(this, time)
1241+ }
1242+
1243+ return ProxyStream
1244+}(HoldSubjectSource))