rxjs-rails 2.3.22 → 2.3.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rxjs/rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/rx.aggregates.js +178 -146
  4. data/vendor/assets/javascripts/rx.aggregates.min.js +1 -1
  5. data/vendor/assets/javascripts/rx.all.compat.js +1706 -1156
  6. data/vendor/assets/javascripts/rx.all.compat.min.js +4 -4
  7. data/vendor/assets/javascripts/rx.all.js +1529 -1125
  8. data/vendor/assets/javascripts/rx.all.min.js +4 -3
  9. data/vendor/assets/javascripts/rx.async.compat.js +15 -79
  10. data/vendor/assets/javascripts/rx.async.compat.min.js +1 -1
  11. data/vendor/assets/javascripts/rx.async.js +15 -79
  12. data/vendor/assets/javascripts/rx.async.min.js +1 -1
  13. data/vendor/assets/javascripts/rx.backpressure.js +38 -15
  14. data/vendor/assets/javascripts/rx.backpressure.min.js +1 -1
  15. data/vendor/assets/javascripts/rx.binding.js +42 -54
  16. data/vendor/assets/javascripts/rx.binding.min.js +1 -1
  17. data/vendor/assets/javascripts/rx.coincidence.js +6 -6
  18. data/vendor/assets/javascripts/rx.coincidence.min.js +1 -1
  19. data/vendor/assets/javascripts/rx.compat.js +1234 -828
  20. data/vendor/assets/javascripts/rx.compat.min.js +2 -2
  21. data/vendor/assets/javascripts/rx.experimental.js +12 -6
  22. data/vendor/assets/javascripts/rx.experimental.min.js +1 -1
  23. data/vendor/assets/javascripts/rx.joinpatterns.js +15 -11
  24. data/vendor/assets/javascripts/rx.joinpatterns.min.js +1 -1
  25. data/vendor/assets/javascripts/rx.js +1159 -791
  26. data/vendor/assets/javascripts/rx.lite.compat.js +1264 -920
  27. data/vendor/assets/javascripts/rx.lite.compat.min.js +2 -2
  28. data/vendor/assets/javascripts/rx.lite.extras.js +99 -27
  29. data/vendor/assets/javascripts/rx.lite.extras.min.js +1 -1
  30. data/vendor/assets/javascripts/rx.lite.js +1192 -886
  31. data/vendor/assets/javascripts/rx.lite.min.js +2 -2
  32. data/vendor/assets/javascripts/rx.min.js +2 -2
  33. data/vendor/assets/javascripts/rx.testing.js +64 -63
  34. data/vendor/assets/javascripts/rx.testing.min.js +1 -1
  35. data/vendor/assets/javascripts/rx.time.js +32 -35
  36. data/vendor/assets/javascripts/rx.time.min.js +1 -1
  37. metadata +3 -3
@@ -24,7 +24,7 @@
24
24
  var Rx = {
25
25
  internals: {},
26
26
  config: {
27
- Promise: root.Promise,
27
+ Promise: root.Promise
28
28
  },
29
29
  helpers: { }
30
30
  };
@@ -64,7 +64,8 @@
64
64
  var sequenceContainsNoElements = 'Sequence contains no elements.';
65
65
  var argumentOutOfRange = 'Argument out of range';
66
66
  var objectDisposed = 'Object has been disposed';
67
- function checkDisposed() { if (this.isDisposed) { throw new Error(objectDisposed); } }
67
+ function checkDisposed(self) { if (self.isDisposed) { throw new Error(objectDisposed); } }
68
+ function cloneArray(arr) { for(var a = [], i = 0, len = arr.length; i < len; i++) { a.push(arr[i]); } return a;}
68
69
 
69
70
  Rx.config.longStackSupport = false;
70
71
  var hasStacks = false;
@@ -182,11 +183,41 @@
182
183
 
183
184
  Rx.helpers.iterator = $iterator$;
184
185
 
185
- var deprecate = Rx.helpers.deprecate = function (name, alternative) {
186
- /*if (typeof console !== "undefined" && typeof console.warn === "function") {
187
- console.warn(name + ' is deprecated, use ' + alternative + ' instead.', new Error('').stack);
188
- }*/
189
- }
186
+ var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
187
+ if (typeof thisArg === 'undefined') { return func; }
188
+ switch(argCount) {
189
+ case 0:
190
+ return function() {
191
+ return func.call(thisArg)
192
+ };
193
+ case 1:
194
+ return function(arg) {
195
+ return func.call(thisArg, arg);
196
+ }
197
+ case 2:
198
+ return function(value, index) {
199
+ return func.call(thisArg, value, index);
200
+ };
201
+ case 3:
202
+ return function(value, index, collection) {
203
+ return func.call(thisArg, value, index, collection);
204
+ };
205
+ }
206
+
207
+ return function() {
208
+ return func.apply(thisArg, arguments);
209
+ };
210
+ };
211
+
212
+ /** Used to determine if values are of the language type Object */
213
+ var dontEnums = ['toString',
214
+ 'toLocaleString',
215
+ 'valueOf',
216
+ 'hasOwnProperty',
217
+ 'isPrototypeOf',
218
+ 'propertyIsEnumerable',
219
+ 'constructor'],
220
+ dontEnumsLength = dontEnums.length;
190
221
 
191
222
  /** `Object#toString` result shortcuts */
192
223
  var argsClass = '[object Arguments]',
@@ -209,24 +240,12 @@
209
240
  stringProto = String.prototype,
210
241
  propertyIsEnumerable = objectProto.propertyIsEnumerable;
211
242
 
212
- // Fix for Tessel
213
- if (!propertyIsEnumerable) {
214
- propertyIsEnumerable = objectProto.propertyIsEnumerable = function (key) {
215
- for (var k in this) { if (k === key) { return true; } }
216
- return false;
217
- };
218
- }
219
-
220
243
  try {
221
244
  supportNodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
222
245
  } catch (e) {
223
246
  supportNodeClass = true;
224
247
  }
225
248
 
226
- var shadowedProps = [
227
- 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'
228
- ];
229
-
230
249
  var nonEnumProps = {};
231
250
  nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
232
251
  nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
@@ -255,14 +274,10 @@
255
274
  support.nonEnumShadows = !/valueOf/.test(props);
256
275
  }(1));
257
276
 
258
- function isObject(value) {
259
- // check if the value is the ECMAScript language type of Object
260
- // http://es5.github.io/#x8
261
- // and avoid a V8 bug
262
- // https://code.google.com/p/v8/issues/detail?id=2291
277
+ var isObject = Rx.internals.isObject = function(value) {
263
278
  var type = typeof value;
264
279
  return value && (type == 'function' || type == 'object') || false;
265
- }
280
+ };
266
281
 
267
282
  function keysIn(object) {
268
283
  var result = [];
@@ -285,14 +300,14 @@
285
300
  if (support.nonEnumShadows && object !== objectProto) {
286
301
  var ctor = object.constructor,
287
302
  index = -1,
288
- length = shadowedProps.length;
303
+ length = dontEnumsLength;
289
304
 
290
305
  if (object === (ctor && ctor.prototype)) {
291
306
  var className = object === stringProto ? stringClass : object === errorProto ? errorClass : toString.call(object),
292
307
  nonEnum = nonEnumProps[className];
293
308
  }
294
309
  while (++index < length) {
295
- key = shadowedProps[index];
310
+ key = dontEnums[index];
296
311
  if (!(nonEnum && nonEnum[key]) && hasOwnProperty.call(object, key)) {
297
312
  result.push(key);
298
313
  }
@@ -479,13 +494,27 @@
479
494
  return result;
480
495
  }
481
496
 
482
- var slice = Array.prototype.slice;
483
- function argsOrArray(args, idx) {
484
- return args.length === 1 && Array.isArray(args[idx]) ?
485
- args[idx] :
486
- slice.call(args);
497
+ var errorObj = {e: {}};
498
+ var tryCatchTarget;
499
+ function tryCatcher() {
500
+ try {
501
+ return tryCatchTarget.apply(this, arguments);
502
+ } catch (e) {
503
+ errorObj.e = e;
504
+ return errorObj;
505
+ }
506
+ }
507
+ function tryCatch(fn) {
508
+ if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
509
+ tryCatchTarget = fn;
510
+ return tryCatcher;
511
+ }
512
+ function thrower(e) {
513
+ throw e;
487
514
  }
488
- var hasProp = {}.hasOwnProperty;
515
+
516
+ var hasProp = {}.hasOwnProperty,
517
+ slice = Array.prototype.slice;
489
518
 
490
519
  var inherits = this.inherits = Rx.internals.inherits = function (child, parent) {
491
520
  function __() { this.constructor = child; }
@@ -494,9 +523,9 @@
494
523
  };
495
524
 
496
525
  var addProperties = Rx.internals.addProperties = function (obj) {
497
- var sources = slice.call(arguments, 1);
498
- for (var i = 0, len = sources.length; i < len; i++) {
499
- var source = sources[i];
526
+ for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
527
+ for (var idx = 0, ln = sources.length; idx < ln; idx++) {
528
+ var source = sources[idx];
500
529
  for (var prop in source) {
501
530
  obj[prop] = source[prop];
502
531
  }
@@ -542,37 +571,36 @@
542
571
  };
543
572
  }
544
573
 
545
- if (!Array.prototype.forEach) {
546
-
547
- Array.prototype.forEach = function (callback, thisArg) {
548
- var T, k;
574
+ if (!Array.prototype.forEach) {
575
+ Array.prototype.forEach = function (callback, thisArg) {
576
+ var T, k;
549
577
 
550
- if (this == null) {
551
- throw new TypeError(" this is null or not defined");
552
- }
578
+ if (this == null) {
579
+ throw new TypeError(" this is null or not defined");
580
+ }
553
581
 
554
- var O = Object(this);
555
- var len = O.length >>> 0;
582
+ var O = Object(this);
583
+ var len = O.length >>> 0;
556
584
 
557
- if (typeof callback !== "function") {
558
- throw new TypeError(callback + " is not a function");
559
- }
585
+ if (typeof callback !== "function") {
586
+ throw new TypeError(callback + " is not a function");
587
+ }
560
588
 
561
- if (arguments.length > 1) {
562
- T = thisArg;
563
- }
589
+ if (arguments.length > 1) {
590
+ T = thisArg;
591
+ }
564
592
 
565
- k = 0;
566
- while (k < len) {
567
- var kValue;
568
- if (k in O) {
569
- kValue = O[k];
570
- callback.call(T, kValue, k, O);
593
+ k = 0;
594
+ while (k < len) {
595
+ var kValue;
596
+ if (k in O) {
597
+ kValue = O[k];
598
+ callback.call(T, kValue, k, O);
599
+ }
600
+ k++;
571
601
  }
572
- k++;
573
- }
574
- };
575
- }
602
+ };
603
+ }
576
604
 
577
605
  var boxedString = Object("a"),
578
606
  splitString = boxedString[0] != "a" || !(0 in boxedString);
@@ -669,6 +697,45 @@ if (!Array.prototype.forEach) {
669
697
  };
670
698
  }
671
699
 
700
+ // Fix for Tessel
701
+ if (!Object.prototype.propertyIsEnumerable) {
702
+ Object.prototype.propertyIsEnumerable = function (key) {
703
+ for (var k in this) { if (k === key) { return true; } }
704
+ return false;
705
+ };
706
+ }
707
+
708
+ if (!Object.keys) {
709
+ Object.keys = (function() {
710
+ 'use strict';
711
+ var hasOwnProperty = Object.prototype.hasOwnProperty,
712
+ hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
713
+
714
+ return function(obj) {
715
+ if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
716
+ throw new TypeError('Object.keys called on non-object');
717
+ }
718
+
719
+ var result = [], prop, i;
720
+
721
+ for (prop in obj) {
722
+ if (hasOwnProperty.call(obj, prop)) {
723
+ result.push(prop);
724
+ }
725
+ }
726
+
727
+ if (hasDontEnumBug) {
728
+ for (i = 0; i < dontEnumsLength; i++) {
729
+ if (hasOwnProperty.call(obj, dontEnums[i])) {
730
+ result.push(dontEnums[i]);
731
+ }
732
+ }
733
+ }
734
+ return result;
735
+ };
736
+ }());
737
+ }
738
+
672
739
  // Collections
673
740
  function IndexedItem(id, value) {
674
741
  this.id = id;
@@ -728,7 +795,7 @@ if (!Array.prototype.forEach) {
728
795
 
729
796
  priorityProto.removeAt = function (index) {
730
797
  this.items[index] = this.items[--this.length];
731
- delete this.items[this.length];
798
+ this.items[this.length] = undefined;
732
799
  this.heapify();
733
800
  };
734
801
 
@@ -760,9 +827,17 @@ if (!Array.prototype.forEach) {
760
827
  * @constructor
761
828
  */
762
829
  var CompositeDisposable = Rx.CompositeDisposable = function () {
763
- this.disposables = argsOrArray(arguments, 0);
830
+ var args = [];
831
+ if (Array.isArray(arguments[0])) {
832
+ args = arguments[0];
833
+ } else {
834
+ var len = arguments.length;
835
+ args = new Array(len);
836
+ for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
837
+ }
838
+ this.disposables = args;
764
839
  this.isDisposed = false;
765
- this.length = this.disposables.length;
840
+ this.length = args.length;
766
841
  };
767
842
 
768
843
  var CompositeDisposablePrototype = CompositeDisposable.prototype;
@@ -805,28 +880,19 @@ if (!Array.prototype.forEach) {
805
880
  CompositeDisposablePrototype.dispose = function () {
806
881
  if (!this.isDisposed) {
807
882
  this.isDisposed = true;
808
- var currentDisposables = this.disposables.slice(0);
883
+ var len = this.disposables.length, currentDisposables = new Array(len);
884
+ for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
809
885
  this.disposables = [];
810
886
  this.length = 0;
811
887
 
812
- for (var i = 0, len = currentDisposables.length; i < len; i++) {
888
+ for (i = 0; i < len; i++) {
813
889
  currentDisposables[i].dispose();
814
890
  }
815
891
  }
816
892
  };
817
893
 
818
- /**
819
- * Converts the existing CompositeDisposable to an array of disposables
820
- * @returns {Array} An array of disposable objects.
821
- */
822
- CompositeDisposablePrototype.toArray = function () {
823
- return this.disposables.slice(0);
824
- };
825
-
826
894
  /**
827
895
  * Provides a set of static methods for creating Disposables.
828
- *
829
- * @constructor
830
896
  * @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
831
897
  */
832
898
  var Disposable = Rx.Disposable = function (action) {
@@ -875,9 +941,9 @@ if (!Array.prototype.forEach) {
875
941
  * @param {Disposable} value The new underlying disposable.
876
942
  */
877
943
  booleanDisposablePrototype.setDisposable = function (value) {
878
- var shouldDispose = this.isDisposed, old;
944
+ var shouldDispose = this.isDisposed;
879
945
  if (!shouldDispose) {
880
- old = this.current;
946
+ var old = this.current;
881
947
  this.current = value;
882
948
  }
883
949
  old && old.dispose();
@@ -888,10 +954,9 @@ if (!Array.prototype.forEach) {
888
954
  * Disposes the underlying disposable as well as all future replacements.
889
955
  */
890
956
  booleanDisposablePrototype.dispose = function () {
891
- var old;
892
957
  if (!this.isDisposed) {
893
958
  this.isDisposed = true;
894
- old = this.current;
959
+ var old = this.current;
895
960
  this.current = null;
896
961
  }
897
962
  old && old.dispose();
@@ -901,67 +966,63 @@ if (!Array.prototype.forEach) {
901
966
  }());
902
967
  var SerialDisposable = Rx.SerialDisposable = SingleAssignmentDisposable;
903
968
 
904
- /**
905
- * Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
906
- */
907
- var RefCountDisposable = Rx.RefCountDisposable = (function () {
969
+ /**
970
+ * Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
971
+ */
972
+ var RefCountDisposable = Rx.RefCountDisposable = (function () {
973
+
974
+ function InnerDisposable(disposable) {
975
+ this.disposable = disposable;
976
+ this.disposable.count++;
977
+ this.isInnerDisposed = false;
978
+ }
908
979
 
909
- function InnerDisposable(disposable) {
910
- this.disposable = disposable;
911
- this.disposable.count++;
912
- this.isInnerDisposed = false;
980
+ InnerDisposable.prototype.dispose = function () {
981
+ if (!this.disposable.isDisposed && !this.isInnerDisposed) {
982
+ this.isInnerDisposed = true;
983
+ this.disposable.count--;
984
+ if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
985
+ this.disposable.isDisposed = true;
986
+ this.disposable.underlyingDisposable.dispose();
913
987
  }
988
+ }
989
+ };
914
990
 
915
- InnerDisposable.prototype.dispose = function () {
916
- if (!this.disposable.isDisposed) {
917
- if (!this.isInnerDisposed) {
918
- this.isInnerDisposed = true;
919
- this.disposable.count--;
920
- if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
921
- this.disposable.isDisposed = true;
922
- this.disposable.underlyingDisposable.dispose();
923
- }
924
- }
925
- }
926
- };
991
+ /**
992
+ * Initializes a new instance of the RefCountDisposable with the specified disposable.
993
+ * @constructor
994
+ * @param {Disposable} disposable Underlying disposable.
995
+ */
996
+ function RefCountDisposable(disposable) {
997
+ this.underlyingDisposable = disposable;
998
+ this.isDisposed = false;
999
+ this.isPrimaryDisposed = false;
1000
+ this.count = 0;
1001
+ }
927
1002
 
928
- /**
929
- * Initializes a new instance of the RefCountDisposable with the specified disposable.
930
- * @constructor
931
- * @param {Disposable} disposable Underlying disposable.
932
- */
933
- function RefCountDisposable(disposable) {
934
- this.underlyingDisposable = disposable;
935
- this.isDisposed = false;
936
- this.isPrimaryDisposed = false;
937
- this.count = 0;
1003
+ /**
1004
+ * Disposes the underlying disposable only when all dependent disposables have been disposed
1005
+ */
1006
+ RefCountDisposable.prototype.dispose = function () {
1007
+ if (!this.isDisposed && !this.isPrimaryDisposed) {
1008
+ this.isPrimaryDisposed = true;
1009
+ if (this.count === 0) {
1010
+ this.isDisposed = true;
1011
+ this.underlyingDisposable.dispose();
938
1012
  }
1013
+ }
1014
+ };
939
1015
 
940
- /**
941
- * Disposes the underlying disposable only when all dependent disposables have been disposed
942
- */
943
- RefCountDisposable.prototype.dispose = function () {
944
- if (!this.isDisposed) {
945
- if (!this.isPrimaryDisposed) {
946
- this.isPrimaryDisposed = true;
947
- if (this.count === 0) {
948
- this.isDisposed = true;
949
- this.underlyingDisposable.dispose();
950
- }
951
- }
952
- }
953
- };
954
-
955
- /**
956
- * Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
957
- * @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
958
- */
959
- RefCountDisposable.prototype.getDisposable = function () {
960
- return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
961
- };
1016
+ /**
1017
+ * Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
1018
+ * @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
1019
+ */
1020
+ RefCountDisposable.prototype.getDisposable = function () {
1021
+ return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
1022
+ };
962
1023
 
963
- return RefCountDisposable;
964
- })();
1024
+ return RefCountDisposable;
1025
+ })();
965
1026
 
966
1027
  var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
967
1028
  this.scheduler = scheduler;
@@ -1114,7 +1175,7 @@ if (!Array.prototype.forEach) {
1114
1175
  recursiveAction = function (state1) {
1115
1176
  action(state1, function (state2, dueTime1) {
1116
1177
  var isAdded = false, isDone = false,
1117
- d = scheduler[method].call(scheduler, state2, dueTime1, function (scheduler1, state3) {
1178
+ d = scheduler[method](state2, dueTime1, function (scheduler1, state3) {
1118
1179
  if (isAdded) {
1119
1180
  group.remove(d);
1120
1181
  } else {
@@ -1242,18 +1303,9 @@ if (!Array.prototype.forEach) {
1242
1303
  var immediateScheduler = Scheduler.immediate = (function () {
1243
1304
 
1244
1305
  function scheduleNow(state, action) { return action(this, state); }
1306
+ function notSupported() { throw new Error('Not supported'); }
1245
1307
 
1246
- function scheduleRelative(state, dueTime, action) {
1247
- var dt = normalizeTime(dueTime);
1248
- while (dt - this.now() > 0) { }
1249
- return action(this, state);
1250
- }
1251
-
1252
- function scheduleAbsolute(state, dueTime, action) {
1253
- return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action);
1254
- }
1255
-
1256
- return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);
1308
+ return new Scheduler(defaultNow, scheduleNow, notSupported, notSupported);
1257
1309
  }());
1258
1310
 
1259
1311
  /**
@@ -1263,27 +1315,16 @@ if (!Array.prototype.forEach) {
1263
1315
  var queue;
1264
1316
 
1265
1317
  function runTrampoline (q) {
1266
- var item;
1267
1318
  while (q.length > 0) {
1268
- item = q.dequeue();
1319
+ var item = q.dequeue();
1269
1320
  if (!item.isCancelled()) {
1270
- // Note, do not schedule blocking work!
1271
- while (item.dueTime - Scheduler.now() > 0) {
1272
- }
1273
- if (!item.isCancelled()) {
1274
- item.invoke();
1275
- }
1321
+ !item.isCancelled() && item.invoke();
1276
1322
  }
1277
1323
  }
1278
1324
  }
1279
1325
 
1280
1326
  function scheduleNow(state, action) {
1281
- return this.scheduleWithRelativeAndState(state, 0, action);
1282
- }
1283
-
1284
- function scheduleRelative(state, dueTime, action) {
1285
- var dt = this.now() + Scheduler.normalize(dueTime),
1286
- si = new ScheduledItem(this, state, action, dt);
1327
+ var si = new ScheduledItem(this, state, action, this.now());
1287
1328
 
1288
1329
  if (!queue) {
1289
1330
  queue = new PriorityQueue(4);
@@ -1301,11 +1342,9 @@ if (!Array.prototype.forEach) {
1301
1342
  return si.disposable;
1302
1343
  }
1303
1344
 
1304
- function scheduleAbsolute(state, dueTime, action) {
1305
- return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action);
1306
- }
1345
+ function notSupported() { throw new Error('Not supported'); }
1307
1346
 
1308
- var currentScheduler = new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);
1347
+ var currentScheduler = new Scheduler(defaultNow, scheduleNow, notSupported, notSupported);
1309
1348
 
1310
1349
  currentScheduler.scheduleRequired = function () { return !queue; };
1311
1350
  currentScheduler.ensureTrampoline = function (action) {
@@ -1629,31 +1668,20 @@ if (!Array.prototype.forEach) {
1629
1668
 
1630
1669
  Enumerable.prototype.concat = function () {
1631
1670
  var sources = this;
1632
- return new AnonymousObservable(function (observer) {
1633
- var e;
1634
- try {
1635
- e = sources[$iterator$]();
1636
- } catch (err) {
1637
- observer.onError(err);
1638
- return;
1639
- }
1671
+ return new AnonymousObservable(function (o) {
1672
+ var e = sources[$iterator$]();
1640
1673
 
1641
- var isDisposed,
1642
- subscription = new SerialDisposable();
1674
+ var isDisposed, subscription = new SerialDisposable();
1643
1675
  var cancelable = immediateScheduler.scheduleRecursive(function (self) {
1644
- var currentItem;
1645
1676
  if (isDisposed) { return; }
1646
-
1647
1677
  try {
1648
- currentItem = e.next();
1678
+ var currentItem = e.next();
1649
1679
  } catch (ex) {
1650
- observer.onError(ex);
1651
- return;
1680
+ return o.onError(ex);
1652
1681
  }
1653
1682
 
1654
1683
  if (currentItem.done) {
1655
- observer.onCompleted();
1656
- return;
1684
+ return o.onCompleted();
1657
1685
  }
1658
1686
 
1659
1687
  // Check if promise
@@ -1663,9 +1691,9 @@ if (!Array.prototype.forEach) {
1663
1691
  var d = new SingleAssignmentDisposable();
1664
1692
  subscription.setDisposable(d);
1665
1693
  d.setDisposable(currentValue.subscribe(
1666
- observer.onNext.bind(observer),
1667
- observer.onError.bind(observer),
1668
- function () { self(); })
1694
+ function(x) { o.onNext(x); },
1695
+ function(err) { o.onError(err); },
1696
+ self)
1669
1697
  );
1670
1698
  });
1671
1699
 
@@ -1677,14 +1705,55 @@ if (!Array.prototype.forEach) {
1677
1705
 
1678
1706
  Enumerable.prototype.catchError = function () {
1679
1707
  var sources = this;
1680
- return new AnonymousObservable(function (observer) {
1681
- var e;
1682
- try {
1683
- e = sources[$iterator$]();
1684
- } catch (err) {
1685
- observer.onError(err);
1686
- return;
1687
- }
1708
+ return new AnonymousObservable(function (o) {
1709
+ var e = sources[$iterator$]();
1710
+
1711
+ var isDisposed, subscription = new SerialDisposable();
1712
+ var cancelable = immediateScheduler.scheduleRecursiveWithState(null, function (lastException, self) {
1713
+ if (isDisposed) { return; }
1714
+
1715
+ try {
1716
+ var currentItem = e.next();
1717
+ } catch (ex) {
1718
+ return observer.onError(ex);
1719
+ }
1720
+
1721
+ if (currentItem.done) {
1722
+ if (lastException !== null) {
1723
+ o.onError(lastException);
1724
+ } else {
1725
+ o.onCompleted();
1726
+ }
1727
+ return;
1728
+ }
1729
+
1730
+ // Check if promise
1731
+ var currentValue = currentItem.value;
1732
+ isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
1733
+
1734
+ var d = new SingleAssignmentDisposable();
1735
+ subscription.setDisposable(d);
1736
+ d.setDisposable(currentValue.subscribe(
1737
+ function(x) { o.onNext(x); },
1738
+ self,
1739
+ function() { o.onCompleted(); }));
1740
+ });
1741
+ return new CompositeDisposable(subscription, cancelable, disposableCreate(function () {
1742
+ isDisposed = true;
1743
+ }));
1744
+ });
1745
+ };
1746
+
1747
+
1748
+ Enumerable.prototype.catchErrorWhen = function (notificationHandler) {
1749
+ var sources = this;
1750
+ return new AnonymousObservable(function (o) {
1751
+ var exceptions = new Subject(),
1752
+ notifier = new Subject(),
1753
+ handled = notificationHandler(exceptions),
1754
+ notificationDisposable = handled.subscribe(notifier);
1755
+
1756
+ var e = sources[$iterator$]();
1688
1757
 
1689
1758
  var isDisposed,
1690
1759
  lastException,
@@ -1692,19 +1761,17 @@ if (!Array.prototype.forEach) {
1692
1761
  var cancelable = immediateScheduler.scheduleRecursive(function (self) {
1693
1762
  if (isDisposed) { return; }
1694
1763
 
1695
- var currentItem;
1696
1764
  try {
1697
- currentItem = e.next();
1765
+ var currentItem = e.next();
1698
1766
  } catch (ex) {
1699
- observer.onError(ex);
1700
- return;
1767
+ return o.onError(ex);
1701
1768
  }
1702
1769
 
1703
1770
  if (currentItem.done) {
1704
1771
  if (lastException) {
1705
- observer.onError(lastException);
1772
+ o.onError(lastException);
1706
1773
  } else {
1707
- observer.onCompleted();
1774
+ o.onCompleted();
1708
1775
  }
1709
1776
  return;
1710
1777
  }
@@ -1713,17 +1780,24 @@ if (!Array.prototype.forEach) {
1713
1780
  var currentValue = currentItem.value;
1714
1781
  isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
1715
1782
 
1716
- var d = new SingleAssignmentDisposable();
1717
- subscription.setDisposable(d);
1718
- d.setDisposable(currentValue.subscribe(
1719
- observer.onNext.bind(observer),
1783
+ var outer = new SingleAssignmentDisposable();
1784
+ var inner = new SingleAssignmentDisposable();
1785
+ subscription.setDisposable(new CompositeDisposable(inner, outer));
1786
+ outer.setDisposable(currentValue.subscribe(
1787
+ function(x) { o.onNext(x); },
1720
1788
  function (exn) {
1721
- lastException = exn;
1722
- self();
1789
+ inner.setDisposable(notifier.subscribe(self, function(ex) {
1790
+ o.onError(ex);
1791
+ }, function() {
1792
+ o.onCompleted();
1793
+ }));
1794
+
1795
+ exceptions.onNext(exn);
1723
1796
  },
1724
- observer.onCompleted.bind(observer)));
1797
+ function() { o.onCompleted(); }));
1725
1798
  });
1726
- return new CompositeDisposable(subscription, cancelable, disposableCreate(function () {
1799
+
1800
+ return new CompositeDisposable(notificationDisposable, subscription, cancelable, disposableCreate(function () {
1727
1801
  isDisposed = true;
1728
1802
  }));
1729
1803
  });
@@ -1742,13 +1816,15 @@ if (!Array.prototype.forEach) {
1742
1816
  };
1743
1817
 
1744
1818
  var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
1745
- selector || (selector = identity);
1819
+ if (selector) {
1820
+ var selectorFn = bindCallback(selector, thisArg, 3);
1821
+ }
1746
1822
  return new Enumerable(function () {
1747
1823
  var index = -1;
1748
1824
  return new Enumerator(
1749
1825
  function () {
1750
1826
  return ++index < source.length ?
1751
- { done: false, value: selector.call(thisArg, source[index], index, source) } :
1827
+ { done: false, value: !selector ? source[index] : selectorFn(source[index], index, source) } :
1752
1828
  doneEnumerator;
1753
1829
  });
1754
1830
  });
@@ -1759,23 +1835,6 @@ if (!Array.prototype.forEach) {
1759
1835
  */
1760
1836
  var Observer = Rx.Observer = function () { };
1761
1837
 
1762
- /**
1763
- * Creates a notification callback from an observer.
1764
- * @returns The action that forwards its input notification to the underlying observer.
1765
- */
1766
- Observer.prototype.toNotifier = function () {
1767
- var observer = this;
1768
- return function (n) { return n.accept(observer); };
1769
- };
1770
-
1771
- /**
1772
- * Hides the identity of an observer.
1773
- * @returns An observer that hides the identity of the specified observer.
1774
- */
1775
- Observer.prototype.asObserver = function () {
1776
- return new AnonymousObserver(this.onNext.bind(this), this.onError.bind(this), this.onCompleted.bind(this));
1777
- };
1778
-
1779
1838
  /**
1780
1839
  * Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
1781
1840
  * @param {Function} [onNext] Observer's OnNext action implementation.
@@ -1790,21 +1849,6 @@ if (!Array.prototype.forEach) {
1790
1849
  return new AnonymousObserver(onNext, onError, onCompleted);
1791
1850
  };
1792
1851
 
1793
- /**
1794
- * Creates an observer from a notification callback.
1795
- * @param {Function} handler Action that handles a notification.
1796
- * @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
1797
- */
1798
- Observer.fromNotifier = function (handler, thisArg) {
1799
- return new AnonymousObserver(function (x) {
1800
- return handler.call(thisArg, notificationCreateOnNext(x));
1801
- }, function (e) {
1802
- return handler.call(thisArg, notificationCreateOnError(e));
1803
- }, function () {
1804
- return handler.call(thisArg, notificationCreateOnCompleted());
1805
- });
1806
- };
1807
-
1808
1852
  /**
1809
1853
  * Abstract base class for implementations of the Observer class.
1810
1854
  * This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
@@ -1820,6 +1864,15 @@ if (!Array.prototype.forEach) {
1820
1864
  __super__.call(this);
1821
1865
  }
1822
1866
 
1867
+ function notImplemented() {
1868
+ throw new Error('Method not implemented');
1869
+ }
1870
+
1871
+ // Must be implemented by other observers
1872
+ AbstractObserver.prototype.next = notImplemented;
1873
+ AbstractObserver.prototype.error = notImplemented;
1874
+ AbstractObserver.prototype.completed = notImplemented;
1875
+
1823
1876
  /**
1824
1877
  * Notifies the observer of a new element in the sequence.
1825
1878
  * @param {Any} value Next element in the sequence.
@@ -1938,7 +1991,7 @@ if (!Array.prototype.forEach) {
1938
1991
  oldOnError(err);
1939
1992
  };
1940
1993
 
1941
- return subscribe(observer);
1994
+ return subscribe.call(self, observer);
1942
1995
  };
1943
1996
  } else {
1944
1997
  this._subscribe = subscribe;
@@ -1967,7 +2020,7 @@ if (!Array.prototype.forEach) {
1967
2020
  * @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
1968
2021
  */
1969
2022
  observableProto.subscribeOnNext = function (onNext, thisArg) {
1970
- return this._subscribe(observerCreate(arguments.length === 2 ? function(x) { onNext.call(thisArg, x); } : onNext));
2023
+ return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
1971
2024
  };
1972
2025
 
1973
2026
  /**
@@ -1977,7 +2030,7 @@ if (!Array.prototype.forEach) {
1977
2030
  * @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
1978
2031
  */
1979
2032
  observableProto.subscribeOnError = function (onError, thisArg) {
1980
- return this._subscribe(observerCreate(null, arguments.length === 2 ? function(e) { onError.call(thisArg, e); } : onError));
2033
+ return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
1981
2034
  };
1982
2035
 
1983
2036
  /**
@@ -1987,12 +2040,58 @@ if (!Array.prototype.forEach) {
1987
2040
  * @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
1988
2041
  */
1989
2042
  observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
1990
- return this._subscribe(observerCreate(null, null, arguments.length === 2 ? function() { onCompleted.call(thisArg); } : onCompleted));
2043
+ return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
1991
2044
  };
1992
2045
 
1993
2046
  return Observable;
1994
2047
  })();
1995
2048
 
2049
+ var ObservableBase = Rx.ObservableBase = (function (__super__) {
2050
+
2051
+ inherits(ObservableBase, __super__);
2052
+
2053
+ // Fix subscriber to check for undefined or function returned to decorate as Disposable
2054
+ function fixSubscriber(subscriber) {
2055
+ if (subscriber && typeof subscriber.dispose === 'function') { return subscriber; }
2056
+
2057
+ return typeof subscriber === 'function' ?
2058
+ disposableCreate(subscriber) :
2059
+ disposableEmpty;
2060
+ }
2061
+
2062
+ function setDisposable(s, state) {
2063
+ var ado = state[0], self = state[1];
2064
+ try {
2065
+ ado.setDisposable(fixSubscriber(self.subscribeCore(ado)));
2066
+ } catch (e) {
2067
+ if (!ado.fail(e)) { throw e; }
2068
+ }
2069
+ }
2070
+
2071
+ function subscribe(observer) {
2072
+ var ado = new AutoDetachObserver(observer), state = [ado, this];
2073
+
2074
+ if (currentThreadScheduler.scheduleRequired()) {
2075
+ currentThreadScheduler.scheduleWithState(state, setDisposable);
2076
+ } else {
2077
+ setDisposable(null, state);
2078
+ }
2079
+
2080
+ return ado;
2081
+ }
2082
+
2083
+ function ObservableBase() {
2084
+ __super__.call(this, subscribe);
2085
+ }
2086
+
2087
+ ObservableBase.prototype.subscribeCore = function(observer) {
2088
+ throw new Error('Not implemeneted');
2089
+ }
2090
+
2091
+ return ObservableBase;
2092
+
2093
+ }(Observable));
2094
+
1996
2095
  var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
1997
2096
  inherits(ScheduledObserver, __super__);
1998
2097
 
@@ -2056,22 +2155,56 @@ if (!Array.prototype.forEach) {
2056
2155
  return ScheduledObserver;
2057
2156
  }(AbstractObserver));
2058
2157
 
2158
+ var ToArrayObservable = (function(__super__) {
2159
+ inherits(ToArrayObservable, __super__);
2160
+ function ToArrayObservable(source) {
2161
+ this.source = source;
2162
+ __super__.call(this);
2163
+ }
2164
+
2165
+ ToArrayObservable.prototype.subscribeCore = function(observer) {
2166
+ return this.source.subscribe(new ToArrayObserver(observer));
2167
+ };
2168
+
2169
+ return ToArrayObservable;
2170
+ }(ObservableBase));
2171
+
2172
+ function ToArrayObserver(observer) {
2173
+ this.observer = observer;
2174
+ this.a = [];
2175
+ this.isStopped = false;
2176
+ }
2177
+ ToArrayObserver.prototype.onNext = function (x) { if(!this.isStopped) { this.a.push(x); } };
2178
+ ToArrayObserver.prototype.onError = function (e) {
2179
+ if (!this.isStopped) {
2180
+ this.isStopped = true;
2181
+ this.observer.onError(e);
2182
+ }
2183
+ };
2184
+ ToArrayObserver.prototype.onCompleted = function () {
2185
+ if (!this.isStopped) {
2186
+ this.isStopped = true;
2187
+ this.observer.onNext(this.a);
2188
+ this.observer.onCompleted();
2189
+ }
2190
+ };
2191
+ ToArrayObserver.prototype.dispose = function () { this.isStopped = true; }
2192
+ ToArrayObserver.prototype.fail = function (e) {
2193
+ if (!this.isStopped) {
2194
+ this.isStopped = true;
2195
+ this.observer.onError(e);
2196
+ return true;
2197
+ }
2198
+
2199
+ return false;
2200
+ };
2201
+
2059
2202
  /**
2060
- * Creates an array from an observable sequence.
2061
- * @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
2062
- */
2203
+ * Creates an array from an observable sequence.
2204
+ * @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
2205
+ */
2063
2206
  observableProto.toArray = function () {
2064
- var source = this;
2065
- return new AnonymousObservable(function(observer) {
2066
- var arr = [];
2067
- return source.subscribe(
2068
- arr.push.bind(arr),
2069
- observer.onError.bind(observer),
2070
- function () {
2071
- observer.onNext(arr);
2072
- observer.onCompleted();
2073
- });
2074
- }, source);
2207
+ return new ToArrayObservable(this);
2075
2208
  };
2076
2209
 
2077
2210
  /**
@@ -2126,19 +2259,78 @@ if (!Array.prototype.forEach) {
2126
2259
  });
2127
2260
  };
2128
2261
 
2129
- var maxSafeInteger = Math.pow(2, 53) - 1;
2262
+ var FromObservable = (function(__super__) {
2263
+ inherits(FromObservable, __super__);
2264
+ function FromObservable(iterable, mapper, scheduler) {
2265
+ this.iterable = iterable;
2266
+ this.mapper = mapper;
2267
+ this.scheduler = scheduler;
2268
+ __super__.call(this);
2269
+ }
2130
2270
 
2131
- function StringIterable(str) {
2132
- this._s = s;
2133
- }
2271
+ FromObservable.prototype.subscribeCore = function (observer) {
2272
+ var sink = new FromSink(observer, this);
2273
+ return sink.run();
2274
+ };
2134
2275
 
2135
- StringIterable.prototype[$iterator$] = function () {
2136
- return new StringIterator(this._s);
2137
- };
2276
+ return FromObservable;
2277
+ }(ObservableBase));
2138
2278
 
2139
- function StringIterator(str) {
2140
- this._s = s;
2141
- this._l = s.length;
2279
+ var FromSink = (function () {
2280
+ function FromSink(observer, parent) {
2281
+ this.observer = observer;
2282
+ this.parent = parent;
2283
+ }
2284
+
2285
+ FromSink.prototype.run = function () {
2286
+ var list = Object(this.parent.iterable),
2287
+ it = getIterable(list),
2288
+ observer = this.observer,
2289
+ mapper = this.parent.mapper;
2290
+
2291
+ function loopRecursive(i, recurse) {
2292
+ try {
2293
+ var next = it.next();
2294
+ } catch (e) {
2295
+ return observer.onError(e);
2296
+ }
2297
+ if (next.done) {
2298
+ return observer.onCompleted();
2299
+ }
2300
+
2301
+ var result = next.value;
2302
+
2303
+ if (mapper) {
2304
+ try {
2305
+ result = mapper(result, i);
2306
+ } catch (e) {
2307
+ return observer.onError(e);
2308
+ }
2309
+ }
2310
+
2311
+ observer.onNext(result);
2312
+ recurse(i + 1);
2313
+ }
2314
+
2315
+ return this.parent.scheduler.scheduleRecursiveWithState(0, loopRecursive);
2316
+ };
2317
+
2318
+ return FromSink;
2319
+ }());
2320
+
2321
+ var maxSafeInteger = Math.pow(2, 53) - 1;
2322
+
2323
+ function StringIterable(str) {
2324
+ this._s = s;
2325
+ }
2326
+
2327
+ StringIterable.prototype[$iterator$] = function () {
2328
+ return new StringIterator(this._s);
2329
+ };
2330
+
2331
+ function StringIterator(str) {
2332
+ this._s = s;
2333
+ this._l = s.length;
2142
2334
  this._i = 0;
2143
2335
  }
2144
2336
 
@@ -2147,12 +2339,7 @@ if (!Array.prototype.forEach) {
2147
2339
  };
2148
2340
 
2149
2341
  StringIterator.prototype.next = function () {
2150
- if (this._i < this._l) {
2151
- var val = this._s.charAt(this._i++);
2152
- return { done: false, value: val };
2153
- } else {
2154
- return doneEnumerator;
2155
- }
2342
+ return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
2156
2343
  };
2157
2344
 
2158
2345
  function ArrayIterable(a) {
@@ -2174,12 +2361,7 @@ if (!Array.prototype.forEach) {
2174
2361
  };
2175
2362
 
2176
2363
  ArrayIterator.prototype.next = function () {
2177
- if (this._i < this._l) {
2178
- var val = this._a[this._i++];
2179
- return { done: false, value: val };
2180
- } else {
2181
- return doneEnumerator;
2182
- }
2364
+ return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
2183
2365
  };
2184
2366
 
2185
2367
  function numberIsFinite(value) {
@@ -2222,12 +2404,12 @@ if (!Array.prototype.forEach) {
2222
2404
  }
2223
2405
 
2224
2406
  /**
2225
- * This method creates a new Observable sequence from an array-like or iterable object.
2226
- * @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
2227
- * @param {Function} [mapFn] Map function to call on every element of the array.
2228
- * @param {Any} [thisArg] The context to use calling the mapFn if provided.
2229
- * @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
2230
- */
2407
+ * This method creates a new Observable sequence from an array-like or iterable object.
2408
+ * @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
2409
+ * @param {Function} [mapFn] Map function to call on every element of the array.
2410
+ * @param {Any} [thisArg] The context to use calling the mapFn if provided.
2411
+ * @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
2412
+ */
2231
2413
  var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
2232
2414
  if (iterable == null) {
2233
2415
  throw new Error('iterable cannot be null.')
@@ -2235,61 +2417,56 @@ if (!Array.prototype.forEach) {
2235
2417
  if (mapFn && !isFunction(mapFn)) {
2236
2418
  throw new Error('mapFn when provided must be a function');
2237
2419
  }
2420
+ if (mapFn) {
2421
+ var mapper = bindCallback(mapFn, thisArg, 2);
2422
+ }
2238
2423
  isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2239
- var list = Object(iterable), it = getIterable(list);
2240
- return new AnonymousObservable(function (observer) {
2241
- var i = 0;
2242
- return scheduler.scheduleRecursive(function (self) {
2243
- var next;
2244
- try {
2245
- next = it.next();
2246
- } catch (e) {
2247
- observer.onError(e);
2248
- return;
2249
- }
2250
- if (next.done) {
2251
- observer.onCompleted();
2252
- return;
2253
- }
2424
+ return new FromObservable(iterable, mapper, scheduler);
2425
+ }
2254
2426
 
2255
- var result = next.value;
2427
+ var FromArrayObservable = (function(__super__) {
2428
+ inherits(FromArrayObservable, __super__);
2429
+ function FromArrayObservable(args, scheduler) {
2430
+ this.args = args;
2431
+ this.scheduler = scheduler || currentThreadScheduler;
2432
+ __super__.call(this);
2433
+ }
2256
2434
 
2257
- if (mapFn && isFunction(mapFn)) {
2258
- try {
2259
- result = mapFn.call(thisArg, result, i);
2260
- } catch (e) {
2261
- observer.onError(e);
2262
- return;
2263
- }
2264
- }
2435
+ FromArrayObservable.prototype.subscribeCore = function (observer) {
2436
+ var sink = new FromArraySink(observer, this);
2437
+ return sink.run();
2438
+ };
2265
2439
 
2266
- observer.onNext(result);
2267
- i++;
2268
- self();
2269
- });
2270
- });
2440
+ return FromArrayObservable;
2441
+ }(ObservableBase));
2442
+
2443
+ function FromArraySink(observer, parent) {
2444
+ this.observer = observer;
2445
+ this.parent = parent;
2446
+ }
2447
+
2448
+ FromArraySink.prototype.run = function () {
2449
+ var observer = this.observer, args = this.parent.args, len = args.length;
2450
+ function loopRecursive(i, recurse) {
2451
+ if (i < len) {
2452
+ observer.onNext(args[i]);
2453
+ recurse(i + 1);
2454
+ } else {
2455
+ observer.onCompleted();
2456
+ }
2457
+ }
2458
+
2459
+ return this.parent.scheduler.scheduleRecursiveWithState(0, loopRecursive);
2271
2460
  };
2272
2461
 
2273
2462
  /**
2274
- * Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
2275
- * @deprecated use Observable.from or Observable.of
2276
- * @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
2277
- * @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
2278
- */
2463
+ * Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
2464
+ * @deprecated use Observable.from or Observable.of
2465
+ * @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
2466
+ * @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
2467
+ */
2279
2468
  var observableFromArray = Observable.fromArray = function (array, scheduler) {
2280
- deprecate('fromArray', 'from');
2281
- isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2282
- return new AnonymousObservable(function (observer) {
2283
- var count = 0, len = array.length;
2284
- return scheduler.scheduleRecursive(function (self) {
2285
- if (count < len) {
2286
- observer.onNext(array[count++]);
2287
- self();
2288
- } else {
2289
- observer.onCompleted();
2290
- }
2291
- });
2292
- });
2469
+ return new FromArrayObservable(array, scheduler)
2293
2470
  };
2294
2471
 
2295
2472
  /**
@@ -2303,55 +2480,45 @@ if (!Array.prototype.forEach) {
2303
2480
  };
2304
2481
 
2305
2482
  function observableOf (scheduler, array) {
2306
- isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2307
- return new AnonymousObservable(function (observer) {
2308
- var count = 0, len = array.length;
2309
- return scheduler.scheduleRecursive(function (self) {
2310
- if (count < len) {
2311
- observer.onNext(array[count++]);
2312
- self();
2313
- } else {
2314
- observer.onCompleted();
2315
- }
2316
- });
2317
- });
2483
+ return new FromArrayObservable(array, scheduler);
2318
2484
  }
2319
2485
 
2320
2486
  /**
2321
- * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
2322
- * @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
2323
- */
2487
+ * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
2488
+ * @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
2489
+ */
2324
2490
  Observable.of = function () {
2325
- return observableOf(null, arguments);
2491
+ var len = arguments.length, args = new Array(len);
2492
+ for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
2493
+ return new FromArrayObservable(args);
2326
2494
  };
2327
2495
 
2328
2496
  /**
2329
- * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
2330
- * @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
2331
- * @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
2332
- */
2497
+ * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
2498
+ * @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
2499
+ * @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
2500
+ */
2333
2501
  Observable.ofWithScheduler = function (scheduler) {
2334
- return observableOf(scheduler, slice.call(arguments, 1));
2502
+ var len = arguments.length, args = new Array(len - 1);
2503
+ for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
2504
+ return new FromArrayObservable(args, scheduler);
2335
2505
  };
2336
2506
 
2337
2507
  /**
2338
- * Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
2339
- *
2340
- * @example
2341
- * var res = Rx.Observable.range(0, 10);
2342
- * var res = Rx.Observable.range(0, 10, Rx.Scheduler.timeout);
2343
- * @param {Number} start The value of the first integer in the sequence.
2344
- * @param {Number} count The number of sequential integers to generate.
2345
- * @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
2346
- * @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
2508
+ * Convert an object into an observable sequence of [key, value] pairs.
2509
+ * @param {Object} obj The object to inspect.
2510
+ * @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
2511
+ * @returns {Observable} An observable sequence of [key, value] pairs from the object.
2347
2512
  */
2348
- Observable.range = function (start, count, scheduler) {
2349
- isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2513
+ Observable.pairs = function (obj, scheduler) {
2514
+ scheduler || (scheduler = Rx.Scheduler.currentThread);
2350
2515
  return new AnonymousObservable(function (observer) {
2351
- return scheduler.scheduleRecursiveWithState(0, function (i, self) {
2352
- if (i < count) {
2353
- observer.onNext(start + i);
2354
- self(i + 1);
2516
+ var keys = Object.keys(obj), len = keys.length;
2517
+ return scheduler.scheduleRecursiveWithState(0, function (idx, self) {
2518
+ if (idx < len) {
2519
+ var key = keys[idx];
2520
+ observer.onNext([key, obj[key]]);
2521
+ self(idx + 1);
2355
2522
  } else {
2356
2523
  observer.onCompleted();
2357
2524
  }
@@ -2359,6 +2526,58 @@ if (!Array.prototype.forEach) {
2359
2526
  });
2360
2527
  };
2361
2528
 
2529
+ var RangeObservable = (function(__super__) {
2530
+ inherits(RangeObservable, __super__);
2531
+ function RangeObservable(start, count, scheduler) {
2532
+ this.start = start;
2533
+ this.count = count;
2534
+ this.scheduler = scheduler;
2535
+ __super__.call(this);
2536
+ }
2537
+
2538
+ RangeObservable.prototype.subscribeCore = function (observer) {
2539
+ var sink = new RangeSink(observer, this);
2540
+ return sink.run();
2541
+ };
2542
+
2543
+ return RangeObservable;
2544
+ }(ObservableBase));
2545
+
2546
+ var RangeSink = (function () {
2547
+ function RangeSink(observer, parent) {
2548
+ this.observer = observer;
2549
+ this.parent = parent;
2550
+ }
2551
+
2552
+ RangeSink.prototype.run = function () {
2553
+ var start = this.parent.start, count = this.parent.count, observer = this.observer;
2554
+ function loopRecursive(i, recurse) {
2555
+ if (i < count) {
2556
+ observer.onNext(start + i);
2557
+ recurse(i + 1);
2558
+ } else {
2559
+ observer.onCompleted();
2560
+ }
2561
+ }
2562
+
2563
+ return this.parent.scheduler.scheduleRecursiveWithState(0, loopRecursive);
2564
+ };
2565
+
2566
+ return RangeSink;
2567
+ }());
2568
+
2569
+ /**
2570
+ * Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
2571
+ * @param {Number} start The value of the first integer in the sequence.
2572
+ * @param {Number} count The number of sequential integers to generate.
2573
+ * @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
2574
+ * @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
2575
+ */
2576
+ Observable.range = function (start, count, scheduler) {
2577
+ isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2578
+ return new RangeObservable(start, count, scheduler);
2579
+ };
2580
+
2362
2581
  /**
2363
2582
  * Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
2364
2583
  *
@@ -2380,10 +2599,6 @@ if (!Array.prototype.forEach) {
2380
2599
  /**
2381
2600
  * Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
2382
2601
  * There is an alias called 'just', and 'returnValue' for browsers <IE9.
2383
- *
2384
- * @example
2385
- * var res = Rx.Observable.return(42);
2386
- * var res = Rx.Observable.return(42, Rx.Scheduler.timeout);
2387
2602
  * @param {Mixed} value Single element in the resulting observable sequence.
2388
2603
  * @param {Scheduler} scheduler Scheduler to send the single element on. If not specified, defaults to Scheduler.immediate.
2389
2604
  * @returns {Observable} An observable sequence containing the single specified element.
@@ -2400,44 +2615,48 @@ if (!Array.prototype.forEach) {
2400
2615
 
2401
2616
  /** @deprecated use return or just */
2402
2617
  Observable.returnValue = function () {
2403
- deprecate('returnValue', 'return or just');
2618
+ //deprecate('returnValue', 'return or just');
2404
2619
  return observableReturn.apply(null, arguments);
2405
2620
  };
2406
2621
 
2407
2622
  /**
2408
2623
  * Returns an observable sequence that terminates with an exception, using the specified scheduler to send out the single onError message.
2409
2624
  * There is an alias to this method called 'throwError' for browsers <IE9.
2410
- * @param {Mixed} exception An object used for the sequence's termination.
2625
+ * @param {Mixed} error An object used for the sequence's termination.
2411
2626
  * @param {Scheduler} scheduler Scheduler to send the exceptional termination call on. If not specified, defaults to Scheduler.immediate.
2412
2627
  * @returns {Observable} The observable sequence that terminates exceptionally with the specified exception object.
2413
2628
  */
2414
- var observableThrow = Observable['throw'] = Observable.throwException = Observable.throwError = function (exception, scheduler) {
2629
+ var observableThrow = Observable['throw'] = Observable.throwError = function (error, scheduler) {
2415
2630
  isScheduler(scheduler) || (scheduler = immediateScheduler);
2416
2631
  return new AnonymousObservable(function (observer) {
2417
2632
  return scheduler.schedule(function () {
2418
- observer.onError(exception);
2633
+ observer.onError(error);
2419
2634
  });
2420
2635
  });
2421
2636
  };
2422
2637
 
2638
+ /** @deprecated use #some instead */
2639
+ Observable.throwException = function () {
2640
+ //deprecate('throwException', 'throwError');
2641
+ return Observable.throwError.apply(null, arguments);
2642
+ };
2643
+
2423
2644
  function observableCatchHandler(source, handler) {
2424
- return new AnonymousObservable(function (observer) {
2645
+ return new AnonymousObservable(function (o) {
2425
2646
  var d1 = new SingleAssignmentDisposable(), subscription = new SerialDisposable();
2426
2647
  subscription.setDisposable(d1);
2427
- d1.setDisposable(source.subscribe(observer.onNext.bind(observer), function (exception) {
2428
- var d, result;
2648
+ d1.setDisposable(source.subscribe(function (x) { o.onNext(x); }, function (e) {
2429
2649
  try {
2430
- result = handler(exception);
2650
+ var result = handler(e);
2431
2651
  } catch (ex) {
2432
- observer.onError(ex);
2433
- return;
2652
+ return o.onError(ex);
2434
2653
  }
2435
2654
  isPromise(result) && (result = observableFromPromise(result));
2436
2655
 
2437
- d = new SingleAssignmentDisposable();
2656
+ var d = new SingleAssignmentDisposable();
2438
2657
  subscription.setDisposable(d);
2439
- d.setDisposable(result.subscribe(observer));
2440
- }, observer.onCompleted.bind(observer)));
2658
+ d.setDisposable(result.subscribe(o));
2659
+ }, function (x) { o.onCompleted(x); }));
2441
2660
 
2442
2661
  return subscription;
2443
2662
  }, source);
@@ -2451,35 +2670,25 @@ if (!Array.prototype.forEach) {
2451
2670
  * @param {Mixed} handlerOrSecond Exception handler function that returns an observable sequence given the error that occurred in the first sequence, or a second observable sequence used to produce results when an error occurred in the first sequence.
2452
2671
  * @returns {Observable} An observable sequence containing the first sequence's elements, followed by the elements of the handler sequence in case an exception occurred.
2453
2672
  */
2454
- observableProto['catch'] = observableProto.catchError = function (handlerOrSecond) {
2673
+ observableProto['catch'] = observableProto.catchError = observableProto.catchException = function (handlerOrSecond) {
2455
2674
  return typeof handlerOrSecond === 'function' ?
2456
2675
  observableCatchHandler(this, handlerOrSecond) :
2457
2676
  observableCatch([this, handlerOrSecond]);
2458
2677
  };
2459
2678
 
2460
- /**
2461
- * @deprecated use #catch or #catchError instead.
2462
- */
2463
- observableProto.catchException = function (handlerOrSecond) {
2464
- deprecate('catchException', 'catch or catchError');
2465
- return this.catchError(handlerOrSecond);
2466
- };
2467
-
2468
2679
  /**
2469
2680
  * Continues an observable sequence that is terminated by an exception with the next observable sequence.
2470
2681
  * @param {Array | Arguments} args Arguments or an array to use as the next sequence if an error occurs.
2471
2682
  * @returns {Observable} An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully.
2472
2683
  */
2473
- var observableCatch = Observable.catchError = Observable['catch'] = function () {
2474
- return enumerableOf(argsOrArray(arguments, 0)).catchError();
2475
- };
2476
-
2477
- /**
2478
- * @deprecated use #catch or #catchError instead.
2479
- */
2480
- Observable.catchException = function () {
2481
- deprecate('catchException', 'catch or catchError');
2482
- return observableCatch.apply(null, arguments);
2684
+ var observableCatch = Observable.catchError = Observable['catch'] = Observable.catchException = function () {
2685
+ var items = [];
2686
+ if (Array.isArray(arguments[0])) {
2687
+ items = arguments[0];
2688
+ } else {
2689
+ for(var i = 0, len = arguments.length; i < len; i++) { items.push(arguments[i]); }
2690
+ }
2691
+ return enumerableOf(items).catchError();
2483
2692
  };
2484
2693
 
2485
2694
  /**
@@ -2492,7 +2701,8 @@ if (!Array.prototype.forEach) {
2492
2701
  * @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
2493
2702
  */
2494
2703
  observableProto.combineLatest = function () {
2495
- var args = slice.call(arguments);
2704
+ var len = arguments.length, args = new Array(len);
2705
+ for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
2496
2706
  if (Array.isArray(args[0])) {
2497
2707
  args[0].unshift(this);
2498
2708
  } else {
@@ -2510,54 +2720,51 @@ if (!Array.prototype.forEach) {
2510
2720
  * @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
2511
2721
  */
2512
2722
  var combineLatest = Observable.combineLatest = function () {
2513
- var args = slice.call(arguments), resultSelector = args.pop();
2723
+ var len = arguments.length, args = new Array(len);
2724
+ for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
2725
+ var resultSelector = args.pop();
2726
+ len--;
2727
+ Array.isArray(args[0]) && (args = args[0]);
2514
2728
 
2515
- if (Array.isArray(args[0])) {
2516
- args = args[0];
2517
- }
2518
-
2519
- return new AnonymousObservable(function (observer) {
2729
+ return new AnonymousObservable(function (o) {
2520
2730
  var falseFactory = function () { return false; },
2521
- n = args.length,
2522
- hasValue = arrayInitialize(n, falseFactory),
2731
+ hasValue = arrayInitialize(len, falseFactory),
2523
2732
  hasValueAll = false,
2524
- isDone = arrayInitialize(n, falseFactory),
2525
- values = new Array(n);
2733
+ isDone = arrayInitialize(len, falseFactory),
2734
+ values = new Array(len);
2526
2735
 
2527
2736
  function next(i) {
2528
- var res;
2529
2737
  hasValue[i] = true;
2530
2738
  if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
2531
2739
  try {
2532
- res = resultSelector.apply(null, values);
2740
+ var res = resultSelector.apply(null, values);
2533
2741
  } catch (ex) {
2534
- observer.onError(ex);
2742
+ o.onError(ex);
2535
2743
  return;
2536
2744
  }
2537
- observer.onNext(res);
2745
+ o.onNext(res);
2538
2746
  } else if (isDone.filter(function (x, j) { return j !== i; }).every(identity)) {
2539
- observer.onCompleted();
2747
+ o.onCompleted();
2540
2748
  }
2541
2749
  }
2542
2750
 
2543
2751
  function done (i) {
2544
2752
  isDone[i] = true;
2545
- if (isDone.every(identity)) {
2546
- observer.onCompleted();
2547
- }
2753
+ isDone.every(identity) && o.onCompleted();
2548
2754
  }
2549
2755
 
2550
- var subscriptions = new Array(n);
2551
- for (var idx = 0; idx < n; idx++) {
2756
+ var subscriptions = new Array(len);
2757
+ for (var idx = 0; idx < len; idx++) {
2552
2758
  (function (i) {
2553
2759
  var source = args[i], sad = new SingleAssignmentDisposable();
2554
2760
  isPromise(source) && (source = observableFromPromise(source));
2555
2761
  sad.setDisposable(source.subscribe(function (x) {
2556
- values[i] = x;
2557
- next(i);
2558
- }, observer.onError.bind(observer), function () {
2559
- done(i);
2560
- }));
2762
+ values[i] = x;
2763
+ next(i);
2764
+ },
2765
+ function(e) { o.onError(e); },
2766
+ function () { done(i); }
2767
+ ));
2561
2768
  subscriptions[i] = sad;
2562
2769
  }(idx));
2563
2770
  }
@@ -2566,19 +2773,15 @@ if (!Array.prototype.forEach) {
2566
2773
  }, this);
2567
2774
  };
2568
2775
 
2569
- /**
2570
- * Concatenates all the observable sequences. This takes in either an array or variable arguments to concatenate.
2571
- *
2572
- * @example
2573
- * 1 - concatenated = xs.concat(ys, zs);
2574
- * 2 - concatenated = xs.concat([ys, zs]);
2575
- * @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
2576
- */
2577
- observableProto.concat = function () {
2578
- var items = slice.call(arguments, 0);
2579
- items.unshift(this);
2580
- return observableConcat.apply(this, items);
2581
- };
2776
+ /**
2777
+ * Concatenates all the observable sequences. This takes in either an array or variable arguments to concatenate.
2778
+ * @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
2779
+ */
2780
+ observableProto.concat = function () {
2781
+ for(var args = [], i = 0, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
2782
+ args.unshift(this);
2783
+ return observableConcat.apply(null, args);
2784
+ };
2582
2785
 
2583
2786
  /**
2584
2787
  * Concatenates all the observable sequences.
@@ -2586,20 +2789,21 @@ if (!Array.prototype.forEach) {
2586
2789
  * @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
2587
2790
  */
2588
2791
  var observableConcat = Observable.concat = function () {
2589
- return enumerableOf(argsOrArray(arguments, 0)).concat();
2792
+ var args;
2793
+ if (Array.isArray(arguments[0])) {
2794
+ args = arguments[0];
2795
+ } else {
2796
+ args = new Array(arguments.length);
2797
+ for(var i = 0, len = arguments.length; i < len; i++) { args[i] = arguments[i]; }
2798
+ }
2799
+ return enumerableOf(args).concat();
2590
2800
  };
2591
2801
 
2592
2802
  /**
2593
2803
  * Concatenates an observable sequence of observable sequences.
2594
2804
  * @returns {Observable} An observable sequence that contains the elements of each observed inner sequence, in sequential order.
2595
2805
  */
2596
- observableProto.concatAll = function () {
2597
- return this.merge(1);
2598
- };
2599
-
2600
- /** @deprecated Use `concatAll` instead. */
2601
- observableProto.concatObservable = function () {
2602
- deprecate('concatObservable', 'concatAll');
2806
+ observableProto.concatAll = observableProto.concatObservable = function () {
2603
2807
  return this.merge(1);
2604
2808
  };
2605
2809
 
@@ -2616,7 +2820,7 @@ if (!Array.prototype.forEach) {
2616
2820
  observableProto.merge = function (maxConcurrentOrOther) {
2617
2821
  if (typeof maxConcurrentOrOther !== 'number') { return observableMerge(this, maxConcurrentOrOther); }
2618
2822
  var sources = this;
2619
- return new AnonymousObservable(function (observer) {
2823
+ return new AnonymousObservable(function (o) {
2620
2824
  var activeCount = 0, group = new CompositeDisposable(), isStopped = false, q = [];
2621
2825
 
2622
2826
  function subscribe(xs) {
@@ -2626,13 +2830,13 @@ if (!Array.prototype.forEach) {
2626
2830
  // Check for promises support
2627
2831
  isPromise(xs) && (xs = observableFromPromise(xs));
2628
2832
 
2629
- subscription.setDisposable(xs.subscribe(observer.onNext.bind(observer), observer.onError.bind(observer), function () {
2833
+ subscription.setDisposable(xs.subscribe(function (x) { o.onNext(x); }, function (e) { o.onError(e); }, function () {
2630
2834
  group.remove(subscription);
2631
2835
  if (q.length > 0) {
2632
2836
  subscribe(q.shift());
2633
2837
  } else {
2634
2838
  activeCount--;
2635
- isStopped && activeCount === 0 && observer.onCompleted();
2839
+ isStopped && activeCount === 0 && o.onCompleted();
2636
2840
  }
2637
2841
  }));
2638
2842
  }
@@ -2643,9 +2847,9 @@ if (!Array.prototype.forEach) {
2643
2847
  } else {
2644
2848
  q.push(innerSource);
2645
2849
  }
2646
- }, observer.onError.bind(observer), function () {
2850
+ }, function (e) { o.onError(e); }, function () {
2647
2851
  isStopped = true;
2648
- activeCount === 0 && observer.onCompleted();
2852
+ activeCount === 0 && o.onCompleted();
2649
2853
  }));
2650
2854
  return group;
2651
2855
  }, sources);
@@ -2657,16 +2861,16 @@ if (!Array.prototype.forEach) {
2657
2861
  * @returns {Observable} The observable sequence that merges the elements of the observable sequences.
2658
2862
  */
2659
2863
  var observableMerge = Observable.merge = function () {
2660
- var scheduler, sources;
2864
+ var scheduler, sources = [], i, len = arguments.length;
2661
2865
  if (!arguments[0]) {
2662
2866
  scheduler = immediateScheduler;
2663
- sources = slice.call(arguments, 1);
2867
+ for(i = 1; i < len; i++) { sources.push(arguments[i]); }
2664
2868
  } else if (isScheduler(arguments[0])) {
2665
2869
  scheduler = arguments[0];
2666
- sources = slice.call(arguments, 1);
2870
+ for(i = 1; i < len; i++) { sources.push(arguments[i]); }
2667
2871
  } else {
2668
2872
  scheduler = immediateScheduler;
2669
- sources = slice.call(arguments, 0);
2873
+ for(i = 0; i < len; i++) { sources.push(arguments[i]); }
2670
2874
  }
2671
2875
  if (Array.isArray(sources[0])) {
2672
2876
  sources = sources[0];
@@ -2678,9 +2882,9 @@ if (!Array.prototype.forEach) {
2678
2882
  * Merges an observable sequence of observable sequences into an observable sequence.
2679
2883
  * @returns {Observable} The observable sequence that merges the elements of the inner sequences.
2680
2884
  */
2681
- observableProto.mergeAll = function () {
2885
+ observableProto.mergeAll = observableProto.mergeObservable = function () {
2682
2886
  var sources = this;
2683
- return new AnonymousObservable(function (observer) {
2887
+ return new AnonymousObservable(function (o) {
2684
2888
  var group = new CompositeDisposable(),
2685
2889
  isStopped = false,
2686
2890
  m = new SingleAssignmentDisposable();
@@ -2693,26 +2897,18 @@ if (!Array.prototype.forEach) {
2693
2897
  // Check for promises support
2694
2898
  isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
2695
2899
 
2696
- innerSubscription.setDisposable(innerSource.subscribe(observer.onNext.bind(observer), observer.onError.bind(observer), function () {
2900
+ innerSubscription.setDisposable(innerSource.subscribe(function (x) { o.onNext(x); }, function (e) { o.onError(e); }, function () {
2697
2901
  group.remove(innerSubscription);
2698
- isStopped && group.length === 1 && observer.onCompleted();
2902
+ isStopped && group.length === 1 && o.onCompleted();
2699
2903
  }));
2700
- }, observer.onError.bind(observer), function () {
2904
+ }, function (e) { o.onError(e); }, function () {
2701
2905
  isStopped = true;
2702
- group.length === 1 && observer.onCompleted();
2906
+ group.length === 1 && o.onCompleted();
2703
2907
  }));
2704
2908
  return group;
2705
2909
  }, sources);
2706
2910
  };
2707
2911
 
2708
- /**
2709
- * @deprecated use #mergeAll instead.
2710
- */
2711
- observableProto.mergeObservable = function () {
2712
- deprecate('mergeObservable', 'mergeAll');
2713
- return this.mergeAll.apply(this, arguments);
2714
- };
2715
-
2716
2912
  /**
2717
2913
  * Returns the values from the source observable sequence only after the other observable sequence produces a value.
2718
2914
  * @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
@@ -2720,12 +2916,12 @@ if (!Array.prototype.forEach) {
2720
2916
  */
2721
2917
  observableProto.skipUntil = function (other) {
2722
2918
  var source = this;
2723
- return new AnonymousObservable(function (observer) {
2919
+ return new AnonymousObservable(function (o) {
2724
2920
  var isOpen = false;
2725
2921
  var disposables = new CompositeDisposable(source.subscribe(function (left) {
2726
- isOpen && observer.onNext(left);
2727
- }, observer.onError.bind(observer), function () {
2728
- isOpen && observer.onCompleted();
2922
+ isOpen && o.onNext(left);
2923
+ }, function (e) { o.onError(e); }, function () {
2924
+ isOpen && o.onCompleted();
2729
2925
  }));
2730
2926
 
2731
2927
  isPromise(other) && (other = observableFromPromise(other));
@@ -2735,7 +2931,7 @@ if (!Array.prototype.forEach) {
2735
2931
  rightSubscription.setDisposable(other.subscribe(function () {
2736
2932
  isOpen = true;
2737
2933
  rightSubscription.dispose();
2738
- }, observer.onError.bind(observer), function () {
2934
+ }, function (e) { o.onError(e); }, function () {
2739
2935
  rightSubscription.dispose();
2740
2936
  }));
2741
2937
 
@@ -2773,7 +2969,7 @@ if (!Array.prototype.forEach) {
2773
2969
  }
2774
2970
  }));
2775
2971
  },
2776
- observer.onError.bind(observer),
2972
+ function (e) { observer.onError(e); },
2777
2973
  function () {
2778
2974
  isStopped = true;
2779
2975
  !hasLatest && observer.onCompleted();
@@ -2789,15 +2985,79 @@ if (!Array.prototype.forEach) {
2789
2985
  */
2790
2986
  observableProto.takeUntil = function (other) {
2791
2987
  var source = this;
2792
- return new AnonymousObservable(function (observer) {
2988
+ return new AnonymousObservable(function (o) {
2793
2989
  isPromise(other) && (other = observableFromPromise(other));
2794
2990
  return new CompositeDisposable(
2795
- source.subscribe(observer),
2796
- other.subscribe(observer.onCompleted.bind(observer), observer.onError.bind(observer), noop)
2991
+ source.subscribe(o),
2992
+ other.subscribe(function () { o.onCompleted(); }, function (e) { o.onError(e); }, noop)
2797
2993
  );
2798
2994
  }, source);
2799
2995
  };
2800
2996
 
2997
+ /**
2998
+ * Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
2999
+ *
3000
+ * @example
3001
+ * 1 - obs = obs1.withLatestFrom(obs2, obs3, function (o1, o2, o3) { return o1 + o2 + o3; });
3002
+ * 2 - obs = obs1.withLatestFrom([obs2, obs3], function (o1, o2, o3) { return o1 + o2 + o3; });
3003
+ * @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
3004
+ */
3005
+ observableProto.withLatestFrom = function () {
3006
+ for(var args = [], i = 0, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
3007
+ var resultSelector = args.pop(), source = this;
3008
+
3009
+ if (typeof source === 'undefined') {
3010
+ throw new Error('Source observable not found for withLatestFrom().');
3011
+ }
3012
+ if (typeof resultSelector !== 'function') {
3013
+ throw new Error('withLatestFrom() expects a resultSelector function.');
3014
+ }
3015
+ if (Array.isArray(args[0])) {
3016
+ args = args[0];
3017
+ }
3018
+
3019
+ return new AnonymousObservable(function (observer) {
3020
+ var falseFactory = function () { return false; },
3021
+ n = args.length,
3022
+ hasValue = arrayInitialize(n, falseFactory),
3023
+ hasValueAll = false,
3024
+ values = new Array(n);
3025
+
3026
+ var subscriptions = new Array(n + 1);
3027
+ for (var idx = 0; idx < n; idx++) {
3028
+ (function (i) {
3029
+ var other = args[i], sad = new SingleAssignmentDisposable();
3030
+ isPromise(other) && (other = observableFromPromise(other));
3031
+ sad.setDisposable(other.subscribe(function (x) {
3032
+ values[i] = x;
3033
+ hasValue[i] = true;
3034
+ hasValueAll = hasValue.every(identity);
3035
+ }, observer.onError.bind(observer), function () {}));
3036
+ subscriptions[i] = sad;
3037
+ }(idx));
3038
+ }
3039
+
3040
+ var sad = new SingleAssignmentDisposable();
3041
+ sad.setDisposable(source.subscribe(function (x) {
3042
+ var res;
3043
+ var allValues = [x].concat(values);
3044
+ if (!hasValueAll) return;
3045
+ try {
3046
+ res = resultSelector.apply(null, allValues);
3047
+ } catch (ex) {
3048
+ observer.onError(ex);
3049
+ return;
3050
+ }
3051
+ observer.onNext(res);
3052
+ }, observer.onError.bind(observer), function () {
3053
+ observer.onCompleted();
3054
+ }));
3055
+ subscriptions[n] = sad;
3056
+
3057
+ return new CompositeDisposable(subscriptions);
3058
+ }, this);
3059
+ };
3060
+
2801
3061
  function zipArray(second, resultSelector) {
2802
3062
  var first = this;
2803
3063
  return new AnonymousObservable(function (observer) {
@@ -2808,36 +3068,39 @@ if (!Array.prototype.forEach) {
2808
3068
  try {
2809
3069
  result = resultSelector(left, right);
2810
3070
  } catch (e) {
2811
- observer.onError(e);
2812
- return;
3071
+ return observer.onError(e);
2813
3072
  }
2814
3073
  observer.onNext(result);
2815
3074
  } else {
2816
3075
  observer.onCompleted();
2817
3076
  }
2818
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3077
+ }, function (e) { observer.onError(e); }, function () { observer.onCompleted(); });
2819
3078
  }, first);
2820
3079
  }
2821
3080
 
3081
+ function falseFactory() { return false; }
3082
+ function emptyArrayFactory() { return []; }
3083
+
2822
3084
  /**
2823
3085
  * Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
2824
- * The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the sources.
3086
+ * The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
2825
3087
  *
2826
3088
  * @example
2827
3089
  * 1 - res = obs1.zip(obs2, fn);
2828
3090
  * 1 - res = x1.zip([1,2,3], fn);
2829
- * @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
3091
+ * @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
2830
3092
  */
2831
3093
  observableProto.zip = function () {
2832
- if (Array.isArray(arguments[0])) {
2833
- return zipArray.apply(this, arguments);
2834
- }
2835
- var parent = this, sources = slice.call(arguments), resultSelector = sources.pop();
2836
- sources.unshift(parent);
3094
+ if (Array.isArray(arguments[0])) { return zipArray.apply(this, arguments); }
3095
+ var len = arguments.length, args = new Array(len);
3096
+ for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
3097
+
3098
+ var parent = this, resultSelector = args.pop();
3099
+ args.unshift(parent);
2837
3100
  return new AnonymousObservable(function (observer) {
2838
- var n = sources.length,
2839
- queues = arrayInitialize(n, function () { return []; }),
2840
- isDone = arrayInitialize(n, function () { return false; });
3101
+ var n = args.length,
3102
+ queues = arrayInitialize(n, emptyArrayFactory),
3103
+ isDone = arrayInitialize(n, falseFactory);
2841
3104
 
2842
3105
  function next(i) {
2843
3106
  var res, queuedValues;
@@ -2865,12 +3128,12 @@ if (!Array.prototype.forEach) {
2865
3128
  var subscriptions = new Array(n);
2866
3129
  for (var idx = 0; idx < n; idx++) {
2867
3130
  (function (i) {
2868
- var source = sources[i], sad = new SingleAssignmentDisposable();
3131
+ var source = args[i], sad = new SingleAssignmentDisposable();
2869
3132
  isPromise(source) && (source = observableFromPromise(source));
2870
3133
  sad.setDisposable(source.subscribe(function (x) {
2871
3134
  queues[i].push(x);
2872
3135
  next(i);
2873
- }, observer.onError.bind(observer), function () {
3136
+ }, function (e) { observer.onError(e); }, function () {
2874
3137
  done(i);
2875
3138
  }));
2876
3139
  subscriptions[i] = sad;
@@ -2888,7 +3151,9 @@ if (!Array.prototype.forEach) {
2888
3151
  * @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
2889
3152
  */
2890
3153
  Observable.zip = function () {
2891
- var args = slice.call(arguments, 0), first = args.shift();
3154
+ var len = arguments.length, args = new Array(len);
3155
+ for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
3156
+ var first = args.shift();
2892
3157
  return first.zip.apply(first, args);
2893
3158
  };
2894
3159
 
@@ -2898,7 +3163,14 @@ if (!Array.prototype.forEach) {
2898
3163
  * @returns {Observable} An observable sequence containing lists of elements at corresponding indexes.
2899
3164
  */
2900
3165
  Observable.zipArray = function () {
2901
- var sources = argsOrArray(arguments, 0);
3166
+ var sources;
3167
+ if (Array.isArray(arguments[0])) {
3168
+ sources = arguments[0];
3169
+ } else {
3170
+ var len = arguments.length;
3171
+ sources = new Array(len);
3172
+ for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
3173
+ }
2902
3174
  return new AnonymousObservable(function (observer) {
2903
3175
  var n = sources.length,
2904
3176
  queues = arrayInitialize(n, function () { return []; }),
@@ -2929,17 +3201,13 @@ if (!Array.prototype.forEach) {
2929
3201
  subscriptions[i].setDisposable(sources[i].subscribe(function (x) {
2930
3202
  queues[i].push(x);
2931
3203
  next(i);
2932
- }, observer.onError.bind(observer), function () {
3204
+ }, function (e) { observer.onError(e); }, function () {
2933
3205
  done(i);
2934
3206
  }));
2935
3207
  })(idx);
2936
3208
  }
2937
3209
 
2938
- var compositeDisposable = new CompositeDisposable(subscriptions);
2939
- compositeDisposable.add(disposableCreate(function () {
2940
- for (var qIdx = 0, qLen = queues.length; qIdx < qLen; qIdx++) { queues[qIdx] = []; }
2941
- }));
2942
- return compositeDisposable;
3210
+ return new CompositeDisposable(subscriptions);
2943
3211
  });
2944
3212
  };
2945
3213
 
@@ -2948,7 +3216,8 @@ if (!Array.prototype.forEach) {
2948
3216
  * @returns {Observable} An observable sequence that hides the identity of the source sequence.
2949
3217
  */
2950
3218
  observableProto.asObservable = function () {
2951
- return new AnonymousObservable(this.subscribe.bind(this), this);
3219
+ var source = this;
3220
+ return new AnonymousObservable(function (o) { return source.subscribe(o); }, this);
2952
3221
  };
2953
3222
 
2954
3223
  /**
@@ -2957,8 +3226,8 @@ if (!Array.prototype.forEach) {
2957
3226
  */
2958
3227
  observableProto.dematerialize = function () {
2959
3228
  var source = this;
2960
- return new AnonymousObservable(function (observer) {
2961
- return source.subscribe(function (x) { return x.accept(observer); }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3229
+ return new AnonymousObservable(function (o) {
3230
+ return source.subscribe(function (x) { return x.accept(o); }, function(e) { o.onError(e); }, function () { o.onCompleted(); });
2962
3231
  }, this);
2963
3232
  };
2964
3233
 
@@ -2975,32 +3244,33 @@ if (!Array.prototype.forEach) {
2975
3244
  */
2976
3245
  observableProto.distinctUntilChanged = function (keySelector, comparer) {
2977
3246
  var source = this;
2978
- keySelector || (keySelector = identity);
2979
3247
  comparer || (comparer = defaultComparer);
2980
- return new AnonymousObservable(function (observer) {
3248
+ return new AnonymousObservable(function (o) {
2981
3249
  var hasCurrentKey = false, currentKey;
2982
3250
  return source.subscribe(function (value) {
2983
- var comparerEquals = false, key;
3251
+ var key = value;
3252
+ if (keySelector) {
2984
3253
  try {
2985
3254
  key = keySelector(value);
2986
3255
  } catch (e) {
2987
- observer.onError(e);
3256
+ o.onError(e);
2988
3257
  return;
2989
3258
  }
2990
- if (hasCurrentKey) {
2991
- try {
2992
- comparerEquals = comparer(currentKey, key);
2993
- } catch (e) {
2994
- observer.onError(e);
2995
- return;
2996
- }
2997
- }
2998
- if (!hasCurrentKey || !comparerEquals) {
2999
- hasCurrentKey = true;
3000
- currentKey = key;
3001
- observer.onNext(value);
3259
+ }
3260
+ if (hasCurrentKey) {
3261
+ try {
3262
+ var comparerEquals = comparer(currentKey, key);
3263
+ } catch (e) {
3264
+ o.onError(e);
3265
+ return;
3002
3266
  }
3003
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3267
+ }
3268
+ if (!hasCurrentKey || !comparerEquals) {
3269
+ hasCurrentKey = true;
3270
+ currentKey = key;
3271
+ o.onNext(value);
3272
+ }
3273
+ }, function (e) { o.onError(e); }, function () { o.onCompleted(); });
3004
3274
  }, this);
3005
3275
  };
3006
3276
 
@@ -3012,51 +3282,36 @@ if (!Array.prototype.forEach) {
3012
3282
  * @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
3013
3283
  * @returns {Observable} The source sequence with the side-effecting behavior applied.
3014
3284
  */
3015
- observableProto['do'] = observableProto.tap = function (observerOrOnNext, onError, onCompleted) {
3016
- var source = this, onNextFunc;
3017
- if (typeof observerOrOnNext === 'function') {
3018
- onNextFunc = observerOrOnNext;
3019
- } else {
3020
- onNextFunc = observerOrOnNext.onNext.bind(observerOrOnNext);
3021
- onError = observerOrOnNext.onError.bind(observerOrOnNext);
3022
- onCompleted = observerOrOnNext.onCompleted.bind(observerOrOnNext);
3023
- }
3285
+ observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
3286
+ var source = this, tapObserver = typeof observerOrOnNext === 'function' || typeof observerOrOnNext === 'undefined'?
3287
+ observerCreate(observerOrOnNext || noop, onError || noop, onCompleted || noop) :
3288
+ observerOrOnNext;
3024
3289
  return new AnonymousObservable(function (observer) {
3025
3290
  return source.subscribe(function (x) {
3026
3291
  try {
3027
- onNextFunc(x);
3292
+ tapObserver.onNext(x);
3028
3293
  } catch (e) {
3029
3294
  observer.onError(e);
3030
3295
  }
3031
3296
  observer.onNext(x);
3032
3297
  }, function (err) {
3033
- if (onError) {
3034
3298
  try {
3035
- onError(err);
3299
+ tapObserver.onError(err);
3036
3300
  } catch (e) {
3037
3301
  observer.onError(e);
3038
3302
  }
3039
- }
3040
3303
  observer.onError(err);
3041
3304
  }, function () {
3042
- if (onCompleted) {
3043
- try {
3044
- onCompleted();
3045
- } catch (e) {
3046
- observer.onError(e);
3047
- }
3305
+ try {
3306
+ tapObserver.onCompleted();
3307
+ } catch (e) {
3308
+ observer.onError(e);
3048
3309
  }
3049
3310
  observer.onCompleted();
3050
3311
  });
3051
3312
  }, this);
3052
3313
  };
3053
3314
 
3054
- /** @deprecated use #do or #tap instead. */
3055
- observableProto.doAction = function () {
3056
- deprecate('doAction', 'do or tap');
3057
- return this.tap.apply(this, arguments);
3058
- };
3059
-
3060
3315
  /**
3061
3316
  * Invokes an action for each element in the observable sequence.
3062
3317
  * 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.
@@ -3065,7 +3320,7 @@ if (!Array.prototype.forEach) {
3065
3320
  * @returns {Observable} The source sequence with the side-effecting behavior applied.
3066
3321
  */
3067
3322
  observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
3068
- return this.tap(arguments.length === 2 ? function (x) { onNext.call(thisArg, x); } : onNext);
3323
+ return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
3069
3324
  };
3070
3325
 
3071
3326
  /**
@@ -3076,7 +3331,7 @@ if (!Array.prototype.forEach) {
3076
3331
  * @returns {Observable} The source sequence with the side-effecting behavior applied.
3077
3332
  */
3078
3333
  observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
3079
- return this.tap(noop, arguments.length === 2 ? function (e) { onError.call(thisArg, e); } : onError);
3334
+ return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
3080
3335
  };
3081
3336
 
3082
3337
  /**
@@ -3087,7 +3342,7 @@ if (!Array.prototype.forEach) {
3087
3342
  * @returns {Observable} The source sequence with the side-effecting behavior applied.
3088
3343
  */
3089
3344
  observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
3090
- return this.tap(noop, null, arguments.length === 2 ? function () { onCompleted.call(thisArg); } : onCompleted);
3345
+ return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
3091
3346
  };
3092
3347
 
3093
3348
  /**
@@ -3121,7 +3376,7 @@ if (!Array.prototype.forEach) {
3121
3376
  * @deprecated use #finally or #ensure instead.
3122
3377
  */
3123
3378
  observableProto.finallyAction = function (action) {
3124
- deprecate('finallyAction', 'finally or ensure');
3379
+ //deprecate('finallyAction', 'finally or ensure');
3125
3380
  return this.ensure(action);
3126
3381
  };
3127
3382
 
@@ -3131,8 +3386,8 @@ if (!Array.prototype.forEach) {
3131
3386
  */
3132
3387
  observableProto.ignoreElements = function () {
3133
3388
  var source = this;
3134
- return new AnonymousObservable(function (observer) {
3135
- return source.subscribe(noop, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3389
+ return new AnonymousObservable(function (o) {
3390
+ return source.subscribe(noop, function (e) { o.onError(e); }, function () { o.onCompleted(); });
3136
3391
  }, source);
3137
3392
  };
3138
3393
 
@@ -3178,6 +3433,19 @@ if (!Array.prototype.forEach) {
3178
3433
  return enumerableRepeat(this, retryCount).catchError();
3179
3434
  };
3180
3435
 
3436
+ /**
3437
+ * Repeats the source observable sequence upon error each time the notifier emits or until it successfully terminates.
3438
+ * if the notifier completes, the observable sequence completes.
3439
+ *
3440
+ * @example
3441
+ * var timer = Observable.timer(500);
3442
+ * var source = observable.retryWhen(timer);
3443
+ * @param {Observable} [notifier] An observable that triggers the retries or completes the observable with onNext or onCompleted respectively.
3444
+ * @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
3445
+ */
3446
+ observableProto.retryWhen = function (notifier) {
3447
+ return enumerableRepeat(this).catchErrorWhen(notifier);
3448
+ };
3181
3449
  /**
3182
3450
  * Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
3183
3451
  * For aggregation behavior with no intermediate results, see Observable.aggregate.
@@ -3197,7 +3465,7 @@ if (!Array.prototype.forEach) {
3197
3465
  } else {
3198
3466
  accumulator = arguments[0];
3199
3467
  }
3200
- return new AnonymousObservable(function (observer) {
3468
+ return new AnonymousObservable(function (o) {
3201
3469
  var hasAccumulation, accumulation, hasValue;
3202
3470
  return source.subscribe (
3203
3471
  function (x) {
@@ -3210,16 +3478,16 @@ if (!Array.prototype.forEach) {
3210
3478
  hasAccumulation = true;
3211
3479
  }
3212
3480
  } catch (e) {
3213
- observer.onError(e);
3481
+ o.onError(e);
3214
3482
  return;
3215
3483
  }
3216
3484
 
3217
- observer.onNext(accumulation);
3485
+ o.onNext(accumulation);
3218
3486
  },
3219
- observer.onError.bind(observer),
3487
+ function (e) { o.onError(e); },
3220
3488
  function () {
3221
- !hasValue && hasSeed && observer.onNext(seed);
3222
- observer.onCompleted();
3489
+ !hasValue && hasSeed && o.onNext(seed);
3490
+ o.onCompleted();
3223
3491
  }
3224
3492
  );
3225
3493
  }, source);
@@ -3235,12 +3503,12 @@ if (!Array.prototype.forEach) {
3235
3503
  */
3236
3504
  observableProto.skipLast = function (count) {
3237
3505
  var source = this;
3238
- return new AnonymousObservable(function (observer) {
3506
+ return new AnonymousObservable(function (o) {
3239
3507
  var q = [];
3240
3508
  return source.subscribe(function (x) {
3241
3509
  q.push(x);
3242
- q.length > count && observer.onNext(q.shift());
3243
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3510
+ q.length > count && o.onNext(q.shift());
3511
+ }, function (e) { o.onError(e); }, function () { o.onCompleted(); });
3244
3512
  }, source);
3245
3513
  };
3246
3514
 
@@ -3260,8 +3528,8 @@ if (!Array.prototype.forEach) {
3260
3528
  } else {
3261
3529
  scheduler = immediateScheduler;
3262
3530
  }
3263
- values = slice.call(arguments, start);
3264
- return enumerableOf([observableFromArray(values, scheduler), this]).concat();
3531
+ for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
3532
+ return enumerableOf([observableFromArray(args, scheduler), this]).concat();
3265
3533
  };
3266
3534
 
3267
3535
  /**
@@ -3274,21 +3542,22 @@ if (!Array.prototype.forEach) {
3274
3542
  */
3275
3543
  observableProto.takeLast = function (count) {
3276
3544
  var source = this;
3277
- return new AnonymousObservable(function (observer) {
3545
+ return new AnonymousObservable(function (o) {
3278
3546
  var q = [];
3279
3547
  return source.subscribe(function (x) {
3280
3548
  q.push(x);
3281
3549
  q.length > count && q.shift();
3282
- }, observer.onError.bind(observer), function () {
3283
- while (q.length > 0) { observer.onNext(q.shift()); }
3284
- observer.onCompleted();
3550
+ }, function (e) { o.onError(e); }, function () {
3551
+ while (q.length > 0) { o.onNext(q.shift()); }
3552
+ o.onCompleted();
3285
3553
  });
3286
3554
  }, source);
3287
3555
  };
3288
3556
 
3289
3557
  function concatMap(source, selector, thisArg) {
3558
+ var selectorFunc = bindCallback(selector, thisArg, 3);
3290
3559
  return source.map(function (x, i) {
3291
- var result = selector.call(thisArg, x, i, source);
3560
+ var result = selectorFunc(x, i, source);
3292
3561
  isPromise(result) && (result = observableFromPromise(result));
3293
3562
  (isArrayLike(result) || isIterable(result)) && (result = observableFrom(result));
3294
3563
  return result;
@@ -3331,42 +3600,102 @@ if (!Array.prototype.forEach) {
3331
3600
  concatMap(this, function () { return selector; });
3332
3601
  };
3333
3602
 
3603
+ var MapObservable = (function (__super__) {
3604
+ inherits(MapObservable, __super__);
3605
+
3606
+ function MapObservable(source, selector, thisArg) {
3607
+ this.source = source;
3608
+ this.selector = bindCallback(selector, thisArg, 3);
3609
+ __super__.call(this);
3610
+ }
3611
+
3612
+ MapObservable.prototype.internalMap = function (selector, thisArg) {
3613
+ var self = this;
3614
+ return new MapObservable(this.source, function (x, i, o) { return selector(self.selector(x, i, o), i, o); }, thisArg)
3615
+ };
3616
+
3617
+ MapObservable.prototype.subscribeCore = function (observer) {
3618
+ return this.source.subscribe(new MapObserver(observer, this.selector, this));
3619
+ };
3620
+
3621
+ return MapObservable;
3622
+
3623
+ }(ObservableBase));
3624
+
3625
+ function MapObserver(observer, selector, source) {
3626
+ this.observer = observer;
3627
+ this.selector = selector;
3628
+ this.source = source;
3629
+ this.i = 0;
3630
+ this.isStopped = false;
3631
+ }
3632
+
3633
+ MapObserver.prototype.onNext = function(x) {
3634
+ if (this.isStopped) { return; }
3635
+ try {
3636
+ var result = this.selector(x, this.i++, this.source);
3637
+ } catch (e) {
3638
+ return this.observer.onError(e);
3639
+ }
3640
+ this.observer.onNext(result);
3641
+ };
3642
+ MapObserver.prototype.onError = function (e) {
3643
+ if(!this.isStopped) { this.isStopped = true; this.observer.onError(e); }
3644
+ };
3645
+ MapObserver.prototype.onCompleted = function () {
3646
+ if(!this.isStopped) { this.isStopped = true; this.observer.onCompleted(); }
3647
+ };
3648
+ MapObserver.prototype.dispose = function() { this.isStopped = true; };
3649
+ MapObserver.prototype.fail = function (e) {
3650
+ if (!this.isStopped) {
3651
+ this.isStopped = true;
3652
+ this.observer.onError(e);
3653
+ return true;
3654
+ }
3655
+
3656
+ return false;
3657
+ };
3658
+
3334
3659
  /**
3335
- * Projects each element of an observable sequence into a new form by incorporating the element's index.
3336
- * @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
3337
- * @param {Any} [thisArg] Object to use as this when executing callback.
3338
- * @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
3339
- */
3340
- observableProto.select = observableProto.map = function (selector, thisArg) {
3341
- var selectorFn = isFunction(selector) ? selector : function () { return selector; },
3342
- source = this;
3343
- return new AnonymousObservable(function (observer) {
3344
- var count = 0;
3345
- return source.subscribe(function (value) {
3346
- var result;
3347
- try {
3348
- result = selectorFn.call(thisArg, value, count++, source);
3349
- } catch (e) {
3350
- observer.onError(e);
3351
- return;
3352
- }
3353
- observer.onNext(result);
3354
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3355
- }, source);
3660
+ * Projects each element of an observable sequence into a new form by incorporating the element's index.
3661
+ * @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
3662
+ * @param {Any} [thisArg] Object to use as this when executing callback.
3663
+ * @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
3664
+ */
3665
+ observableProto.map = observableProto.select = function (selector, thisArg) {
3666
+ var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
3667
+ return this instanceof MapObservable ?
3668
+ this.internalMap(selectorFn, thisArg) :
3669
+ new MapObservable(this, selectorFn, thisArg);
3356
3670
  };
3357
3671
 
3358
3672
  /**
3359
- * Retrieves the value of a specified property from all elements in the Observable sequence.
3360
- * @param {String} prop The property to pluck.
3673
+ * Retrieves the value of a specified nested property from all elements in
3674
+ * the Observable sequence.
3675
+ * @param {Arguments} arguments The nested properties to pluck.
3361
3676
  * @returns {Observable} Returns a new Observable sequence of property values.
3362
3677
  */
3363
- observableProto.pluck = function (prop) {
3364
- return this.map(function (x) { return x[prop]; });
3678
+ observableProto.pluck = function () {
3679
+ var args = arguments, len = arguments.length;
3680
+ if (len === 0) { throw new Error('List of properties cannot be empty.'); }
3681
+ return this.map(function (x) {
3682
+ var currentProp = x;
3683
+ for (var i = 0; i < len; i++) {
3684
+ var p = currentProp[args[i]];
3685
+ if (typeof p !== 'undefined') {
3686
+ currentProp = p;
3687
+ } else {
3688
+ return undefined;
3689
+ }
3690
+ }
3691
+ return currentProp;
3692
+ });
3365
3693
  };
3366
3694
 
3367
3695
  function flatMap(source, selector, thisArg) {
3696
+ var selectorFunc = bindCallback(selector, thisArg, 3);
3368
3697
  return source.map(function (x, i) {
3369
- var result = selector.call(thisArg, x, i, source);
3698
+ var result = selectorFunc(x, i, source);
3370
3699
  isPromise(result) && (result = observableFromPromise(result));
3371
3700
  (isArrayLike(result) || isIterable(result)) && (result = observableFrom(result));
3372
3701
  return result;
@@ -3429,15 +3758,15 @@ if (!Array.prototype.forEach) {
3429
3758
  observableProto.skip = function (count) {
3430
3759
  if (count < 0) { throw new Error(argumentOutOfRange); }
3431
3760
  var source = this;
3432
- return new AnonymousObservable(function (observer) {
3761
+ return new AnonymousObservable(function (o) {
3433
3762
  var remaining = count;
3434
3763
  return source.subscribe(function (x) {
3435
3764
  if (remaining <= 0) {
3436
- observer.onNext(x);
3765
+ o.onNext(x);
3437
3766
  } else {
3438
3767
  remaining--;
3439
3768
  }
3440
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3769
+ }, function (e) { o.onError(e); }, function () { o.onCompleted(); });
3441
3770
  }, source);
3442
3771
  };
3443
3772
 
@@ -3452,20 +3781,21 @@ if (!Array.prototype.forEach) {
3452
3781
  * @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
3453
3782
  */
3454
3783
  observableProto.skipWhile = function (predicate, thisArg) {
3455
- var source = this;
3456
- return new AnonymousObservable(function (observer) {
3784
+ var source = this,
3785
+ callback = bindCallback(predicate, thisArg, 3);
3786
+ return new AnonymousObservable(function (o) {
3457
3787
  var i = 0, running = false;
3458
3788
  return source.subscribe(function (x) {
3459
3789
  if (!running) {
3460
3790
  try {
3461
- running = !predicate.call(thisArg, x, i++, source);
3791
+ running = !callback(x, i++, source);
3462
3792
  } catch (e) {
3463
- observer.onError(e);
3793
+ o.onError(e);
3464
3794
  return;
3465
3795
  }
3466
3796
  }
3467
- running && observer.onNext(x);
3468
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3797
+ running && o.onNext(x);
3798
+ }, function (e) { o.onError(e); }, function () { o.onCompleted(); });
3469
3799
  }, source);
3470
3800
  };
3471
3801
 
@@ -3482,14 +3812,14 @@ if (!Array.prototype.forEach) {
3482
3812
  if (count < 0) { throw new RangeError(argumentOutOfRange); }
3483
3813
  if (count === 0) { return observableEmpty(scheduler); }
3484
3814
  var source = this;
3485
- return new AnonymousObservable(function (observer) {
3815
+ return new AnonymousObservable(function (o) {
3486
3816
  var remaining = count;
3487
3817
  return source.subscribe(function (x) {
3488
3818
  if (remaining-- > 0) {
3489
- observer.onNext(x);
3490
- remaining === 0 && observer.onCompleted();
3819
+ o.onNext(x);
3820
+ remaining === 0 && o.onCompleted();
3491
3821
  }
3492
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3822
+ }, function (e) { o.onError(e); }, function () { o.onCompleted(); });
3493
3823
  }, source);
3494
3824
  };
3495
3825
 
@@ -3501,52 +3831,92 @@ if (!Array.prototype.forEach) {
3501
3831
  * @returns {Observable} An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes.
3502
3832
  */
3503
3833
  observableProto.takeWhile = function (predicate, thisArg) {
3504
- var source = this;
3505
- return new AnonymousObservable(function (observer) {
3834
+ var source = this,
3835
+ callback = bindCallback(predicate, thisArg, 3);
3836
+ return new AnonymousObservable(function (o) {
3506
3837
  var i = 0, running = true;
3507
3838
  return source.subscribe(function (x) {
3508
3839
  if (running) {
3509
3840
  try {
3510
- running = predicate.call(thisArg, x, i++, source);
3841
+ running = callback(x, i++, source);
3511
3842
  } catch (e) {
3512
- observer.onError(e);
3843
+ o.onError(e);
3513
3844
  return;
3514
3845
  }
3515
3846
  if (running) {
3516
- observer.onNext(x);
3847
+ o.onNext(x);
3517
3848
  } else {
3518
- observer.onCompleted();
3849
+ o.onCompleted();
3519
3850
  }
3520
3851
  }
3521
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3852
+ }, function (e) { o.onError(e); }, function () { o.onCompleted(); });
3522
3853
  }, source);
3523
3854
  };
3524
3855
 
3856
+ var FilterObservable = (function (__super__) {
3857
+ inherits(FilterObservable, __super__);
3858
+
3859
+ function FilterObservable(source, predicate, thisArg) {
3860
+ this.source = source;
3861
+ this.predicate = bindCallback(predicate, thisArg, 3);
3862
+ __super__.call(this);
3863
+ }
3864
+
3865
+ FilterObservable.prototype.subscribeCore = function (observer) {
3866
+ return this.source.subscribe(new FilterObserver(observer, this.predicate, this));
3867
+ };
3868
+
3869
+ FilterObservable.prototype.internalFilter = function(predicate, thisArg) {
3870
+ var self = this;
3871
+ return new FilterObservable(this.source, function(x, i, o) { return self.predicate(x, i, o) && predicate(x, i, o); }, thisArg);
3872
+ };
3873
+
3874
+ return FilterObservable;
3875
+
3876
+ }(ObservableBase));
3877
+
3878
+ function FilterObserver(observer, predicate, source) {
3879
+ this.observer = observer;
3880
+ this.predicate = predicate;
3881
+ this.source = source;
3882
+ this.i = 0;
3883
+ this.isStopped = false;
3884
+ }
3885
+
3886
+ FilterObserver.prototype.onNext = function(x) {
3887
+ if (this.isStopped) { return; }
3888
+ try {
3889
+ var shouldYield = this.predicate(x, this.i++, this.source);
3890
+ } catch (e) {
3891
+ return this.observer.onError(e);
3892
+ }
3893
+ shouldYield && this.observer.onNext(x);
3894
+ };
3895
+ FilterObserver.prototype.onError = function (e) {
3896
+ if(!this.isStopped) { this.isStopped = true; this.observer.onError(e); }
3897
+ };
3898
+ FilterObserver.prototype.onCompleted = function () {
3899
+ if(!this.isStopped) { this.isStopped = true; this.observer.onCompleted(); }
3900
+ };
3901
+ FilterObserver.prototype.dispose = function() { this.isStopped = true; };
3902
+ FilterObserver.prototype.fail = function (e) {
3903
+ if (!this.isStopped) {
3904
+ this.isStopped = true;
3905
+ this.observer.onError(e);
3906
+ return true;
3907
+ }
3908
+ return false;
3909
+ };
3910
+
3525
3911
  /**
3526
- * Filters the elements of an observable sequence based on a predicate by incorporating the element's index.
3527
- *
3528
- * @example
3529
- * var res = source.where(function (value) { return value < 10; });
3530
- * var res = source.where(function (value, index) { return value < 10 || index < 10; });
3531
- * @param {Function} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element.
3532
- * @param {Any} [thisArg] Object to use as this when executing callback.
3533
- * @returns {Observable} An observable sequence that contains elements from the input sequence that satisfy the condition.
3534
- */
3535
- observableProto.where = observableProto.filter = function (predicate, thisArg) {
3536
- var source = this;
3537
- return new AnonymousObservable(function (observer) {
3538
- var count = 0;
3539
- return source.subscribe(function (value) {
3540
- var shouldRun;
3541
- try {
3542
- shouldRun = predicate.call(thisArg, value, count++, source);
3543
- } catch (e) {
3544
- observer.onError(e);
3545
- return;
3546
- }
3547
- shouldRun && observer.onNext(value);
3548
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
3549
- }, source);
3912
+ * Filters the elements of an observable sequence based on a predicate by incorporating the element's index.
3913
+ * @param {Function} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element.
3914
+ * @param {Any} [thisArg] Object to use as this when executing callback.
3915
+ * @returns {Observable} An observable sequence that contains elements from the input sequence that satisfy the condition.
3916
+ */
3917
+ observableProto.filter = observableProto.where = function (predicate, thisArg) {
3918
+ return this instanceof FilterObservable ? this.internalFilter(predicate, thisArg) :
3919
+ new FilterObservable(this, predicate, thisArg);
3550
3920
  };
3551
3921
 
3552
3922
  /**
@@ -3559,7 +3929,7 @@ if (!Array.prototype.forEach) {
3559
3929
  */
3560
3930
  Observable.fromCallback = function (func, context, selector) {
3561
3931
  return function () {
3562
- var args = slice.call(arguments, 0);
3932
+ for(var args = [], i = 0, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
3563
3933
 
3564
3934
  return new AnonymousObservable(function (observer) {
3565
3935
  function handler() {
@@ -3569,8 +3939,7 @@ if (!Array.prototype.forEach) {
3569
3939
  try {
3570
3940
  results = selector(results);
3571
3941
  } catch (err) {
3572
- observer.onError(err);
3573
- return;
3942
+ return observer.onError(err);
3574
3943
  }
3575
3944
 
3576
3945
  observer.onNext(results);
@@ -3600,7 +3969,7 @@ if (!Array.prototype.forEach) {
3600
3969
  */
3601
3970
  Observable.fromNodeCallback = function (func, context, selector) {
3602
3971
  return function () {
3603
- var args = slice.call(arguments, 0);
3972
+ for(var args = [], i = 0, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
3604
3973
 
3605
3974
  return new AnonymousObservable(function (observer) {
3606
3975
  function handler(err) {
@@ -3609,14 +3978,13 @@ if (!Array.prototype.forEach) {
3609
3978
  return;
3610
3979
  }
3611
3980
 
3612
- var results = slice.call(arguments, 1);
3981
+ for(var results = [], i = 1, len = arguments.length; i < len; i++) { results.push(arguments[i]); }
3613
3982
 
3614
3983
  if (selector) {
3615
3984
  try {
3616
3985
  results = selector(results);
3617
3986
  } catch (e) {
3618
- observer.onError(e);
3619
- return;
3987
+ return observer.onError(e);
3620
3988
  }
3621
3989
  observer.onNext(results);
3622
3990
  } else {
@@ -3734,19 +4102,6 @@ if (!Array.prototype.forEach) {
3734
4102
  */
3735
4103
  Rx.config.useNativeEvents = false;
3736
4104
 
3737
- // Check for Angular/jQuery/Zepto support
3738
- var jq =
3739
- !!root.angular && !!angular.element ? angular.element :
3740
- (!!root.jQuery ? root.jQuery : (
3741
- !!root.Zepto ? root.Zepto : null));
3742
-
3743
- // Check for ember
3744
- var ember = !!root.Ember && typeof root.Ember.addListener === 'function';
3745
-
3746
- // Check for Backbone.Marionette. Note if using AMD add Marionette as a dependency of rxjs
3747
- // for proper loading order!
3748
- var marionette = !!root.Backbone && !!root.Backbone.Marionette;
3749
-
3750
4105
  /**
3751
4106
  * Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList.
3752
4107
  *
@@ -3769,25 +4124,13 @@ if (!Array.prototype.forEach) {
3769
4124
 
3770
4125
  // Use only if non-native events are allowed
3771
4126
  if (!Rx.config.useNativeEvents) {
3772
- if (marionette) {
4127
+ // Handles jq, Angular.js, Zepto, Marionette, Ember.js
4128
+ if (typeof element.on === 'function' && typeof element.off === 'function') {
3773
4129
  return fromEventPattern(
3774
4130
  function (h) { element.on(eventName, h); },
3775
4131
  function (h) { element.off(eventName, h); },
3776
4132
  selector);
3777
4133
  }
3778
- if (ember) {
3779
- return fromEventPattern(
3780
- function (h) { Ember.addListener(element, eventName, h); },
3781
- function (h) { Ember.removeListener(element, eventName, h); },
3782
- selector);
3783
- }
3784
- if (jq) {
3785
- var $elem = jq(element);
3786
- return fromEventPattern(
3787
- function (h) { $elem.on(eventName, h); },
3788
- function (h) { $elem.off(eventName, h); },
3789
- selector);
3790
- }
3791
4134
  }
3792
4135
  return new AnonymousObservable(function (observer) {
3793
4136
  return createEventListener(
@@ -4062,7 +4405,7 @@ if (!Array.prototype.forEach) {
4062
4405
  return subscription;
4063
4406
  };
4064
4407
 
4065
- __super__.call(this, subject.subscribe.bind(subject));
4408
+ __super__.call(this, function (o) { return subject.subscribe(o); });
4066
4409
  }
4067
4410
 
4068
4411
  ConnectableObservable.prototype.refCount = function () {
@@ -4092,15 +4435,15 @@ if (!Array.prototype.forEach) {
4092
4435
 
4093
4436
  function observableTimerDateAndPeriod(dueTime, period, scheduler) {
4094
4437
  return new AnonymousObservable(function (observer) {
4095
- var count = 0, d = dueTime, p = normalizeTime(period);
4096
- return scheduler.scheduleRecursiveWithAbsolute(d, function (self) {
4438
+ var d = dueTime, p = normalizeTime(period);
4439
+ return scheduler.scheduleRecursiveWithAbsoluteAndState(0, d, function (count, self) {
4097
4440
  if (p > 0) {
4098
4441
  var now = scheduler.now();
4099
4442
  d = d + p;
4100
4443
  d <= now && (d = now + p);
4101
4444
  }
4102
- observer.onNext(count++);
4103
- self(d);
4445
+ observer.onNext(count);
4446
+ self(count + 1, d);
4104
4447
  });
4105
4448
  });
4106
4449
  }
@@ -4305,7 +4648,7 @@ if (!Array.prototype.forEach) {
4305
4648
  * @deprecated use #debounce or #throttleWithTimeout instead.
4306
4649
  */
4307
4650
  observableProto.throttle = function(dueTime, scheduler) {
4308
- deprecate('throttle', 'debounce or throttleWithTimeout');
4651
+ //deprecate('throttle', 'debounce or throttleWithTimeout');
4309
4652
  return this.debounce(dueTime, scheduler);
4310
4653
  };
4311
4654
 
@@ -4437,18 +4780,16 @@ if (!Array.prototype.forEach) {
4437
4780
  var duration = +windowDuration || 0;
4438
4781
  if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
4439
4782
  var source = this;
4440
- return new AnonymousObservable(function (observer) {
4783
+ return new AnonymousObservable(function (o) {
4441
4784
  var lastOnNext = 0;
4442
4785
  return source.subscribe(
4443
4786
  function (x) {
4444
4787
  var now = scheduler.now();
4445
4788
  if (lastOnNext === 0 || now - lastOnNext >= duration) {
4446
4789
  lastOnNext = now;
4447
- observer.onNext(x);
4790
+ o.onNext(x);
4448
4791
  }
4449
- },
4450
- observer.onError.bind(observer),
4451
- observer.onCompleted.bind(observer)
4792
+ },function (e) { o.onError(e); }, function () { o.onCompleted(); }
4452
4793
  );
4453
4794
  }, source);
4454
4795
  };
@@ -4512,7 +4853,7 @@ if (!Array.prototype.forEach) {
4512
4853
  };
4513
4854
 
4514
4855
  function combineLatestSource(source, subject, resultSelector) {
4515
- return new AnonymousObservable(function (observer) {
4856
+ return new AnonymousObservable(function (o) {
4516
4857
  var hasValue = [false, false],
4517
4858
  hasValueAll = false,
4518
4859
  isDone = false,
@@ -4525,20 +4866,20 @@ if (!Array.prototype.forEach) {
4525
4866
  hasValue[i] = true;
4526
4867
  if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
4527
4868
  if (err) {
4528
- observer.onError(err);
4869
+ o.onError(err);
4529
4870
  return;
4530
4871
  }
4531
4872
 
4532
4873
  try {
4533
4874
  res = resultSelector.apply(null, values);
4534
4875
  } catch (ex) {
4535
- observer.onError(ex);
4876
+ o.onError(ex);
4536
4877
  return;
4537
4878
  }
4538
- observer.onNext(res);
4879
+ o.onNext(res);
4539
4880
  }
4540
4881
  if (isDone && values[1]) {
4541
- observer.onCompleted();
4882
+ o.onCompleted();
4542
4883
  }
4543
4884
  }
4544
4885
 
@@ -4549,20 +4890,20 @@ if (!Array.prototype.forEach) {
4549
4890
  },
4550
4891
  function (e) {
4551
4892
  if (values[1]) {
4552
- observer.onError(e);
4893
+ o.onError(e);
4553
4894
  } else {
4554
4895
  err = e;
4555
4896
  }
4556
4897
  },
4557
4898
  function () {
4558
4899
  isDone = true;
4559
- values[1] && observer.onCompleted();
4900
+ values[1] && o.onCompleted();
4560
4901
  }),
4561
4902
  subject.subscribe(
4562
4903
  function (x) {
4563
4904
  next(x, 1);
4564
4905
  },
4565
- observer.onError.bind(observer),
4906
+ function (e) { o.onError(e); },
4566
4907
  function () {
4567
4908
  isDone = true;
4568
4909
  next(true, 1);
@@ -4575,7 +4916,7 @@ if (!Array.prototype.forEach) {
4575
4916
 
4576
4917
  inherits(PausableBufferedObservable, __super__);
4577
4918
 
4578
- function subscribe(observer) {
4919
+ function subscribe(o) {
4579
4920
  var q = [], previousShouldFire;
4580
4921
 
4581
4922
  var subscription =
@@ -4592,14 +4933,14 @@ if (!Array.prototype.forEach) {
4592
4933
  // change in shouldFire
4593
4934
  if (results.shouldFire) {
4594
4935
  while (q.length > 0) {
4595
- observer.onNext(q.shift());
4936
+ o.onNext(q.shift());
4596
4937
  }
4597
4938
  }
4598
4939
  } else {
4599
4940
  previousShouldFire = results.shouldFire;
4600
4941
  // new data
4601
4942
  if (results.shouldFire) {
4602
- observer.onNext(results.data);
4943
+ o.onNext(results.data);
4603
4944
  } else {
4604
4945
  q.push(results.data);
4605
4946
  }
@@ -4608,16 +4949,16 @@ if (!Array.prototype.forEach) {
4608
4949
  function (err) {
4609
4950
  // Empty buffer before sending error
4610
4951
  while (q.length > 0) {
4611
- observer.onNext(q.shift());
4952
+ o.onNext(q.shift());
4612
4953
  }
4613
- observer.onError(err);
4954
+ o.onError(err);
4614
4955
  },
4615
4956
  function () {
4616
4957
  // Empty buffer before sending completion
4617
4958
  while (q.length > 0) {
4618
- observer.onNext(q.shift());
4959
+ o.onNext(q.shift());
4619
4960
  }
4620
- observer.onCompleted();
4961
+ o.onCompleted();
4621
4962
  }
4622
4963
  );
4623
4964
  return subscription;
@@ -4840,31 +5181,29 @@ if (!Array.prototype.forEach) {
4840
5181
  disposableEmpty;
4841
5182
  }
4842
5183
 
5184
+ function setDisposable(s, state) {
5185
+ var ado = state[0], subscribe = state[1];
5186
+ try {
5187
+ ado.setDisposable(fixSubscriber(subscribe(ado)));
5188
+ } catch (e) {
5189
+ if (!ado.fail(e)) { throw e; }
5190
+ }
5191
+ }
5192
+
4843
5193
  function AnonymousObservable(subscribe, parent) {
4844
5194
  this.source = parent;
4845
- if (!(this instanceof AnonymousObservable)) {
4846
- return new AnonymousObservable(subscribe);
4847
- }
4848
5195
 
4849
5196
  function s(observer) {
4850
- var setDisposable = function () {
4851
- try {
4852
- autoDetachObserver.setDisposable(fixSubscriber(subscribe(autoDetachObserver)));
4853
- } catch (e) {
4854
- if (!autoDetachObserver.fail(e)) {
4855
- throw e;
4856
- }
4857
- }
4858
- };
4859
5197
 
4860
- var autoDetachObserver = new AutoDetachObserver(observer);
5198
+ var ado = new AutoDetachObserver(observer), state = [ado, subscribe];
5199
+
4861
5200
  if (currentThreadScheduler.scheduleRequired()) {
4862
- currentThreadScheduler.schedule(setDisposable);
5201
+ currentThreadScheduler.scheduleWithState(state, setDisposable);
4863
5202
  } else {
4864
- setDisposable();
5203
+ setDisposable(null, state);
4865
5204
  }
4866
5205
 
4867
- return autoDetachObserver;
5206
+ return ado;
4868
5207
  }
4869
5208
 
4870
5209
  __super__.call(this, s);
@@ -4891,7 +5230,7 @@ if (!Array.prototype.forEach) {
4891
5230
  this.observer.onNext(value);
4892
5231
  noError = true;
4893
5232
  } catch (e) {
4894
- throw e;
5233
+ return thrower(e);
4895
5234
  } finally {
4896
5235
  !noError && this.dispose();
4897
5236
  }
@@ -4901,7 +5240,7 @@ if (!Array.prototype.forEach) {
4901
5240
  try {
4902
5241
  this.observer.onError(err);
4903
5242
  } catch (e) {
4904
- throw e;
5243
+ return thrower(e);
4905
5244
  } finally {
4906
5245
  this.dispose();
4907
5246
  }
@@ -4911,7 +5250,7 @@ if (!Array.prototype.forEach) {
4911
5250
  try {
4912
5251
  this.observer.onCompleted();
4913
5252
  } catch (e) {
4914
- throw e;
5253
+ return thrower(e);
4915
5254
  } finally {
4916
5255
  this.dispose();
4917
5256
  }
@@ -4928,130 +5267,121 @@ if (!Array.prototype.forEach) {
4928
5267
  return AutoDetachObserver;
4929
5268
  }(AbstractObserver));
4930
5269
 
4931
- /** @private */
4932
- var InnerSubscription = function (subject, observer) {
4933
- this.subject = subject;
4934
- this.observer = observer;
4935
- };
5270
+ var InnerSubscription = function (subject, observer) {
5271
+ this.subject = subject;
5272
+ this.observer = observer;
5273
+ };
4936
5274
 
4937
- /**
4938
- * @private
4939
- * @memberOf InnerSubscription
4940
- */
4941
- InnerSubscription.prototype.dispose = function () {
4942
- if (!this.subject.isDisposed && this.observer !== null) {
4943
- var idx = this.subject.observers.indexOf(this.observer);
4944
- this.subject.observers.splice(idx, 1);
4945
- this.observer = null;
4946
- }
4947
- };
5275
+ InnerSubscription.prototype.dispose = function () {
5276
+ if (!this.subject.isDisposed && this.observer !== null) {
5277
+ var idx = this.subject.observers.indexOf(this.observer);
5278
+ this.subject.observers.splice(idx, 1);
5279
+ this.observer = null;
5280
+ }
5281
+ };
5282
+
5283
+ /**
5284
+ * Represents an object that is both an observable sequence as well as an observer.
5285
+ * Each notification is broadcasted to all subscribed observers.
5286
+ */
5287
+ var Subject = Rx.Subject = (function (__super__) {
5288
+ function subscribe(observer) {
5289
+ checkDisposed(this);
5290
+ if (!this.isStopped) {
5291
+ this.observers.push(observer);
5292
+ return new InnerSubscription(this, observer);
5293
+ }
5294
+ if (this.hasError) {
5295
+ observer.onError(this.error);
5296
+ return disposableEmpty;
5297
+ }
5298
+ observer.onCompleted();
5299
+ return disposableEmpty;
5300
+ }
5301
+
5302
+ inherits(Subject, __super__);
4948
5303
 
4949
5304
  /**
4950
- * Represents an object that is both an observable sequence as well as an observer.
4951
- * Each notification is broadcasted to all subscribed observers.
5305
+ * Creates a subject.
4952
5306
  */
4953
- var Subject = Rx.Subject = (function (_super) {
4954
- function subscribe(observer) {
4955
- checkDisposed.call(this);
4956
- if (!this.isStopped) {
4957
- this.observers.push(observer);
4958
- return new InnerSubscription(this, observer);
4959
- }
4960
- if (this.exception) {
4961
- observer.onError(this.exception);
4962
- return disposableEmpty;
4963
- }
4964
- observer.onCompleted();
4965
- return disposableEmpty;
4966
- }
5307
+ function Subject() {
5308
+ __super__.call(this, subscribe);
5309
+ this.isDisposed = false,
5310
+ this.isStopped = false,
5311
+ this.observers = [];
5312
+ this.hasError = false;
5313
+ }
5314
+
5315
+ addProperties(Subject.prototype, Observer.prototype, {
5316
+ /**
5317
+ * Indicates whether the subject has observers subscribed to it.
5318
+ * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
5319
+ */
5320
+ hasObservers: function () { return this.observers.length > 0; },
5321
+ /**
5322
+ * Notifies all subscribed observers about the end of the sequence.
5323
+ */
5324
+ onCompleted: function () {
5325
+ checkDisposed(this);
5326
+ if (!this.isStopped) {
5327
+ this.isStopped = true;
5328
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5329
+ os[i].onCompleted();
5330
+ }
4967
5331
 
4968
- inherits(Subject, _super);
4969
-
4970
- /**
4971
- * Creates a subject.
4972
- * @constructor
4973
- */
4974
- function Subject() {
4975
- _super.call(this, subscribe);
4976
- this.isDisposed = false,
4977
- this.isStopped = false,
4978
- this.observers = [];
5332
+ this.observers.length = 0;
4979
5333
  }
5334
+ },
5335
+ /**
5336
+ * Notifies all subscribed observers about the exception.
5337
+ * @param {Mixed} error The exception to send to all observers.
5338
+ */
5339
+ onError: function (error) {
5340
+ checkDisposed(this);
5341
+ if (!this.isStopped) {
5342
+ this.isStopped = true;
5343
+ this.error = error;
5344
+ this.hasError = true;
5345
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5346
+ os[i].onError(error);
5347
+ }
4980
5348
 
4981
- addProperties(Subject.prototype, Observer, {
4982
- /**
4983
- * Indicates whether the subject has observers subscribed to it.
4984
- * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
4985
- */
4986
- hasObservers: function () {
4987
- return this.observers.length > 0;
4988
- },
4989
- /**
4990
- * Notifies all subscribed observers about the end of the sequence.
4991
- */
4992
- onCompleted: function () {
4993
- checkDisposed.call(this);
4994
- if (!this.isStopped) {
4995
- var os = this.observers.slice(0);
4996
- this.isStopped = true;
4997
- for (var i = 0, len = os.length; i < len; i++) {
4998
- os[i].onCompleted();
4999
- }
5000
-
5001
- this.observers = [];
5002
- }
5003
- },
5004
- /**
5005
- * Notifies all subscribed observers about the exception.
5006
- * @param {Mixed} error The exception to send to all observers.
5007
- */
5008
- onError: function (exception) {
5009
- checkDisposed.call(this);
5010
- if (!this.isStopped) {
5011
- var os = this.observers.slice(0);
5012
- this.isStopped = true;
5013
- this.exception = exception;
5014
- for (var i = 0, len = os.length; i < len; i++) {
5015
- os[i].onError(exception);
5016
- }
5017
-
5018
- this.observers = [];
5019
- }
5020
- },
5021
- /**
5022
- * Notifies all subscribed observers about the arrival of the specified element in the sequence.
5023
- * @param {Mixed} value The value to send to all observers.
5024
- */
5025
- onNext: function (value) {
5026
- checkDisposed.call(this);
5027
- if (!this.isStopped) {
5028
- var os = this.observers.slice(0);
5029
- for (var i = 0, len = os.length; i < len; i++) {
5030
- os[i].onNext(value);
5031
- }
5032
- }
5033
- },
5034
- /**
5035
- * Unsubscribe all observers and release resources.
5036
- */
5037
- dispose: function () {
5038
- this.isDisposed = true;
5039
- this.observers = null;
5040
- }
5041
- });
5349
+ this.observers.length = 0;
5350
+ }
5351
+ },
5352
+ /**
5353
+ * Notifies all subscribed observers about the arrival of the specified element in the sequence.
5354
+ * @param {Mixed} value The value to send to all observers.
5355
+ */
5356
+ onNext: function (value) {
5357
+ checkDisposed(this);
5358
+ if (!this.isStopped) {
5359
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5360
+ os[i].onNext(value);
5361
+ }
5362
+ }
5363
+ },
5364
+ /**
5365
+ * Unsubscribe all observers and release resources.
5366
+ */
5367
+ dispose: function () {
5368
+ this.isDisposed = true;
5369
+ this.observers = null;
5370
+ }
5371
+ });
5042
5372
 
5043
- /**
5044
- * Creates a subject from the specified observer and observable.
5045
- * @param {Observer} observer The observer used to send messages to the subject.
5046
- * @param {Observable} observable The observable used to subscribe to messages sent from the subject.
5047
- * @returns {Subject} Subject implemented using the given observer and observable.
5048
- */
5049
- Subject.create = function (observer, observable) {
5050
- return new AnonymousSubject(observer, observable);
5051
- };
5373
+ /**
5374
+ * Creates a subject from the specified observer and observable.
5375
+ * @param {Observer} observer The observer used to send messages to the subject.
5376
+ * @param {Observable} observable The observable used to subscribe to messages sent from the subject.
5377
+ * @returns {Subject} Subject implemented using the given observer and observable.
5378
+ */
5379
+ Subject.create = function (observer, observable) {
5380
+ return new AnonymousSubject(observer, observable);
5381
+ };
5052
5382
 
5053
- return Subject;
5054
- }(Observable));
5383
+ return Subject;
5384
+ }(Observable));
5055
5385
 
5056
5386
  /**
5057
5387
  * Represents the result of an asynchronous operation.
@@ -5060,21 +5390,17 @@ if (!Array.prototype.forEach) {
5060
5390
  var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
5061
5391
 
5062
5392
  function subscribe(observer) {
5063
- checkDisposed.call(this);
5393
+ checkDisposed(this);
5064
5394
 
5065
5395
  if (!this.isStopped) {
5066
5396
  this.observers.push(observer);
5067
5397
  return new InnerSubscription(this, observer);
5068
5398
  }
5069
5399
 
5070
- var ex = this.exception,
5071
- hv = this.hasValue,
5072
- v = this.value;
5073
-
5074
- if (ex) {
5075
- observer.onError(ex);
5076
- } else if (hv) {
5077
- observer.onNext(v);
5400
+ if (this.hasError) {
5401
+ observer.onError(this.error);
5402
+ } else if (this.hasValue) {
5403
+ observer.onNext(this.value);
5078
5404
  observer.onCompleted();
5079
5405
  } else {
5080
5406
  observer.onCompleted();
@@ -5094,10 +5420,9 @@ if (!Array.prototype.forEach) {
5094
5420
 
5095
5421
  this.isDisposed = false;
5096
5422
  this.isStopped = false;
5097
- this.value = null;
5098
5423
  this.hasValue = false;
5099
5424
  this.observers = [];
5100
- this.exception = null;
5425
+ this.hasError = false;
5101
5426
  }
5102
5427
 
5103
5428
  addProperties(AsyncSubject.prototype, Observer, {
@@ -5106,34 +5431,32 @@ if (!Array.prototype.forEach) {
5106
5431
  * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
5107
5432
  */
5108
5433
  hasObservers: function () {
5109
- checkDisposed.call(this);
5434
+ checkDisposed(this);
5110
5435
  return this.observers.length > 0;
5111
5436
  },
5112
5437
  /**
5113
5438
  * Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
5114
5439
  */
5115
5440
  onCompleted: function () {
5116
- var o, i, len;
5117
- checkDisposed.call(this);
5441
+ var i, len;
5442
+ checkDisposed(this);
5118
5443
  if (!this.isStopped) {
5119
5444
  this.isStopped = true;
5120
- var os = this.observers.slice(0),
5121
- v = this.value,
5122
- hv = this.hasValue;
5123
-
5124
- if (hv) {
5125
- for (i = 0, len = os.length; i < len; i++) {
5126
- o = os[i];
5127
- o.onNext(v);
5445
+ var os = cloneArray(this.observers), len = os.length;
5446
+
5447
+ if (this.hasValue) {
5448
+ for (i = 0; i < len; i++) {
5449
+ var o = os[i];
5450
+ o.onNext(this.value);
5128
5451
  o.onCompleted();
5129
5452
  }
5130
5453
  } else {
5131
- for (i = 0, len = os.length; i < len; i++) {
5454
+ for (i = 0; i < len; i++) {
5132
5455
  os[i].onCompleted();
5133
5456
  }
5134
5457
  }
5135
5458
 
5136
- this.observers = [];
5459
+ this.observers.length = 0;
5137
5460
  }
5138
5461
  },
5139
5462
  /**
@@ -5141,17 +5464,17 @@ if (!Array.prototype.forEach) {
5141
5464
  * @param {Mixed} error The Error to send to all observers.
5142
5465
  */
5143
5466
  onError: function (error) {
5144
- checkDisposed.call(this);
5467
+ checkDisposed(this);
5145
5468
  if (!this.isStopped) {
5146
- var os = this.observers.slice(0);
5147
5469
  this.isStopped = true;
5148
- this.exception = error;
5470
+ this.hasError = true;
5471
+ this.error = error;
5149
5472
 
5150
- for (var i = 0, len = os.length; i < len; i++) {
5473
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5151
5474
  os[i].onError(error);
5152
5475
  }
5153
5476
 
5154
- this.observers = [];
5477
+ this.observers.length = 0;
5155
5478
  }
5156
5479
  },
5157
5480
  /**
@@ -5159,7 +5482,7 @@ if (!Array.prototype.forEach) {
5159
5482
  * @param {Mixed} value The value to store in the subject.
5160
5483
  */
5161
5484
  onNext: function (value) {
5162
- checkDisposed.call(this);
5485
+ checkDisposed(this);
5163
5486
  if (this.isStopped) { return; }
5164
5487
  this.value = value;
5165
5488
  this.hasValue = true;
@@ -5181,18 +5504,22 @@ if (!Array.prototype.forEach) {
5181
5504
  var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
5182
5505
  inherits(AnonymousSubject, __super__);
5183
5506
 
5507
+ function subscribe(observer) {
5508
+ return this.observable.subscribe(observer);
5509
+ }
5510
+
5184
5511
  function AnonymousSubject(observer, observable) {
5185
5512
  this.observer = observer;
5186
5513
  this.observable = observable;
5187
- __super__.call(this, this.observable.subscribe.bind(this.observable));
5514
+ __super__.call(this, subscribe);
5188
5515
  }
5189
5516
 
5190
- addProperties(AnonymousSubject.prototype, Observer, {
5517
+ addProperties(AnonymousSubject.prototype, Observer.prototype, {
5191
5518
  onCompleted: function () {
5192
5519
  this.observer.onCompleted();
5193
5520
  },
5194
- onError: function (exception) {
5195
- this.observer.onError(exception);
5521
+ onError: function (error) {
5522
+ this.observer.onError(error);
5196
5523
  },
5197
5524
  onNext: function (value) {
5198
5525
  this.observer.onNext(value);
@@ -5208,15 +5535,14 @@ if (!Array.prototype.forEach) {
5208
5535
  */
5209
5536
  var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
5210
5537
  function subscribe(observer) {
5211
- checkDisposed.call(this);
5538
+ checkDisposed(this);
5212
5539
  if (!this.isStopped) {
5213
5540
  this.observers.push(observer);
5214
5541
  observer.onNext(this.value);
5215
5542
  return new InnerSubscription(this, observer);
5216
5543
  }
5217
- var ex = this.exception;
5218
- if (ex) {
5219
- observer.onError(ex);
5544
+ if (this.hasError) {
5545
+ observer.onError(this.error);
5220
5546
  } else {
5221
5547
  observer.onCompleted();
5222
5548
  }
@@ -5226,7 +5552,6 @@ if (!Array.prototype.forEach) {
5226
5552
  inherits(BehaviorSubject, __super__);
5227
5553
 
5228
5554
  /**
5229
- * @constructor
5230
5555
  * Initializes a new instance of the BehaviorSubject class which creates a subject that caches its last value and starts with the specified value.
5231
5556
  * @param {Mixed} value Initial value sent to observers when no other value has been received by the subject yet.
5232
5557
  */
@@ -5236,7 +5561,7 @@ if (!Array.prototype.forEach) {
5236
5561
  this.observers = [],
5237
5562
  this.isDisposed = false,
5238
5563
  this.isStopped = false,
5239
- this.exception = null;
5564
+ this.hasError = false;
5240
5565
  }
5241
5566
 
5242
5567
  addProperties(BehaviorSubject.prototype, Observer, {
@@ -5244,47 +5569,46 @@ if (!Array.prototype.forEach) {
5244
5569
  * Indicates whether the subject has observers subscribed to it.
5245
5570
  * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
5246
5571
  */
5247
- hasObservers: function () {
5248
- return this.observers.length > 0;
5249
- },
5572
+ hasObservers: function () { return this.observers.length > 0; },
5250
5573
  /**
5251
5574
  * Notifies all subscribed observers about the end of the sequence.
5252
5575
  */
5253
5576
  onCompleted: function () {
5254
- checkDisposed.call(this);
5577
+ checkDisposed(this);
5255
5578
  if (this.isStopped) { return; }
5256
5579
  this.isStopped = true;
5257
- for (var i = 0, os = this.observers.slice(0), len = os.length; i < len; i++) {
5580
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5258
5581
  os[i].onCompleted();
5259
5582
  }
5260
5583
 
5261
- this.observers = [];
5584
+ this.observers.length = 0;
5262
5585
  },
5263
5586
  /**
5264
5587
  * Notifies all subscribed observers about the exception.
5265
5588
  * @param {Mixed} error The exception to send to all observers.
5266
5589
  */
5267
5590
  onError: function (error) {
5268
- checkDisposed.call(this);
5591
+ checkDisposed(this);
5269
5592
  if (this.isStopped) { return; }
5270
5593
  this.isStopped = true;
5271
- this.exception = error;
5594
+ this.hasError = true;
5595
+ this.error = error;
5272
5596
 
5273
- for (var i = 0, os = this.observers.slice(0), len = os.length; i < len; i++) {
5597
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5274
5598
  os[i].onError(error);
5275
5599
  }
5276
5600
 
5277
- this.observers = [];
5601
+ this.observers.length = 0;
5278
5602
  },
5279
5603
  /**
5280
5604
  * Notifies all subscribed observers about the arrival of the specified element in the sequence.
5281
5605
  * @param {Mixed} value The value to send to all observers.
5282
5606
  */
5283
5607
  onNext: function (value) {
5284
- checkDisposed.call(this);
5608
+ checkDisposed(this);
5285
5609
  if (this.isStopped) { return; }
5286
5610
  this.value = value;
5287
- for (var i = 0, os = this.observers.slice(0), len = os.length; i < len; i++) {
5611
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5288
5612
  os[i].onNext(value);
5289
5613
  }
5290
5614
  },
@@ -5318,7 +5642,7 @@ if (!Array.prototype.forEach) {
5318
5642
  function subscribe(observer) {
5319
5643
  var so = new ScheduledObserver(this.scheduler, observer),
5320
5644
  subscription = createRemovableDisposable(this, so);
5321
- checkDisposed.call(this);
5645
+ checkDisposed(this);
5322
5646
  this._trim(this.scheduler.now());
5323
5647
  this.observers.push(so);
5324
5648
 
@@ -5357,7 +5681,7 @@ if (!Array.prototype.forEach) {
5357
5681
  __super__.call(this, subscribe);
5358
5682
  }
5359
5683
 
5360
- addProperties(ReplaySubject.prototype, Observer, {
5684
+ addProperties(ReplaySubject.prototype, Observer.prototype, {
5361
5685
  /**
5362
5686
  * Indicates whether the subject has observers subscribed to it.
5363
5687
  * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
@@ -5378,15 +5702,14 @@ if (!Array.prototype.forEach) {
5378
5702
  * @param {Mixed} value The value to send to all observers.
5379
5703
  */
5380
5704
  onNext: function (value) {
5381
- checkDisposed.call(this);
5705
+ checkDisposed(this);
5382
5706
  if (this.isStopped) { return; }
5383
5707
  var now = this.scheduler.now();
5384
5708
  this.q.push({ interval: now, value: value });
5385
5709
  this._trim(now);
5386
5710
 
5387
- var o = this.observers.slice(0);
5388
- for (var i = 0, len = o.length; i < len; i++) {
5389
- var observer = o[i];
5711
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5712
+ var observer = os[i];
5390
5713
  observer.onNext(value);
5391
5714
  observer.ensureActive();
5392
5715
  }
@@ -5396,37 +5719,35 @@ if (!Array.prototype.forEach) {
5396
5719
  * @param {Mixed} error The exception to send to all observers.
5397
5720
  */
5398
5721
  onError: function (error) {
5399
- checkDisposed.call(this);
5722
+ checkDisposed(this);
5400
5723
  if (this.isStopped) { return; }
5401
5724
  this.isStopped = true;
5402
5725
  this.error = error;
5403
5726
  this.hasError = true;
5404
5727
  var now = this.scheduler.now();
5405
5728
  this._trim(now);
5406
- var o = this.observers.slice(0);
5407
- for (var i = 0, len = o.length; i < len; i++) {
5408
- var observer = o[i];
5729
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5730
+ var observer = os[i];
5409
5731
  observer.onError(error);
5410
5732
  observer.ensureActive();
5411
5733
  }
5412
- this.observers = [];
5734
+ this.observers.length = 0;
5413
5735
  },
5414
5736
  /**
5415
5737
  * Notifies all subscribed observers about the end of the sequence.
5416
5738
  */
5417
5739
  onCompleted: function () {
5418
- checkDisposed.call(this);
5740
+ checkDisposed(this);
5419
5741
  if (this.isStopped) { return; }
5420
5742
  this.isStopped = true;
5421
5743
  var now = this.scheduler.now();
5422
5744
  this._trim(now);
5423
- var o = this.observers.slice(0);
5424
- for (var i = 0, len = o.length; i < len; i++) {
5425
- var observer = o[i];
5745
+ for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
5746
+ var observer = os[i];
5426
5747
  observer.onCompleted();
5427
5748
  observer.ensureActive();
5428
5749
  }
5429
- this.observers = [];
5750
+ this.observers.length = 0;
5430
5751
  },
5431
5752
  /**
5432
5753
  * Unsubscribe all observers and release resources.
@@ -5440,23 +5761,46 @@ if (!Array.prototype.forEach) {
5440
5761
  return ReplaySubject;
5441
5762
  }(Observable));
5442
5763
 
5443
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
5444
- root.Rx = Rx;
5764
+ /**
5765
+ * Used to pause and resume streams.
5766
+ */
5767
+ Rx.Pauser = (function (__super__) {
5768
+ inherits(Pauser, __super__);
5445
5769
 
5446
- define(function() {
5447
- return Rx;
5448
- });
5449
- } else if (freeExports && freeModule) {
5450
- // in Node.js or RingoJS
5451
- if (moduleExports) {
5452
- (freeModule.exports = Rx).Rx = Rx;
5453
- } else {
5454
- freeExports.Rx = Rx;
5455
- }
5770
+ function Pauser() {
5771
+ __super__.call(this);
5772
+ }
5773
+
5774
+ /**
5775
+ * Pauses the underlying sequence.
5776
+ */
5777
+ Pauser.prototype.pause = function () { this.onNext(false); };
5778
+
5779
+ /**
5780
+ * Resumes the underlying sequence.
5781
+ */
5782
+ Pauser.prototype.resume = function () { this.onNext(true); };
5783
+
5784
+ return Pauser;
5785
+ }(Subject));
5786
+
5787
+ if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
5788
+ root.Rx = Rx;
5789
+
5790
+ define(function() {
5791
+ return Rx;
5792
+ });
5793
+ } else if (freeExports && freeModule) {
5794
+ // in Node.js or RingoJS
5795
+ if (moduleExports) {
5796
+ (freeModule.exports = Rx).Rx = Rx;
5456
5797
  } else {
5457
- // in a browser or Rhino
5458
- root.Rx = Rx;
5798
+ freeExports.Rx = Rx;
5459
5799
  }
5800
+ } else {
5801
+ // in a browser or Rhino
5802
+ root.Rx = Rx;
5803
+ }
5460
5804
 
5461
5805
  // All code before this point will be filtered from stack traces.
5462
5806
  var rEndingLine = captureLine();