rxjs-rails 2.3.22 → 2.3.25

Sign up to get free protection for your applications and to get access to all the features.
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();