rxjs-rails 2.3.0 → 2.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rxjs/rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/rx.aggregates.js +115 -27
  4. data/vendor/assets/javascripts/rx.aggregates.min.js +1 -1
  5. data/vendor/assets/javascripts/rx.all.compat.js +2751 -2702
  6. data/vendor/assets/javascripts/rx.all.compat.min.js +3 -3
  7. data/vendor/assets/javascripts/rx.all.js +2605 -2589
  8. data/vendor/assets/javascripts/rx.all.min.js +3 -3
  9. data/vendor/assets/javascripts/rx.async.compat.js +41 -22
  10. data/vendor/assets/javascripts/rx.async.compat.min.js +1 -1
  11. data/vendor/assets/javascripts/rx.async.js +41 -22
  12. data/vendor/assets/javascripts/rx.async.min.js +1 -1
  13. data/vendor/assets/javascripts/rx.backpressure.js +41 -45
  14. data/vendor/assets/javascripts/rx.backpressure.min.js +1 -1
  15. data/vendor/assets/javascripts/rx.binding.js +81 -111
  16. data/vendor/assets/javascripts/rx.binding.min.js +1 -1
  17. data/vendor/assets/javascripts/rx.coincidence.js +567 -486
  18. data/vendor/assets/javascripts/rx.coincidence.min.js +1 -1
  19. data/vendor/assets/javascripts/rx.compat.js +1430 -1532
  20. data/vendor/assets/javascripts/rx.compat.min.js +2 -2
  21. data/vendor/assets/javascripts/rx.core.compat.js +76 -127
  22. data/vendor/assets/javascripts/rx.core.compat.min.js +1 -1
  23. data/vendor/assets/javascripts/rx.core.js +76 -127
  24. data/vendor/assets/javascripts/rx.core.min.js +1 -1
  25. data/vendor/assets/javascripts/rx.experimental.js +36 -36
  26. data/vendor/assets/javascripts/rx.experimental.min.js +1 -1
  27. data/vendor/assets/javascripts/rx.joinpatterns.js +281 -281
  28. data/vendor/assets/javascripts/rx.js +1286 -1421
  29. data/vendor/assets/javascripts/rx.lite.compat.js +1443 -1749
  30. data/vendor/assets/javascripts/rx.lite.compat.min.js +2 -2
  31. data/vendor/assets/javascripts/rx.lite.extras.js +133 -205
  32. data/vendor/assets/javascripts/rx.lite.extras.min.js +1 -1
  33. data/vendor/assets/javascripts/rx.lite.js +1319 -1658
  34. data/vendor/assets/javascripts/rx.lite.min.js +2 -2
  35. data/vendor/assets/javascripts/rx.min.js +2 -2
  36. data/vendor/assets/javascripts/rx.testing.js +302 -322
  37. data/vendor/assets/javascripts/rx.testing.min.js +1 -1
  38. data/vendor/assets/javascripts/rx.time.js +90 -75
  39. data/vendor/assets/javascripts/rx.time.min.js +1 -1
  40. data/vendor/assets/javascripts/rx.virtualtime.js +264 -279
  41. data/vendor/assets/javascripts/rx.virtualtime.min.js +1 -1
  42. metadata +10 -11
@@ -1,4 +1,4 @@
1
- // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
1
+ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
2
2
 
3
3
  ;(function (undefined) {
4
4
 
@@ -41,7 +41,7 @@
41
41
  defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
42
42
  defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
43
43
  defaultError = Rx.helpers.defaultError = function (err) { throw err; },
44
- isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.then === 'function' && p.then !== Rx.Observable.prototype.then; },
44
+ isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.then === 'function'; },
45
45
  asArray = Rx.helpers.asArray = function () { return Array.prototype.slice.call(arguments); },
46
46
  not = Rx.helpers.not = function (a) { return !a; };
47
47
 
@@ -82,9 +82,9 @@
82
82
  propertyIsEnumerable = objectProto.propertyIsEnumerable;
83
83
 
84
84
  try {
85
- suportNodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
85
+ suportNodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
86
86
  } catch(e) {
87
- suportNodeClass = true;
87
+ suportNodeClass = true;
88
88
  }
89
89
 
90
90
  var shadowedProps = [
@@ -395,191 +395,169 @@
395
395
  return a;
396
396
  }
397
397
 
398
- // Collections
399
- var IndexedItem = function (id, value) {
400
- this.id = id;
401
- this.value = value;
402
- };
403
-
404
- IndexedItem.prototype.compareTo = function (other) {
405
- var c = this.value.compareTo(other.value);
406
- if (c === 0) {
407
- c = this.id - other.id;
408
- }
409
- return c;
410
- };
411
-
412
- // Priority Queue for Scheduling
413
- var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
414
- this.items = new Array(capacity);
415
- this.length = 0;
416
- };
417
-
418
- var priorityProto = PriorityQueue.prototype;
419
- priorityProto.isHigherPriority = function (left, right) {
420
- return this.items[left].compareTo(this.items[right]) < 0;
421
- };
422
-
423
- priorityProto.percolate = function (index) {
424
- if (index >= this.length || index < 0) {
425
- return;
426
- }
427
- var parent = index - 1 >> 1;
428
- if (parent < 0 || parent === index) {
429
- return;
430
- }
431
- if (this.isHigherPriority(index, parent)) {
432
- var temp = this.items[index];
433
- this.items[index] = this.items[parent];
434
- this.items[parent] = temp;
435
- this.percolate(parent);
436
- }
437
- };
438
-
439
- priorityProto.heapify = function (index) {
440
- if (index === undefined) {
441
- index = 0;
442
- }
443
- if (index >= this.length || index < 0) {
444
- return;
445
- }
446
- var left = 2 * index + 1,
447
- right = 2 * index + 2,
448
- first = index;
449
- if (left < this.length && this.isHigherPriority(left, first)) {
450
- first = left;
451
- }
452
- if (right < this.length && this.isHigherPriority(right, first)) {
453
- first = right;
454
- }
455
- if (first !== index) {
456
- var temp = this.items[index];
457
- this.items[index] = this.items[first];
458
- this.items[first] = temp;
459
- this.heapify(first);
460
- }
461
- };
462
-
463
- priorityProto.peek = function () { return this.items[0].value; };
464
-
465
- priorityProto.removeAt = function (index) {
466
- this.items[index] = this.items[--this.length];
467
- delete this.items[this.length];
468
- this.heapify();
469
- };
470
-
471
- priorityProto.dequeue = function () {
472
- var result = this.peek();
473
- this.removeAt(0);
474
- return result;
475
- };
476
-
477
- priorityProto.enqueue = function (item) {
478
- var index = this.length++;
479
- this.items[index] = new IndexedItem(PriorityQueue.count++, item);
480
- this.percolate(index);
481
- };
482
-
483
- priorityProto.remove = function (item) {
484
- for (var i = 0; i < this.length; i++) {
485
- if (this.items[i].value === item) {
486
- this.removeAt(i);
487
- return true;
488
- }
489
- }
490
- return false;
491
- };
398
+ // Collections
399
+ var IndexedItem = function (id, value) {
400
+ this.id = id;
401
+ this.value = value;
402
+ };
403
+
404
+ IndexedItem.prototype.compareTo = function (other) {
405
+ var c = this.value.compareTo(other.value);
406
+ if (c === 0) {
407
+ c = this.id - other.id;
408
+ }
409
+ return c;
410
+ };
411
+
412
+ // Priority Queue for Scheduling
413
+ var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
414
+ this.items = new Array(capacity);
415
+ this.length = 0;
416
+ };
417
+
418
+ var priorityProto = PriorityQueue.prototype;
419
+ priorityProto.isHigherPriority = function (left, right) {
420
+ return this.items[left].compareTo(this.items[right]) < 0;
421
+ };
422
+
423
+ priorityProto.percolate = function (index) {
424
+ if (index >= this.length || index < 0) {
425
+ return;
426
+ }
427
+ var parent = index - 1 >> 1;
428
+ if (parent < 0 || parent === index) {
429
+ return;
430
+ }
431
+ if (this.isHigherPriority(index, parent)) {
432
+ var temp = this.items[index];
433
+ this.items[index] = this.items[parent];
434
+ this.items[parent] = temp;
435
+ this.percolate(parent);
436
+ }
437
+ };
438
+
439
+ priorityProto.heapify = function (index) {
440
+ if (index === undefined) {
441
+ index = 0;
442
+ }
443
+ if (index >= this.length || index < 0) {
444
+ return;
445
+ }
446
+ var left = 2 * index + 1,
447
+ right = 2 * index + 2,
448
+ first = index;
449
+ if (left < this.length && this.isHigherPriority(left, first)) {
450
+ first = left;
451
+ }
452
+ if (right < this.length && this.isHigherPriority(right, first)) {
453
+ first = right;
454
+ }
455
+ if (first !== index) {
456
+ var temp = this.items[index];
457
+ this.items[index] = this.items[first];
458
+ this.items[first] = temp;
459
+ this.heapify(first);
460
+ }
461
+ };
462
+
463
+ priorityProto.peek = function () { return this.items[0].value; };
464
+
465
+ priorityProto.removeAt = function (index) {
466
+ this.items[index] = this.items[--this.length];
467
+ delete this.items[this.length];
468
+ this.heapify();
469
+ };
470
+
471
+ priorityProto.dequeue = function () {
472
+ var result = this.peek();
473
+ this.removeAt(0);
474
+ return result;
475
+ };
476
+
477
+ priorityProto.enqueue = function (item) {
478
+ var index = this.length++;
479
+ this.items[index] = new IndexedItem(PriorityQueue.count++, item);
480
+ this.percolate(index);
481
+ };
482
+
483
+ priorityProto.remove = function (item) {
484
+ for (var i = 0; i < this.length; i++) {
485
+ if (this.items[i].value === item) {
486
+ this.removeAt(i);
487
+ return true;
488
+ }
489
+ }
490
+ return false;
491
+ };
492
492
  PriorityQueue.count = 0;
493
- /**
494
- * Represents a group of disposable resources that are disposed together.
495
- * @constructor
496
- */
497
- var CompositeDisposable = Rx.CompositeDisposable = function () {
498
- this.disposables = argsOrArray(arguments, 0);
499
- this.isDisposed = false;
500
- this.length = this.disposables.length;
501
- };
502
-
503
- var CompositeDisposablePrototype = CompositeDisposable.prototype;
504
-
505
- /**
506
- * Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
507
- * @param {Mixed} item Disposable to add.
508
- */
509
- CompositeDisposablePrototype.add = function (item) {
510
- if (this.isDisposed) {
511
- item.dispose();
512
- } else {
513
- this.disposables.push(item);
514
- this.length++;
515
- }
516
- };
517
-
518
- /**
519
- * Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
520
- * @param {Mixed} item Disposable to remove.
521
- * @returns {Boolean} true if found; false otherwise.
522
- */
523
- CompositeDisposablePrototype.remove = function (item) {
524
- var shouldDispose = false;
525
- if (!this.isDisposed) {
526
- var idx = this.disposables.indexOf(item);
527
- if (idx !== -1) {
528
- shouldDispose = true;
529
- this.disposables.splice(idx, 1);
530
- this.length--;
531
- item.dispose();
532
- }
533
-
534
- }
535
- return shouldDispose;
536
- };
493
+ /**
494
+ * Represents a group of disposable resources that are disposed together.
495
+ * @constructor
496
+ */
497
+ var CompositeDisposable = Rx.CompositeDisposable = function () {
498
+ this.disposables = argsOrArray(arguments, 0);
499
+ this.isDisposed = false;
500
+ this.length = this.disposables.length;
501
+ };
537
502
 
538
- /**
539
- * Disposes all disposables in the group and removes them from the group.
540
- */
541
- CompositeDisposablePrototype.dispose = function () {
542
- if (!this.isDisposed) {
543
- this.isDisposed = true;
544
- var currentDisposables = this.disposables.slice(0);
545
- this.disposables = [];
546
- this.length = 0;
503
+ var CompositeDisposablePrototype = CompositeDisposable.prototype;
547
504
 
548
- for (var i = 0, len = currentDisposables.length; i < len; i++) {
549
- currentDisposables[i].dispose();
550
- }
551
- }
552
- };
505
+ /**
506
+ * Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
507
+ * @param {Mixed} item Disposable to add.
508
+ */
509
+ CompositeDisposablePrototype.add = function (item) {
510
+ if (this.isDisposed) {
511
+ item.dispose();
512
+ } else {
513
+ this.disposables.push(item);
514
+ this.length++;
515
+ }
516
+ };
553
517
 
554
- /**
555
- * Removes and disposes all disposables from the CompositeDisposable, but does not dispose the CompositeDisposable.
556
- */
557
- CompositeDisposablePrototype.clear = function () {
558
- var currentDisposables = this.disposables.slice(0);
559
- this.disposables = [];
560
- this.length = 0;
561
- for (var i = 0, len = currentDisposables.length; i < len; i++) {
562
- currentDisposables[i].dispose();
563
- }
564
- };
518
+ /**
519
+ * Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
520
+ * @param {Mixed} item Disposable to remove.
521
+ * @returns {Boolean} true if found; false otherwise.
522
+ */
523
+ CompositeDisposablePrototype.remove = function (item) {
524
+ var shouldDispose = false;
525
+ if (!this.isDisposed) {
526
+ var idx = this.disposables.indexOf(item);
527
+ if (idx !== -1) {
528
+ shouldDispose = true;
529
+ this.disposables.splice(idx, 1);
530
+ this.length--;
531
+ item.dispose();
532
+ }
533
+ }
534
+ return shouldDispose;
535
+ };
565
536
 
566
- /**
567
- * Determines whether the CompositeDisposable contains a specific disposable.
568
- * @param {Mixed} item Disposable to search for.
569
- * @returns {Boolean} true if the disposable was found; otherwise, false.
570
- */
571
- CompositeDisposablePrototype.contains = function (item) {
572
- return this.disposables.indexOf(item) !== -1;
573
- };
537
+ /**
538
+ * Disposes all disposables in the group and removes them from the group.
539
+ */
540
+ CompositeDisposablePrototype.dispose = function () {
541
+ if (!this.isDisposed) {
542
+ this.isDisposed = true;
543
+ var currentDisposables = this.disposables.slice(0);
544
+ this.disposables = [];
545
+ this.length = 0;
546
+
547
+ for (var i = 0, len = currentDisposables.length; i < len; i++) {
548
+ currentDisposables[i].dispose();
549
+ }
550
+ }
551
+ };
574
552
 
575
- /**
576
- * Converts the existing CompositeDisposable to an array of disposables
577
- * @returns {Array} An array of disposable objects.
578
- */
579
- CompositeDisposablePrototype.toArray = function () {
580
- return this.disposables.slice(0);
581
- };
582
-
553
+ /**
554
+ * Converts the existing CompositeDisposable to an array of disposables
555
+ * @returns {Array} An array of disposable objects.
556
+ */
557
+ CompositeDisposablePrototype.toArray = function () {
558
+ return this.disposables.slice(0);
559
+ };
560
+
583
561
  /**
584
562
  * Provides a set of static methods for creating Disposables.
585
563
  *
@@ -611,90 +589,52 @@
611
589
  */
612
590
  var disposableEmpty = Disposable.empty = { dispose: noop };
613
591
 
614
- var BooleanDisposable = (function () {
615
- function BooleanDisposable (isSingle) {
616
- this.isSingle = isSingle;
617
- this.isDisposed = false;
618
- this.current = null;
619
- }
620
-
621
- var booleanDisposablePrototype = BooleanDisposable.prototype;
622
-
623
- /**
624
- * Gets the underlying disposable.
625
- * @return The underlying disposable.
626
- */
627
- booleanDisposablePrototype.getDisposable = function () {
628
- return this.current;
629
- };
630
-
631
- /**
632
- * Sets the underlying disposable.
633
- * @param {Disposable} value The new underlying disposable.
634
- */
635
- booleanDisposablePrototype.setDisposable = function (value) {
636
- if (this.current && this.isSingle) {
637
- throw new Error('Disposable has already been assigned');
638
- }
639
-
640
- var shouldDispose = this.isDisposed, old;
641
- if (!shouldDispose) {
642
- old = this.current;
643
- this.current = value;
644
- }
645
- if (old) {
646
- old.dispose();
647
- }
648
- if (shouldDispose && value) {
649
- value.dispose();
650
- }
651
- };
652
-
653
- /**
654
- * Disposes the underlying disposable as well as all future replacements.
655
- */
656
- booleanDisposablePrototype.dispose = function () {
657
- var old;
658
- if (!this.isDisposed) {
659
- this.isDisposed = true;
660
- old = this.current;
661
- this.current = null;
662
- }
663
- if (old) {
664
- old.dispose();
665
- }
666
- };
592
+ var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable =
593
+ SerialDisposable = Rx.SerialDisposable = (function () {
594
+ function BooleanDisposable () {
595
+ this.isDisposed = false;
596
+ this.current = null;
597
+ }
667
598
 
668
- return BooleanDisposable;
669
- }());
599
+ var booleanDisposablePrototype = BooleanDisposable.prototype;
670
600
 
671
601
  /**
672
- * Represents a disposable resource which only allows a single assignment of its underlying disposable resource.
673
- * If an underlying disposable resource has already been set, future attempts to set the underlying disposable resource will throw an Error.
602
+ * Gets the underlying disposable.
603
+ * @return The underlying disposable.
674
604
  */
675
- var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = (function (super_) {
676
- inherits(SingleAssignmentDisposable, super_);
677
-
678
- function SingleAssignmentDisposable() {
679
- super_.call(this, true);
680
- }
681
-
682
- return SingleAssignmentDisposable;
683
- }(BooleanDisposable));
605
+ booleanDisposablePrototype.getDisposable = function () {
606
+ return this.current;
607
+ };
684
608
 
685
609
  /**
686
- * Represents a disposable resource whose underlying disposable resource can be replaced by another disposable resource, causing automatic disposal of the previous underlying disposable resource.
687
- */
688
- var SerialDisposable = Rx.SerialDisposable = (function (super_) {
689
- inherits(SerialDisposable, super_);
690
-
691
- function SerialDisposable() {
692
- super_.call(this, false);
693
- }
610
+ * Sets the underlying disposable.
611
+ * @param {Disposable} value The new underlying disposable.
612
+ */
613
+ booleanDisposablePrototype.setDisposable = function (value) {
614
+ var shouldDispose = this.isDisposed, old;
615
+ if (!shouldDispose) {
616
+ old = this.current;
617
+ this.current = value;
618
+ }
619
+ old && old.dispose();
620
+ shouldDispose && value && value.dispose();
621
+ };
694
622
 
695
- return SerialDisposable;
696
- }(BooleanDisposable));
623
+ /**
624
+ * Disposes the underlying disposable as well as all future replacements.
625
+ */
626
+ booleanDisposablePrototype.dispose = function () {
627
+ var old;
628
+ if (!this.isDisposed) {
629
+ this.isDisposed = true;
630
+ old = this.current;
631
+ this.current = null;
632
+ }
633
+ old && old.dispose();
634
+ };
697
635
 
636
+ return BooleanDisposable;
637
+ }());
698
638
  /**
699
639
  * Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
700
640
  */
@@ -757,394 +697,433 @@
757
697
  return RefCountDisposable;
758
698
  })();
759
699
 
760
- var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
761
- this.scheduler = scheduler;
762
- this.state = state;
763
- this.action = action;
764
- this.dueTime = dueTime;
765
- this.comparer = comparer || defaultSubComparer;
766
- this.disposable = new SingleAssignmentDisposable();
700
+ var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
701
+ this.scheduler = scheduler;
702
+ this.state = state;
703
+ this.action = action;
704
+ this.dueTime = dueTime;
705
+ this.comparer = comparer || defaultSubComparer;
706
+ this.disposable = new SingleAssignmentDisposable();
707
+ }
708
+
709
+ ScheduledItem.prototype.invoke = function () {
710
+ this.disposable.setDisposable(this.invokeCore());
711
+ };
712
+
713
+ ScheduledItem.prototype.compareTo = function (other) {
714
+ return this.comparer(this.dueTime, other.dueTime);
715
+ };
716
+
717
+ ScheduledItem.prototype.isCancelled = function () {
718
+ return this.disposable.isDisposed;
719
+ };
720
+
721
+ ScheduledItem.prototype.invokeCore = function () {
722
+ return this.action(this.scheduler, this.state);
723
+ };
724
+
725
+ /** Provides a set of static properties to access commonly used schedulers. */
726
+ var Scheduler = Rx.Scheduler = (function () {
727
+
728
+ function Scheduler(now, schedule, scheduleRelative, scheduleAbsolute) {
729
+ this.now = now;
730
+ this._schedule = schedule;
731
+ this._scheduleRelative = scheduleRelative;
732
+ this._scheduleAbsolute = scheduleAbsolute;
767
733
  }
768
734
 
769
- ScheduledItem.prototype.invoke = function () {
770
- this.disposable.setDisposable(this.invokeCore());
771
- };
772
-
773
- ScheduledItem.prototype.compareTo = function (other) {
774
- return this.comparer(this.dueTime, other.dueTime);
775
- };
776
-
777
- ScheduledItem.prototype.isCancelled = function () {
778
- return this.disposable.isDisposed;
779
- };
780
-
781
- ScheduledItem.prototype.invokeCore = function () {
782
- return this.action(this.scheduler, this.state);
783
- };
784
-
785
- /** Provides a set of static properties to access commonly used schedulers. */
786
- var Scheduler = Rx.Scheduler = (function () {
787
-
788
- function Scheduler(now, schedule, scheduleRelative, scheduleAbsolute) {
789
- this.now = now;
790
- this._schedule = schedule;
791
- this._scheduleRelative = scheduleRelative;
792
- this._scheduleAbsolute = scheduleAbsolute;
793
- }
794
-
795
- function invokeRecImmediate(scheduler, pair) {
796
- var state = pair.first, action = pair.second, group = new CompositeDisposable(),
797
- recursiveAction = function (state1) {
798
- action(state1, function (state2) {
799
- var isAdded = false, isDone = false,
800
- d = scheduler.scheduleWithState(state2, function (scheduler1, state3) {
801
- if (isAdded) {
802
- group.remove(d);
803
- } else {
804
- isDone = true;
805
- }
806
- recursiveAction(state3);
807
- return disposableEmpty;
808
- });
809
- if (!isDone) {
810
- group.add(d);
811
- isAdded = true;
812
- }
813
- });
814
- };
815
- recursiveAction(state);
816
- return group;
817
- }
818
-
819
- function invokeRecDate(scheduler, pair, method) {
820
- var state = pair.first, action = pair.second, group = new CompositeDisposable(),
821
- recursiveAction = function (state1) {
822
- action(state1, function (state2, dueTime1) {
823
- var isAdded = false, isDone = false,
824
- d = scheduler[method].call(scheduler, state2, dueTime1, function (scheduler1, state3) {
825
- if (isAdded) {
826
- group.remove(d);
827
- } else {
828
- isDone = true;
829
- }
830
- recursiveAction(state3);
831
- return disposableEmpty;
832
- });
833
- if (!isDone) {
834
- group.add(d);
835
- isAdded = true;
836
- }
837
- });
838
- };
839
- recursiveAction(state);
840
- return group;
841
- }
842
-
843
- function invokeAction(scheduler, action) {
844
- action();
735
+ function invokeRecImmediate(scheduler, pair) {
736
+ var state = pair.first, action = pair.second, group = new CompositeDisposable(),
737
+ recursiveAction = function (state1) {
738
+ action(state1, function (state2) {
739
+ var isAdded = false, isDone = false,
740
+ d = scheduler.scheduleWithState(state2, function (scheduler1, state3) {
741
+ if (isAdded) {
742
+ group.remove(d);
743
+ } else {
744
+ isDone = true;
745
+ }
746
+ recursiveAction(state3);
845
747
  return disposableEmpty;
846
- }
847
-
848
- var schedulerProto = Scheduler.prototype;
849
-
850
- /**
851
- * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
852
- * @param {Number} period Period for running the work periodically.
853
- * @param {Function} action Action to be executed.
854
- * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
855
- */
856
- schedulerProto.schedulePeriodic = function (period, action) {
857
- return this.schedulePeriodicWithState(null, period, function () {
858
- action();
859
- });
860
- };
861
-
862
- /**
863
- * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
864
- * @param {Mixed} state Initial state passed to the action upon the first iteration.
865
- * @param {Number} period Period for running the work periodically.
866
- * @param {Function} action Action to be executed, potentially updating the state.
867
- * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
868
- */
869
- schedulerProto.schedulePeriodicWithState = function (state, period, action) {
870
- var s = state, id = setInterval(function () {
871
- s = action(s);
872
- }, period);
873
- return disposableCreate(function () {
874
- clearInterval(id);
875
- });
876
- };
748
+ });
749
+ if (!isDone) {
750
+ group.add(d);
751
+ isAdded = true;
752
+ }
753
+ });
754
+ };
755
+ recursiveAction(state);
756
+ return group;
757
+ }
877
758
 
878
- /**
879
- * Schedules an action to be executed.
880
- * @param {Function} action Action to execute.
881
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
882
- */
883
- schedulerProto.schedule = function (action) {
884
- return this._schedule(action, invokeAction);
885
- };
759
+ function invokeRecDate(scheduler, pair, method) {
760
+ var state = pair.first, action = pair.second, group = new CompositeDisposable(),
761
+ recursiveAction = function (state1) {
762
+ action(state1, function (state2, dueTime1) {
763
+ var isAdded = false, isDone = false,
764
+ d = scheduler[method].call(scheduler, state2, dueTime1, function (scheduler1, state3) {
765
+ if (isAdded) {
766
+ group.remove(d);
767
+ } else {
768
+ isDone = true;
769
+ }
770
+ recursiveAction(state3);
771
+ return disposableEmpty;
772
+ });
773
+ if (!isDone) {
774
+ group.add(d);
775
+ isAdded = true;
776
+ }
777
+ });
778
+ };
779
+ recursiveAction(state);
780
+ return group;
781
+ }
886
782
 
887
- /**
888
- * Schedules an action to be executed.
889
- * @param state State passed to the action to be executed.
890
- * @param {Function} action Action to be executed.
891
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
892
- */
893
- schedulerProto.scheduleWithState = function (state, action) {
894
- return this._schedule(state, action);
895
- };
783
+ function invokeAction(scheduler, action) {
784
+ action();
785
+ return disposableEmpty;
786
+ }
896
787
 
897
- /**
898
- * Schedules an action to be executed after the specified relative due time.
899
- * @param {Function} action Action to execute.
900
- * @param {Number} dueTime Relative time after which to execute the action.
901
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
902
- */
903
- schedulerProto.scheduleWithRelative = function (dueTime, action) {
904
- return this._scheduleRelative(action, dueTime, invokeAction);
905
- };
788
+ var schedulerProto = Scheduler.prototype;
906
789
 
907
- /**
908
- * Schedules an action to be executed after dueTime.
909
- * @param {Mixed} state State passed to the action to be executed.
910
- * @param {Function} action Action to be executed.
911
- * @param {Number} dueTime Relative time after which to execute the action.
912
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
913
- */
914
- schedulerProto.scheduleWithRelativeAndState = function (state, dueTime, action) {
915
- return this._scheduleRelative(state, dueTime, action);
916
- };
790
+ /**
791
+ * Schedules an action to be executed.
792
+ * @param {Function} action Action to execute.
793
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
794
+ */
795
+ schedulerProto.schedule = function (action) {
796
+ return this._schedule(action, invokeAction);
797
+ };
917
798
 
918
- /**
919
- * Schedules an action to be executed at the specified absolute due time.
920
- * @param {Function} action Action to execute.
921
- * @param {Number} dueTime Absolute time at which to execute the action.
922
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
923
- */
924
- schedulerProto.scheduleWithAbsolute = function (dueTime, action) {
925
- return this._scheduleAbsolute(action, dueTime, invokeAction);
926
- };
799
+ /**
800
+ * Schedules an action to be executed.
801
+ * @param state State passed to the action to be executed.
802
+ * @param {Function} action Action to be executed.
803
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
804
+ */
805
+ schedulerProto.scheduleWithState = function (state, action) {
806
+ return this._schedule(state, action);
807
+ };
927
808
 
928
- /**
929
- * Schedules an action to be executed at dueTime.
930
- * @param {Mixed} state State passed to the action to be executed.
931
- * @param {Function} action Action to be executed.
932
- * @param {Number}dueTime Absolute time at which to execute the action.
933
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
934
- */
935
- schedulerProto.scheduleWithAbsoluteAndState = function (state, dueTime, action) {
936
- return this._scheduleAbsolute(state, dueTime, action);
937
- };
809
+ /**
810
+ * Schedules an action to be executed after the specified relative due time.
811
+ * @param {Function} action Action to execute.
812
+ * @param {Number} dueTime Relative time after which to execute the action.
813
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
814
+ */
815
+ schedulerProto.scheduleWithRelative = function (dueTime, action) {
816
+ return this._scheduleRelative(action, dueTime, invokeAction);
817
+ };
938
818
 
939
- /**
940
- * Schedules an action to be executed recursively.
941
- * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action.
942
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
943
- */
944
- schedulerProto.scheduleRecursive = function (action) {
945
- return this.scheduleRecursiveWithState(action, function (_action, self) {
946
- _action(function () {
947
- self(_action);
948
- });
949
- });
950
- };
819
+ /**
820
+ * Schedules an action to be executed after dueTime.
821
+ * @param state State passed to the action to be executed.
822
+ * @param {Function} action Action to be executed.
823
+ * @param {Number} dueTime Relative time after which to execute the action.
824
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
825
+ */
826
+ schedulerProto.scheduleWithRelativeAndState = function (state, dueTime, action) {
827
+ return this._scheduleRelative(state, dueTime, action);
828
+ };
951
829
 
952
- /**
953
- * Schedules an action to be executed recursively.
954
- * @param {Mixed} state State passed to the action to be executed.
955
- * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
956
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
957
- */
958
- schedulerProto.scheduleRecursiveWithState = function (state, action) {
959
- return this.scheduleWithState({ first: state, second: action }, function (s, p) {
960
- return invokeRecImmediate(s, p);
961
- });
962
- };
830
+ /**
831
+ * Schedules an action to be executed at the specified absolute due time.
832
+ * @param {Function} action Action to execute.
833
+ * @param {Number} dueTime Absolute time at which to execute the action.
834
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
835
+ */
836
+ schedulerProto.scheduleWithAbsolute = function (dueTime, action) {
837
+ return this._scheduleAbsolute(action, dueTime, invokeAction);
838
+ };
963
839
 
964
- /**
965
- * Schedules an action to be executed recursively after a specified relative due time.
966
- * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified relative time.
967
- * @param {Number}dueTime Relative time after which to execute the action for the first time.
968
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
969
- */
970
- schedulerProto.scheduleRecursiveWithRelative = function (dueTime, action) {
971
- return this.scheduleRecursiveWithRelativeAndState(action, dueTime, function (_action, self) {
972
- _action(function (dt) {
973
- self(_action, dt);
974
- });
975
- });
976
- };
840
+ /**
841
+ * Schedules an action to be executed at dueTime.
842
+ * @param {Mixed} state State passed to the action to be executed.
843
+ * @param {Function} action Action to be executed.
844
+ * @param {Number}dueTime Absolute time at which to execute the action.
845
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
846
+ */
847
+ schedulerProto.scheduleWithAbsoluteAndState = function (state, dueTime, action) {
848
+ return this._scheduleAbsolute(state, dueTime, action);
849
+ };
977
850
 
978
- /**
979
- * Schedules an action to be executed recursively after a specified relative due time.
980
- * @param {Mixed} state State passed to the action to be executed.
981
- * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
982
- * @param {Number}dueTime Relative time after which to execute the action for the first time.
983
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
984
- */
985
- schedulerProto.scheduleRecursiveWithRelativeAndState = function (state, dueTime, action) {
986
- return this._scheduleRelative({ first: state, second: action }, dueTime, function (s, p) {
987
- return invokeRecDate(s, p, 'scheduleWithRelativeAndState');
988
- });
989
- };
851
+ /** Gets the current time according to the local machine's system clock. */
852
+ Scheduler.now = defaultNow;
990
853
 
991
- /**
992
- * Schedules an action to be executed recursively at a specified absolute due time.
993
- * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified absolute time.
994
- * @param {Number}dueTime Absolute time at which to execute the action for the first time.
995
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
996
- */
997
- schedulerProto.scheduleRecursiveWithAbsolute = function (dueTime, action) {
998
- return this.scheduleRecursiveWithAbsoluteAndState(action, dueTime, function (_action, self) {
999
- _action(function (dt) {
1000
- self(_action, dt);
1001
- });
1002
- });
1003
- };
854
+ /**
855
+ * Normalizes the specified TimeSpan value to a positive value.
856
+ * @param {Number} timeSpan The time span value to normalize.
857
+ * @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
858
+ */
859
+ Scheduler.normalize = function (timeSpan) {
860
+ timeSpan < 0 && (timeSpan = 0);
861
+ return timeSpan;
862
+ };
1004
863
 
1005
- /**
1006
- * Schedules an action to be executed recursively at a specified absolute due time.
1007
- * @param {Mixed} state State passed to the action to be executed.
1008
- * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
1009
- * @param {Number}dueTime Absolute time at which to execute the action for the first time.
1010
- * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
1011
- */
1012
- schedulerProto.scheduleRecursiveWithAbsoluteAndState = function (state, dueTime, action) {
1013
- return this._scheduleAbsolute({ first: state, second: action }, dueTime, function (s, p) {
1014
- return invokeRecDate(s, p, 'scheduleWithAbsoluteAndState');
1015
- });
1016
- };
864
+ return Scheduler;
865
+ }());
1017
866
 
1018
- /** Gets the current time according to the local machine's system clock. */
1019
- Scheduler.now = defaultNow;
867
+ var normalizeTime = Scheduler.normalize;
868
+
869
+ (function (schedulerProto) {
870
+ function invokeRecImmediate(scheduler, pair) {
871
+ var state = pair.first, action = pair.second, group = new CompositeDisposable(),
872
+ recursiveAction = function (state1) {
873
+ action(state1, function (state2) {
874
+ var isAdded = false, isDone = false,
875
+ d = scheduler.scheduleWithState(state2, function (scheduler1, state3) {
876
+ if (isAdded) {
877
+ group.remove(d);
878
+ } else {
879
+ isDone = true;
880
+ }
881
+ recursiveAction(state3);
882
+ return disposableEmpty;
883
+ });
884
+ if (!isDone) {
885
+ group.add(d);
886
+ isAdded = true;
887
+ }
888
+ });
889
+ };
890
+ recursiveAction(state);
891
+ return group;
892
+ }
1020
893
 
1021
- /**
1022
- * Normalizes the specified TimeSpan value to a positive value.
1023
- * @param {Number} timeSpan The time span value to normalize.
1024
- * @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
1025
- */
1026
- Scheduler.normalize = function (timeSpan) {
1027
- if (timeSpan < 0) {
1028
- timeSpan = 0;
894
+ function invokeRecDate(scheduler, pair, method) {
895
+ var state = pair.first, action = pair.second, group = new CompositeDisposable(),
896
+ recursiveAction = function (state1) {
897
+ action(state1, function (state2, dueTime1) {
898
+ var isAdded = false, isDone = false,
899
+ d = scheduler[method].call(scheduler, state2, dueTime1, function (scheduler1, state3) {
900
+ if (isAdded) {
901
+ group.remove(d);
902
+ } else {
903
+ isDone = true;
1029
904
  }
1030
- return timeSpan;
1031
- };
905
+ recursiveAction(state3);
906
+ return disposableEmpty;
907
+ });
908
+ if (!isDone) {
909
+ group.add(d);
910
+ isAdded = true;
911
+ }
912
+ });
913
+ };
914
+ recursiveAction(state);
915
+ return group;
916
+ }
1032
917
 
1033
- return Scheduler;
1034
- }());
918
+ function scheduleInnerRecursive(action, self) {
919
+ action(function(dt) { self(action, dt); });
920
+ }
1035
921
 
1036
- var normalizeTime = Scheduler.normalize;
1037
-
1038
- /**
1039
- * Gets a scheduler that schedules work immediately on the current thread.
1040
- */
1041
- var immediateScheduler = Scheduler.immediate = (function () {
922
+ /**
923
+ * Schedules an action to be executed recursively.
924
+ * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action.
925
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
926
+ */
927
+ schedulerProto.scheduleRecursive = function (action) {
928
+ return this.scheduleRecursiveWithState(action, function (_action, self) {
929
+ _action(function () { self(_action); }); });
930
+ };
1042
931
 
1043
- function scheduleNow(state, action) { return action(this, state); }
932
+ /**
933
+ * Schedules an action to be executed recursively.
934
+ * @param {Mixed} state State passed to the action to be executed.
935
+ * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
936
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
937
+ */
938
+ schedulerProto.scheduleRecursiveWithState = function (state, action) {
939
+ return this.scheduleWithState({ first: state, second: action }, invokeRecImmediate);
940
+ };
1044
941
 
1045
- function scheduleRelative(state, dueTime, action) {
1046
- var dt = normalizeTime(dt);
1047
- while (dt - this.now() > 0) { }
1048
- return action(this, state);
1049
- }
942
+ /**
943
+ * Schedules an action to be executed recursively after a specified relative due time.
944
+ * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified relative time.
945
+ * @param {Number}dueTime Relative time after which to execute the action for the first time.
946
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
947
+ */
948
+ schedulerProto.scheduleRecursiveWithRelative = function (dueTime, action) {
949
+ return this.scheduleRecursiveWithRelativeAndState(action, dueTime, scheduleInnerRecursive);
950
+ };
1050
951
 
1051
- function scheduleAbsolute(state, dueTime, action) {
1052
- return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action);
1053
- }
952
+ /**
953
+ * Schedules an action to be executed recursively after a specified relative due time.
954
+ * @param {Mixed} state State passed to the action to be executed.
955
+ * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
956
+ * @param {Number}dueTime Relative time after which to execute the action for the first time.
957
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
958
+ */
959
+ schedulerProto.scheduleRecursiveWithRelativeAndState = function (state, dueTime, action) {
960
+ return this._scheduleRelative({ first: state, second: action }, dueTime, function (s, p) {
961
+ return invokeRecDate(s, p, 'scheduleWithRelativeAndState');
962
+ });
963
+ };
1054
964
 
1055
- return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);
1056
- }());
965
+ /**
966
+ * Schedules an action to be executed recursively at a specified absolute due time.
967
+ * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified absolute time.
968
+ * @param {Number}dueTime Absolute time at which to execute the action for the first time.
969
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
970
+ */
971
+ schedulerProto.scheduleRecursiveWithAbsolute = function (dueTime, action) {
972
+ return this.scheduleRecursiveWithAbsoluteAndState(action, dueTime, scheduleInnerRecursive);
973
+ };
1057
974
 
1058
- /**
1059
- * Gets a scheduler that schedules work as soon as possible on the current thread.
975
+ /**
976
+ * Schedules an action to be executed recursively at a specified absolute due time.
977
+ * @param {Mixed} state State passed to the action to be executed.
978
+ * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
979
+ * @param {Number}dueTime Absolute time at which to execute the action for the first time.
980
+ * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
1060
981
  */
1061
- var currentThreadScheduler = Scheduler.currentThread = (function () {
1062
- var queue;
1063
-
1064
- function runTrampoline (q) {
1065
- var item;
1066
- while (q.length > 0) {
1067
- item = q.dequeue();
1068
- if (!item.isCancelled()) {
1069
- // Note, do not schedule blocking work!
1070
- while (item.dueTime - Scheduler.now() > 0) {
1071
- }
1072
- if (!item.isCancelled()) {
1073
- item.invoke();
1074
- }
1075
- }
1076
- }
1077
- }
982
+ schedulerProto.scheduleRecursiveWithAbsoluteAndState = function (state, dueTime, action) {
983
+ return this._scheduleAbsolute({ first: state, second: action }, dueTime, function (s, p) {
984
+ return invokeRecDate(s, p, 'scheduleWithAbsoluteAndState');
985
+ });
986
+ };
987
+ }(Scheduler.prototype));
1078
988
 
1079
- function scheduleNow(state, action) {
1080
- return this.scheduleWithRelativeAndState(state, 0, action);
1081
- }
989
+ (function (schedulerProto) {
990
+ /**
991
+ * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
992
+ * @param {Number} period Period for running the work periodically.
993
+ * @param {Function} action Action to be executed.
994
+ * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
995
+ */
996
+ Scheduler.prototype.schedulePeriodic = function (period, action) {
997
+ return this.schedulePeriodicWithState(null, period, action);
998
+ };
1082
999
 
1083
- function scheduleRelative(state, dueTime, action) {
1084
- var dt = this.now() + Scheduler.normalize(dueTime),
1085
- si = new ScheduledItem(this, state, action, dt),
1086
- t;
1087
- if (!queue) {
1088
- queue = new PriorityQueue(4);
1089
- queue.enqueue(si);
1090
- try {
1091
- runTrampoline(queue);
1092
- } catch (e) {
1093
- throw e;
1094
- } finally {
1095
- queue = null;
1096
- }
1097
- } else {
1098
- queue.enqueue(si);
1099
- }
1100
- return si.disposable;
1101
- }
1000
+ /**
1001
+ * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
1002
+ * @param {Mixed} state Initial state passed to the action upon the first iteration.
1003
+ * @param {Number} period Period for running the work periodically.
1004
+ * @param {Function} action Action to be executed, potentially updating the state.
1005
+ * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
1006
+ */
1007
+ Scheduler.prototype.schedulePeriodicWithState = function (state, period, action) {
1008
+ var s = state;
1009
+
1010
+ var id = setInterval(function () {
1011
+ s = action(s);
1012
+ }, period);
1013
+
1014
+ return disposableCreate(function () {
1015
+ clearInterval(id);
1016
+ });
1017
+ };
1018
+ }(Scheduler.prototype));
1019
+
1020
+ /**
1021
+ * Gets a scheduler that schedules work immediately on the current thread.
1022
+ */
1023
+ var immediateScheduler = Scheduler.immediate = (function () {
1024
+
1025
+ function scheduleNow(state, action) { return action(this, state); }
1026
+
1027
+ function scheduleRelative(state, dueTime, action) {
1028
+ var dt = normalizeTime(dt);
1029
+ while (dt - this.now() > 0) { }
1030
+ return action(this, state);
1031
+ }
1032
+
1033
+ function scheduleAbsolute(state, dueTime, action) {
1034
+ return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action);
1035
+ }
1036
+
1037
+ return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);
1038
+ }());
1102
1039
 
1103
- function scheduleAbsolute(state, dueTime, action) {
1104
- return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action);
1040
+ /**
1041
+ * Gets a scheduler that schedules work as soon as possible on the current thread.
1042
+ */
1043
+ var currentThreadScheduler = Scheduler.currentThread = (function () {
1044
+ var queue;
1045
+
1046
+ function runTrampoline (q) {
1047
+ var item;
1048
+ while (q.length > 0) {
1049
+ item = q.dequeue();
1050
+ if (!item.isCancelled()) {
1051
+ // Note, do not schedule blocking work!
1052
+ while (item.dueTime - Scheduler.now() > 0) {
1053
+ }
1054
+ if (!item.isCancelled()) {
1055
+ item.invoke();
1056
+ }
1105
1057
  }
1058
+ }
1059
+ }
1106
1060
 
1107
- var currentScheduler = new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);
1108
- currentScheduler.scheduleRequired = function () { return queue === null; };
1109
- currentScheduler.ensureTrampoline = function (action) {
1110
- if (queue === null) {
1111
- return this.schedule(action);
1112
- } else {
1113
- return action();
1114
- }
1115
- };
1061
+ function scheduleNow(state, action) {
1062
+ return this.scheduleWithRelativeAndState(state, 0, action);
1063
+ }
1116
1064
 
1117
- return currentScheduler;
1118
- }());
1065
+ function scheduleRelative(state, dueTime, action) {
1066
+ var dt = this.now() + Scheduler.normalize(dueTime),
1067
+ si = new ScheduledItem(this, state, action, dt);
1119
1068
 
1120
- var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
1121
- function tick(command, recurse) {
1122
- recurse(0, this._period);
1123
- try {
1124
- this._state = this._action(this._state);
1125
- } catch (e) {
1126
- this._cancel.dispose();
1127
- throw e;
1128
- }
1069
+ if (!queue) {
1070
+ queue = new PriorityQueue(4);
1071
+ queue.enqueue(si);
1072
+ try {
1073
+ runTrampoline(queue);
1074
+ } catch (e) {
1075
+ throw e;
1076
+ } finally {
1077
+ queue = null;
1129
1078
  }
1079
+ } else {
1080
+ queue.enqueue(si);
1081
+ }
1082
+ return si.disposable;
1083
+ }
1130
1084
 
1131
- function SchedulePeriodicRecursive(scheduler, state, period, action) {
1132
- this._scheduler = scheduler;
1133
- this._state = state;
1134
- this._period = period;
1135
- this._action = action;
1136
- }
1085
+ function scheduleAbsolute(state, dueTime, action) {
1086
+ return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action);
1087
+ }
1137
1088
 
1138
- SchedulePeriodicRecursive.prototype.start = function () {
1139
- var d = new SingleAssignmentDisposable();
1140
- this._cancel = d;
1141
- d.setDisposable(this._scheduler.scheduleRecursiveWithRelativeAndState(0, this._period, tick.bind(this)));
1089
+ var currentScheduler = new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);
1090
+
1091
+ currentScheduler.scheduleRequired = function () { return !queue; };
1092
+ currentScheduler.ensureTrampoline = function (action) {
1093
+ if (!queue) { this.schedule(action); } else { action(); }
1094
+ };
1142
1095
 
1143
- return d;
1144
- };
1096
+ return currentScheduler;
1097
+ }());
1145
1098
 
1146
- return SchedulePeriodicRecursive;
1147
- }());
1099
+ var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
1100
+ function tick(command, recurse) {
1101
+ recurse(0, this._period);
1102
+ try {
1103
+ this._state = this._action(this._state);
1104
+ } catch (e) {
1105
+ this._cancel.dispose();
1106
+ throw e;
1107
+ }
1108
+ }
1109
+
1110
+ function SchedulePeriodicRecursive(scheduler, state, period, action) {
1111
+ this._scheduler = scheduler;
1112
+ this._state = state;
1113
+ this._period = period;
1114
+ this._action = action;
1115
+ }
1116
+
1117
+ SchedulePeriodicRecursive.prototype.start = function () {
1118
+ var d = new SingleAssignmentDisposable();
1119
+ this._cancel = d;
1120
+ d.setDisposable(this._scheduler.scheduleRecursiveWithRelativeAndState(0, this._period, tick.bind(this)));
1121
+
1122
+ return d;
1123
+ };
1124
+
1125
+ return SchedulePeriodicRecursive;
1126
+ }());
1148
1127
 
1149
1128
 
1150
1129
  var scheduleMethod, clearMethod = noop;
@@ -1390,150 +1369,150 @@
1390
1369
  };
1391
1370
  }());
1392
1371
 
1393
- var Enumerator = Rx.internals.Enumerator = function (next) {
1394
- this._next = next;
1395
- };
1396
-
1397
- Enumerator.prototype.next = function () {
1398
- return this._next();
1399
- };
1400
-
1401
- Enumerator.prototype[$iterator$] = function () { return this; }
1402
-
1403
- var Enumerable = Rx.internals.Enumerable = function (iterator) {
1404
- this._iterator = iterator;
1405
- };
1406
-
1407
- Enumerable.prototype[$iterator$] = function () {
1408
- return this._iterator();
1409
- };
1410
-
1411
- Enumerable.prototype.concat = function () {
1412
- var sources = this;
1413
- return new AnonymousObservable(function (observer) {
1414
- var e;
1415
- try {
1416
- e = sources[$iterator$]();
1417
- } catch(err) {
1418
- observer.onError();
1419
- return;
1420
- }
1421
-
1422
- var isDisposed,
1423
- subscription = new SerialDisposable();
1424
- var cancelable = immediateScheduler.scheduleRecursive(function (self) {
1425
- var currentItem;
1426
- if (isDisposed) { return; }
1427
-
1428
- try {
1429
- currentItem = e.next();
1430
- } catch (ex) {
1431
- observer.onError(ex);
1432
- return;
1433
- }
1434
-
1435
- if (currentItem.done) {
1436
- observer.onCompleted();
1437
- return;
1438
- }
1439
-
1440
- // Check if promise
1441
- var currentValue = currentItem.value;
1442
- isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
1443
-
1444
- var d = new SingleAssignmentDisposable();
1445
- subscription.setDisposable(d);
1446
- d.setDisposable(currentValue.subscribe(
1447
- observer.onNext.bind(observer),
1448
- observer.onError.bind(observer),
1449
- function () { self(); })
1450
- );
1451
- });
1452
-
1453
- return new CompositeDisposable(subscription, cancelable, disposableCreate(function () {
1454
- isDisposed = true;
1455
- }));
1456
- });
1457
- };
1458
-
1459
- Enumerable.prototype.catchException = function () {
1460
- var sources = this;
1461
- return new AnonymousObservable(function (observer) {
1462
- var e;
1463
- try {
1464
- e = sources[$iterator$]();
1465
- } catch(err) {
1466
- observer.onError();
1467
- return;
1468
- }
1469
-
1470
- var isDisposed,
1471
- lastException,
1472
- subscription = new SerialDisposable();
1473
- var cancelable = immediateScheduler.scheduleRecursive(function (self) {
1474
- if (isDisposed) { return; }
1475
-
1476
- var currentItem;
1477
- try {
1478
- currentItem = e.next();
1479
- } catch (ex) {
1480
- observer.onError(ex);
1481
- return;
1482
- }
1483
-
1484
- if (currentItem.done) {
1485
- if (lastException) {
1486
- observer.onError(lastException);
1487
- } else {
1488
- observer.onCompleted();
1489
- }
1490
- return;
1491
- }
1492
-
1493
- // Check if promise
1494
- var currentValue = currentItem.value;
1495
- isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
1496
-
1497
- var d = new SingleAssignmentDisposable();
1498
- subscription.setDisposable(d);
1499
- d.setDisposable(currentValue.subscribe(
1500
- observer.onNext.bind(observer),
1501
- function (exn) {
1502
- lastException = exn;
1503
- self();
1504
- },
1505
- observer.onCompleted.bind(observer)));
1506
- });
1507
- return new CompositeDisposable(subscription, cancelable, disposableCreate(function () {
1508
- isDisposed = true;
1509
- }));
1510
- });
1511
- };
1512
-
1513
- var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
1514
- if (repeatCount == null) { repeatCount = -1; }
1515
- return new Enumerable(function () {
1516
- var left = repeatCount;
1517
- return new Enumerator(function () {
1518
- if (left === 0) { return doneEnumerator; }
1519
- if (left > 0) { left--; }
1520
- return { done: false, value: value };
1521
- });
1522
- });
1523
- };
1524
-
1525
- var enumerableFor = Enumerable.forEach = function (source, selector, thisArg) {
1526
- selector || (selector = identity);
1527
- return new Enumerable(function () {
1528
- var index = -1;
1529
- return new Enumerator(
1530
- function () {
1531
- return ++index < source.length ?
1532
- { done: false, value: selector.call(thisArg, source[index], index, source) } :
1533
- doneEnumerator;
1534
- });
1535
- });
1536
- };
1372
+ var Enumerator = Rx.internals.Enumerator = function (next) {
1373
+ this._next = next;
1374
+ };
1375
+
1376
+ Enumerator.prototype.next = function () {
1377
+ return this._next();
1378
+ };
1379
+
1380
+ Enumerator.prototype[$iterator$] = function () { return this; }
1381
+
1382
+ var Enumerable = Rx.internals.Enumerable = function (iterator) {
1383
+ this._iterator = iterator;
1384
+ };
1385
+
1386
+ Enumerable.prototype[$iterator$] = function () {
1387
+ return this._iterator();
1388
+ };
1389
+
1390
+ Enumerable.prototype.concat = function () {
1391
+ var sources = this;
1392
+ return new AnonymousObservable(function (observer) {
1393
+ var e;
1394
+ try {
1395
+ e = sources[$iterator$]();
1396
+ } catch(err) {
1397
+ observer.onError();
1398
+ return;
1399
+ }
1400
+
1401
+ var isDisposed,
1402
+ subscription = new SerialDisposable();
1403
+ var cancelable = immediateScheduler.scheduleRecursive(function (self) {
1404
+ var currentItem;
1405
+ if (isDisposed) { return; }
1406
+
1407
+ try {
1408
+ currentItem = e.next();
1409
+ } catch (ex) {
1410
+ observer.onError(ex);
1411
+ return;
1412
+ }
1413
+
1414
+ if (currentItem.done) {
1415
+ observer.onCompleted();
1416
+ return;
1417
+ }
1418
+
1419
+ // Check if promise
1420
+ var currentValue = currentItem.value;
1421
+ isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
1422
+
1423
+ var d = new SingleAssignmentDisposable();
1424
+ subscription.setDisposable(d);
1425
+ d.setDisposable(currentValue.subscribe(
1426
+ observer.onNext.bind(observer),
1427
+ observer.onError.bind(observer),
1428
+ function () { self(); })
1429
+ );
1430
+ });
1431
+
1432
+ return new CompositeDisposable(subscription, cancelable, disposableCreate(function () {
1433
+ isDisposed = true;
1434
+ }));
1435
+ });
1436
+ };
1437
+
1438
+ Enumerable.prototype.catchException = function () {
1439
+ var sources = this;
1440
+ return new AnonymousObservable(function (observer) {
1441
+ var e;
1442
+ try {
1443
+ e = sources[$iterator$]();
1444
+ } catch(err) {
1445
+ observer.onError();
1446
+ return;
1447
+ }
1448
+
1449
+ var isDisposed,
1450
+ lastException,
1451
+ subscription = new SerialDisposable();
1452
+ var cancelable = immediateScheduler.scheduleRecursive(function (self) {
1453
+ if (isDisposed) { return; }
1454
+
1455
+ var currentItem;
1456
+ try {
1457
+ currentItem = e.next();
1458
+ } catch (ex) {
1459
+ observer.onError(ex);
1460
+ return;
1461
+ }
1462
+
1463
+ if (currentItem.done) {
1464
+ if (lastException) {
1465
+ observer.onError(lastException);
1466
+ } else {
1467
+ observer.onCompleted();
1468
+ }
1469
+ return;
1470
+ }
1471
+
1472
+ // Check if promise
1473
+ var currentValue = currentItem.value;
1474
+ isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
1475
+
1476
+ var d = new SingleAssignmentDisposable();
1477
+ subscription.setDisposable(d);
1478
+ d.setDisposable(currentValue.subscribe(
1479
+ observer.onNext.bind(observer),
1480
+ function (exn) {
1481
+ lastException = exn;
1482
+ self();
1483
+ },
1484
+ observer.onCompleted.bind(observer)));
1485
+ });
1486
+ return new CompositeDisposable(subscription, cancelable, disposableCreate(function () {
1487
+ isDisposed = true;
1488
+ }));
1489
+ });
1490
+ };
1491
+
1492
+ var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
1493
+ if (repeatCount == null) { repeatCount = -1; }
1494
+ return new Enumerable(function () {
1495
+ var left = repeatCount;
1496
+ return new Enumerator(function () {
1497
+ if (left === 0) { return doneEnumerator; }
1498
+ if (left > 0) { left--; }
1499
+ return { done: false, value: value };
1500
+ });
1501
+ });
1502
+ };
1503
+
1504
+ var enumerableFor = Enumerable.forEach = function (source, selector, thisArg) {
1505
+ selector || (selector = identity);
1506
+ return new Enumerable(function () {
1507
+ var index = -1;
1508
+ return new Enumerator(
1509
+ function () {
1510
+ return ++index < source.length ?
1511
+ { done: false, value: selector.call(thisArg, source[index], index, source) } :
1512
+ doneEnumerator;
1513
+ });
1514
+ });
1515
+ };
1537
1516
 
1538
1517
  /**
1539
1518
  * Supports push-style iteration over an observable sequence.
@@ -1839,20 +1818,20 @@
1839
1818
  });
1840
1819
  };
1841
1820
 
1842
- /**
1843
- * Creates an observable sequence from a specified subscribe method implementation.
1844
- *
1845
- * @example
1846
- * var res = Rx.Observable.create(function (observer) { return function () { } );
1847
- * var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
1848
- * var res = Rx.Observable.create(function (observer) { } );
1849
- *
1850
- * @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
1851
- * @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
1852
- */
1853
- Observable.create = Observable.createWithDisposable = function (subscribe) {
1854
- return new AnonymousObservable(subscribe);
1855
- };
1821
+ /**
1822
+ * Creates an observable sequence from a specified subscribe method implementation.
1823
+ *
1824
+ * @example
1825
+ * var res = Rx.Observable.create(function (observer) { return function () { } );
1826
+ * var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
1827
+ * var res = Rx.Observable.create(function (observer) { } );
1828
+ *
1829
+ * @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
1830
+ * @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
1831
+ */
1832
+ Observable.create = Observable.createWithDisposable = function (subscribe) {
1833
+ return new AnonymousObservable(subscribe);
1834
+ };
1856
1835
 
1857
1836
  /**
1858
1837
  * Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
@@ -2006,49 +1985,6 @@
2006
1985
  });
2007
1986
  };
2008
1987
 
2009
- /**
2010
- * Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
2011
- *
2012
- * @example
2013
- * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
2014
- * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
2015
- * @param {Mixed} initialState Initial state.
2016
- * @param {Function} condition Condition to terminate generation (upon returning false).
2017
- * @param {Function} iterate Iteration step function.
2018
- * @param {Function} resultSelector Selector function for results produced in the sequence.
2019
- * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
2020
- * @returns {Observable} The generated sequence.
2021
- */
2022
- Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
2023
- isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2024
- return new AnonymousObservable(function (observer) {
2025
- var first = true, state = initialState;
2026
- return scheduler.scheduleRecursive(function (self) {
2027
- var hasResult, result;
2028
- try {
2029
- if (first) {
2030
- first = false;
2031
- } else {
2032
- state = iterate(state);
2033
- }
2034
- hasResult = condition(state);
2035
- if (hasResult) {
2036
- result = resultSelector(state);
2037
- }
2038
- } catch (exception) {
2039
- observer.onError(exception);
2040
- return;
2041
- }
2042
- if (hasResult) {
2043
- observer.onNext(result);
2044
- self();
2045
- } else {
2046
- observer.onCompleted();
2047
- }
2048
- });
2049
- });
2050
- };
2051
-
2052
1988
  /**
2053
1989
  * Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
2054
1990
  * @returns {Observable} An observable sequence whose observers will never get called.
@@ -2337,63 +2273,53 @@
2337
2273
  return this.merge(1);
2338
2274
  };
2339
2275
 
2340
- /**
2341
- * Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
2342
- * Or merges two observable sequences into a single observable sequence.
2343
- *
2344
- * @example
2345
- * 1 - merged = sources.merge(1);
2346
- * 2 - merged = source.merge(otherSource);
2347
- * @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
2348
- * @returns {Observable} The observable sequence that merges the elements of the inner sequences.
2349
- */
2350
- observableProto.merge = function (maxConcurrentOrOther) {
2351
- if (typeof maxConcurrentOrOther !== 'number') {
2352
- return observableMerge(this, maxConcurrentOrOther);
2276
+ /**
2277
+ * Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
2278
+ * Or merges two observable sequences into a single observable sequence.
2279
+ *
2280
+ * @example
2281
+ * 1 - merged = sources.merge(1);
2282
+ * 2 - merged = source.merge(otherSource);
2283
+ * @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
2284
+ * @returns {Observable} The observable sequence that merges the elements of the inner sequences.
2285
+ */
2286
+ observableProto.merge = function (maxConcurrentOrOther) {
2287
+ if (typeof maxConcurrentOrOther !== 'number') { return observableMerge(this, maxConcurrentOrOther); }
2288
+ var sources = this;
2289
+ return new AnonymousObservable(function (observer) {
2290
+ var activeCount = 0, group = new CompositeDisposable(), isStopped = false, q = [];
2291
+
2292
+ function subscribe(xs) {
2293
+ var subscription = new SingleAssignmentDisposable();
2294
+ group.add(subscription);
2295
+
2296
+ // Check for promises support
2297
+ isPromise(xs) && (xs = observableFromPromise(xs));
2298
+
2299
+ subscription.setDisposable(xs.subscribe(observer.onNext.bind(observer), observer.onError.bind(observer), function () {
2300
+ group.remove(subscription);
2301
+ if (q.length > 0) {
2302
+ subscribe(q.shift());
2303
+ } else {
2304
+ activeCount--;
2305
+ isStopped && activeCount === 0 && observer.onCompleted();
2306
+ }
2307
+ }));
2308
+ }
2309
+ group.add(sources.subscribe(function (innerSource) {
2310
+ if (activeCount < maxConcurrentOrOther) {
2311
+ activeCount++;
2312
+ subscribe(innerSource);
2313
+ } else {
2314
+ q.push(innerSource);
2353
2315
  }
2354
- var sources = this;
2355
- return new AnonymousObservable(function (observer) {
2356
- var activeCount = 0,
2357
- group = new CompositeDisposable(),
2358
- isStopped = false,
2359
- q = [],
2360
- subscribe = function (xs) {
2361
- var subscription = new SingleAssignmentDisposable();
2362
- group.add(subscription);
2363
-
2364
- // Check for promises support
2365
- if (isPromise(xs)) { xs = observableFromPromise(xs); }
2366
-
2367
- subscription.setDisposable(xs.subscribe(observer.onNext.bind(observer), observer.onError.bind(observer), function () {
2368
- var s;
2369
- group.remove(subscription);
2370
- if (q.length > 0) {
2371
- s = q.shift();
2372
- subscribe(s);
2373
- } else {
2374
- activeCount--;
2375
- if (isStopped && activeCount === 0) {
2376
- observer.onCompleted();
2377
- }
2378
- }
2379
- }));
2380
- };
2381
- group.add(sources.subscribe(function (innerSource) {
2382
- if (activeCount < maxConcurrentOrOther) {
2383
- activeCount++;
2384
- subscribe(innerSource);
2385
- } else {
2386
- q.push(innerSource);
2387
- }
2388
- }, observer.onError.bind(observer), function () {
2389
- isStopped = true;
2390
- if (activeCount === 0) {
2391
- observer.onCompleted();
2392
- }
2393
- }));
2394
- return group;
2395
- });
2396
- };
2316
+ }, observer.onError.bind(observer), function () {
2317
+ isStopped = true;
2318
+ activeCount === 0 && observer.onCompleted();
2319
+ }));
2320
+ return group;
2321
+ });
2322
+ };
2397
2323
 
2398
2324
  /**
2399
2325
  * Merges all the observable sequences into a single observable sequence.
@@ -2744,84 +2670,84 @@
2744
2670
  var comparerEquals = false, key;
2745
2671
  try {
2746
2672
  key = keySelector(value);
2747
- } catch (exception) {
2748
- observer.onError(exception);
2749
- return;
2750
- }
2751
- if (hasCurrentKey) {
2752
- try {
2753
- comparerEquals = comparer(currentKey, key);
2754
- } catch (exception) {
2755
- observer.onError(exception);
2756
- return;
2757
- }
2758
- }
2759
- if (!hasCurrentKey || !comparerEquals) {
2760
- hasCurrentKey = true;
2761
- currentKey = key;
2762
- observer.onNext(value);
2763
- }
2764
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
2765
- });
2766
- };
2767
-
2768
- /**
2769
- * Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
2770
- * This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
2771
- *
2772
- * @example
2773
- * var res = observable.doAction(observer);
2774
- * var res = observable.doAction(onNext);
2775
- * var res = observable.doAction(onNext, onError);
2776
- * var res = observable.doAction(onNext, onError, onCompleted);
2777
- * @param {Mixed} observerOrOnNext Action to invoke for each element in the observable sequence or an observer.
2778
- * @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
2779
- * @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
2780
- * @returns {Observable} The source sequence with the side-effecting behavior applied.
2781
- */
2782
- observableProto['do'] = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
2783
- var source = this, onNextFunc;
2784
- if (typeof observerOrOnNext === 'function') {
2785
- onNextFunc = observerOrOnNext;
2786
- } else {
2787
- onNextFunc = observerOrOnNext.onNext.bind(observerOrOnNext);
2788
- onError = observerOrOnNext.onError.bind(observerOrOnNext);
2789
- onCompleted = observerOrOnNext.onCompleted.bind(observerOrOnNext);
2790
- }
2791
- return new AnonymousObservable(function (observer) {
2792
- return source.subscribe(function (x) {
2793
- try {
2794
- onNextFunc(x);
2795
- } catch (e) {
2796
- observer.onError(e);
2797
- }
2798
- observer.onNext(x);
2799
- }, function (exception) {
2800
- if (!onError) {
2801
- observer.onError(exception);
2802
- } else {
2803
- try {
2804
- onError(exception);
2805
- } catch (e) {
2806
- observer.onError(e);
2807
- }
2673
+ } catch (exception) {
2808
2674
  observer.onError(exception);
2675
+ return;
2809
2676
  }
2810
- }, function () {
2811
- if (!onCompleted) {
2812
- observer.onCompleted();
2813
- } else {
2677
+ if (hasCurrentKey) {
2814
2678
  try {
2815
- onCompleted();
2816
- } catch (e) {
2817
- observer.onError(e);
2679
+ comparerEquals = comparer(currentKey, key);
2680
+ } catch (exception) {
2681
+ observer.onError(exception);
2682
+ return;
2818
2683
  }
2819
- observer.onCompleted();
2820
2684
  }
2821
- });
2685
+ if (!hasCurrentKey || !comparerEquals) {
2686
+ hasCurrentKey = true;
2687
+ currentKey = key;
2688
+ observer.onNext(value);
2689
+ }
2690
+ }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
2822
2691
  });
2823
2692
  };
2824
2693
 
2694
+ /**
2695
+ * Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
2696
+ * This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
2697
+ *
2698
+ * @example
2699
+ * var res = observable.do(observer);
2700
+ * var res = observable.do(onNext);
2701
+ * var res = observable.do(onNext, onError);
2702
+ * var res = observable.do(onNext, onError, onCompleted);
2703
+ * @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an observer.
2704
+ * @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
2705
+ * @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
2706
+ * @returns {Observable} The source sequence with the side-effecting behavior applied.
2707
+ */
2708
+ observableProto['do'] = observableProto.doAction = observableProto.tap = function (observerOrOnNext, onError, onCompleted) {
2709
+ var source = this, onNextFunc;
2710
+ if (typeof observerOrOnNext === 'function') {
2711
+ onNextFunc = observerOrOnNext;
2712
+ } else {
2713
+ onNextFunc = observerOrOnNext.onNext.bind(observerOrOnNext);
2714
+ onError = observerOrOnNext.onError.bind(observerOrOnNext);
2715
+ onCompleted = observerOrOnNext.onCompleted.bind(observerOrOnNext);
2716
+ }
2717
+ return new AnonymousObservable(function (observer) {
2718
+ return source.subscribe(function (x) {
2719
+ try {
2720
+ onNextFunc(x);
2721
+ } catch (e) {
2722
+ observer.onError(e);
2723
+ }
2724
+ observer.onNext(x);
2725
+ }, function (err) {
2726
+ if (!onError) {
2727
+ observer.onError(err);
2728
+ } else {
2729
+ try {
2730
+ onError(err);
2731
+ } catch (e) {
2732
+ observer.onError(e);
2733
+ }
2734
+ observer.onError(err);
2735
+ }
2736
+ }, function () {
2737
+ if (!onCompleted) {
2738
+ observer.onCompleted();
2739
+ } else {
2740
+ try {
2741
+ onCompleted();
2742
+ } catch (e) {
2743
+ observer.onError(e);
2744
+ }
2745
+ observer.onCompleted();
2746
+ }
2747
+ });
2748
+ });
2749
+ };
2750
+
2825
2751
  /**
2826
2752
  * Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
2827
2753
  *
@@ -3003,96 +2929,59 @@
3003
2929
  return enumerableFor([observableFromArray(values, scheduler), this]).concat();
3004
2930
  };
3005
2931
 
3006
- /**
3007
- * Returns a specified number of contiguous elements from the end of an observable sequence, using an optional scheduler to drain the queue.
3008
- *
3009
- * @example
3010
- * var res = source.takeLast(5);
3011
- * var res = source.takeLast(5, Rx.Scheduler.timeout);
3012
- *
3013
- * @description
3014
- * This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
3015
- * the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
3016
- * @param {Number} count Number of elements to take from the end of the source sequence.
3017
- * @param {Scheduler} [scheduler] Scheduler used to drain the queue upon completion of the source sequence.
3018
- * @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
3019
- */
3020
- observableProto.takeLast = function (count, scheduler) {
3021
- return this.takeLastBuffer(count).selectMany(function (xs) { return observableFromArray(xs, scheduler); });
3022
- };
3023
-
3024
- /**
3025
- * Returns an array with the specified number of contiguous elements from the end of an observable sequence.
3026
- *
3027
- * @description
3028
- * This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
3029
- * source sequence, this buffer is produced on the result sequence.
3030
- * @param {Number} count Number of elements to take from the end of the source sequence.
3031
- * @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
3032
- */
3033
- observableProto.takeLastBuffer = function (count) {
3034
- var source = this;
3035
- return new AnonymousObservable(function (observer) {
3036
- var q = [];
3037
- return source.subscribe(function (x) {
3038
- q.push(x);
3039
- if (q.length > count) {
3040
- q.shift();
3041
- }
3042
- }, observer.onError.bind(observer), function () {
3043
- observer.onNext(q);
3044
- observer.onCompleted();
3045
- });
3046
- });
3047
- };
2932
+ /**
2933
+ * Returns a specified number of contiguous elements from the end of an observable sequence.
2934
+ *
2935
+ * @example
2936
+ * var res = source.takeLast(5);
2937
+ *
2938
+ * @description
2939
+ * This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
2940
+ * the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
2941
+ * @param {Number} count Number of elements to take from the end of the source sequence.
2942
+ * @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
2943
+ */
2944
+ observableProto.takeLast = function (count) {
2945
+ var source = this;
2946
+ return new AnonymousObservable(function (observer) {
2947
+ var q = [];
2948
+ return source.subscribe(function (x) {
2949
+ q.push(x);
2950
+ q.length > count && q.shift();
2951
+ }, observer.onError.bind(observer), function () {
2952
+ while(q.length > 0) { observer.onNext(q.shift()); }
2953
+ observer.onCompleted();
2954
+ });
2955
+ });
2956
+ };
3048
2957
 
3049
- function concatMap(selector) {
3050
- return this.map(function (x, i) {
3051
- var result = selector(x, i);
2958
+ function concatMap(source, selector, thisArg) {
2959
+ return source.map(function (x, i) {
2960
+ var result = selector.call(thisArg, x, i);
3052
2961
  return isPromise(result) ? observableFromPromise(result) : result;
3053
2962
  }).concatAll();
3054
2963
  }
3055
2964
 
3056
- function concatMapObserver(onNext, onError, onCompleted) {
3057
- var source = this;
3058
- return new AnonymousObservable(function (observer) {
3059
- var index = 0;
3060
-
3061
- return source.subscribe(
3062
- function (x) {
3063
- observer.onNext(onNext(x, index++));
3064
- },
3065
- function (err) {
3066
- observer.onNext(onError(err));
3067
- observer.completed();
3068
- },
3069
- function () {
3070
- observer.onNext(onCompleted());
3071
- observer.onCompleted();
3072
- });
3073
- }).concatAll();
3074
- }
3075
-
3076
2965
  /**
3077
2966
  * One of the Following:
3078
2967
  * Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
3079
2968
  *
3080
2969
  * @example
3081
- * var res = source.selectMany(function (x) { return Rx.Observable.range(0, x); });
2970
+ * var res = source.concatMap(function (x) { return Rx.Observable.range(0, x); });
3082
2971
  * Or:
3083
2972
  * Projects each element of an observable sequence to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence.
3084
2973
  *
3085
- * var res = source.selectMany(function (x) { return Rx.Observable.range(0, x); }, function (x, y) { return x + y; });
2974
+ * var res = source.concatMap(function (x) { return Rx.Observable.range(0, x); }, function (x, y) { return x + y; });
3086
2975
  * Or:
3087
2976
  * Projects each element of the source observable sequence to the other observable sequence and merges the resulting observable sequences into one observable sequence.
3088
2977
  *
3089
- * var res = source.selectMany(Rx.Observable.fromArray([1,2,3]));
2978
+ * var res = source.concatMap(Rx.Observable.fromArray([1,2,3]));
3090
2979
  * @param selector A transform function to apply to each element or an observable sequence to project each element from the
3091
2980
  * source sequence onto which could be either an observable or Promise.
3092
2981
  * @param {Function} [resultSelector] A transform function to apply to each element of the intermediate sequence.
3093
2982
  * @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.
3094
2983
  */
3095
- observableProto.selectConcat = observableProto.concatMap = function (selector, resultSelector) {
2984
+ observableProto.selectConcat = observableProto.concatMap = function (selector, resultSelector, thisArg) {
3096
2985
  if (resultSelector) {
3097
2986
  return this.concatMap(function (x, i) {
3098
2987
  var selectorResult = selector(x, i),
@@ -3103,12 +2992,9 @@
3103
2992
  });
3104
2993
  });
3105
2994
  }
3106
- if (typeof selector === 'function') {
3107
- return concatMap.call(this, selector);
3108
- }
3109
- return concatMap.call(this, function () {
3110
- return selector;
3111
- });
2995
+ return typeof selector === 'function' ?
2996
+ concatMap(this, selector, thisArg) :
2997
+ concatMap(this, function () { return selector; });
3112
2998
  };
3113
2999
 
3114
3000
  /**
@@ -3143,33 +3029,13 @@
3143
3029
  return this.select(function (x) { return x[property]; });
3144
3030
  };
3145
3031
 
3146
- function selectMany(selector) {
3147
- return this.select(function (x, i) {
3148
- var result = selector(x, i);
3032
+ function flatMap(source, selector, thisArg) {
3033
+ return source.map(function (x, i) {
3034
+ var result = selector.call(thisArg, x, i);
3149
3035
  return isPromise(result) ? observableFromPromise(result) : result;
3150
3036
  }).mergeObservable();
3151
3037
  }
3152
3038
 
3153
- function selectManyObserver(onNext, onError, onCompleted) {
3154
- var source = this;
3155
- return new AnonymousObservable(function (observer) {
3156
- var index = 0;
3157
-
3158
- return source.subscribe(
3159
- function (x) {
3160
- observer.onNext(onNext(x, index++));
3161
- },
3162
- function (err) {
3163
- observer.onNext(onError(err));
3164
- observer.completed();
3165
- },
3166
- function () {
3167
- observer.onNext(onCompleted());
3168
- observer.onCompleted();
3169
- });
3170
- }).mergeAll();
3171
- }
3172
-
3173
3039
  /**
3174
3040
  * One of the Following:
3175
3041
  * Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
@@ -3187,25 +3053,23 @@
3187
3053
  * @param selector A transform function to apply to each element or an observable sequence to project each element from the
3188
3054
  * source sequence onto which could be either an observable or Promise.
3189
3055
  * @param {Function} [resultSelector] A transform function to apply to each element of the intermediate sequence.
3056
+ * @param {Any} [thisArg] Object to use as this when executing callback.
3190
3057
  * @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.
3191
3058
  */
3192
- observableProto.selectMany = observableProto.flatMap = function (selector, resultSelector) {
3059
+ observableProto.selectMany = observableProto.flatMap = function (selector, resultSelector, thisArg) {
3193
3060
  if (resultSelector) {
3194
- return this.selectMany(function (x, i) {
3061
+ return this.flatMap(function (x, i) {
3195
3062
  var selectorResult = selector(x, i),
3196
3063
  result = isPromise(selectorResult) ? observableFromPromise(selectorResult) : selectorResult;
3197
3064
 
3198
- return result.select(function (y) {
3065
+ return result.map(function (y) {
3199
3066
  return resultSelector(x, y, i);
3200
3067
  });
3201
- });
3068
+ }, thisArg);
3202
3069
  }
3203
- if (typeof selector === 'function') {
3204
- return selectMany.call(this, selector);
3205
- }
3206
- return selectMany.call(this, function () {
3207
- return selector;
3208
- });
3070
+ return typeof selector === 'function' ?
3071
+ flatMap(this, selector, thisArg) :
3072
+ flatMap(this, function () { return selector; });
3209
3073
  };
3210
3074
 
3211
3075
  /**
@@ -3403,7 +3267,7 @@
3403
3267
 
3404
3268
  args.push(handler);
3405
3269
  func.apply(context, args);
3406
- });
3270
+ }).publishLast().refCount();
3407
3271
  };
3408
3272
  };
3409
3273
 
@@ -3448,18 +3312,11 @@
3448
3312
 
3449
3313
  args.push(handler);
3450
3314
  func.apply(context, args);
3451
- });
3315
+ }).publishLast().refCount();
3452
3316
  };
3453
3317
  };
3454
3318
 
3455
3319
  function createListener (element, name, handler) {
3456
- // Node.js specific
3457
- if (element.addListener) {
3458
- element.addListener(name, handler);
3459
- return disposableCreate(function () {
3460
- element.removeListener(name, handler);
3461
- });
3462
- }
3463
3320
  if (element.addEventListener) {
3464
3321
  element.addEventListener(name, handler, false);
3465
3322
  return disposableCreate(function () {
@@ -3473,7 +3330,7 @@
3473
3330
  var disposables = new CompositeDisposable();
3474
3331
 
3475
3332
  // Asume NodeList
3476
- if (typeof el.item === 'function' && typeof el.length === 'number') {
3333
+ if (Object.prototype.toString.call(el) === '[object NodeList]') {
3477
3334
  for (var i = 0, len = el.length; i < len; i++) {
3478
3335
  disposables.add(createEventListener(el.item(i), eventName, handler));
3479
3336
  }
@@ -3484,6 +3341,11 @@
3484
3341
  return disposables;
3485
3342
  }
3486
3343
 
3344
+ /**
3345
+ * Configuration option to determine whether to use native events only
3346
+ */
3347
+ Rx.config.useNativeEvents = false;
3348
+
3487
3349
  // Check for Angular/jQuery/Zepto support
3488
3350
  var jq =
3489
3351
  !!root.angular && !!angular.element ? angular.element :
@@ -3492,6 +3354,10 @@
3492
3354
 
3493
3355
  // Check for ember
3494
3356
  var ember = !!root.Ember && typeof root.Ember.addListener === 'function';
3357
+
3358
+ // Check for Backbone.Marionette. Note if using AMD add Marionette as a dependency of rxjs
3359
+ // for proper loading order!
3360
+ var marionette = !!root.Backbone && !!root.Backbone.Marionette;
3495
3361
 
3496
3362
  /**
3497
3363
  * Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList.
@@ -3505,18 +3371,35 @@
3505
3371
  * @returns {Observable} An observable sequence of events from the specified element and the specified event.
3506
3372
  */
3507
3373
  Observable.fromEvent = function (element, eventName, selector) {
3508
- if (ember) {
3509
- return fromEventPattern(
3510
- function (h) { Ember.addListener(element, eventName, h); },
3511
- function (h) { Ember.removeListener(element, eventName, h); },
3512
- selector);
3513
- }
3514
- if (jq) {
3515
- var $elem = jq(element);
3374
+ // Node.js specific
3375
+ if (element.addListener) {
3516
3376
  return fromEventPattern(
3517
- function (h) { $elem.on(eventName, h); },
3518
- function (h) { $elem.off(eventName, h); },
3377
+ function (h) { element.addListener(eventName, h); },
3378
+ function (h) { element.removeListener(eventName, h); },
3519
3379
  selector);
3380
+ }
3381
+
3382
+ // Use only if non-native events are allowed
3383
+ if (!Rx.config.useNativeEvents) {
3384
+ if (marionette) {
3385
+ return fromEventPattern(
3386
+ function (h) { element.on(eventName, h); },
3387
+ function (h) { element.off(eventName, h); },
3388
+ selector);
3389
+ }
3390
+ if (ember) {
3391
+ return fromEventPattern(
3392
+ function (h) { Ember.addListener(element, eventName, h); },
3393
+ function (h) { Ember.removeListener(element, eventName, h); },
3394
+ selector);
3395
+ }
3396
+ if (jq) {
3397
+ var $elem = jq(element);
3398
+ return fromEventPattern(
3399
+ function (h) { $elem.on(eventName, h); },
3400
+ function (h) { $elem.off(eventName, h); },
3401
+ selector);
3402
+ }
3520
3403
  }
3521
3404
  return new AnonymousObservable(function (observer) {
3522
3405
  return createEventListener(
@@ -3576,21 +3459,19 @@
3576
3459
  * @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
3577
3460
  */
3578
3461
  var observableFromPromise = Observable.fromPromise = function (promise) {
3579
- return new AnonymousObservable(function (observer) {
3462
+ return observableDefer(function () {
3463
+ var subject = new Rx.AsyncSubject();
3464
+
3580
3465
  promise.then(
3581
3466
  function (value) {
3582
- observer.onNext(value);
3583
- observer.onCompleted();
3584
- },
3585
- function (reason) {
3586
- observer.onError(reason);
3587
- });
3467
+ if (!subject.isDisposed) {
3468
+ subject.onNext(value);
3469
+ subject.onCompleted();
3470
+ }
3471
+ },
3472
+ subject.onError.bind(subject));
3588
3473
 
3589
- return function () {
3590
- if (promise && promise.abort) {
3591
- promise.abort();
3592
- }
3593
- }
3474
+ return subject;
3594
3475
  });
3595
3476
  };
3596
3477
  /*
@@ -3640,32 +3521,32 @@
3640
3521
  return observableFromPromise(promise);
3641
3522
  }
3642
3523
 
3643
- /**
3644
- * Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
3645
- * subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
3646
- * invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
3647
- *
3648
- * @example
3649
- * 1 - res = source.multicast(observable);
3650
- * 2 - res = source.multicast(function () { return new Subject(); }, function (x) { return x; });
3651
- *
3652
- * @param {Function|Subject} subjectOrSubjectSelector
3653
- * Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
3654
- * Or:
3655
- * Subject to push source elements into.
3656
- *
3657
- * @param {Function} [selector] Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if <paramref name="subjectOrSubjectSelector" is a factory function.
3658
- * @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
3659
- */
3660
- observableProto.multicast = function (subjectOrSubjectSelector, selector) {
3661
- var source = this;
3662
- return typeof subjectOrSubjectSelector === 'function' ?
3663
- new AnonymousObservable(function (observer) {
3664
- var connectable = source.multicast(subjectOrSubjectSelector());
3665
- return new CompositeDisposable(selector(connectable).subscribe(observer), connectable.connect());
3666
- }) :
3667
- new ConnectableObservable(source, subjectOrSubjectSelector);
3668
- };
3524
+ /**
3525
+ * Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
3526
+ * subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
3527
+ * invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
3528
+ *
3529
+ * @example
3530
+ * 1 - res = source.multicast(observable);
3531
+ * 2 - res = source.multicast(function () { return new Subject(); }, function (x) { return x; });
3532
+ *
3533
+ * @param {Function|Subject} subjectOrSubjectSelector
3534
+ * Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
3535
+ * Or:
3536
+ * Subject to push source elements into.
3537
+ *
3538
+ * @param {Function} [selector] Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if <paramref name="subjectOrSubjectSelector" is a factory function.
3539
+ * @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
3540
+ */
3541
+ observableProto.multicast = function (subjectOrSubjectSelector, selector) {
3542
+ var source = this;
3543
+ return typeof subjectOrSubjectSelector === 'function' ?
3544
+ new AnonymousObservable(function (observer) {
3545
+ var connectable = source.multicast(subjectOrSubjectSelector());
3546
+ return new CompositeDisposable(selector(connectable).subscribe(observer), connectable.connect());
3547
+ }) :
3548
+ new ConnectableObservable(source, subjectOrSubjectSelector);
3549
+ };
3669
3550
 
3670
3551
  /**
3671
3552
  * Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence.
@@ -3796,108 +3677,59 @@
3796
3677
  return this.replay(null, bufferSize, window, scheduler).refCount();
3797
3678
  };
3798
3679
 
3799
- /** @private */
3800
- var ConnectableObservable = Rx.ConnectableObservable = (function (_super) {
3801
- inherits(ConnectableObservable, _super);
3802
-
3803
- /**
3804
- * @constructor
3805
- * @private
3806
- */
3807
- function ConnectableObservable(source, subject) {
3808
- var state = {
3809
- subject: subject,
3810
- source: source.asObservable(),
3811
- hasSubscription: false,
3812
- subscription: null
3813
- };
3814
-
3815
- this.connect = function () {
3816
- if (!state.hasSubscription) {
3817
- state.hasSubscription = true;
3818
- state.subscription = new CompositeDisposable(state.source.subscribe(state.subject), disposableCreate(function () {
3819
- state.hasSubscription = false;
3820
- }));
3821
- }
3822
- return state.subscription;
3823
- };
3824
-
3825
- function subscribe(observer) {
3826
- return state.subject.subscribe(observer);
3827
- }
3828
-
3829
- _super.call(this, subscribe);
3830
- }
3831
-
3832
- /**
3833
- * @private
3834
- * @memberOf ConnectableObservable
3835
- */
3836
- ConnectableObservable.prototype.connect = function () { return this.connect(); };
3837
-
3838
- /**
3839
- * @private
3840
- * @memberOf ConnectableObservable
3841
- */
3842
- ConnectableObservable.prototype.refCount = function () {
3843
- var connectableSubscription = null, count = 0, source = this;
3844
- return new AnonymousObservable(function (observer) {
3845
- var shouldConnect, subscription;
3846
- count++;
3847
- shouldConnect = count === 1;
3848
- subscription = source.subscribe(observer);
3849
- if (shouldConnect) {
3850
- connectableSubscription = source.connect();
3851
- }
3852
- return disposableCreate(function () {
3853
- subscription.dispose();
3854
- count--;
3855
- if (count === 0) {
3856
- connectableSubscription.dispose();
3857
- }
3858
- });
3859
- });
3860
- };
3861
-
3862
- return ConnectableObservable;
3863
- }(Observable));
3864
-
3865
- function observableTimerTimeSpan(dueTime, scheduler) {
3866
- var d = normalizeTime(dueTime);
3867
- return new AnonymousObservable(function (observer) {
3868
- return scheduler.scheduleWithRelative(d, function () {
3869
- observer.onNext(0);
3870
- observer.onCompleted();
3871
- });
3872
- });
3873
- }
3874
-
3875
- function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
3876
- if (dueTime === period) {
3877
- return new AnonymousObservable(function (observer) {
3878
- return scheduler.schedulePeriodicWithState(0, period, function (count) {
3879
- observer.onNext(count);
3880
- return count + 1;
3881
- });
3680
+ var ConnectableObservable = Rx.ConnectableObservable = (function (__super__) {
3681
+ inherits(ConnectableObservable, __super__);
3682
+
3683
+ function ConnectableObservable(source, subject) {
3684
+ var hasSubscription = false,
3685
+ subscription,
3686
+ sourceObservable = source.asObservable();
3687
+
3688
+ this.connect = function () {
3689
+ if (!hasSubscription) {
3690
+ hasSubscription = true;
3691
+ subscription = new CompositeDisposable(sourceObservable.subscribe(subject), disposableCreate(function () {
3692
+ hasSubscription = false;
3693
+ }));
3694
+ }
3695
+ return subscription;
3696
+ };
3697
+
3698
+ __super__.call(this, subject.subscribe.bind(subject));
3699
+ }
3700
+
3701
+ ConnectableObservable.prototype.refCount = function () {
3702
+ var connectableSubscription, count = 0, source = this;
3703
+ return new AnonymousObservable(function (observer) {
3704
+ var shouldConnect = ++count === 1,
3705
+ subscription = source.subscribe(observer);
3706
+ shouldConnect && (connectableSubscription = source.connect());
3707
+ return function () {
3708
+ subscription.dispose();
3709
+ --count === 0 && connectableSubscription.dispose();
3710
+ };
3711
+ });
3712
+ };
3713
+
3714
+ return ConnectableObservable;
3715
+ }(Observable));
3716
+ function observableTimerDate(dueTime, scheduler) {
3717
+ return new AnonymousObservable(function (observer) {
3718
+ return scheduler.scheduleWithAbsolute(dueTime, function () {
3719
+ observer.onNext(0);
3720
+ observer.onCompleted();
3882
3721
  });
3883
- }
3884
- return observableDefer(function () {
3885
- return observableTimerDateAndPeriod(scheduler.now() + dueTime, period, scheduler);
3886
3722
  });
3887
3723
  }
3888
3724
 
3889
3725
  function observableTimerDateAndPeriod(dueTime, period, scheduler) {
3890
- var p = normalizeTime(period);
3891
3726
  return new AnonymousObservable(function (observer) {
3892
- var count = 0, d = dueTime;
3727
+ var count = 0, d = dueTime, p = normalizeTime(period);
3893
3728
  return scheduler.scheduleRecursiveWithAbsolute(d, function (self) {
3894
- var now;
3895
3729
  if (p > 0) {
3896
- now = scheduler.now();
3730
+ var now = scheduler.now();
3897
3731
  d = d + p;
3898
- if (d <= now) {
3899
- d = now + p;
3900
- }
3732
+ d <= now && (d = now + p);
3901
3733
  }
3902
3734
  observer.onNext(count++);
3903
3735
  self(d);
@@ -3905,6 +3737,28 @@
3905
3737
  });
3906
3738
  }
3907
3739
 
3740
+ function observableTimerTimeSpan(dueTime, scheduler) {
3741
+ return new AnonymousObservable(function (observer) {
3742
+ return scheduler.scheduleWithRelative(normalizeTime(dueTime), function () {
3743
+ observer.onNext(0);
3744
+ observer.onCompleted();
3745
+ });
3746
+ });
3747
+ }
3748
+
3749
+ function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
3750
+ return dueTime === period ?
3751
+ new AnonymousObservable(function (observer) {
3752
+ return scheduler.schedulePeriodicWithState(0, period, function (count) {
3753
+ observer.onNext(count);
3754
+ return count + 1;
3755
+ });
3756
+ }) :
3757
+ observableDefer(function () {
3758
+ return observableTimerDateAndPeriod(scheduler.now() + dueTime, period, scheduler);
3759
+ });
3760
+ }
3761
+
3908
3762
  /**
3909
3763
  * Returns an observable sequence that produces a value after each period.
3910
3764
  *
@@ -3924,12 +3778,17 @@
3924
3778
  * Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
3925
3779
  *
3926
3780
  * @example
3927
- * var res = Rx.Observable.timer(5000);
3928
- * var res = Rx.Observable.timer(5000, 1000);
3929
- * var res = Rx.Observable.timer(5000, Rx.Scheduler.timeout);
3930
- * var res = Rx.Observable.timer(5000, 1000, Rx.Scheduler.timeout);
3781
+ * 1 - res = Rx.Observable.timer(new Date());
3782
+ * 2 - res = Rx.Observable.timer(new Date(), 1000);
3783
+ * 3 - res = Rx.Observable.timer(new Date(), Rx.Scheduler.timeout);
3784
+ * 4 - res = Rx.Observable.timer(new Date(), 1000, Rx.Scheduler.timeout);
3931
3785
  *
3932
- * @param {Number} dueTime Relative time (specified as an integer denoting milliseconds) at which to produce the first value.
3786
+ * 5 - res = Rx.Observable.timer(5000);
3787
+ * 6 - res = Rx.Observable.timer(5000, 1000);
3788
+ * 7 - res = Rx.Observable.timer(5000, Rx.Scheduler.timeout);
3789
+ * 8 - res = Rx.Observable.timer(5000, 1000, Rx.Scheduler.timeout);
3790
+ *
3791
+ * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
3933
3792
  * @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
3934
3793
  * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
3935
3794
  * @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
@@ -3937,30 +3796,24 @@
3937
3796
  var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
3938
3797
  var period;
3939
3798
  isScheduler(scheduler) || (scheduler = timeoutScheduler);
3940
- if (typeof periodOrScheduler === 'number') {
3799
+ if (periodOrScheduler !== undefined && typeof periodOrScheduler === 'number') {
3941
3800
  period = periodOrScheduler;
3942
- } else if (typeof periodOrScheduler === 'object' && typeof periodOrScheduler.now === 'function') {
3801
+ } else if (periodOrScheduler !== undefined && typeof periodOrScheduler === 'object') {
3943
3802
  scheduler = periodOrScheduler;
3944
3803
  }
3945
- return notDefined(period) ?
3804
+ if (dueTime instanceof Date && period === undefined) {
3805
+ return observableTimerDate(dueTime.getTime(), scheduler);
3806
+ }
3807
+ if (dueTime instanceof Date && period !== undefined) {
3808
+ period = periodOrScheduler;
3809
+ return observableTimerDateAndPeriod(dueTime.getTime(), period, scheduler);
3810
+ }
3811
+ return period === undefined ?
3946
3812
  observableTimerTimeSpan(dueTime, scheduler) :
3947
3813
  observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
3948
3814
  };
3949
3815
 
3950
- /**
3951
- * Time shifts the observable sequence by dueTime. The relative time intervals between the values are preserved.
3952
- *
3953
- * @example
3954
- * var res = Rx.Observable.delay(5000);
3955
- * var res = Rx.Observable.delay(5000, 1000, Rx.Scheduler.timeout);
3956
- * @memberOf Observable#
3957
- * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
3958
- * @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
3959
- * @returns {Observable} Time-shifted sequence.
3960
- */
3961
- observableProto.delay = function (dueTime, scheduler) {
3962
- isScheduler(scheduler) || (scheduler = timeoutScheduler);
3963
- var source = this;
3816
+ function observableDelayTimeSpan(source, dueTime, scheduler) {
3964
3817
  return new AnonymousObservable(function (observer) {
3965
3818
  var active = false,
3966
3819
  cancelable = new SerialDisposable(),
@@ -3988,9 +3841,9 @@
3988
3841
  cancelable.setDisposable(d);
3989
3842
  d.setDisposable(scheduler.scheduleRecursiveWithRelative(dueTime, function (self) {
3990
3843
  var e, recurseDueTime, result, shouldRecurse;
3991
-
3992
- if (exception !== null) { return; }
3993
-
3844
+ if (exception !== null) {
3845
+ return;
3846
+ }
3994
3847
  running = true;
3995
3848
  do {
3996
3849
  result = null;
@@ -4001,7 +3854,6 @@
4001
3854
  result.accept(observer);
4002
3855
  }
4003
3856
  } while (result !== null);
4004
-
4005
3857
  shouldRecurse = false;
4006
3858
  recurseDueTime = 0;
4007
3859
  if (q.length > 0) {
@@ -4023,6 +3875,33 @@
4023
3875
  });
4024
3876
  return new CompositeDisposable(subscription, cancelable);
4025
3877
  });
3878
+ }
3879
+
3880
+ function observableDelayDate(source, dueTime, scheduler) {
3881
+ return observableDefer(function () {
3882
+ return observableDelayTimeSpan(source, dueTime - scheduler.now(), scheduler);
3883
+ });
3884
+ }
3885
+
3886
+ /**
3887
+ * Time shifts the observable sequence by dueTime. The relative time intervals between the values are preserved.
3888
+ *
3889
+ * @example
3890
+ * 1 - res = Rx.Observable.delay(new Date());
3891
+ * 2 - res = Rx.Observable.delay(new Date(), Rx.Scheduler.timeout);
3892
+ *
3893
+ * 3 - res = Rx.Observable.delay(5000);
3894
+ * 4 - res = Rx.Observable.delay(5000, 1000, Rx.Scheduler.timeout);
3895
+ * @memberOf Observable#
3896
+ * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
3897
+ * @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
3898
+ * @returns {Observable} Time-shifted sequence.
3899
+ */
3900
+ observableProto.delay = function (dueTime, scheduler) {
3901
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
3902
+ return dueTime instanceof Date ?
3903
+ observableDelayDate(this, dueTime.getTime(), scheduler) :
3904
+ observableDelayTimeSpan(this, dueTime, scheduler);
4026
3905
  };
4027
3906
 
4028
3907
  /**
@@ -4041,29 +3920,6 @@
4041
3920
  return this.throttleWithSelector(function () { return observableTimer(dueTime, scheduler); })
4042
3921
  };
4043
3922
 
4044
- /**
4045
- * Records the time interval between consecutive values in an observable sequence.
4046
- *
4047
- * @example
4048
- * 1 - res = source.timeInterval();
4049
- * 2 - res = source.timeInterval(Rx.Scheduler.timeout);
4050
- *
4051
- * @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
4052
- * @returns {Observable} An observable sequence with time interval information on values.
4053
- */
4054
- observableProto.timeInterval = function (scheduler) {
4055
- var source = this;
4056
- isScheduler(scheduler) || (scheduler = timeoutScheduler);
4057
- return observableDefer(function () {
4058
- var last = scheduler.now();
4059
- return source.map(function (x) {
4060
- var now = scheduler.now(), span = now - last;
4061
- last = now;
4062
- return { value: x, interval: span };
4063
- });
4064
- });
4065
- };
4066
-
4067
3923
  /**
4068
3924
  * Records the timestamp for each value in an observable sequence.
4069
3925
  *
@@ -4191,60 +4047,6 @@
4191
4047
  });
4192
4048
  };
4193
4049
 
4194
- /**
4195
- * Generates an observable sequence by iterating a state from an initial state until the condition fails.
4196
- *
4197
- * @example
4198
- * res = source.generateWithRelativeTime(0,
4199
- * function (x) { return return true; },
4200
- * function (x) { return x + 1; },
4201
- * function (x) { return x; },
4202
- * function (x) { return 500; }
4203
- * );
4204
- *
4205
- * @param {Mixed} initialState Initial state.
4206
- * @param {Function} condition Condition to terminate generation (upon returning false).
4207
- * @param {Function} iterate Iteration step function.
4208
- * @param {Function} resultSelector Selector function for results produced in the sequence.
4209
- * @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
4210
- * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
4211
- * @returns {Observable} The generated sequence.
4212
- */
4213
- Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
4214
- isScheduler(scheduler) || (scheduler = timeoutScheduler);
4215
- return new AnonymousObservable(function (observer) {
4216
- var first = true,
4217
- hasResult = false,
4218
- result,
4219
- state = initialState,
4220
- time;
4221
- return scheduler.scheduleRecursiveWithRelative(0, function (self) {
4222
- hasResult && observer.onNext(result);
4223
-
4224
- try {
4225
- if (first) {
4226
- first = false;
4227
- } else {
4228
- state = iterate(state);
4229
- }
4230
- hasResult = condition(state);
4231
- if (hasResult) {
4232
- result = resultSelector(state);
4233
- time = timeSelector(state);
4234
- }
4235
- } catch (e) {
4236
- observer.onError(e);
4237
- return;
4238
- }
4239
- if (hasResult) {
4240
- self(time);
4241
- } else {
4242
- observer.onCompleted();
4243
- }
4244
- });
4245
- });
4246
- };
4247
-
4248
4050
  /**
4249
4051
  * Time shifts the observable sequence by delaying the subscription.
4250
4052
  *
@@ -4495,38 +4297,20 @@
4495
4297
  });
4496
4298
  };
4497
4299
 
4498
- /**
4499
- * Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
4500
- *
4501
- * @example
4502
- * 1 - res = source.takeLastWithTime(5000, [optional timer scheduler], [optional loop scheduler]);
4503
- * @description
4504
- * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4505
- * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4506
- * result sequence. This causes elements to be delayed with duration.
4507
- * @param {Number} duration Duration for taking elements from the end of the sequence.
4508
- * @param {Scheduler} [timerScheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4509
- * @param {Scheduler} [loopScheduler] Scheduler to drain the collected elements. If not specified, defaults to Rx.Scheduler.immediate.
4510
- * @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
4511
- */
4512
- observableProto.takeLastWithTime = function (duration, timerScheduler, loopScheduler) {
4513
- return this.takeLastBufferWithTime(duration, timerScheduler).selectMany(function (xs) { return observableFromArray(xs, loopScheduler); });
4514
- };
4515
-
4516
4300
  /**
4517
- * Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
4301
+ * Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
4518
4302
  *
4519
4303
  * @example
4520
- * 1 - res = source.takeLastBufferWithTime(5000, [optional scheduler]);
4304
+ * 1 - res = source.takeLastWithTime(5000, [optional timer scheduler], [optional loop scheduler]);
4521
4305
  * @description
4522
4306
  * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4523
4307
  * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4524
- * result sequence. This causes elements to be delayed with duration.
4308
+ * result sequence. This causes elements to be delayed with duration.
4525
4309
  * @param {Number} duration Duration for taking elements from the end of the sequence.
4526
- * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4527
- * @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
4310
+ * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4311
+ * @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
4528
4312
  */
4529
- observableProto.takeLastBufferWithTime = function (duration, scheduler) {
4313
+ observableProto.takeLastWithTime = function (duration, scheduler) {
4530
4314
  var source = this;
4531
4315
  isScheduler(scheduler) || (scheduler = timeoutScheduler);
4532
4316
  return new AnonymousObservable(function (observer) {
@@ -4539,18 +4323,17 @@
4539
4323
  q.shift();
4540
4324
  }
4541
4325
  }, observer.onError.bind(observer), function () {
4542
- var now = scheduler.now(), res = [];
4326
+ var now = scheduler.now();
4543
4327
  while (q.length > 0) {
4544
4328
  var next = q.shift();
4545
4329
  if (now - next.interval <= duration) {
4546
- res.push(next.value);
4330
+ observer.onNext(next.value);
4547
4331
  }
4548
4332
  }
4549
4333
 
4550
- observer.onNext(res);
4551
4334
  observer.onCompleted();
4552
4335
  });
4553
- });
4336
+ });
4554
4337
  };
4555
4338
 
4556
4339
  /**
@@ -4601,56 +4384,6 @@
4601
4384
  });
4602
4385
  };
4603
4386
 
4604
- /**
4605
- * Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
4606
- * Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
4607
- *
4608
- * @examples
4609
- * 1 - res = source.skipUntilWithTime(new Date(), [optional scheduler]);
4610
- * 2 - res = source.skipUntilWithTime(5000, [optional scheduler]);
4611
- * @param startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
4612
- * @param scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4613
- * @returns {Observable} An observable sequence with the elements skipped until the specified start time.
4614
- */
4615
- observableProto.skipUntilWithTime = function (startTime, scheduler) {
4616
- isScheduler(scheduler) || (scheduler = timeoutScheduler);
4617
- var source = this, schedulerMethod = startTime instanceof Date ?
4618
- 'scheduleWithAbsolute' :
4619
- 'scheduleWithRelative';
4620
- return new AnonymousObservable(function (observer) {
4621
- var open = false;
4622
-
4623
- return new CompositeDisposable(
4624
- scheduler[schedulerMethod](startTime, function () { open = true; }),
4625
- source.subscribe(
4626
- function (x) { open && observer.onNext(x); },
4627
- observer.onError.bind(observer),
4628
- observer.onCompleted.bind(observer)));
4629
- });
4630
- };
4631
-
4632
- /**
4633
- * Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
4634
- *
4635
- * @example
4636
- * 1 - res = source.takeUntilWithTime(new Date(), [optional scheduler]);
4637
- * 2 - res = source.takeUntilWithTime(5000, [optional scheduler]);
4638
- * @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
4639
- * @param {Scheduler} scheduler Scheduler to run the timer on.
4640
- * @returns {Observable} An observable sequence with the elements taken until the specified end time.
4641
- */
4642
- observableProto.takeUntilWithTime = function (endTime, scheduler) {
4643
- isScheduler(scheduler) || (scheduler = timeoutScheduler);
4644
- var source = this, schedulerMethod = endTime instanceof Date ?
4645
- 'scheduleWithAbsolute' :
4646
- 'scheduleWithRelative';
4647
- return new AnonymousObservable(function (observer) {
4648
- return new CompositeDisposable(scheduler[schedulerMethod](endTime, function () {
4649
- observer.onCompleted();
4650
- }), source.subscribe(observer));
4651
- });
4652
- };
4653
-
4654
4387
  var PausableObservable = (function (_super) {
4655
4388
 
4656
4389
  inherits(PausableObservable, _super);
@@ -4660,7 +4393,7 @@
4660
4393
  subscription = conn.subscribe(observer),
4661
4394
  connection = disposableEmpty;
4662
4395
 
4663
- var pausable = this.subject.distinctUntilChanged().subscribe(function (b) {
4396
+ var pausable = this.pauser.distinctUntilChanged().subscribe(function (b) {
4664
4397
  if (b) {
4665
4398
  connection = conn.connect();
4666
4399
  } else {
@@ -4672,27 +4405,25 @@
4672
4405
  return new CompositeDisposable(subscription, connection, pausable);
4673
4406
  }
4674
4407
 
4675
- function PausableObservable(source, subject) {
4408
+ function PausableObservable(source, pauser) {
4676
4409
  this.source = source;
4677
- this.subject = subject || new Subject();
4678
- this.isPaused = true;
4410
+ this.controller = new Subject();
4411
+
4412
+ if (pauser && pauser.subscribe) {
4413
+ this.pauser = this.controller.merge(pauser);
4414
+ } else {
4415
+ this.pauser = this.controller;
4416
+ }
4417
+
4679
4418
  _super.call(this, subscribe);
4680
4419
  }
4681
4420
 
4682
4421
  PausableObservable.prototype.pause = function () {
4683
- if (this.isPaused === true){
4684
- return;
4685
- }
4686
- this.isPaused = true;
4687
- this.subject.onNext(false);
4422
+ this.controller.onNext(false);
4688
4423
  };
4689
4424
 
4690
4425
  PausableObservable.prototype.resume = function () {
4691
- if (this.isPaused === false){
4692
- return;
4693
- }
4694
- this.isPaused = false;
4695
- this.subject.onNext(true);
4426
+ this.controller.onNext(true);
4696
4427
  };
4697
4428
 
4698
4429
  return PausableObservable;
@@ -4759,30 +4490,33 @@
4759
4490
  inherits(PausableBufferedObservable, _super);
4760
4491
 
4761
4492
  function subscribe(observer) {
4762
- var q = [], previous = true;
4493
+ var q = [], previousShouldFire;
4763
4494
 
4764
4495
  var subscription =
4765
4496
  combineLatestSource(
4766
4497
  this.source,
4767
- this.subject.distinctUntilChanged(),
4498
+ this.pauser.distinctUntilChanged().startWith(false),
4768
4499
  function (data, shouldFire) {
4769
4500
  return { data: data, shouldFire: shouldFire };
4770
4501
  })
4771
4502
  .subscribe(
4772
4503
  function (results) {
4773
- if (results.shouldFire && previous) {
4774
- observer.onNext(results.data);
4775
- }
4776
- if (results.shouldFire && !previous) {
4777
- while (q.length > 0) {
4778
- observer.onNext(q.shift());
4504
+ if (previousShouldFire !== undefined && results.shouldFire != previousShouldFire) {
4505
+ // change in shouldFire
4506
+ if (results.shouldFire) {
4507
+ while (q.length > 0) {
4508
+ observer.onNext(q.shift());
4509
+ }
4510
+ }
4511
+ } else {
4512
+ // new data
4513
+ if (results.shouldFire) {
4514
+ observer.onNext(results.data);
4515
+ } else {
4516
+ q.push(results.data);
4779
4517
  }
4780
- previous = true;
4781
- } else if (!results.shouldFire && !previous) {
4782
- q.push(results.data);
4783
- } else if (!results.shouldFire && previous) {
4784
- previous = false;
4785
4518
  }
4519
+ previousShouldFire = results.shouldFire;
4786
4520
 
4787
4521
  },
4788
4522
  function (err) {
@@ -4800,33 +4534,28 @@
4800
4534
  observer.onCompleted();
4801
4535
  }
4802
4536
  );
4803
-
4804
- this.subject.onNext(false);
4805
-
4806
4537
  return subscription;
4807
4538
  }
4808
4539
 
4809
- function PausableBufferedObservable(source, subject) {
4540
+ function PausableBufferedObservable(source, pauser) {
4810
4541
  this.source = source;
4811
- this.subject = subject || new Subject();
4812
- this.isPaused = true;
4542
+ this.controller = new Subject();
4543
+
4544
+ if (pauser && pauser.subscribe) {
4545
+ this.pauser = this.controller.merge(pauser);
4546
+ } else {
4547
+ this.pauser = this.controller;
4548
+ }
4549
+
4813
4550
  _super.call(this, subscribe);
4814
4551
  }
4815
4552
 
4816
4553
  PausableBufferedObservable.prototype.pause = function () {
4817
- if (this.isPaused === true){
4818
- return;
4819
- }
4820
- this.isPaused = true;
4821
- this.subject.onNext(false);
4554
+ this.controller.onNext(false);
4822
4555
  };
4823
4556
 
4824
4557
  PausableBufferedObservable.prototype.resume = function () {
4825
- if (this.isPaused === false){
4826
- return;
4827
- }
4828
- this.isPaused = false;
4829
- this.subject.onNext(true);
4558
+ this.controller.onNext(true);
4830
4559
  };
4831
4560
 
4832
4561
  return PausableBufferedObservable;
@@ -5007,50 +4736,6 @@
5007
4736
 
5008
4737
  return ControlledSubject;
5009
4738
  }(Observable));
5010
- /**
5011
- * Returns a new observable that triggers on the second and subsequent triggerings of the input observable.
5012
- * The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as a pair.
5013
- * The argument passed to the N-1th triggering is held in hidden internal state until the Nth triggering occurs.
5014
- * @returns {Observable} An observable that triggers on successive pairs of observations from the input observable as an array.
5015
- */
5016
- observableProto.pairwise = function () {
5017
- var source = this;
5018
- return new AnonymousObservable(function (observer) {
5019
- var previous, hasPrevious = false;
5020
- return source.subscribe(
5021
- function (x) {
5022
- if (hasPrevious) {
5023
- observer.onNext([previous, x]);
5024
- } else {
5025
- hasPrevious = true;
5026
- }
5027
- previous = x;
5028
- },
5029
- observer.onError.bind(observer),
5030
- observer.onCompleted.bind(observer));
5031
- });
5032
- };
5033
- /**
5034
- * Returns two observables which partition the observations of the source by the given function.
5035
- * The first will trigger observations for those values for which the predicate returns true.
5036
- * The second will trigger observations for those values where the predicate returns false.
5037
- * The predicate is executed once for each subscribed observer.
5038
- * Both also propagate all error observations arising from the source and each completes
5039
- * when the source completes.
5040
- * @param {Function} predicate
5041
- * The function to determine which output Observable will trigger a particular observation.
5042
- * @returns {Array}
5043
- * An array of observables. The first triggers when the predicate returns true,
5044
- * and the second triggers when the predicate returns false.
5045
- */
5046
- observableProto.partition = function(predicate, thisArg) {
5047
- var published = this.publish().refCount();
5048
- return [
5049
- published.filter(predicate, thisArg),
5050
- published.filter(function (x, i, o) { return !predicate.call(thisArg, x, i, o); })
5051
- ];
5052
- };
5053
-
5054
4739
  /*
5055
4740
  * Performs a exclusive waiting for the first to finish before subscribing to another observable.
5056
4741
  * Observables that come in between subscriptions will be dropped on the floor.
@@ -5166,13 +4851,11 @@
5166
4851
 
5167
4852
  // Fix subscriber to check for undefined or function returned to decorate as Disposable
5168
4853
  function fixSubscriber(subscriber) {
5169
- if (typeof subscriber === 'undefined') {
5170
- subscriber = disposableEmpty;
5171
- } else if (typeof subscriber === 'function') {
5172
- subscriber = disposableCreate(subscriber);
5173
- }
4854
+ if (subscriber && typeof subscriber.dispose === 'function') { return subscriber; }
5174
4855
 
5175
- return subscriber;
4856
+ return typeof subscriber === 'function' ?
4857
+ disposableCreate(subscriber) :
4858
+ disposableEmpty;
5176
4859
  }
5177
4860
 
5178
4861
  function AnonymousObservable(subscribe) {
@@ -5269,23 +4952,23 @@
5269
4952
  return AutoDetachObserver;
5270
4953
  }(AbstractObserver));
5271
4954
 
5272
- /** @private */
5273
- var InnerSubscription = function (subject, observer) {
5274
- this.subject = subject;
5275
- this.observer = observer;
5276
- };
5277
-
5278
- /**
5279
- * @private
5280
- * @memberOf InnerSubscription
5281
- */
5282
- InnerSubscription.prototype.dispose = function () {
5283
- if (!this.subject.isDisposed && this.observer !== null) {
5284
- var idx = this.subject.observers.indexOf(this.observer);
5285
- this.subject.observers.splice(idx, 1);
5286
- this.observer = null;
5287
- }
5288
- };
4955
+ /** @private */
4956
+ var InnerSubscription = function (subject, observer) {
4957
+ this.subject = subject;
4958
+ this.observer = observer;
4959
+ };
4960
+
4961
+ /**
4962
+ * @private
4963
+ * @memberOf InnerSubscription
4964
+ */
4965
+ InnerSubscription.prototype.dispose = function () {
4966
+ if (!this.subject.isDisposed && this.observer !== null) {
4967
+ var idx = this.subject.observers.indexOf(this.observer);
4968
+ this.subject.observers.splice(idx, 1);
4969
+ this.observer = null;
4970
+ }
4971
+ };
5289
4972
 
5290
4973
  /**
5291
4974
  * Represents an object that is both an observable sequence as well as an observer.
@@ -5394,176 +5077,154 @@
5394
5077
  return Subject;
5395
5078
  }(Observable));
5396
5079
 
5397
- /**
5398
- * Represents the result of an asynchronous operation.
5399
- * The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
5400
- */
5401
- var AsyncSubject = Rx.AsyncSubject = (function (_super) {
5402
-
5403
- function subscribe(observer) {
5404
- checkDisposed.call(this);
5405
-
5406
- if (!this.isStopped) {
5407
- this.observers.push(observer);
5408
- return new InnerSubscription(this, observer);
5409
- }
5410
-
5411
- var ex = this.exception,
5412
- hv = this.hasValue,
5413
- v = this.value;
5414
-
5415
- if (ex) {
5416
- observer.onError(ex);
5417
- } else if (hv) {
5418
- observer.onNext(v);
5419
- observer.onCompleted();
5420
- } else {
5421
- observer.onCompleted();
5422
- }
5423
-
5424
- return disposableEmpty;
5425
- }
5080
+ /**
5081
+ * Represents the result of an asynchronous operation.
5082
+ * The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
5083
+ */
5084
+ var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
5426
5085
 
5427
- inherits(AsyncSubject, _super);
5086
+ function subscribe(observer) {
5087
+ checkDisposed.call(this);
5088
+
5089
+ if (!this.isStopped) {
5090
+ this.observers.push(observer);
5091
+ return new InnerSubscription(this, observer);
5092
+ }
5428
5093
 
5429
- /**
5430
- * Creates a subject that can only receive one value and that value is cached for all future observations.
5431
- * @constructor
5432
- */
5433
- function AsyncSubject() {
5434
- _super.call(this, subscribe);
5094
+ var ex = this.exception,
5095
+ hv = this.hasValue,
5096
+ v = this.value;
5435
5097
 
5436
- this.isDisposed = false;
5437
- this.isStopped = false;
5438
- this.value = null;
5439
- this.hasValue = false;
5440
- this.observers = [];
5441
- this.exception = null;
5442
- }
5098
+ if (ex) {
5099
+ observer.onError(ex);
5100
+ } else if (hv) {
5101
+ observer.onNext(v);
5102
+ observer.onCompleted();
5103
+ } else {
5104
+ observer.onCompleted();
5105
+ }
5443
5106
 
5444
- addProperties(AsyncSubject.prototype, Observer, {
5445
- /**
5446
- * Indicates whether the subject has observers subscribed to it.
5447
- * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
5448
- */
5449
- hasObservers: function () {
5450
- checkDisposed.call(this);
5451
- return this.observers.length > 0;
5452
- },
5453
- /**
5454
- * Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
5455
- */
5456
- onCompleted: function () {
5457
- var o, i, len;
5458
- checkDisposed.call(this);
5459
- if (!this.isStopped) {
5460
- this.isStopped = true;
5461
- var os = this.observers.slice(0),
5462
- v = this.value,
5463
- hv = this.hasValue;
5464
-
5465
- if (hv) {
5466
- for (i = 0, len = os.length; i < len; i++) {
5467
- o = os[i];
5468
- o.onNext(v);
5469
- o.onCompleted();
5470
- }
5471
- } else {
5472
- for (i = 0, len = os.length; i < len; i++) {
5473
- os[i].onCompleted();
5474
- }
5475
- }
5107
+ return disposableEmpty;
5108
+ }
5476
5109
 
5477
- this.observers = [];
5478
- }
5479
- },
5480
- /**
5481
- * Notifies all subscribed observers about the exception.
5482
- * @param {Mixed} error The exception to send to all observers.
5483
- */
5484
- onError: function (exception) {
5485
- checkDisposed.call(this);
5486
- if (!this.isStopped) {
5487
- var os = this.observers.slice(0);
5488
- this.isStopped = true;
5489
- this.exception = exception;
5110
+ inherits(AsyncSubject, __super__);
5490
5111
 
5491
- for (var i = 0, len = os.length; i < len; i++) {
5492
- os[i].onError(exception);
5493
- }
5112
+ /**
5113
+ * Creates a subject that can only receive one value and that value is cached for all future observations.
5114
+ * @constructor
5115
+ */
5116
+ function AsyncSubject() {
5117
+ __super__.call(this, subscribe);
5118
+
5119
+ this.isDisposed = false;
5120
+ this.isStopped = false;
5121
+ this.value = null;
5122
+ this.hasValue = false;
5123
+ this.observers = [];
5124
+ this.exception = null;
5125
+ }
5494
5126
 
5495
- this.observers = [];
5496
- }
5497
- },
5498
- /**
5499
- * Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
5500
- * @param {Mixed} value The value to store in the subject.
5501
- */
5502
- onNext: function (value) {
5503
- checkDisposed.call(this);
5504
- if (!this.isStopped) {
5505
- this.value = value;
5506
- this.hasValue = true;
5507
- }
5508
- },
5509
- /**
5510
- * Unsubscribe all observers and release resources.
5511
- */
5512
- dispose: function () {
5513
- this.isDisposed = true;
5514
- this.observers = null;
5515
- this.exception = null;
5516
- this.value = null;
5127
+ addProperties(AsyncSubject.prototype, Observer, {
5128
+ /**
5129
+ * Indicates whether the subject has observers subscribed to it.
5130
+ * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
5131
+ */
5132
+ hasObservers: function () {
5133
+ checkDisposed.call(this);
5134
+ return this.observers.length > 0;
5135
+ },
5136
+ /**
5137
+ * Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
5138
+ */
5139
+ onCompleted: function () {
5140
+ var o, i, len;
5141
+ checkDisposed.call(this);
5142
+ if (!this.isStopped) {
5143
+ this.isStopped = true;
5144
+ var os = this.observers.slice(0),
5145
+ v = this.value,
5146
+ hv = this.hasValue;
5147
+
5148
+ if (hv) {
5149
+ for (i = 0, len = os.length; i < len; i++) {
5150
+ o = os[i];
5151
+ o.onNext(v);
5152
+ o.onCompleted();
5517
5153
  }
5518
- });
5519
-
5520
- return AsyncSubject;
5521
- }(Observable));
5522
-
5523
- /** @private */
5524
- var AnonymousSubject = (function (_super) {
5525
- inherits(AnonymousSubject, _super);
5154
+ } else {
5155
+ for (i = 0, len = os.length; i < len; i++) {
5156
+ os[i].onCompleted();
5157
+ }
5158
+ }
5526
5159
 
5527
- function subscribe(observer) {
5528
- return this.observable.subscribe(observer);
5160
+ this.observers = [];
5529
5161
  }
5162
+ },
5163
+ /**
5164
+ * Notifies all subscribed observers about the error.
5165
+ * @param {Mixed} error The Error to send to all observers.
5166
+ */
5167
+ onError: function (error) {
5168
+ checkDisposed.call(this);
5169
+ if (!this.isStopped) {
5170
+ var os = this.observers.slice(0);
5171
+ this.isStopped = true;
5172
+ this.exception = error;
5173
+
5174
+ for (var i = 0, len = os.length; i < len; i++) {
5175
+ os[i].onError(error);
5176
+ }
5530
5177
 
5531
- /**
5532
- * @private
5533
- * @constructor
5534
- */
5535
- function AnonymousSubject(observer, observable) {
5536
- _super.call(this, subscribe);
5537
- this.observer = observer;
5538
- this.observable = observable;
5178
+ this.observers = [];
5539
5179
  }
5180
+ },
5181
+ /**
5182
+ * Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
5183
+ * @param {Mixed} value The value to store in the subject.
5184
+ */
5185
+ onNext: function (value) {
5186
+ checkDisposed.call(this);
5187
+ if (this.isStopped) { return; }
5188
+ this.value = value;
5189
+ this.hasValue = true;
5190
+ },
5191
+ /**
5192
+ * Unsubscribe all observers and release resources.
5193
+ */
5194
+ dispose: function () {
5195
+ this.isDisposed = true;
5196
+ this.observers = null;
5197
+ this.exception = null;
5198
+ this.value = null;
5199
+ }
5200
+ });
5540
5201
 
5541
- addProperties(AnonymousSubject.prototype, Observer, {
5542
- /**
5543
- * @private
5544
- * @memberOf AnonymousSubject#
5545
- */
5546
- onCompleted: function () {
5547
- this.observer.onCompleted();
5548
- },
5549
- /**
5550
- * @private
5551
- * @memberOf AnonymousSubject#
5552
- */
5553
- onError: function (exception) {
5554
- this.observer.onError(exception);
5555
- },
5556
- /**
5557
- * @private
5558
- * @memberOf AnonymousSubject#
5559
- */
5560
- onNext: function (value) {
5561
- this.observer.onNext(value);
5562
- }
5563
- });
5202
+ return AsyncSubject;
5203
+ }(Observable));
5564
5204
 
5565
- return AnonymousSubject;
5566
- }(Observable));
5205
+ var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
5206
+ inherits(AnonymousSubject, __super__);
5207
+
5208
+ function AnonymousSubject(observer, observable) {
5209
+ this.observer = observer;
5210
+ this.observable = observable;
5211
+ __super__.call(this, this.observable.subscribe.bind(this.observable));
5212
+ }
5213
+
5214
+ addProperties(AnonymousSubject.prototype, Observer, {
5215
+ onCompleted: function () {
5216
+ this.observer.onCompleted();
5217
+ },
5218
+ onError: function (exception) {
5219
+ this.observer.onError(exception);
5220
+ },
5221
+ onNext: function (value) {
5222
+ this.observer.onNext(value);
5223
+ }
5224
+ });
5225
+
5226
+ return AnonymousSubject;
5227
+ }(Observable));
5567
5228
 
5568
5229
  /**
5569
5230
  * Represents a value that changes over time.
@@ -5827,21 +5488,21 @@
5827
5488
  return ReplaySubject;
5828
5489
  }(Observable));
5829
5490
 
5830
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
5831
- root.Rx = Rx;
5832
-
5833
- define(function() {
5834
- return Rx;
5835
- });
5836
- } else if (freeExports && freeModule) {
5837
- // in Node.js or RingoJS
5838
- if (moduleExports) {
5839
- (freeModule.exports = Rx).Rx = Rx;
5840
- } else {
5841
- freeExports.Rx = Rx;
5842
- }
5843
- } else {
5844
- // in a browser or Rhino
5845
- root.Rx = Rx;
5491
+ if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
5492
+ root.Rx = Rx;
5493
+
5494
+ define(function() {
5495
+ return Rx;
5496
+ });
5497
+ } else if (freeExports && freeModule) {
5498
+ // in Node.js or RingoJS
5499
+ if (moduleExports) {
5500
+ (freeModule.exports = Rx).Rx = Rx;
5501
+ } else {
5502
+ freeExports.Rx = Rx;
5503
+ }
5504
+ } else {
5505
+ // in a browser or Rhino
5506
+ root.Rx = Rx;
5846
5507
  }
5847
5508
  }.call(this));