work.suroh.tk/node_modules/rx/dist/rx.js

6184 lines
207 KiB
JavaScript
Raw Normal View History

2019-12-02 12:22:45 +00:00
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = Date.now,
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) { for(var a = [], i = 0, len = arr.length; i < len; i++) { a.push(arr[i]); } return a;}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
schedulerProto.catchError = schedulerProto['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
}(Scheduler.prototype));
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
var CatchScheduler = (function (__super__) {
inherits(CatchScheduler, __super__);
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
__super__.call(this);
}
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () { return this._scheduler.now(); };
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) { thrower(res.e); }
return disposableEmpty;
}
return disposableFixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this, failed = false, d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) { return null; }
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) { thrower(res.e); }
d.dispose();
return null;
}
return res;
}));
return d;
};
return CatchScheduler;
}(Scheduler));
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var self = this;
return new AnonymousObserver(
function (x) { self.onNext(x); },
function (err) { self.onError(err); },
function () { self.onCompleted(); });
};
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var cb = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return cb(notificationCreateOnNext(x));
}, function (e) {
return cb(notificationCreateOnError(e));
}, function () {
return cb(notificationCreateOnCompleted());
});
};
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.prototype.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
Observer.prototype.makeSafe = function(disposable) {
return new AnonymousSafeObserver(this._onNext, this._onError, this._onCompleted, disposable);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Diposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var FromPromiseObservable = (function(__super__) {
inherits(FromPromiseObservable, __super__);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
__super__.call(this);
}
function scheduleNext(s, state) {
var o = state[0], data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0], err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function(o) {
var sad = new SingleAssignmentDisposable(), self = this, p = this._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p
.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
return FromPromiseObservable;
}(ObservableBase));
/**
* Converts a Promise to an Observable sequence
* @param {Promise} An ES6 Compliant promise.
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
var observableFromPromise = Observable.fromPromise = function (promise, scheduler) {
scheduler || (scheduler = defaultScheduler);
return new FromPromiseObservable(promise, scheduler);
};
/*
* Converts an existing observable sequence to an ES6 Compatible Promise
* @example
* var promise = Rx.Observable.return(42).toPromise(RSVP.Promise);
*
* // With config
* Rx.config.Promise = RSVP.Promise;
* var promise = Rx.Observable.return(42).toPromise();
* @param {Function} [promiseCtor] The constructor of the promise. If not provided, it looks for it in Rx.config.Promise.
* @returns {Promise} An ES6 compatible promise with the last value from the observable sequence.
*/
observableProto.toPromise = function (promiseCtor) {
promiseCtor || (promiseCtor = Rx.config.Promise);
if (!promiseCtor) { throw new NotSupportedError('Promise type not provided nor in Rx.config.Promise'); }
var source = this;
return new promiseCtor(function (resolve, reject) {
// No cancellation can be done
var value;
source.subscribe(function (v) {
value = v;
}, reject, function () {
resolve(value);
});
});
};
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers <IE9.
* @param {Mixed} value Single element in the resulting observable sequence.
* @param {Scheduler} scheduler Scheduler to send the single element on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence containing the single specified element.
*/
var observableReturn = Observable['return'] = Observable.just = function (value, scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new JustObservable(value, scheduler);
};
var ThrowObservable = (function(__super__) {
inherits(ThrowObservable, __super__);
function ThrowObservable(error, scheduler) {
this._error = error;
this._scheduler = scheduler;
__super__.call(this);
}
ThrowObservable.prototype.subscribeCore = function (o) {
var state = [this._error, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var e = state[0], o = state[1];
o.onError(e);
return disposableEmpty;
}
return ThrowObservable;
}(ObservableBase));
/**
* Returns an observable sequence that terminates with an exception, using the specified scheduler to send out the single onError message.
* There is an alias to this method called 'throwError' for browsers <IE9.
* @param {Mixed} error An object used for the sequence's termination.
* @param {Scheduler} scheduler Scheduler to send the exceptional termination call on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} The observable sequence that terminates exceptionally with the specified exception object.
*/
var observableThrow = Observable['throw'] = function (error, scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new ThrowObservable(error, scheduler);
};
var UsingObservable = (function (__super__) {
inherits(UsingObservable, __super__);
function UsingObservable(resFn, obsFn) {
this._resFn = resFn;
this._obsFn = obsFn;
__super__.call(this);
}
UsingObservable.prototype.subscribeCore = function (o) {
var disposable = disposableEmpty;
var resource = tryCatch(this._resFn)();
if (resource === errorObj) {
return new BinaryDisposable(observableThrow(resource.e).subscribe(o), disposable);
}
resource && (disposable = resource);
var source = tryCatch(this._obsFn)(resource);
if (source === errorObj) {
return new BinaryDisposable(observableThrow(source.e).subscribe(o), disposable);
}
return new BinaryDisposable(source.subscribe(o), disposable);
};
return UsingObservable;
}(ObservableBase));
/**
* Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
* @param {Function} resourceFactory Factory function to obtain a resource object.
* @param {Function} observableFactory Factory function to obtain an observable sequence that depends on the obtained resource.
* @returns {Observable} An observable sequence whose lifetime controls the lifetime of the dependent resource object.
*/
Observable.using = function (resourceFactory, observableFactory) {
return new UsingObservable(resourceFactory, observableFactory);
};
/**
* Propagates the observable sequence or Promise that reacts first.
* @param {Observable} rightSource Second observable sequence or Promise.
* @returns {Observable} {Observable} An observable sequence that surfaces either of the given sequences, whichever reacted first.
*/
observableProto.amb = function (rightSource) {
var leftSource = this;
return new AnonymousObservable(function (observer) {
var choice,
leftChoice = 'L', rightChoice = 'R',
leftSubscription = new SingleAssignmentDisposable(),
rightSubscription = new SingleAssignmentDisposable();
isPromise(rightSource) && (rightSource = observableFromPromise(rightSource));
function choiceL() {
if (!choice) {
choice = leftChoice;
rightSubscription.dispose();
}
}
function choiceR() {
if (!choice) {
choice = rightChoice;
leftSubscription.dispose();
}
}
var leftSubscribe = observerCreate(
function (left) {
choiceL();
choice === leftChoice && observer.onNext(left);
},
function (e) {
choiceL();
choice === leftChoice && observer.onError(e);
},
function () {
choiceL();
choice === leftChoice && observer.onCompleted();
}
);
var rightSubscribe = observerCreate(
function (right) {
choiceR();
choice === rightChoice && observer.onNext(right);
},
function (e) {
choiceR();
choice === rightChoice && observer.onError(e);
},
function () {
choiceR();
choice === rightChoice && observer.onCompleted();
}
);
leftSubscription.setDisposable(leftSource.subscribe(leftSubscribe));
rightSubscription.setDisposable(rightSource.subscribe(rightSubscribe));
return new BinaryDisposable(leftSubscription, rightSubscription);
});
};
function amb(p, c) { return p.amb(c); }
/**
* Propagates the observable sequence or Promise that reacts first.
* @returns {Observable} An observable sequence that surfaces any of the given sequences, whichever reacted first.
*/
Observable.amb = function () {
var acc = observableNever(), items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(items);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
for (var i = 0, len = items.length; i < len; i++) {
acc = amb(acc, items[i]);
}
return acc;
};
var CatchObservable = (function (__super__) {
inherits(CatchObservable, __super__);
function CatchObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
CatchObservable.prototype.subscribeCore = function (o) {
var d1 = new SingleAssignmentDisposable(), subscription = new SerialDisposable();
subscription.setDisposable(d1);
d1.setDisposable(this.source.subscribe(new CatchObserver(o, subscription, this._fn)));
return subscription;
};
return CatchObservable;
}(ObservableBase));
var CatchObserver = (function(__super__) {
inherits(CatchObserver, __super__);
function CatchObserver(o, s, fn) {
this._o = o;
this._s = s;
this._fn = fn;
__super__.call(this);
}
CatchObserver.prototype.next = function (x) { this._o.onNext(x); };
CatchObserver.prototype.completed = function () { return this._o.onCompleted(); };
CatchObserver.prototype.error = function (e) {
var result = tryCatch(this._fn)(e);
if (result === errorObj) { return this._o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
var d = new SingleAssignmentDisposable();
this._s.setDisposable(d);
d.setDisposable(result.subscribe(this._o));
};
return CatchObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated by an exception with the next observable sequence.
* @param {Mixed} handlerOrSecond Exception handler function that returns an observable sequence given the error that occurred in the first sequence, or a second observable sequence used to produce results when an error occurred in the first sequence.
* @returns {Observable} An observable sequence containing the first sequence's elements, followed by the elements of the handler sequence in case an exception occurred.
*/
observableProto['catch'] = function (handlerOrSecond) {
return isFunction(handlerOrSecond) ? new CatchObservable(this, handlerOrSecond) : observableCatch([this, handlerOrSecond]);
};
/**
* Continues an observable sequence that is terminated by an exception with the next observable sequence.
* @param {Array | Arguments} args Arguments or an array to use as the next sequence if an error occurs.
* @returns {Observable} An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully.
*/
var observableCatch = Observable['catch'] = function () {
var items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(len);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
return enumerableOf(items).catchError();
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element.
* This can be in the form of an argument list of observables or an array.
*
* @example
* 1 - obs = observable.combineLatest(obs1, obs2, obs3, function (o1, o2, o3) { return o1 + o2 + o3; });
* 2 - obs = observable.combineLatest([obs1, obs2, obs3], function (o1, o2, o3) { return o1 + o2 + o3; });
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.combineLatest = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args[0].unshift(this);
} else {
args.unshift(this);
}
return combineLatest.apply(this, args);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var CombineLatestObservable = (function(__super__) {
inherits(CombineLatestObservable, __super__);
function CombineLatestObservable(params, cb) {
this._params = params;
this._cb = cb;
__super__.call(this);
}
CombineLatestObservable.prototype.subscribeCore = function(observer) {
var len = this._params.length,
subscriptions = new Array(len);
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
isDone: arrayInitialize(len, falseFactory),
values: new Array(len)
};
for (var i = 0; i < len; i++) {
var source = this._params[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new CombineLatestObserver(observer, i, this._cb, state)));
}
return new NAryDisposable(subscriptions);
};
return CombineLatestObservable;
}(ObservableBase));
var CombineLatestObserver = (function (__super__) {
inherits(CombineLatestObserver, __super__);
function CombineLatestObserver(o, i, cb, state) {
this._o = o;
this._i = i;
this._cb = cb;
this._state = state;
__super__.call(this);
}
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
CombineLatestObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
if (this._state.hasValueAll || (this._state.hasValueAll = this._state.hasValue.every(identity))) {
var res = tryCatch(this._cb).apply(null, this._state.values);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._state.isDone.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
CombineLatestObserver.prototype.error = function (e) {
this._o.onError(e);
};
CombineLatestObserver.prototype.completed = function () {
this._state.isDone[this._i] = true;
this._state.isDone.every(identity) && this._o.onCompleted();
};
return CombineLatestObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element.
*
* @example
* 1 - obs = Rx.Observable.combineLatest(obs1, obs2, obs3, function (o1, o2, o3) { return o1 + o2 + o3; });
* 2 - obs = Rx.Observable.combineLatest([obs1, obs2, obs3], function (o1, o2, o3) { return o1 + o2 + o3; });
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
var combineLatest = Observable.combineLatest = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new CombineLatestObservable(args, resultSelector);
};
/**
* Concatenates all the observable sequences. This takes in either an array or variable arguments to concatenate.
* @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
*/
observableProto.concat = function () {
for(var args = [], i = 0, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
args.unshift(this);
return observableConcat.apply(null, args);
};
var ConcatObserver = (function(__super__) {
inherits(ConcatObserver, __super__);
function ConcatObserver(s, fn) {
this._s = s;
this._fn = fn;
__super__.call(this);
}
ConcatObserver.prototype.next = function (x) { this._s.o.onNext(x); };
ConcatObserver.prototype.error = function (e) { this._s.o.onError(e); };
ConcatObserver.prototype.completed = function () { this._s.i++; this._fn(this._s); };
return ConcatObserver;
}(AbstractObserver));
var ConcatObservable = (function(__super__) {
inherits(ConcatObservable, __super__);
function ConcatObservable(sources) {
this._sources = sources;
__super__.call(this);
}
function scheduleRecursive (state, recurse) {
if (state.disposable.isDisposed) { return; }
if (state.i === state.sources.length) { return state.o.onCompleted(); }
// Check if promise
var currentValue = state.sources[state.i];
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new ConcatObserver(state, recurse)));
}
ConcatObservable.prototype.subscribeCore = function(o) {
var subscription = new SerialDisposable();
var disposable = disposableCreate(noop);
var state = {
o: o,
i: 0,
subscription: subscription,
disposable: disposable,
sources: this._sources
};
var cancelable = immediateScheduler.scheduleRecursive(state, scheduleRecursive);
return new NAryDisposable([subscription, disposable, cancelable]);
};
return ConcatObservable;
}(ObservableBase));
/**
* Concatenates all the observable sequences.
* @param {Array | Arguments} args Arguments or an array to concat to the observable sequence.
* @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
*/
var observableConcat = Observable.concat = function () {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(arguments.length);
for(var i = 0, len = arguments.length; i < len; i++) { args[i] = arguments[i]; }
}
return new ConcatObservable(args);
};
/**
* Concatenates an observable sequence of observable sequences.
* @returns {Observable} An observable sequence that contains the elements of each observed inner sequence, in sequential order.
*/
observableProto.concatAll = function () {
return this.merge(1);
};
var MergeObservable = (function (__super__) {
inherits(MergeObservable, __super__);
function MergeObservable(source, maxConcurrent) {
this.source = source;
this.maxConcurrent = maxConcurrent;
__super__.call(this);
}
MergeObservable.prototype.subscribeCore = function(observer) {
var g = new CompositeDisposable();
g.add(this.source.subscribe(new MergeObserver(observer, this.maxConcurrent, g)));
return g;
};
return MergeObservable;
}(ObservableBase));
var MergeObserver = (function (__super__) {
function MergeObserver(o, max, g) {
this.o = o;
this.max = max;
this.g = g;
this.done = false;
this.q = [];
this.activeCount = 0;
__super__.call(this);
}
inherits(MergeObserver, __super__);
MergeObserver.prototype.handleSubscribe = function (xs) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(xs) && (xs = observableFromPromise(xs));
sad.setDisposable(xs.subscribe(new InnerObserver(this, sad)));
};
MergeObserver.prototype.next = function (innerSource) {
if(this.activeCount < this.max) {
this.activeCount++;
this.handleSubscribe(innerSource);
} else {
this.q.push(innerSource);
}
};
MergeObserver.prototype.error = function (e) { this.o.onError(e); };
MergeObserver.prototype.completed = function () { this.done = true; this.activeCount === 0 && this.o.onCompleted(); };
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) { this.parent.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this.parent.o.onError(e); };
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
if (this.parent.q.length > 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* 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.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
/**
* Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.concatMapObserver = observableProto.selectConcatObserver = function(onNext, onError, onCompleted, thisArg) {
var source = this,
onNextFunc = bindCallback(onNext, thisArg, 2),
onErrorFunc = bindCallback(onError, thisArg, 1),
onCompletedFunc = bindCallback(onCompleted, thisArg, 0);
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNextFunc(x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onErrorFunc(err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompletedFunc();
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, this).concatAll();
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
/**
* Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.flatMapObserver = observableProto.selectManyObserver = function (onNext, onError, onCompleted, thisArg) {
var source = this;
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNext.call(thisArg, x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onError.call(thisArg, err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompleted.call(thisArg);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, source).mergeAll();
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case <paramref name="count count</paramref> is set to 0.
* @returns {Observable} An observable sequence that contains the specified number of elements from the start of the input sequence.
*/
observableProto.take = function (count, scheduler) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
if (count === 0) { return observableEmpty(scheduler); }
return new TakeObservable(this, count);
};
var TakeWhileObservable = (function (__super__) {
inherits(TakeWhileObservable, __super__);
function TakeWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
TakeWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeWhileObserver(o, this));
};
return TakeWhileObservable;
}(ObservableBase));
var TakeWhileObserver = (function (__super__) {
inherits(TakeWhileObserver, __super__);
function TakeWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = true;
__super__.call(this);
}
TakeWhileObserver.prototype.next = function (x) {
if (this._r) {
this._r = tryCatch(this._p._fn)(x, this._i++, this._p);
if (this._r === errorObj) { return this._o.onError(this._r.e); }
}
if (this._r) {
this._o.onNext(x);
} else {
this._o.onCompleted();
}
};
TakeWhileObserver.prototype.error = function (e) { this._o.onError(e); };
TakeWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeWhileObserver;
}(AbstractObserver));
/**
* Returns elements from an observable sequence as long as a specified condition is true.
* The element's index is used in the logic of the predicate function.
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes.
*/
observableProto.takeWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new TakeWhileObservable(this, fn);
};
var FilterObservable = (function (__super__) {
inherits(FilterObservable, __super__);
function FilterObservable(source, predicate, thisArg) {
this.source = source;
this.predicate = bindCallback(predicate, thisArg, 3);
__super__.call(this);
}
FilterObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.predicate, this));
};
function innerPredicate(predicate, self) {
return function(x, i, o) { return self.predicate(x, i, o) && predicate.call(this, x, i, o); }
}
FilterObservable.prototype.internalFilter = function(predicate, thisArg) {
return new FilterObservable(this.source, innerPredicate(predicate, this), thisArg);
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, predicate, source) {
this.o = o;
this.predicate = predicate;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var shouldYield = tryCatch(this.predicate)(x, this.i++, this.source);
if (shouldYield === errorObj) {
return this.o.onError(shouldYield.e);
}
shouldYield && this.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return FilterObservable;
}(ObservableBase));
/**
* Filters the elements of an observable sequence based on a predicate by incorporating the element's index.
* @param {Function} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains elements from the input sequence that satisfy the condition.
*/
observableProto.filter = observableProto.where = function (predicate, thisArg) {
return this instanceof FilterObservable ? this.internalFilter(predicate, thisArg) :
new FilterObservable(this, predicate, thisArg);
};
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
var InnerSubscription = function (s, o) {
this._s = s;
this._o = o;
};
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));