rxjs-rails 2.2.27 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +0 -3
  3. data/lib/rxjs/rails/version.rb +1 -1
  4. data/vendor/assets/javascripts/rx.aggregates.min.js +1 -1
  5. data/vendor/assets/javascripts/rx.all.compat.js +1545 -1441
  6. data/vendor/assets/javascripts/rx.all.compat.min.js +3 -3
  7. data/vendor/assets/javascripts/rx.all.js +1545 -1441
  8. data/vendor/assets/javascripts/rx.all.min.js +3 -3
  9. data/vendor/assets/javascripts/rx.async.compat.js +149 -152
  10. data/vendor/assets/javascripts/rx.async.compat.min.js +1 -1
  11. data/vendor/assets/javascripts/rx.async.js +140 -143
  12. data/vendor/assets/javascripts/rx.async.min.js +1 -1
  13. data/vendor/assets/javascripts/rx.backpressure.min.js +1 -1
  14. data/vendor/assets/javascripts/rx.binding.js +18 -18
  15. data/vendor/assets/javascripts/rx.binding.min.js +1 -1
  16. data/vendor/assets/javascripts/rx.coincidence.min.js +1 -1
  17. data/vendor/assets/javascripts/rx.compat.js +490 -339
  18. data/vendor/assets/javascripts/rx.compat.min.js +2 -2
  19. data/vendor/assets/javascripts/rx.core.compat.js +109 -141
  20. data/vendor/assets/javascripts/rx.core.compat.min.js +1 -1
  21. data/vendor/assets/javascripts/rx.core.js +109 -141
  22. data/vendor/assets/javascripts/rx.core.min.js +1 -1
  23. data/vendor/assets/javascripts/rx.experimental.js +129 -136
  24. data/vendor/assets/javascripts/rx.experimental.min.js +1 -1
  25. data/vendor/assets/javascripts/rx.joinpatterns.js +59 -59
  26. data/vendor/assets/javascripts/rx.joinpatterns.min.js +1 -1
  27. data/vendor/assets/javascripts/rx.js +490 -339
  28. data/vendor/assets/javascripts/rx.lite.compat.js +1099 -954
  29. data/vendor/assets/javascripts/rx.lite.compat.min.js +2 -2
  30. data/vendor/assets/javascripts/rx.lite.extras.min.js +1 -1
  31. data/vendor/assets/javascripts/rx.lite.js +1099 -954
  32. data/vendor/assets/javascripts/rx.lite.min.js +2 -2
  33. data/vendor/assets/javascripts/rx.min.js +2 -2
  34. data/vendor/assets/javascripts/rx.testing.min.js +1 -1
  35. data/vendor/assets/javascripts/rx.time.js +715 -747
  36. data/vendor/assets/javascripts/rx.time.min.js +1 -1
  37. data/vendor/assets/javascripts/rx.virtualtime.min.js +1 -1
  38. metadata +11 -10
@@ -31,6 +31,8 @@
31
31
 
32
32
  // Defaults
33
33
  var noop = Rx.helpers.noop = function () { },
34
+ notDefined = Rx.helpers.notDefined = function (x) { return typeof x === 'undefined'; },
35
+ isScheduler = Rx.helpers.isScheduler = function (x) { return x instanceof Rx.Scheduler; },
34
36
  identity = Rx.helpers.identity = function (x) { return x; },
35
37
  pluck = Rx.helpers.pluck = function (property) { return function (x) { return x[property]; }; },
36
38
  just = Rx.helpers.just = function (value) { return function () { return value; }; },
@@ -50,14 +52,13 @@
50
52
  function checkDisposed() { if (this.isDisposed) { throw new Error(objectDisposed); } }
51
53
 
52
54
  // Shim in iterator support
53
- var $iterator$ = (typeof Symbol === 'object' && Symbol.iterator) ||
55
+ var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
54
56
  '_es6shim_iterator_';
55
- // Firefox ships a partial implementation using the name @@iterator.
56
- // https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14
57
- // So use that name if we detect it.
57
+ // Bug for mozilla version
58
58
  if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
59
59
  $iterator$ = '@@iterator';
60
60
  }
61
+
61
62
  var doneEnumerator = { done: true, value: undefined };
62
63
 
63
64
  /** `Object#toString` result shortcuts */
@@ -1401,140 +1402,111 @@
1401
1402
  return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);
1402
1403
  })();
1403
1404
 
1404
- /**
1405
- * Represents a notification to an observer.
1406
- */
1407
- var Notification = Rx.Notification = (function () {
1408
- function Notification(kind, hasValue) {
1409
- this.hasValue = hasValue == null ? false : hasValue;
1410
- this.kind = kind;
1411
- }
1412
-
1413
- var NotificationPrototype = Notification.prototype;
1414
-
1415
- /**
1416
- * Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
1417
- *
1418
- * @memberOf Notification
1419
- * @param {Any} observerOrOnNext Delegate to invoke for an OnNext notification or Observer to invoke the notification on..
1420
- * @param {Function} onError Delegate to invoke for an OnError notification.
1421
- * @param {Function} onCompleted Delegate to invoke for an OnCompleted notification.
1422
- * @returns {Any} Result produced by the observation.
1423
- */
1424
- NotificationPrototype.accept = function (observerOrOnNext, onError, onCompleted) {
1425
- if (arguments.length === 1 && typeof observerOrOnNext === 'object') {
1426
- return this._acceptObservable(observerOrOnNext);
1427
- }
1428
- return this._accept(observerOrOnNext, onError, onCompleted);
1429
- };
1430
-
1431
- /**
1432
- * Returns an observable sequence with a single notification.
1433
- *
1434
- * @memberOf Notification
1435
- * @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
1436
- * @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
1437
- */
1438
- NotificationPrototype.toObservable = function (scheduler) {
1439
- var notification = this;
1440
- scheduler || (scheduler = immediateScheduler);
1441
- return new AnonymousObservable(function (observer) {
1442
- return scheduler.schedule(function () {
1443
- notification._acceptObservable(observer);
1444
- if (notification.kind === 'N') {
1445
- observer.onCompleted();
1446
- }
1447
- });
1448
- });
1449
- };
1450
-
1451
- return Notification;
1452
- })();
1405
+ /**
1406
+ * Represents a notification to an observer.
1407
+ */
1408
+ var Notification = Rx.Notification = (function () {
1409
+ function Notification(kind, hasValue) {
1410
+ this.hasValue = hasValue == null ? false : hasValue;
1411
+ this.kind = kind;
1412
+ }
1453
1413
 
1454
1414
  /**
1455
- * Creates an object that represents an OnNext notification to an observer.
1456
- * @param {Any} value The value contained in the notification.
1457
- * @returns {Notification} The OnNext notification containing the value.
1415
+ * Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
1416
+ *
1417
+ * @memberOf Notification
1418
+ * @param {Any} observerOrOnNext Delegate to invoke for an OnNext notification or Observer to invoke the notification on..
1419
+ * @param {Function} onError Delegate to invoke for an OnError notification.
1420
+ * @param {Function} onCompleted Delegate to invoke for an OnCompleted notification.
1421
+ * @returns {Any} Result produced by the observation.
1458
1422
  */
1459
- var notificationCreateOnNext = Notification.createOnNext = (function () {
1460
-
1461
- function _accept (onNext) {
1462
- return onNext(this.value);
1463
- }
1464
-
1465
- function _acceptObservable(observer) {
1466
- return observer.onNext(this.value);
1467
- }
1468
-
1469
- function toString () {
1470
- return 'OnNext(' + this.value + ')';
1471
- }
1472
-
1473
- return function (value) {
1474
- var notification = new Notification('N', true);
1475
- notification.value = value;
1476
- notification._accept = _accept;
1477
- notification._acceptObservable = _acceptObservable;
1478
- notification.toString = toString;
1479
- return notification;
1480
- };
1481
- }());
1423
+ Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
1424
+ return observerOrOnNext && typeof observerOrOnNext === 'object' ?
1425
+ this._acceptObservable(observerOrOnNext) :
1426
+ this._accept(observerOrOnNext, onError, onCompleted);
1427
+ };
1482
1428
 
1483
1429
  /**
1484
- * Creates an object that represents an OnError notification to an observer.
1485
- * @param {Any} error The exception contained in the notification.
1486
- * @returns {Notification} The OnError notification containing the exception.
1430
+ * Returns an observable sequence with a single notification.
1431
+ *
1432
+ * @memberOf Notifications
1433
+ * @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
1434
+ * @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
1487
1435
  */
1488
- var notificationCreateOnError = Notification.createOnError = (function () {
1489
-
1490
- function _accept (onNext, onError) {
1491
- return onError(this.exception);
1492
- }
1493
-
1494
- function _acceptObservable(observer) {
1495
- return observer.onError(this.exception);
1496
- }
1497
-
1498
- function toString () {
1499
- return 'OnError(' + this.exception + ')';
1500
- }
1436
+ Notification.prototype.toObservable = function (scheduler) {
1437
+ var notification = this;
1438
+ isScheduler(scheduler) || (scheduler = immediateScheduler);
1439
+ return new AnonymousObservable(function (observer) {
1440
+ return scheduler.schedule(function () {
1441
+ notification._acceptObservable(observer);
1442
+ notification.kind === 'N' && observer.onCompleted();
1443
+ });
1444
+ });
1445
+ };
1501
1446
 
1502
- return function (exception) {
1503
- var notification = new Notification('E');
1504
- notification.exception = exception;
1505
- notification._accept = _accept;
1506
- notification._acceptObservable = _acceptObservable;
1507
- notification.toString = toString;
1508
- return notification;
1509
- };
1510
- }());
1447
+ return Notification;
1448
+ })();
1511
1449
 
1512
- /**
1513
- * Creates an object that represents an OnCompleted notification to an observer.
1514
- * @returns {Notification} The OnCompleted notification.
1515
- */
1516
- var notificationCreateOnCompleted = Notification.createOnCompleted = (function () {
1450
+ /**
1451
+ * Creates an object that represents an OnNext notification to an observer.
1452
+ * @param {Any} value The value contained in the notification.
1453
+ * @returns {Notification} The OnNext notification containing the value.
1454
+ */
1455
+ var notificationCreateOnNext = Notification.createOnNext = (function () {
1456
+
1457
+ function _accept (onNext) { return onNext(this.value); }
1458
+ function _acceptObservable(observer) { return observer.onNext(this.value); }
1459
+ function toString () { return 'OnNext(' + this.value + ')'; }
1460
+
1461
+ return function (value) {
1462
+ var notification = new Notification('N', true);
1463
+ notification.value = value;
1464
+ notification._accept = _accept;
1465
+ notification._acceptObservable = _acceptObservable;
1466
+ notification.toString = toString;
1467
+ return notification;
1468
+ };
1469
+ }());
1517
1470
 
1518
- function _accept (onNext, onError, onCompleted) {
1519
- return onCompleted();
1520
- }
1471
+ /**
1472
+ * Creates an object that represents an OnError notification to an observer.
1473
+ * @param {Any} error The exception contained in the notification.
1474
+ * @returns {Notification} The OnError notification containing the exception.
1475
+ */
1476
+ var notificationCreateOnError = Notification.createOnError = (function () {
1477
+
1478
+ function _accept (onNext, onError) { return onError(this.exception); }
1479
+ function _acceptObservable(observer) { return observer.onError(this.exception); }
1480
+ function toString () { return 'OnError(' + this.exception + ')'; }
1481
+
1482
+ return function (exception) {
1483
+ var notification = new Notification('E');
1484
+ notification.exception = exception;
1485
+ notification._accept = _accept;
1486
+ notification._acceptObservable = _acceptObservable;
1487
+ notification.toString = toString;
1488
+ return notification;
1489
+ };
1490
+ }());
1521
1491
 
1522
- function _acceptObservable(observer) {
1523
- return observer.onCompleted();
1524
- }
1492
+ /**
1493
+ * Creates an object that represents an OnCompleted notification to an observer.
1494
+ * @returns {Notification} The OnCompleted notification.
1495
+ */
1496
+ var notificationCreateOnCompleted = Notification.createOnCompleted = (function () {
1525
1497
 
1526
- function toString () {
1527
- return 'OnCompleted()';
1528
- }
1498
+ function _accept (onNext, onError, onCompleted) { return onCompleted(); }
1499
+ function _acceptObservable(observer) { return observer.onCompleted(); }
1500
+ function toString () { return 'OnCompleted()'; }
1529
1501
 
1530
- return function () {
1531
- var notification = new Notification('C');
1532
- notification._accept = _accept;
1533
- notification._acceptObservable = _acceptObservable;
1534
- notification.toString = toString;
1535
- return notification;
1536
- };
1537
- }());
1502
+ return function () {
1503
+ var notification = new Notification('C');
1504
+ notification._accept = _accept;
1505
+ notification._acceptObservable = _acceptObservable;
1506
+ notification.toString = toString;
1507
+ return notification;
1508
+ };
1509
+ }());
1538
1510
 
1539
1511
  var Enumerator = Rx.internals.Enumerator = function (next) {
1540
1512
  this._next = next;
@@ -2021,130 +1993,180 @@
2021
1993
  });
2022
1994
  };
2023
1995
 
2024
- /**
2025
- * Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
2026
- *
2027
- * @example
2028
- * var res = Rx.Observable.empty();
2029
- * var res = Rx.Observable.empty(Rx.Scheduler.timeout);
2030
- * @param {Scheduler} [scheduler] Scheduler to send the termination call on.
2031
- * @returns {Observable} An observable sequence with no elements.
2032
- */
2033
- var observableEmpty = Observable.empty = function (scheduler) {
2034
- scheduler || (scheduler = immediateScheduler);
2035
- return new AnonymousObservable(function (observer) {
2036
- return scheduler.schedule(function () {
2037
- observer.onCompleted();
2038
- });
2039
- });
2040
- };
1996
+ /**
1997
+ * Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
1998
+ *
1999
+ * @example
2000
+ * var res = Rx.Observable.empty();
2001
+ * var res = Rx.Observable.empty(Rx.Scheduler.timeout);
2002
+ * @param {Scheduler} [scheduler] Scheduler to send the termination call on.
2003
+ * @returns {Observable} An observable sequence with no elements.
2004
+ */
2005
+ var observableEmpty = Observable.empty = function (scheduler) {
2006
+ isScheduler(scheduler) || (scheduler = immediateScheduler);
2007
+ return new AnonymousObservable(function (observer) {
2008
+ return scheduler.schedule(function () {
2009
+ observer.onCompleted();
2010
+ });
2011
+ });
2012
+ };
2041
2013
 
2042
- /**
2043
- * Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
2044
- *
2045
- * @example
2046
- * var res = Rx.Observable.fromArray([1,2,3]);
2047
- * var res = Rx.Observable.fromArray([1,2,3], Rx.Scheduler.timeout);
2048
- * @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
2049
- * @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
2050
- */
2051
- var observableFromArray = Observable.fromArray = function (array, scheduler) {
2052
- scheduler || (scheduler = currentThreadScheduler);
2053
- return new AnonymousObservable(function (observer) {
2054
- var count = 0;
2055
- return scheduler.scheduleRecursive(function (self) {
2056
- if (count < array.length) {
2057
- observer.onNext(array[count++]);
2058
- self();
2059
- } else {
2060
- observer.onCompleted();
2061
- }
2062
- });
2063
- });
2064
- };
2014
+ var maxSafeInteger = Math.pow(2, 53) - 1;
2015
+
2016
+ function numberIsFinite(value) {
2017
+ return typeof value === 'number' && root.isFinite(value);
2018
+ }
2019
+
2020
+ function isNan(n) {
2021
+ return n !== n;
2022
+ }
2023
+
2024
+ function isIterable(o) {
2025
+ return o[$iterator$] !== undefined;
2026
+ }
2027
+
2028
+ function sign(value) {
2029
+ var number = +value;
2030
+ if (number === 0) { return number; }
2031
+ if (isNaN(number)) { return number; }
2032
+ return number < 0 ? -1 : 1;
2033
+ }
2034
+
2035
+ function toLength(o) {
2036
+ var len = +o.length;
2037
+ if (isNaN(len)) { return 0; }
2038
+ if (len === 0 || !numberIsFinite(len)) { return len; }
2039
+ len = sign(len) * Math.floor(Math.abs(len));
2040
+ if (len <= 0) { return 0; }
2041
+ if (len > maxSafeInteger) { return maxSafeInteger; }
2042
+ return len;
2043
+ }
2044
+
2045
+ function isCallable(f) {
2046
+ return Object.prototype.toString.call(f) === '[object Function]' && typeof f === 'function';
2047
+ }
2048
+
2049
+ /**
2050
+ * This method creates a new Observable sequence from an array-like or iterable object.
2051
+ * @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
2052
+ * @param {Function} [mapFn] Map function to call on every element of the array.
2053
+ * @param {Any} [thisArg] The context to use calling the mapFn if provided.
2054
+ * @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
2055
+ */
2056
+ Observable.from = function (iterable, mapFn, thisArg, scheduler) {
2057
+ if (iterable == null) {
2058
+ throw new Error('iterable cannot be null.')
2059
+ }
2060
+ if (mapFn && !isCallable(mapFn)) {
2061
+ throw new Error('mapFn when provided must be a function');
2062
+ }
2063
+ isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2064
+ return new AnonymousObservable(function (observer) {
2065
+ var list = Object(iterable),
2066
+ objIsIterable = isIterable(list),
2067
+ len = objIsIterable ? 0 : toLength(list),
2068
+ it = objIsIterable ? list[$iterator$]() : null,
2069
+ i = 0;
2070
+ return scheduler.scheduleRecursive(function (self) {
2071
+ if (i < len || objIsIterable) {
2072
+ var result;
2073
+ if (objIsIterable) {
2074
+ var next = it.next();
2075
+ if (next.done) {
2076
+ observer.onCompleted();
2077
+ return;
2078
+ }
2079
+
2080
+ result = next.value;
2081
+ } else {
2082
+ result = list[i];
2083
+ }
2084
+
2085
+ if (mapFn && isCallable(mapFn)) {
2086
+ try {
2087
+ result = thisArg ? mapFn.call(thisArg, result, i) : mapFn(result, i);
2088
+ } catch (e) {
2089
+ observer.onError(e);
2090
+ return;
2091
+ }
2092
+ }
2065
2093
 
2094
+ observer.onNext(result);
2095
+ i++;
2096
+ self();
2097
+ } else {
2098
+ observer.onCompleted();
2099
+ }
2100
+ });
2101
+ });
2102
+ };
2066
2103
  /**
2067
- * Converts an iterable into an Observable sequence
2104
+ * Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
2068
2105
  *
2069
2106
  * @example
2070
- * var res = Rx.Observable.fromIterable(new Map());
2071
- * var res = Rx.Observable.fromIterable(new Set(), Rx.Scheduler.timeout);
2107
+ * var res = Rx.Observable.fromArray([1,2,3]);
2108
+ * var res = Rx.Observable.fromArray([1,2,3], Rx.Scheduler.timeout);
2072
2109
  * @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
2073
- * @returns {Observable} The observable sequence whose elements are pulled from the given generator sequence.
2110
+ * @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
2074
2111
  */
2075
- Observable.fromIterable = function (iterable, scheduler) {
2076
- scheduler || (scheduler = currentThreadScheduler);
2112
+ var observableFromArray = Observable.fromArray = function (array, scheduler) {
2113
+ isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2077
2114
  return new AnonymousObservable(function (observer) {
2078
- var iterator;
2079
- try {
2080
- iterator = iterable[$iterator$]();
2081
- } catch (e) {
2082
- observer.onError(e);
2083
- return;
2084
- }
2115
+ var count = 0, len = array.length;
2116
+ return scheduler.scheduleRecursive(function (self) {
2117
+ if (count < len) {
2118
+ observer.onNext(array[count++]);
2119
+ self();
2120
+ } else {
2121
+ observer.onCompleted();
2122
+ }
2123
+ });
2124
+ });
2125
+ };
2085
2126
 
2127
+ /**
2128
+ * Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
2129
+ *
2130
+ * @example
2131
+ * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
2132
+ * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
2133
+ * @param {Mixed} initialState Initial state.
2134
+ * @param {Function} condition Condition to terminate generation (upon returning false).
2135
+ * @param {Function} iterate Iteration step function.
2136
+ * @param {Function} resultSelector Selector function for results produced in the sequence.
2137
+ * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
2138
+ * @returns {Observable} The generated sequence.
2139
+ */
2140
+ Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
2141
+ isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2142
+ return new AnonymousObservable(function (observer) {
2143
+ var first = true, state = initialState;
2086
2144
  return scheduler.scheduleRecursive(function (self) {
2087
- var next;
2145
+ var hasResult, result;
2088
2146
  try {
2089
- next = iterator.next();
2090
- } catch (err) {
2091
- observer.onError(err);
2147
+ if (first) {
2148
+ first = false;
2149
+ } else {
2150
+ state = iterate(state);
2151
+ }
2152
+ hasResult = condition(state);
2153
+ if (hasResult) {
2154
+ result = resultSelector(state);
2155
+ }
2156
+ } catch (exception) {
2157
+ observer.onError(exception);
2092
2158
  return;
2093
2159
  }
2094
-
2095
- if (next.done) {
2096
- observer.onCompleted();
2097
- } else {
2098
- observer.onNext(next.value);
2160
+ if (hasResult) {
2161
+ observer.onNext(result);
2099
2162
  self();
2163
+ } else {
2164
+ observer.onCompleted();
2100
2165
  }
2101
2166
  });
2102
2167
  });
2103
2168
  };
2104
2169
 
2105
- /**
2106
- * Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
2107
- *
2108
- * @example
2109
- * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
2110
- * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
2111
- * @param {Mixed} initialState Initial state.
2112
- * @param {Function} condition Condition to terminate generation (upon returning false).
2113
- * @param {Function} iterate Iteration step function.
2114
- * @param {Function} resultSelector Selector function for results produced in the sequence.
2115
- * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
2116
- * @returns {Observable} The generated sequence.
2117
- */
2118
- Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
2119
- scheduler || (scheduler = currentThreadScheduler);
2120
- return new AnonymousObservable(function (observer) {
2121
- var first = true, state = initialState;
2122
- return scheduler.scheduleRecursive(function (self) {
2123
- var hasResult, result;
2124
- try {
2125
- if (first) {
2126
- first = false;
2127
- } else {
2128
- state = iterate(state);
2129
- }
2130
- hasResult = condition(state);
2131
- if (hasResult) {
2132
- result = resultSelector(state);
2133
- }
2134
- } catch (exception) {
2135
- observer.onError(exception);
2136
- return;
2137
- }
2138
- if (hasResult) {
2139
- observer.onNext(result);
2140
- self();
2141
- } else {
2142
- observer.onCompleted();
2143
- }
2144
- });
2145
- });
2146
- };
2147
-
2148
2170
  /**
2149
2171
  * Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
2150
2172
  * @returns {Observable} An observable sequence whose observers will never get called.
@@ -2155,118 +2177,140 @@
2155
2177
  });
2156
2178
  };
2157
2179
 
2158
- /**
2159
- * Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
2160
- *
2161
- * @example
2162
- * var res = Rx.Observable.range(0, 10);
2163
- * var res = Rx.Observable.range(0, 10, Rx.Scheduler.timeout);
2164
- * @param {Number} start The value of the first integer in the sequence.
2165
- * @param {Number} count The number of sequential integers to generate.
2166
- * @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
2167
- * @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
2168
- */
2169
- Observable.range = function (start, count, scheduler) {
2170
- scheduler || (scheduler = currentThreadScheduler);
2171
- return new AnonymousObservable(function (observer) {
2172
- return scheduler.scheduleRecursiveWithState(0, function (i, self) {
2173
- if (i < count) {
2174
- observer.onNext(start + i);
2175
- self(i + 1);
2176
- } else {
2177
- observer.onCompleted();
2178
- }
2179
- });
2180
- });
2181
- };
2182
-
2183
- /**
2184
- * Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
2185
- *
2186
- * @example
2187
- * var res = Rx.Observable.repeat(42);
2188
- * var res = Rx.Observable.repeat(42, 4);
2189
- * 3 - res = Rx.Observable.repeat(42, 4, Rx.Scheduler.timeout);
2190
- * 4 - res = Rx.Observable.repeat(42, null, Rx.Scheduler.timeout);
2191
- * @param {Mixed} value Element to repeat.
2192
- * @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
2193
- * @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
2194
- * @returns {Observable} An observable sequence that repeats the given element the specified number of times.
2195
- */
2196
- Observable.repeat = function (value, repeatCount, scheduler) {
2197
- scheduler || (scheduler = currentThreadScheduler);
2198
- if (repeatCount == null) {
2199
- repeatCount = -1;
2200
- }
2201
- return observableReturn(value, scheduler).repeat(repeatCount);
2202
- };
2203
-
2204
- /**
2205
- * Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
2206
- * There is an alias called 'returnValue' for browsers <IE9.
2207
- *
2208
- * @example
2209
- * var res = Rx.Observable.return(42);
2210
- * var res = Rx.Observable.return(42, Rx.Scheduler.timeout);
2211
- * @param {Mixed} value Single element in the resulting observable sequence.
2212
- * @param {Scheduler} scheduler Scheduler to send the single element on. If not specified, defaults to Scheduler.immediate.
2213
- * @returns {Observable} An observable sequence containing the single specified element.
2214
- */
2215
- var observableReturn = Observable['return'] = Observable.returnValue = function (value, scheduler) {
2216
- scheduler || (scheduler = immediateScheduler);
2217
- return new AnonymousObservable(function (observer) {
2218
- return scheduler.schedule(function () {
2219
- observer.onNext(value);
2220
- observer.onCompleted();
2221
- });
2222
- });
2223
- };
2180
+ /**
2181
+ * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
2182
+ * @example
2183
+ * var res = Rx.Observable.of(1,2,3);
2184
+ * @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
2185
+ */
2186
+ Observable.of = function () {
2187
+ var len = arguments.length, args = new Array(len);
2188
+ for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
2189
+ return observableFromArray(args);
2190
+ };
2224
2191
 
2225
- /**
2226
- * Returns an observable sequence that terminates with an exception, using the specified scheduler to send out the single onError message.
2227
- * There is an alias to this method called 'throwException' for browsers <IE9.
2228
- *
2229
- * @example
2230
- * var res = Rx.Observable.throwException(new Error('Error'));
2231
- * var res = Rx.Observable.throwException(new Error('Error'), Rx.Scheduler.timeout);
2232
- * @param {Mixed} exception An object used for the sequence's termination.
2233
- * @param {Scheduler} scheduler Scheduler to send the exceptional termination call on. If not specified, defaults to Scheduler.immediate.
2234
- * @returns {Observable} The observable sequence that terminates exceptionally with the specified exception object.
2235
- */
2236
- var observableThrow = Observable['throw'] = Observable.throwException = function (exception, scheduler) {
2237
- scheduler || (scheduler = immediateScheduler);
2238
- return new AnonymousObservable(function (observer) {
2239
- return scheduler.schedule(function () {
2240
- observer.onError(exception);
2241
- });
2242
- });
2243
- };
2192
+ /**
2193
+ * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
2194
+ * @example
2195
+ * var res = Rx.Observable.of(1,2,3);
2196
+ * @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
2197
+ * @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
2198
+ */
2199
+ var observableOf = Observable.ofWithScheduler = function (scheduler) {
2200
+ var len = arguments.length - 1, args = new Array(len);
2201
+ for(var i = 0; i < len; i++) { args[i] = arguments[i + 1]; }
2202
+ return observableFromArray(args, scheduler);
2203
+ };
2244
2204
 
2245
- function observableCatchHandler(source, handler) {
2205
+ /**
2206
+ * Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
2207
+ *
2208
+ * @example
2209
+ * var res = Rx.Observable.range(0, 10);
2210
+ * var res = Rx.Observable.range(0, 10, Rx.Scheduler.timeout);
2211
+ * @param {Number} start The value of the first integer in the sequence.
2212
+ * @param {Number} count The number of sequential integers to generate.
2213
+ * @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
2214
+ * @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
2215
+ */
2216
+ Observable.range = function (start, count, scheduler) {
2217
+ isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2246
2218
  return new AnonymousObservable(function (observer) {
2247
- var d1 = new SingleAssignmentDisposable(), subscription = new SerialDisposable();
2248
- subscription.setDisposable(d1);
2249
- d1.setDisposable(source.subscribe(observer.onNext.bind(observer), function (exception) {
2250
- var d, result;
2251
- try {
2252
- result = handler(exception);
2253
- } catch (ex) {
2254
- observer.onError(ex);
2255
- return;
2219
+ return scheduler.scheduleRecursiveWithState(0, function (i, self) {
2220
+ if (i < count) {
2221
+ observer.onNext(start + i);
2222
+ self(i + 1);
2223
+ } else {
2224
+ observer.onCompleted();
2256
2225
  }
2257
- isPromise(result) && (result = observableFromPromise(result));
2258
-
2259
- d = new SingleAssignmentDisposable();
2260
- subscription.setDisposable(d);
2261
- d.setDisposable(result.subscribe(observer));
2262
- }, observer.onCompleted.bind(observer)));
2263
-
2264
- return subscription;
2226
+ });
2265
2227
  });
2266
- }
2228
+ };
2267
2229
 
2268
2230
  /**
2269
- * Continues an observable sequence that is terminated by an exception with the next observable sequence.
2231
+ * Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
2232
+ *
2233
+ * @example
2234
+ * var res = Rx.Observable.repeat(42);
2235
+ * var res = Rx.Observable.repeat(42, 4);
2236
+ * 3 - res = Rx.Observable.repeat(42, 4, Rx.Scheduler.timeout);
2237
+ * 4 - res = Rx.Observable.repeat(42, null, Rx.Scheduler.timeout);
2238
+ * @param {Mixed} value Element to repeat.
2239
+ * @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
2240
+ * @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
2241
+ * @returns {Observable} An observable sequence that repeats the given element the specified number of times.
2242
+ */
2243
+ Observable.repeat = function (value, repeatCount, scheduler) {
2244
+ isScheduler(scheduler) || (scheduler = currentThreadScheduler);
2245
+ return observableReturn(value, scheduler).repeat(repeatCount == null ? -1 : repeatCount);
2246
+ };
2247
+
2248
+ /**
2249
+ * Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
2250
+ * There is an alias called 'just', and 'returnValue' for browsers <IE9.
2251
+ *
2252
+ * @example
2253
+ * var res = Rx.Observable.return(42);
2254
+ * var res = Rx.Observable.return(42, Rx.Scheduler.timeout);
2255
+ * @param {Mixed} value Single element in the resulting observable sequence.
2256
+ * @param {Scheduler} scheduler Scheduler to send the single element on. If not specified, defaults to Scheduler.immediate.
2257
+ * @returns {Observable} An observable sequence containing the single specified element.
2258
+ */
2259
+ var observableReturn = Observable['return'] = Observable.returnValue = Observable.just = function (value, scheduler) {
2260
+ isScheduler(scheduler) || (scheduler = immediateScheduler);
2261
+ return new AnonymousObservable(function (observer) {
2262
+ return scheduler.schedule(function () {
2263
+ observer.onNext(value);
2264
+ observer.onCompleted();
2265
+ });
2266
+ });
2267
+ };
2268
+
2269
+ /**
2270
+ * Returns an observable sequence that terminates with an exception, using the specified scheduler to send out the single onError message.
2271
+ * There is an alias to this method called 'throwException' for browsers <IE9.
2272
+ *
2273
+ * @example
2274
+ * var res = Rx.Observable.throw(new Error('Error'));
2275
+ * var res = Rx.Observable.throw(new Error('Error'), Rx.Scheduler.timeout);
2276
+ * @param {Mixed} exception An object used for the sequence's termination.
2277
+ * @param {Scheduler} scheduler Scheduler to send the exceptional termination call on. If not specified, defaults to Scheduler.immediate.
2278
+ * @returns {Observable} The observable sequence that terminates exceptionally with the specified exception object.
2279
+ */
2280
+ var observableThrow = Observable['throw'] = Observable.throwException = function (exception, scheduler) {
2281
+ isScheduler(scheduler) || (scheduler = immediateScheduler);
2282
+ return new AnonymousObservable(function (observer) {
2283
+ return scheduler.schedule(function () {
2284
+ observer.onError(exception);
2285
+ });
2286
+ });
2287
+ };
2288
+
2289
+ function observableCatchHandler(source, handler) {
2290
+ return new AnonymousObservable(function (observer) {
2291
+ var d1 = new SingleAssignmentDisposable(), subscription = new SerialDisposable();
2292
+ subscription.setDisposable(d1);
2293
+ d1.setDisposable(source.subscribe(observer.onNext.bind(observer), function (exception) {
2294
+ var d, result;
2295
+ try {
2296
+ result = handler(exception);
2297
+ } catch (ex) {
2298
+ observer.onError(ex);
2299
+ return;
2300
+ }
2301
+ isPromise(result) && (result = observableFromPromise(result));
2302
+
2303
+ d = new SingleAssignmentDisposable();
2304
+ subscription.setDisposable(d);
2305
+ d.setDisposable(result.subscribe(observer));
2306
+ }, observer.onCompleted.bind(observer)));
2307
+
2308
+ return subscription;
2309
+ });
2310
+ }
2311
+
2312
+ /**
2313
+ * Continues an observable sequence that is terminated by an exception with the next observable sequence.
2270
2314
  * @example
2271
2315
  * 1 - xs.catchException(ys)
2272
2316
  * 2 - xs.catchException(function (ex) { return ys(ex); })
@@ -2969,18 +3013,19 @@
2969
3013
  return enumerableRepeat(this, repeatCount).concat();
2970
3014
  };
2971
3015
 
2972
- /**
2973
- * Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
2974
- *
2975
- * @example
2976
- * var res = retried = retry.repeat();
2977
- * var res = retried = retry.repeat(42);
2978
- * @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
2979
- * @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
2980
- */
2981
- observableProto.retry = function (retryCount) {
2982
- return enumerableRepeat(this, retryCount).catchException();
2983
- };
3016
+ /**
3017
+ * Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
3018
+ * Note if you encounter an error and want it to retry once, then you must use .retry(2);
3019
+ *
3020
+ * @example
3021
+ * var res = retried = retry.repeat();
3022
+ * var res = retried = retry.repeat(2);
3023
+ * @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
3024
+ * @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
3025
+ */
3026
+ observableProto.retry = function (retryCount) {
3027
+ return enumerableRepeat(this, retryCount).catchException();
3028
+ };
2984
3029
 
2985
3030
  /**
2986
3031
  * Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
@@ -3289,7 +3334,7 @@
3289
3334
  * @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source producing an Observable of Observable sequences
3290
3335
  * and that at any point in time produces the elements of the most recent inner observable sequence that has been received.
3291
3336
  */
3292
- observableProto.selectSwitch = observableProto.flatMapLatest = function (selector, thisArg) {
3337
+ observableProto.selectSwitch = observableProto.flatMapLatest = observableProto.switchMap = function (selector, thisArg) {
3293
3338
  return this.select(selector, thisArg).switchLatest();
3294
3339
  };
3295
3340
 
@@ -3438,96 +3483,92 @@
3438
3483
  });
3439
3484
  };
3440
3485
 
3441
- /**
3442
- * Converts a callback function to an observable sequence.
3443
- *
3444
- * @param {Function} function Function with a callback as the last parameter to convert to an Observable sequence.
3445
- * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
3446
- * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
3447
- * @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next.
3448
- * @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array.
3449
- */
3450
- Observable.fromCallback = function (func, scheduler, context, selector) {
3451
- scheduler || (scheduler = immediateScheduler);
3452
- return function () {
3453
- var args = slice.call(arguments, 0);
3486
+ /**
3487
+ * Converts a callback function to an observable sequence.
3488
+ *
3489
+ * @param {Function} function Function with a callback as the last parameter to convert to an Observable sequence.
3490
+ * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
3491
+ * @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next.
3492
+ * @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array.
3493
+ */
3494
+ Observable.fromCallback = function (func, context, selector) {
3495
+ return function () {
3496
+ var args = slice.call(arguments, 0);
3454
3497
 
3455
- return new AnonymousObservable(function (observer) {
3456
- return scheduler.schedule(function () {
3457
- function handler(e) {
3458
- var results = e;
3459
-
3460
- if (selector) {
3461
- try {
3462
- results = selector(arguments);
3463
- } catch (err) {
3464
- observer.onError(err);
3465
- return;
3466
- }
3467
- } else {
3468
- if (results.length === 1) {
3469
- results = results[0];
3470
- }
3471
- }
3498
+ return new AnonymousObservable(function (observer) {
3499
+ function handler(e) {
3500
+ var results = e;
3501
+
3502
+ if (selector) {
3503
+ try {
3504
+ results = selector(arguments);
3505
+ } catch (err) {
3506
+ observer.onError(err);
3507
+ return;
3508
+ }
3472
3509
 
3473
- observer.onNext(results);
3474
- observer.onCompleted();
3475
- }
3510
+ observer.onNext(results);
3511
+ } else {
3512
+ if (results.length <= 1) {
3513
+ observer.onNext.apply(observer, results);
3514
+ } else {
3515
+ observer.onNext(results);
3516
+ }
3517
+ }
3518
+
3519
+ observer.onCompleted();
3520
+ }
3476
3521
 
3477
- args.push(handler);
3478
- func.apply(context, args);
3479
- });
3480
- });
3481
- };
3522
+ args.push(handler);
3523
+ func.apply(context, args);
3524
+ });
3482
3525
  };
3526
+ };
3483
3527
 
3484
- /**
3485
- * Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
3486
- * @param {Function} func The function to call
3487
- * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
3488
- * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
3489
- * @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
3490
- * @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array.
3491
- */
3492
- Observable.fromNodeCallback = function (func, scheduler, context, selector) {
3493
- scheduler || (scheduler = immediateScheduler);
3494
- return function () {
3495
- var args = slice.call(arguments, 0);
3528
+ /**
3529
+ * Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
3530
+ * @param {Function} func The function to call
3531
+ * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
3532
+ * @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
3533
+ * @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array.
3534
+ */
3535
+ Observable.fromNodeCallback = function (func, context, selector) {
3536
+ return function () {
3537
+ var args = slice.call(arguments, 0);
3496
3538
 
3497
- return new AnonymousObservable(function (observer) {
3498
- return scheduler.schedule(function () {
3499
-
3500
- function handler(err) {
3501
- if (err) {
3502
- observer.onError(err);
3503
- return;
3504
- }
3539
+ return new AnonymousObservable(function (observer) {
3540
+ function handler(err) {
3541
+ if (err) {
3542
+ observer.onError(err);
3543
+ return;
3544
+ }
3505
3545
 
3506
- var results = slice.call(arguments, 1);
3507
-
3508
- if (selector) {
3509
- try {
3510
- results = selector(results);
3511
- } catch (e) {
3512
- observer.onError(e);
3513
- return;
3514
- }
3515
- } else {
3516
- if (results.length === 1) {
3517
- results = results[0];
3518
- }
3519
- }
3546
+ var results = slice.call(arguments, 1);
3547
+
3548
+ if (selector) {
3549
+ try {
3550
+ results = selector(results);
3551
+ } catch (e) {
3552
+ observer.onError(e);
3553
+ return;
3554
+ }
3555
+ observer.onNext(results);
3556
+ } else {
3557
+ if (results.length <= 1) {
3558
+ observer.onNext.apply(observer, results);
3559
+ } else {
3560
+ observer.onNext(results);
3561
+ }
3562
+ }
3520
3563
 
3521
- observer.onNext(results);
3522
- observer.onCompleted();
3523
- }
3564
+ observer.onCompleted();
3565
+ }
3524
3566
 
3525
- args.push(handler);
3526
- func.apply(context, args);
3527
- });
3528
- });
3529
- };
3567
+ args.push(handler);
3568
+ func.apply(context, args);
3569
+ });
3530
3570
  };
3571
+ };
3531
3572
 
3532
3573
  function fixEvent(event) {
3533
3574
  var stopPropagation = function () {
@@ -3922,24 +3963,24 @@
3922
3963
  }, selector);
3923
3964
  };
3924
3965
 
3925
- /**
3926
- * Returns an observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
3927
- * This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
3928
- *
3929
- * @example
3930
- * var res = source.shareReplay(3);
3931
- * var res = source.shareReplay(3, 500);
3932
- * var res = source.shareReplay(3, 500, scheduler);
3933
- *
3966
+ /**
3967
+ * Returns an observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
3968
+ * This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
3969
+ *
3970
+ * @example
3971
+ * var res = source.shareReplay(3);
3972
+ * var res = source.shareReplay(3, 500);
3973
+ * var res = source.shareReplay(3, 500, scheduler);
3974
+ *
3934
3975
 
3935
- * @param bufferSize [Optional] Maximum element count of the replay buffer.
3936
- * @param window [Optional] Maximum time length of the replay buffer.
3937
- * @param scheduler [Optional] Scheduler where connected observers within the selector function will be invoked on.
3938
- * @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
3939
- */
3940
- observableProto.shareReplay = function (bufferSize, window, scheduler) {
3941
- return this.replay(null, bufferSize, window, scheduler).refCount();
3942
- };
3976
+ * @param bufferSize [Optional] Maximum element count of the replay buffer.
3977
+ * @param window [Optional] Maximum time length of the replay buffer.
3978
+ * @param scheduler [Optional] Scheduler where connected observers within the selector function will be invoked on.
3979
+ * @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
3980
+ */
3981
+ observableProto.shareReplay = function (bufferSize, window, scheduler) {
3982
+ return this.replay(null, bufferSize, window, scheduler).refCount();
3983
+ };
3943
3984
 
3944
3985
  /** @private */
3945
3986
  var ConnectableObservable = Rx.ConnectableObservable = (function (_super) {
@@ -4017,259 +4058,268 @@
4017
4058
  });
4018
4059
  }
4019
4060
 
4020
- function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
4021
- if (dueTime === period) {
4022
- return new AnonymousObservable(function (observer) {
4023
- return scheduler.schedulePeriodicWithState(0, period, function (count) {
4024
- observer.onNext(count);
4025
- return count + 1;
4026
- });
4027
- });
4028
- }
4029
- return observableDefer(function () {
4030
- return observableTimerDateAndPeriod(scheduler.now() + dueTime, period, scheduler);
4061
+ function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
4062
+ if (dueTime === period) {
4063
+ return new AnonymousObservable(function (observer) {
4064
+ return scheduler.schedulePeriodicWithState(0, period, function (count) {
4065
+ observer.onNext(count);
4066
+ return count + 1;
4031
4067
  });
4068
+ });
4032
4069
  }
4070
+ return observableDefer(function () {
4071
+ return observableTimerDateAndPeriod(scheduler.now() + dueTime, period, scheduler);
4072
+ });
4073
+ }
4033
4074
 
4034
- /**
4035
- * Returns an observable sequence that produces a value after each period.
4036
- *
4037
- * @example
4038
- * 1 - res = Rx.Observable.interval(1000);
4039
- * 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
4040
- *
4041
- * @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
4042
- * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
4043
- * @returns {Observable} An observable sequence that produces a value after each period.
4044
- */
4045
- var observableinterval = Observable.interval = function (period, scheduler) {
4046
- scheduler || (scheduler = timeoutScheduler);
4047
- return observableTimerTimeSpanAndPeriod(period, period, scheduler);
4048
- };
4049
-
4050
- /**
4051
- * Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
4052
- *
4053
- * @example
4054
- * var res = Rx.Observable.timer(5000);
4055
- * var res = Rx.Observable.timer(5000, 1000);
4056
- * var res = Rx.Observable.timer(5000, Rx.Scheduler.timeout);
4057
- * var res = Rx.Observable.timer(5000, 1000, Rx.Scheduler.timeout);
4058
- *
4059
- * @param {Number} dueTime Relative time (specified as an integer denoting milliseconds) at which to produce the first value.
4060
- * @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
4061
- * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
4062
- * @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
4063
- */
4064
- var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
4065
- var period;
4066
- scheduler || (scheduler = timeoutScheduler);
4067
- if (typeof periodOrScheduler === 'number') {
4068
- period = periodOrScheduler;
4069
- } else if (typeof periodOrScheduler === 'object' && 'now' in periodOrScheduler) {
4070
- scheduler = periodOrScheduler;
4075
+ function observableTimerDateAndPeriod(dueTime, period, scheduler) {
4076
+ var p = normalizeTime(period);
4077
+ return new AnonymousObservable(function (observer) {
4078
+ var count = 0, d = dueTime;
4079
+ return scheduler.scheduleRecursiveWithAbsolute(d, function (self) {
4080
+ var now;
4081
+ if (p > 0) {
4082
+ now = scheduler.now();
4083
+ d = d + p;
4084
+ if (d <= now) {
4085
+ d = now + p;
4086
+ }
4071
4087
  }
4072
- return period === undefined ?
4073
- observableTimerTimeSpan(dueTime, scheduler) :
4074
- observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
4075
- };
4076
-
4077
- /**
4078
- * Time shifts the observable sequence by dueTime. The relative time intervals between the values are preserved.
4079
- *
4080
- * @example
4081
- * var res = Rx.Observable.delay(5000);
4082
- * var res = Rx.Observable.delay(5000, 1000, Rx.Scheduler.timeout);
4083
- * @memberOf Observable#
4084
- * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
4085
- * @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
4086
- * @returns {Observable} Time-shifted sequence.
4087
- */
4088
- observableProto.delay = function (dueTime, scheduler) {
4089
- scheduler || (scheduler = timeoutScheduler);
4090
- var source = this;
4091
- return new AnonymousObservable(function (observer) {
4092
- var active = false,
4093
- cancelable = new SerialDisposable(),
4094
- exception = null,
4095
- q = [],
4096
- running = false,
4097
- subscription;
4098
- subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
4099
- var d, shouldRun;
4100
- if (notification.value.kind === 'E') {
4101
- q = [];
4102
- q.push(notification);
4103
- exception = notification.value.exception;
4104
- shouldRun = !running;
4105
- } else {
4106
- q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
4107
- shouldRun = !active;
4108
- active = true;
4109
- }
4110
- if (shouldRun) {
4111
- if (exception !== null) {
4112
- observer.onError(exception);
4113
- } else {
4114
- d = new SingleAssignmentDisposable();
4115
- cancelable.setDisposable(d);
4116
- d.setDisposable(scheduler.scheduleRecursiveWithRelative(dueTime, function (self) {
4117
- var e, recurseDueTime, result, shouldRecurse;
4118
- if (exception !== null) {
4119
- return;
4120
- }
4121
- running = true;
4122
- do {
4123
- result = null;
4124
- if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
4125
- result = q.shift().value;
4126
- }
4127
- if (result !== null) {
4128
- result.accept(observer);
4129
- }
4130
- } while (result !== null);
4131
- shouldRecurse = false;
4132
- recurseDueTime = 0;
4133
- if (q.length > 0) {
4134
- shouldRecurse = true;
4135
- recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
4136
- } else {
4137
- active = false;
4138
- }
4139
- e = exception;
4140
- running = false;
4141
- if (e !== null) {
4142
- observer.onError(e);
4143
- } else if (shouldRecurse) {
4144
- self(recurseDueTime);
4145
- }
4146
- }));
4147
- }
4148
- }
4149
- });
4150
- return new CompositeDisposable(subscription, cancelable);
4151
- });
4152
- };
4153
-
4154
- /**
4155
- * Ignores values from an observable sequence which are followed by another value before dueTime.
4156
- *
4157
- * @example
4158
- * 1 - res = source.throttle(5000); // 5 seconds
4159
- * 2 - res = source.throttle(5000, scheduler);
4160
- *
4161
- * @param {Number} dueTime Duration of the throttle period for each value (specified as an integer denoting milliseconds).
4162
- * @param {Scheduler} [scheduler] Scheduler to run the throttle timers on. If not specified, the timeout scheduler is used.
4163
- * @returns {Observable} The throttled sequence.
4164
- */
4165
- observableProto.throttle = function (dueTime, scheduler) {
4166
- scheduler || (scheduler = timeoutScheduler);
4167
- var source = this;
4168
- return this.throttleWithSelector(function () { return observableTimer(dueTime, scheduler); })
4169
- };
4170
-
4171
- /**
4172
- * Records the time interval between consecutive values in an observable sequence.
4173
- *
4174
- * @example
4175
- * 1 - res = source.timeInterval();
4176
- * 2 - res = source.timeInterval(Rx.Scheduler.timeout);
4177
- *
4178
- * @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
4179
- * @returns {Observable} An observable sequence with time interval information on values.
4180
- */
4181
- observableProto.timeInterval = function (scheduler) {
4182
- var source = this;
4183
- scheduler || (scheduler = timeoutScheduler);
4184
- return observableDefer(function () {
4185
- var last = scheduler.now();
4186
- return source.select(function (x) {
4187
- var now = scheduler.now(), span = now - last;
4188
- last = now;
4189
- return {
4190
- value: x,
4191
- interval: span
4192
- };
4193
- });
4194
- });
4195
- };
4196
-
4197
- /**
4198
- * Records the timestamp for each value in an observable sequence.
4199
- *
4200
- * @example
4201
- * 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
4202
- * 2 - res = source.timestamp(Rx.Scheduler.timeout);
4203
- *
4204
- * @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the timeout scheduler is used.
4205
- * @returns {Observable} An observable sequence with timestamp information on values.
4206
- */
4207
- observableProto.timestamp = function (scheduler) {
4208
- scheduler || (scheduler = timeoutScheduler);
4209
- return this.select(function (x) {
4210
- return {
4211
- value: x,
4212
- timestamp: scheduler.now()
4213
- };
4214
- });
4215
- };
4216
-
4217
- function sampleObservable(source, sampler) {
4218
-
4219
- return new AnonymousObservable(function (observer) {
4220
- var atEnd, value, hasValue;
4088
+ observer.onNext(count++);
4089
+ self(d);
4090
+ });
4091
+ });
4092
+ }
4221
4093
 
4222
- function sampleSubscribe() {
4223
- if (hasValue) {
4224
- hasValue = false;
4225
- observer.onNext(value);
4226
- }
4227
- if (atEnd) {
4228
- observer.onCompleted();
4229
- }
4230
- }
4094
+ /**
4095
+ * Returns an observable sequence that produces a value after each period.
4096
+ *
4097
+ * @example
4098
+ * 1 - res = Rx.Observable.interval(1000);
4099
+ * 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
4100
+ *
4101
+ * @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
4102
+ * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
4103
+ * @returns {Observable} An observable sequence that produces a value after each period.
4104
+ */
4105
+ var observableinterval = Observable.interval = function (period, scheduler) {
4106
+ return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : timeoutScheduler);
4107
+ };
4231
4108
 
4232
- return new CompositeDisposable(
4233
- source.subscribe(function (newValue) {
4234
- hasValue = true;
4235
- value = newValue;
4236
- }, observer.onError.bind(observer), function () {
4237
- atEnd = true;
4238
- }),
4239
- sampler.subscribe(sampleSubscribe, observer.onError.bind(observer), sampleSubscribe)
4240
- );
4241
- });
4109
+ /**
4110
+ * Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
4111
+ *
4112
+ * @example
4113
+ * var res = Rx.Observable.timer(5000);
4114
+ * var res = Rx.Observable.timer(5000, 1000);
4115
+ * var res = Rx.Observable.timer(5000, Rx.Scheduler.timeout);
4116
+ * var res = Rx.Observable.timer(5000, 1000, Rx.Scheduler.timeout);
4117
+ *
4118
+ * @param {Number} dueTime Relative time (specified as an integer denoting milliseconds) at which to produce the first value.
4119
+ * @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
4120
+ * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
4121
+ * @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
4122
+ */
4123
+ var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
4124
+ var period;
4125
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4126
+ if (typeof periodOrScheduler === 'number') {
4127
+ period = periodOrScheduler;
4128
+ } else if (typeof periodOrScheduler === 'object' && typeof periodOrScheduler.now === 'function') {
4129
+ scheduler = periodOrScheduler;
4242
4130
  }
4243
-
4244
- /**
4245
- * Samples the observable sequence at each interval.
4246
- *
4247
- * @example
4248
- * 1 - res = source.sample(sampleObservable); // Sampler tick sequence
4249
- * 2 - res = source.sample(5000); // 5 seconds
4250
- * 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
4251
- *
4252
- * @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
4253
- * @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
4254
- * @returns {Observable} Sampled observable sequence.
4255
- */
4256
- observableProto.sample = function (intervalOrSampler, scheduler) {
4257
- scheduler || (scheduler = timeoutScheduler);
4258
- if (typeof intervalOrSampler === 'number') {
4259
- return sampleObservable(this, observableinterval(intervalOrSampler, scheduler));
4260
- }
4261
- return sampleObservable(this, intervalOrSampler);
4262
- };
4131
+ return notDefined(period) ?
4132
+ observableTimerTimeSpan(dueTime, scheduler) :
4133
+ observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
4134
+ };
4263
4135
 
4264
4136
  /**
4265
- * Returns the source observable sequence or the other observable sequence if dueTime elapses.
4137
+ * Time shifts the observable sequence by dueTime. The relative time intervals between the values are preserved.
4266
4138
  *
4267
4139
  * @example
4268
- * 1 - res = source.timeout(new Date()); // As a date
4269
- * 2 - res = source.timeout(5000); // 5 seconds
4270
- * 3 - res = source.timeout(new Date(), Rx.Observable.returnValue(42)); // As a date and timeout observable
4271
- * 4 - res = source.timeout(5000, Rx.Observable.returnValue(42)); // 5 seconds and timeout observable
4272
- * 5 - res = source.timeout(new Date(), Rx.Observable.returnValue(42), Rx.Scheduler.timeout); // As a date and timeout observable
4140
+ * var res = Rx.Observable.delay(5000);
4141
+ * var res = Rx.Observable.delay(5000, 1000, Rx.Scheduler.timeout);
4142
+ * @memberOf Observable#
4143
+ * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
4144
+ * @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
4145
+ * @returns {Observable} Time-shifted sequence.
4146
+ */
4147
+ observableProto.delay = function (dueTime, scheduler) {
4148
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4149
+ var source = this;
4150
+ return new AnonymousObservable(function (observer) {
4151
+ var active = false,
4152
+ cancelable = new SerialDisposable(),
4153
+ exception = null,
4154
+ q = [],
4155
+ running = false,
4156
+ subscription;
4157
+ subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
4158
+ var d, shouldRun;
4159
+ if (notification.value.kind === 'E') {
4160
+ q = [];
4161
+ q.push(notification);
4162
+ exception = notification.value.exception;
4163
+ shouldRun = !running;
4164
+ } else {
4165
+ q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
4166
+ shouldRun = !active;
4167
+ active = true;
4168
+ }
4169
+ if (shouldRun) {
4170
+ if (exception !== null) {
4171
+ observer.onError(exception);
4172
+ } else {
4173
+ d = new SingleAssignmentDisposable();
4174
+ cancelable.setDisposable(d);
4175
+ d.setDisposable(scheduler.scheduleRecursiveWithRelative(dueTime, function (self) {
4176
+ var e, recurseDueTime, result, shouldRecurse;
4177
+
4178
+ if (exception !== null) { return; }
4179
+
4180
+ running = true;
4181
+ do {
4182
+ result = null;
4183
+ if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
4184
+ result = q.shift().value;
4185
+ }
4186
+ if (result !== null) {
4187
+ result.accept(observer);
4188
+ }
4189
+ } while (result !== null);
4190
+
4191
+ shouldRecurse = false;
4192
+ recurseDueTime = 0;
4193
+ if (q.length > 0) {
4194
+ shouldRecurse = true;
4195
+ recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
4196
+ } else {
4197
+ active = false;
4198
+ }
4199
+ e = exception;
4200
+ running = false;
4201
+ if (e !== null) {
4202
+ observer.onError(e);
4203
+ } else if (shouldRecurse) {
4204
+ self(recurseDueTime);
4205
+ }
4206
+ }));
4207
+ }
4208
+ }
4209
+ });
4210
+ return new CompositeDisposable(subscription, cancelable);
4211
+ });
4212
+ };
4213
+
4214
+ /**
4215
+ * Ignores values from an observable sequence which are followed by another value before dueTime.
4216
+ *
4217
+ * @example
4218
+ * 1 - res = source.throttle(5000); // 5 seconds
4219
+ * 2 - res = source.throttle(5000, scheduler);
4220
+ *
4221
+ * @param {Number} dueTime Duration of the throttle period for each value (specified as an integer denoting milliseconds).
4222
+ * @param {Scheduler} [scheduler] Scheduler to run the throttle timers on. If not specified, the timeout scheduler is used.
4223
+ * @returns {Observable} The throttled sequence.
4224
+ */
4225
+ observableProto.throttle = function (dueTime, scheduler) {
4226
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4227
+ return this.throttleWithSelector(function () { return observableTimer(dueTime, scheduler); })
4228
+ };
4229
+
4230
+ /**
4231
+ * Records the time interval between consecutive values in an observable sequence.
4232
+ *
4233
+ * @example
4234
+ * 1 - res = source.timeInterval();
4235
+ * 2 - res = source.timeInterval(Rx.Scheduler.timeout);
4236
+ *
4237
+ * @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
4238
+ * @returns {Observable} An observable sequence with time interval information on values.
4239
+ */
4240
+ observableProto.timeInterval = function (scheduler) {
4241
+ var source = this;
4242
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4243
+ return observableDefer(function () {
4244
+ var last = scheduler.now();
4245
+ return source.map(function (x) {
4246
+ var now = scheduler.now(), span = now - last;
4247
+ last = now;
4248
+ return { value: x, interval: span };
4249
+ });
4250
+ });
4251
+ };
4252
+
4253
+ /**
4254
+ * Records the timestamp for each value in an observable sequence.
4255
+ *
4256
+ * @example
4257
+ * 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
4258
+ * 2 - res = source.timestamp(Rx.Scheduler.timeout);
4259
+ *
4260
+ * @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the timeout scheduler is used.
4261
+ * @returns {Observable} An observable sequence with timestamp information on values.
4262
+ */
4263
+ observableProto.timestamp = function (scheduler) {
4264
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4265
+ return this.map(function (x) {
4266
+ return { value: x, timestamp: scheduler.now() };
4267
+ });
4268
+ };
4269
+
4270
+ function sampleObservable(source, sampler) {
4271
+
4272
+ return new AnonymousObservable(function (observer) {
4273
+ var atEnd, value, hasValue;
4274
+
4275
+ function sampleSubscribe() {
4276
+ if (hasValue) {
4277
+ hasValue = false;
4278
+ observer.onNext(value);
4279
+ }
4280
+ atEnd && observer.onCompleted();
4281
+ }
4282
+
4283
+ return new CompositeDisposable(
4284
+ source.subscribe(function (newValue) {
4285
+ hasValue = true;
4286
+ value = newValue;
4287
+ }, observer.onError.bind(observer), function () {
4288
+ atEnd = true;
4289
+ }),
4290
+ sampler.subscribe(sampleSubscribe, observer.onError.bind(observer), sampleSubscribe)
4291
+ );
4292
+ });
4293
+ }
4294
+
4295
+ /**
4296
+ * Samples the observable sequence at each interval.
4297
+ *
4298
+ * @example
4299
+ * 1 - res = source.sample(sampleObservable); // Sampler tick sequence
4300
+ * 2 - res = source.sample(5000); // 5 seconds
4301
+ * 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
4302
+ *
4303
+ * @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
4304
+ * @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
4305
+ * @returns {Observable} Sampled observable sequence.
4306
+ */
4307
+ observableProto.sample = function (intervalOrSampler, scheduler) {
4308
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4309
+ return typeof intervalOrSampler === 'number' ?
4310
+ sampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
4311
+ sampleObservable(this, intervalOrSampler);
4312
+ };
4313
+
4314
+ /**
4315
+ * Returns the source observable sequence or the other observable sequence if dueTime elapses.
4316
+ *
4317
+ * @example
4318
+ * 1 - res = source.timeout(new Date()); // As a date
4319
+ * 2 - res = source.timeout(5000); // 5 seconds
4320
+ * 3 - res = source.timeout(new Date(), Rx.Observable.returnValue(42)); // As a date and timeout observable
4321
+ * 4 - res = source.timeout(5000, Rx.Observable.returnValue(42)); // 5 seconds and timeout observable
4322
+ * 5 - res = source.timeout(new Date(), Rx.Observable.returnValue(42), Rx.Scheduler.timeout); // As a date and timeout observable
4273
4323
  * 6 - res = source.timeout(5000, Rx.Observable.returnValue(42), Rx.Scheduler.timeout); // 5 seconds and timeout observable
4274
4324
  *
4275
4325
  * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) when a timeout occurs.
@@ -4279,7 +4329,7 @@
4279
4329
  */
4280
4330
  observableProto.timeout = function (dueTime, other, scheduler) {
4281
4331
  other || (other = observableThrow(new Error('Timeout')));
4282
- scheduler || (scheduler = timeoutScheduler);
4332
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4283
4333
 
4284
4334
  var source = this, schedulerMethod = dueTime instanceof Date ?
4285
4335
  'scheduleWithAbsolute' :
@@ -4327,76 +4377,74 @@
4327
4377
  });
4328
4378
  };
4329
4379
 
4330
- /**
4331
- * Generates an observable sequence by iterating a state from an initial state until the condition fails.
4332
- *
4333
- * @example
4334
- * res = source.generateWithRelativeTime(0,
4335
- * function (x) { return return true; },
4336
- * function (x) { return x + 1; },
4337
- * function (x) { return x; },
4338
- * function (x) { return 500; }
4339
- * );
4340
- *
4341
- * @param {Mixed} initialState Initial state.
4342
- * @param {Function} condition Condition to terminate generation (upon returning false).
4343
- * @param {Function} iterate Iteration step function.
4344
- * @param {Function} resultSelector Selector function for results produced in the sequence.
4345
- * @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
4346
- * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
4347
- * @returns {Observable} The generated sequence.
4348
- */
4349
- Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
4350
- scheduler || (scheduler = timeoutScheduler);
4351
- return new AnonymousObservable(function (observer) {
4352
- var first = true,
4353
- hasResult = false,
4354
- result,
4355
- state = initialState,
4356
- time;
4357
- return scheduler.scheduleRecursiveWithRelative(0, function (self) {
4358
- if (hasResult) {
4359
- observer.onNext(result);
4360
- }
4361
- try {
4362
- if (first) {
4363
- first = false;
4364
- } else {
4365
- state = iterate(state);
4366
- }
4367
- hasResult = condition(state);
4368
- if (hasResult) {
4369
- result = resultSelector(state);
4370
- time = timeSelector(state);
4371
- }
4372
- } catch (e) {
4373
- observer.onError(e);
4374
- return;
4375
- }
4376
- if (hasResult) {
4377
- self(time);
4378
- } else {
4379
- observer.onCompleted();
4380
- }
4381
- });
4382
- });
4383
- };
4380
+ /**
4381
+ * Generates an observable sequence by iterating a state from an initial state until the condition fails.
4382
+ *
4383
+ * @example
4384
+ * res = source.generateWithRelativeTime(0,
4385
+ * function (x) { return return true; },
4386
+ * function (x) { return x + 1; },
4387
+ * function (x) { return x; },
4388
+ * function (x) { return 500; }
4389
+ * );
4390
+ *
4391
+ * @param {Mixed} initialState Initial state.
4392
+ * @param {Function} condition Condition to terminate generation (upon returning false).
4393
+ * @param {Function} iterate Iteration step function.
4394
+ * @param {Function} resultSelector Selector function for results produced in the sequence.
4395
+ * @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
4396
+ * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
4397
+ * @returns {Observable} The generated sequence.
4398
+ */
4399
+ Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
4400
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4401
+ return new AnonymousObservable(function (observer) {
4402
+ var first = true,
4403
+ hasResult = false,
4404
+ result,
4405
+ state = initialState,
4406
+ time;
4407
+ return scheduler.scheduleRecursiveWithRelative(0, function (self) {
4408
+ hasResult && observer.onNext(result);
4384
4409
 
4385
- /**
4386
- * Time shifts the observable sequence by delaying the subscription.
4387
- *
4388
- * @example
4389
- * 1 - res = source.delaySubscription(5000); // 5s
4390
- * 2 - res = source.delaySubscription(5000, Rx.Scheduler.timeout); // 5 seconds
4391
- *
4392
- * @param {Number} dueTime Absolute or relative time to perform the subscription at.
4393
- * @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
4394
- * @returns {Observable} Time-shifted sequence.
4395
- */
4396
- observableProto.delaySubscription = function (dueTime, scheduler) {
4397
- scheduler || (scheduler = timeoutScheduler);
4398
- return this.delayWithSelector(observableTimer(dueTime, scheduler), function () { return observableEmpty(); });
4399
- };
4410
+ try {
4411
+ if (first) {
4412
+ first = false;
4413
+ } else {
4414
+ state = iterate(state);
4415
+ }
4416
+ hasResult = condition(state);
4417
+ if (hasResult) {
4418
+ result = resultSelector(state);
4419
+ time = timeSelector(state);
4420
+ }
4421
+ } catch (e) {
4422
+ observer.onError(e);
4423
+ return;
4424
+ }
4425
+ if (hasResult) {
4426
+ self(time);
4427
+ } else {
4428
+ observer.onCompleted();
4429
+ }
4430
+ });
4431
+ });
4432
+ };
4433
+
4434
+ /**
4435
+ * Time shifts the observable sequence by delaying the subscription.
4436
+ *
4437
+ * @example
4438
+ * 1 - res = source.delaySubscription(5000); // 5s
4439
+ * 2 - res = source.delaySubscription(5000, Rx.Scheduler.timeout); // 5 seconds
4440
+ *
4441
+ * @param {Number} dueTime Absolute or relative time to perform the subscription at.
4442
+ * @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
4443
+ * @returns {Observable} Time-shifted sequence.
4444
+ */
4445
+ observableProto.delaySubscription = function (dueTime, scheduler) {
4446
+ return this.delayWithSelector(observableTimer(dueTime, isScheduler(scheduler) ? scheduler : timeoutScheduler), observableEmpty);
4447
+ };
4400
4448
 
4401
4449
  /**
4402
4450
  * Time shifts the observable sequence based on a subscription delay and a delay selector function for each element.
@@ -4542,96 +4590,96 @@
4542
4590
  });
4543
4591
  };
4544
4592
 
4545
- /**
4546
- * Ignores values from an observable sequence which are followed by another value within a computed throttle duration.
4547
- *
4548
- * @example
4549
- * 1 - res = source.delayWithSelector(function (x) { return Rx.Scheduler.timer(x + x); });
4550
- *
4551
- * @param {Function} throttleDurationSelector Selector function to retrieve a sequence indicating the throttle duration for each given element.
4552
- * @returns {Observable} The throttled sequence.
4553
- */
4554
- observableProto.throttleWithSelector = function (throttleDurationSelector) {
4555
- var source = this;
4556
- return new AnonymousObservable(function (observer) {
4557
- var value, hasValue = false, cancelable = new SerialDisposable(), id = 0, subscription = source.subscribe(function (x) {
4558
- var throttle;
4559
- try {
4560
- throttle = throttleDurationSelector(x);
4561
- } catch (e) {
4562
- observer.onError(e);
4563
- return;
4564
- }
4565
- hasValue = true;
4566
- value = x;
4567
- id++;
4568
- var currentid = id, d = new SingleAssignmentDisposable();
4569
- cancelable.setDisposable(d);
4570
- d.setDisposable(throttle.subscribe(function () {
4571
- if (hasValue && id === currentid) {
4572
- observer.onNext(value);
4573
- }
4574
- hasValue = false;
4575
- d.dispose();
4576
- }, observer.onError.bind(observer), function () {
4577
- if (hasValue && id === currentid) {
4578
- observer.onNext(value);
4579
- }
4580
- hasValue = false;
4581
- d.dispose();
4582
- }));
4583
- }, function (e) {
4584
- cancelable.dispose();
4585
- observer.onError(e);
4586
- hasValue = false;
4587
- id++;
4588
- }, function () {
4589
- cancelable.dispose();
4590
- if (hasValue) {
4591
- observer.onNext(value);
4592
- }
4593
- observer.onCompleted();
4594
- hasValue = false;
4595
- id++;
4596
- });
4597
- return new CompositeDisposable(subscription, cancelable);
4598
- });
4599
- };
4593
+ /**
4594
+ * Ignores values from an observable sequence which are followed by another value within a computed throttle duration.
4595
+ *
4596
+ * @example
4597
+ * 1 - res = source.delayWithSelector(function (x) { return Rx.Scheduler.timer(x + x); });
4598
+ *
4599
+ * @param {Function} throttleDurationSelector Selector function to retrieve a sequence indicating the throttle duration for each given element.
4600
+ * @returns {Observable} The throttled sequence.
4601
+ */
4602
+ observableProto.throttleWithSelector = function (throttleDurationSelector) {
4603
+ var source = this;
4604
+ return new AnonymousObservable(function (observer) {
4605
+ var value, hasValue = false, cancelable = new SerialDisposable(), id = 0, subscription = source.subscribe(function (x) {
4606
+ var throttle;
4607
+ try {
4608
+ throttle = throttleDurationSelector(x);
4609
+ } catch (e) {
4610
+ observer.onError(e);
4611
+ return;
4612
+ }
4613
+ hasValue = true;
4614
+ value = x;
4615
+ id++;
4616
+ var currentid = id, d = new SingleAssignmentDisposable();
4617
+ cancelable.setDisposable(d);
4618
+ d.setDisposable(throttle.subscribe(function () {
4619
+ if (hasValue && id === currentid) {
4620
+ observer.onNext(value);
4621
+ }
4622
+ hasValue = false;
4623
+ d.dispose();
4624
+ }, observer.onError.bind(observer), function () {
4625
+ if (hasValue && id === currentid) {
4626
+ observer.onNext(value);
4627
+ }
4628
+ hasValue = false;
4629
+ d.dispose();
4630
+ }));
4631
+ }, function (e) {
4632
+ cancelable.dispose();
4633
+ observer.onError(e);
4634
+ hasValue = false;
4635
+ id++;
4636
+ }, function () {
4637
+ cancelable.dispose();
4638
+ if (hasValue) {
4639
+ observer.onNext(value);
4640
+ }
4641
+ observer.onCompleted();
4642
+ hasValue = false;
4643
+ id++;
4644
+ });
4645
+ return new CompositeDisposable(subscription, cancelable);
4646
+ });
4647
+ };
4600
4648
 
4601
- /**
4602
- * Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
4603
- *
4604
- * 1 - res = source.skipLastWithTime(5000);
4605
- * 2 - res = source.skipLastWithTime(5000, scheduler);
4606
- *
4607
- * @description
4608
- * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4609
- * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4610
- * result sequence. This causes elements to be delayed with duration.
4611
- * @param {Number} duration Duration for skipping elements from the end of the sequence.
4612
- * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
4613
- * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
4614
- */
4615
- observableProto.skipLastWithTime = function (duration, scheduler) {
4616
- scheduler || (scheduler = timeoutScheduler);
4617
- var source = this;
4618
- return new AnonymousObservable(function (observer) {
4619
- var q = [];
4620
- return source.subscribe(function (x) {
4621
- var now = scheduler.now();
4622
- q.push({ interval: now, value: x });
4623
- while (q.length > 0 && now - q[0].interval >= duration) {
4624
- observer.onNext(q.shift().value);
4625
- }
4626
- }, observer.onError.bind(observer), function () {
4627
- var now = scheduler.now();
4628
- while (q.length > 0 && now - q[0].interval >= duration) {
4629
- observer.onNext(q.shift().value);
4630
- }
4631
- observer.onCompleted();
4632
- });
4633
- });
4634
- };
4649
+ /**
4650
+ * Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
4651
+ *
4652
+ * 1 - res = source.skipLastWithTime(5000);
4653
+ * 2 - res = source.skipLastWithTime(5000, scheduler);
4654
+ *
4655
+ * @description
4656
+ * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4657
+ * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4658
+ * result sequence. This causes elements to be delayed with duration.
4659
+ * @param {Number} duration Duration for skipping elements from the end of the sequence.
4660
+ * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
4661
+ * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
4662
+ */
4663
+ observableProto.skipLastWithTime = function (duration, scheduler) {
4664
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4665
+ var source = this;
4666
+ return new AnonymousObservable(function (observer) {
4667
+ var q = [];
4668
+ return source.subscribe(function (x) {
4669
+ var now = scheduler.now();
4670
+ q.push({ interval: now, value: x });
4671
+ while (q.length > 0 && now - q[0].interval >= duration) {
4672
+ observer.onNext(q.shift().value);
4673
+ }
4674
+ }, observer.onError.bind(observer), function () {
4675
+ var now = scheduler.now();
4676
+ while (q.length > 0 && now - q[0].interval >= duration) {
4677
+ observer.onNext(q.shift().value);
4678
+ }
4679
+ observer.onCompleted();
4680
+ });
4681
+ });
4682
+ };
4635
4683
 
4636
4684
  /**
4637
4685
  * Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
@@ -4651,102 +4699,93 @@
4651
4699
  return this.takeLastBufferWithTime(duration, timerScheduler).selectMany(function (xs) { return observableFromArray(xs, loopScheduler); });
4652
4700
  };
4653
4701
 
4654
- /**
4655
- * Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
4656
- *
4657
- * @example
4658
- * 1 - res = source.takeLastBufferWithTime(5000, [optional scheduler]);
4659
- * @description
4660
- * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4661
- * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4662
- * result sequence. This causes elements to be delayed with duration.
4663
- * @param {Number} duration Duration for taking elements from the end of the sequence.
4664
- * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4665
- * @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
4666
- */
4667
- observableProto.takeLastBufferWithTime = function (duration, scheduler) {
4668
- var source = this;
4669
- scheduler || (scheduler = timeoutScheduler);
4670
- return new AnonymousObservable(function (observer) {
4671
- var q = [];
4672
-
4673
- return source.subscribe(function (x) {
4674
- var now = scheduler.now();
4675
- q.push({ interval: now, value: x });
4676
- while (q.length > 0 && now - q[0].interval >= duration) {
4677
- q.shift();
4678
- }
4679
- }, observer.onError.bind(observer), function () {
4680
- var now = scheduler.now(), res = [];
4681
- while (q.length > 0) {
4682
- var next = q.shift();
4683
- if (now - next.interval <= duration) {
4684
- res.push(next.value);
4685
- }
4686
- }
4687
-
4688
- observer.onNext(res);
4689
- observer.onCompleted();
4690
- });
4691
- });
4692
- };
4702
+ /**
4703
+ * Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
4704
+ *
4705
+ * @example
4706
+ * 1 - res = source.takeLastBufferWithTime(5000, [optional scheduler]);
4707
+ * @description
4708
+ * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4709
+ * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4710
+ * result sequence. This causes elements to be delayed with duration.
4711
+ * @param {Number} duration Duration for taking elements from the end of the sequence.
4712
+ * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4713
+ * @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
4714
+ */
4715
+ observableProto.takeLastBufferWithTime = function (duration, scheduler) {
4716
+ var source = this;
4717
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4718
+ return new AnonymousObservable(function (observer) {
4719
+ var q = [];
4693
4720
 
4694
- /**
4695
- * Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
4696
- *
4697
- * @example
4698
- * 1 - res = source.takeWithTime(5000, [optional scheduler]);
4699
- * @description
4700
- * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4701
- * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4702
- * result sequence. This causes elements to be delayed with duration.
4703
- * @param {Number} duration Duration for taking elements from the start of the sequence.
4704
- * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4705
- * @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
4706
- */
4707
- observableProto.takeWithTime = function (duration, scheduler) {
4708
- var source = this;
4709
- scheduler || (scheduler = timeoutScheduler);
4710
- return new AnonymousObservable(function (observer) {
4711
- var t = scheduler.scheduleWithRelative(duration, function () {
4712
- observer.onCompleted();
4713
- });
4721
+ return source.subscribe(function (x) {
4722
+ var now = scheduler.now();
4723
+ q.push({ interval: now, value: x });
4724
+ while (q.length > 0 && now - q[0].interval >= duration) {
4725
+ q.shift();
4726
+ }
4727
+ }, observer.onError.bind(observer), function () {
4728
+ var now = scheduler.now(), res = [];
4729
+ while (q.length > 0) {
4730
+ var next = q.shift();
4731
+ if (now - next.interval <= duration) {
4732
+ res.push(next.value);
4733
+ }
4734
+ }
4714
4735
 
4715
- return new CompositeDisposable(t, source.subscribe(observer));
4716
- });
4717
- };
4736
+ observer.onNext(res);
4737
+ observer.onCompleted();
4738
+ });
4739
+ });
4740
+ };
4718
4741
 
4719
- /**
4720
- * Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
4721
- *
4722
- * @example
4723
- * 1 - res = source.skipWithTime(5000, [optional scheduler]);
4724
- *
4725
- * @description
4726
- * Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
4727
- * This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
4728
- * may not execute immediately, despite the zero due time.
4729
- *
4730
- * Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
4731
- * @param {Number} duration Duration for skipping elements from the start of the sequence.
4732
- * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4733
- * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
4734
- */
4735
- observableProto.skipWithTime = function (duration, scheduler) {
4736
- var source = this;
4737
- scheduler || (scheduler = timeoutScheduler);
4738
- return new AnonymousObservable(function (observer) {
4739
- var open = false,
4740
- t = scheduler.scheduleWithRelative(duration, function () { open = true; }),
4741
- d = source.subscribe(function (x) {
4742
- if (open) {
4743
- observer.onNext(x);
4744
- }
4745
- }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
4742
+ /**
4743
+ * Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
4744
+ *
4745
+ * @example
4746
+ * 1 - res = source.takeWithTime(5000, [optional scheduler]);
4747
+ * @description
4748
+ * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
4749
+ * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
4750
+ * result sequence. This causes elements to be delayed with duration.
4751
+ * @param {Number} duration Duration for taking elements from the start of the sequence.
4752
+ * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4753
+ * @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
4754
+ */
4755
+ observableProto.takeWithTime = function (duration, scheduler) {
4756
+ var source = this;
4757
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4758
+ return new AnonymousObservable(function (observer) {
4759
+ return new CompositeDisposable(scheduler.scheduleWithRelative(duration, observer.onCompleted.bind(observer)), source.subscribe(observer));
4760
+ });
4761
+ };
4746
4762
 
4747
- return new CompositeDisposable(t, d);
4748
- });
4749
- };
4763
+ /**
4764
+ * Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
4765
+ *
4766
+ * @example
4767
+ * 1 - res = source.skipWithTime(5000, [optional scheduler]);
4768
+ *
4769
+ * @description
4770
+ * Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
4771
+ * This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
4772
+ * may not execute immediately, despite the zero due time.
4773
+ *
4774
+ * Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
4775
+ * @param {Number} duration Duration for skipping elements from the start of the sequence.
4776
+ * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
4777
+ * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
4778
+ */
4779
+ observableProto.skipWithTime = function (duration, scheduler) {
4780
+ var source = this;
4781
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4782
+ return new AnonymousObservable(function (observer) {
4783
+ var open = false;
4784
+ return new CompositeDisposable(
4785
+ scheduler.scheduleWithRelative(duration, function () { open = true; }),
4786
+ source.subscribe(function (x) { open && observer.onNext(x); }, observer.onError.bind(observer), observer.onCompleted.bind(observer)));
4787
+ });
4788
+ };
4750
4789
 
4751
4790
  /**
4752
4791
  * Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
@@ -4760,7 +4799,7 @@
4760
4799
  * @returns {Observable} An observable sequence with the elements skipped until the specified start time.
4761
4800
  */
4762
4801
  observableProto.skipUntilWithTime = function (startTime, scheduler) {
4763
- scheduler || (scheduler = timeoutScheduler);
4802
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4764
4803
  var source = this, schedulerMethod = startTime instanceof Date ?
4765
4804
  'scheduleWithAbsolute' :
4766
4805
  'scheduleWithRelative';
@@ -4787,7 +4826,7 @@
4787
4826
  * @returns {Observable} An observable sequence with the elements taken until the specified end time.
4788
4827
  */
4789
4828
  observableProto.takeUntilWithTime = function (endTime, scheduler) {
4790
- scheduler || (scheduler = timeoutScheduler);
4829
+ isScheduler(scheduler) || (scheduler = timeoutScheduler);
4791
4830
  var source = this, schedulerMethod = endTime instanceof Date ?
4792
4831
  'scheduleWithAbsolute' :
4793
4832
  'scheduleWithRelative';
@@ -5198,6 +5237,116 @@
5198
5237
  ];
5199
5238
  };
5200
5239
 
5240
+ /*
5241
+ * Performs a exclusive waiting for the first to finish before subscribing to another observable.
5242
+ * Observables that come in between subscriptions will be dropped on the floor.
5243
+ * @returns {Observable} A exclusive observable with only the results that happen when subscribed.
5244
+ */
5245
+ observableProto.exclusive = function () {
5246
+ var sources = this;
5247
+ return new AnonymousObservable(function (observer) {
5248
+ var hasCurrent = false,
5249
+ isStopped = false,
5250
+ m = new SingleAssignmentDisposable(),
5251
+ g = new CompositeDisposable();
5252
+
5253
+ g.add(m);
5254
+
5255
+ m.setDisposable(sources.subscribe(
5256
+ function (innerSource) {
5257
+ if (!hasCurrent) {
5258
+ hasCurrent = true;
5259
+
5260
+ isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
5261
+
5262
+ var innerSubscription = new SingleAssignmentDisposable();
5263
+ g.add(innerSubscription);
5264
+
5265
+ innerSubscription.setDisposable(innerSource.subscribe(
5266
+ observer.onNext.bind(observer),
5267
+ observer.onError.bind(observer),
5268
+ function () {
5269
+ g.remove(innerSubscription);
5270
+ hasCurrent = false;
5271
+ if (isStopped && g.length === 1) {
5272
+ observer.onCompleted();
5273
+ }
5274
+ }));
5275
+ }
5276
+ },
5277
+ observer.onError.bind(observer),
5278
+ function () {
5279
+ isStopped = true;
5280
+ if (!hasCurrent && g.length === 1) {
5281
+ observer.onCompleted();
5282
+ }
5283
+ }));
5284
+
5285
+ return g;
5286
+ });
5287
+ };
5288
+ /*
5289
+ * Performs a exclusive map waiting for the first to finish before subscribing to another observable.
5290
+ * Observables that come in between subscriptions will be dropped on the floor.
5291
+ * @param {Function} selector Selector to invoke for every item in the current subscription.
5292
+ * @param {Any} [thisArg] An optional context to invoke with the selector parameter.
5293
+ * @returns {Observable} An exclusive observable with only the results that happen when subscribed.
5294
+ */
5295
+ observableProto.exclusiveMap = function (selector, thisArg) {
5296
+ var sources = this;
5297
+ return new AnonymousObservable(function (observer) {
5298
+ var index = 0,
5299
+ hasCurrent = false,
5300
+ isStopped = true,
5301
+ m = new SingleAssignmentDisposable(),
5302
+ g = new CompositeDisposable();
5303
+
5304
+ g.add(m);
5305
+
5306
+ m.setDisposable(sources.subscribe(
5307
+ function (innerSource) {
5308
+
5309
+ if (!hasCurrent) {
5310
+ hasCurrent = true;
5311
+
5312
+ innerSubscription = new SingleAssignmentDisposable();
5313
+ g.add(innerSubscription);
5314
+
5315
+ isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
5316
+
5317
+ innerSubscription.setDisposable(innerSource.subscribe(
5318
+ function (x) {
5319
+ var result;
5320
+ try {
5321
+ result = selector.call(thisArg, x, index++, innerSource);
5322
+ } catch (e) {
5323
+ observer.onError(e);
5324
+ return;
5325
+ }
5326
+
5327
+ observer.onNext(result);
5328
+ },
5329
+ observer.onError.bind(observer),
5330
+ function () {
5331
+ g.remove(innerSubscription);
5332
+ hasCurrent = false;
5333
+
5334
+ if (isStopped && g.length === 1) {
5335
+ observer.onCompleted();
5336
+ }
5337
+ }));
5338
+ }
5339
+ },
5340
+ observer.onError.bind(observer),
5341
+ function () {
5342
+ isStopped = true;
5343
+ if (g.length === 1 && !hasCurrent) {
5344
+ observer.onCompleted();
5345
+ }
5346
+ }));
5347
+ return g;
5348
+ });
5349
+ };
5201
5350
  var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
5202
5351
  inherits(AnonymousObservable, __super__);
5203
5352
 
@@ -5218,25 +5367,21 @@
5218
5367
  }
5219
5368
 
5220
5369
  function s(observer) {
5221
- var autoDetachObserver = new AutoDetachObserver(observer);
5222
- if (currentThreadScheduler.scheduleRequired()) {
5223
- currentThreadScheduler.schedule(function () {
5224
- try {
5225
- autoDetachObserver.setDisposable(fixSubscriber(subscribe(autoDetachObserver)));
5226
- } catch (e) {
5227
- if (!autoDetachObserver.fail(e)) {
5228
- throw e;
5229
- }
5230
- }
5231
- });
5232
- } else {
5370
+ var setDisposable = function () {
5233
5371
  try {
5234
5372
  autoDetachObserver.setDisposable(fixSubscriber(subscribe(autoDetachObserver)));
5235
5373
  } catch (e) {
5236
5374
  if (!autoDetachObserver.fail(e)) {
5237
5375
  throw e;
5238
- }
5376
+ }
5239
5377
  }
5378
+ };
5379
+
5380
+ var autoDetachObserver = new AutoDetachObserver(observer);
5381
+ if (currentThreadScheduler.scheduleRequired()) {
5382
+ currentThreadScheduler.schedule(setDisposable);
5383
+ } else {
5384
+ setDisposable();
5240
5385
  }
5241
5386
 
5242
5387
  return autoDetachObserver;