@reactivex/rxjs
Version:
Reactive Extensions for modern JavaScript
1,358 lines (1,322 loc) • 483 kB
JavaScript
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global global, define, System, Reflect, Promise */
var __extends;
var __assign;
var __decorate;
var __param;
var __metadata;
var __awaiter;
(function (factory) {
var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
if (typeof System === "object" && typeof System.register === "function") {
System.register("tslib", [], function (exporter) {
factory(createExporter(root, exporter));
return { setters: [], execute: function() { } };
});
}
else if (typeof define === "function" && define.amd) {
define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
}
else if (typeof module === "object" && typeof module.exports === "object") {
factory(createExporter(root, createExporter(module.exports)));
}
else {
factory(createExporter(root));
}
function createExporter(exports, previous) {
return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
}
})
(function (exporter) {
__extends = function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
__assign = Object.assign || function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
__decorate = function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
__param = function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
__metadata = function (metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
};
__awaiter = function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
exporter("__extends", __extends);
exporter("__assign", __assign);
exporter("__decorate", __decorate);
exporter("__param", __param);
exporter("__metadata", __metadata);
exporter("__awaiter", __awaiter);
});(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.Rx = global.Rx || {})));
}(this, (function (exports) { 'use strict';
/**
* window: browser in DOM main thread
* self: browser in WebWorker
* global: Node.js/other
*/
var root = (typeof window == 'object' && window.window === window && window
|| typeof self == 'object' && self.self === self && self
|| typeof global == 'object' && global.global === global && global);
if (!root) {
throw new Error('RxJS could not find any global context (window, self, global)');
}
function isFunction(x) {
return typeof x === 'function';
}
var isArray = Array.isArray || (function (x) { return x && typeof x.length === 'number'; });
function isObject(x) {
return x != null && typeof x === 'object';
}
// typeof any so that it we don't have to cast when comparing a result to the error object
var errorObject = { e: {} };
var tryCatchTarget;
function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
}
catch (e) {
errorObject.e = e;
return errorObject;
}
}
function tryCatch(fn) {
tryCatchTarget = fn;
return tryCatcher;
}
/**
* An error thrown when one or more errors have occurred during the
* `unsubscribe` of a {@link Subscription}.
*/
var UnsubscriptionError = (function (_super) {
__extends(UnsubscriptionError, _super);
function UnsubscriptionError(errors) {
_super.call(this);
this.errors = errors;
var err = Error.call(this, errors ?
errors.length + " errors occurred during unsubscription:\n " + errors.map(function (err, i) { return ((i + 1) + ") " + err.toString()); }).join('\n ') : '');
this.name = err.name = 'UnsubscriptionError';
this.stack = err.stack;
this.message = err.message;
}
return UnsubscriptionError;
}(Error));
/**
* Represents a disposable resource, such as the execution of an Observable. A
* Subscription has one important method, `unsubscribe`, that takes no argument
* and just disposes the resource held by the subscription.
*
* Additionally, subscriptions may be grouped together through the `add()`
* method, which will attach a child Subscription to the current Subscription.
* When a Subscription is unsubscribed, all its children (and its grandchildren)
* will be unsubscribed as well.
*
* @class Subscription
*/
var Subscription = (function () {
/**
* @param {function(): void} [unsubscribe] A function describing how to
* perform the disposal of resources when the `unsubscribe` method is called.
*/
function Subscription(unsubscribe) {
/**
* A flag to indicate whether this Subscription has already been unsubscribed.
* @type {boolean}
*/
this.closed = false;
if (unsubscribe) {
this._unsubscribe = unsubscribe;
}
}
/**
* Disposes the resources held by the subscription. May, for instance, cancel
* an ongoing Observable execution or cancel any other type of work that
* started when the Subscription was created.
* @return {void}
*/
Subscription.prototype.unsubscribe = function () {
var hasErrors = false;
var errors;
if (this.closed) {
return;
}
this.closed = true;
var _a = this, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions;
this._subscriptions = null;
if (isFunction(_unsubscribe)) {
var trial = tryCatch(_unsubscribe).call(this);
if (trial === errorObject) {
hasErrors = true;
(errors = errors || []).push(errorObject.e);
}
}
if (isArray(_subscriptions)) {
var index = -1;
var len = _subscriptions.length;
while (++index < len) {
var sub = _subscriptions[index];
if (isObject(sub)) {
var trial = tryCatch(sub.unsubscribe).call(sub);
if (trial === errorObject) {
hasErrors = true;
errors = errors || [];
var err = errorObject.e;
if (err instanceof UnsubscriptionError) {
errors = errors.concat(err.errors);
}
else {
errors.push(err);
}
}
}
}
}
if (hasErrors) {
throw new UnsubscriptionError(errors);
}
};
/**
* Adds a tear down to be called during the unsubscribe() of this
* Subscription.
*
* If the tear down being added is a subscription that is already
* unsubscribed, is the same reference `add` is being called on, or is
* `Subscription.EMPTY`, it will not be added.
*
* If this subscription is already in an `closed` state, the passed
* tear down logic will be executed immediately.
*
* @param {TeardownLogic} teardown The additional logic to execute on
* teardown.
* @return {Subscription} Returns the Subscription used or created to be
* added to the inner subscriptions list. This Subscription can be used with
* `remove()` to remove the passed teardown logic from the inner subscriptions
* list.
*/
Subscription.prototype.add = function (teardown) {
if (!teardown || (teardown === Subscription.EMPTY)) {
return Subscription.EMPTY;
}
if (teardown === this) {
return this;
}
var sub = teardown;
switch (typeof teardown) {
case 'function':
sub = new Subscription(teardown);
case 'object':
if (sub.closed || typeof sub.unsubscribe !== 'function') {
break;
}
else if (this.closed) {
sub.unsubscribe();
}
else {
(this._subscriptions || (this._subscriptions = [])).push(sub);
}
break;
default:
throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.');
}
return sub;
};
/**
* Removes a Subscription from the internal list of subscriptions that will
* unsubscribe during the unsubscribe process of this Subscription.
* @param {Subscription} subscription The subscription to remove.
* @return {void}
*/
Subscription.prototype.remove = function (subscription) {
// HACK: This might be redundant because of the logic in `add()`
if (subscription == null || (subscription === this) || (subscription === Subscription.EMPTY)) {
return;
}
var subscriptions = this._subscriptions;
if (subscriptions) {
var subscriptionIndex = subscriptions.indexOf(subscription);
if (subscriptionIndex !== -1) {
subscriptions.splice(subscriptionIndex, 1);
}
}
};
Subscription.EMPTY = (function (empty) {
empty.closed = true;
return empty;
}(new Subscription()));
return Subscription;
}());
var empty = {
closed: true,
next: function (value) { },
error: function (err) { throw err; },
complete: function () { }
};
var Symbol$1 = root.Symbol;
var $$rxSubscriber = (typeof Symbol$1 === 'function' && typeof Symbol$1.for === 'function') ?
Symbol$1.for('rxSubscriber') : '@@rxSubscriber';
/**
* Implements the {@link Observer} interface and extends the
* {@link Subscription} class. While the {@link Observer} is the public API for
* consuming the values of an {@link Observable}, all Observers get converted to
* a Subscriber, in order to provide Subscription-like capabilities such as
* `unsubscribe`. Subscriber is a common type in RxJS, and crucial for
* implementing operators, but it is rarely used as a public API.
*
* @class Subscriber<T>
*/
var Subscriber = (function (_super) {
__extends(Subscriber, _super);
/**
* @param {Observer|function(value: T): void} [destinationOrNext] A partially
* defined Observer or a `next` callback function.
* @param {function(e: ?any): void} [error] The `error` callback of an
* Observer.
* @param {function(): void} [complete] The `complete` callback of an
* Observer.
*/
function Subscriber(destinationOrNext, error, complete) {
_super.call(this);
this.syncErrorValue = null;
this.syncErrorThrown = false;
this.syncErrorThrowable = false;
this.isStopped = false;
switch (arguments.length) {
case 0:
this.destination = empty;
break;
case 1:
if (!destinationOrNext) {
this.destination = empty;
break;
}
if (typeof destinationOrNext === 'object') {
if (destinationOrNext instanceof Subscriber) {
this.destination = destinationOrNext;
this.destination.add(this);
}
else {
this.syncErrorThrowable = true;
this.destination = new SafeSubscriber(this, destinationOrNext);
}
break;
}
default:
this.syncErrorThrowable = true;
this.destination = new SafeSubscriber(this, destinationOrNext, error, complete);
break;
}
}
Subscriber.prototype[$$rxSubscriber] = function () { return this; };
/**
* A static factory for a Subscriber, given a (potentially partial) definition
* of an Observer.
* @param {function(x: ?T): void} [next] The `next` callback of an Observer.
* @param {function(e: ?any): void} [error] The `error` callback of an
* Observer.
* @param {function(): void} [complete] The `complete` callback of an
* Observer.
* @return {Subscriber<T>} A Subscriber wrapping the (partially defined)
* Observer represented by the given arguments.
*/
Subscriber.create = function (next, error, complete) {
var subscriber = new Subscriber(next, error, complete);
subscriber.syncErrorThrowable = false;
return subscriber;
};
/**
* The {@link Observer} callback to receive notifications of type `next` from
* the Observable, with a value. The Observable may call this method 0 or more
* times.
* @param {T} [value] The `next` value.
* @return {void}
*/
Subscriber.prototype.next = function (value) {
if (!this.isStopped) {
this._next(value);
}
};
/**
* The {@link Observer} callback to receive notifications of type `error` from
* the Observable, with an attached {@link Error}. Notifies the Observer that
* the Observable has experienced an error condition.
* @param {any} [err] The `error` exception.
* @return {void}
*/
Subscriber.prototype.error = function (err) {
if (!this.isStopped) {
this.isStopped = true;
this._error(err);
}
};
/**
* The {@link Observer} callback to receive a valueless notification of type
* `complete` from the Observable. Notifies the Observer that the Observable
* has finished sending push-based notifications.
* @return {void}
*/
Subscriber.prototype.complete = function () {
if (!this.isStopped) {
this.isStopped = true;
this._complete();
}
};
Subscriber.prototype.unsubscribe = function () {
if (this.closed) {
return;
}
this.isStopped = true;
_super.prototype.unsubscribe.call(this);
};
Subscriber.prototype._next = function (value) {
this.destination.next(value);
};
Subscriber.prototype._error = function (err) {
this.destination.error(err);
this.unsubscribe();
};
Subscriber.prototype._complete = function () {
this.destination.complete();
this.unsubscribe();
};
return Subscriber;
}(Subscription));
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var SafeSubscriber = (function (_super) {
__extends(SafeSubscriber, _super);
function SafeSubscriber(_parent, observerOrNext, error, complete) {
_super.call(this);
this._parent = _parent;
var next;
var context = this;
if (isFunction(observerOrNext)) {
next = observerOrNext;
}
else if (observerOrNext) {
context = observerOrNext;
next = observerOrNext.next;
error = observerOrNext.error;
complete = observerOrNext.complete;
if (isFunction(context.unsubscribe)) {
this.add(context.unsubscribe.bind(context));
}
context.unsubscribe = this.unsubscribe.bind(this);
}
this._context = context;
this._next = next;
this._error = error;
this._complete = complete;
}
SafeSubscriber.prototype.next = function (value) {
if (!this.isStopped && this._next) {
var _parent = this._parent;
if (!_parent.syncErrorThrowable) {
this.__tryOrUnsub(this._next, value);
}
else if (this.__tryOrSetError(_parent, this._next, value)) {
this.unsubscribe();
}
}
};
SafeSubscriber.prototype.error = function (err) {
if (!this.isStopped) {
var _parent = this._parent;
if (this._error) {
if (!_parent.syncErrorThrowable) {
this.__tryOrUnsub(this._error, err);
this.unsubscribe();
}
else {
this.__tryOrSetError(_parent, this._error, err);
this.unsubscribe();
}
}
else if (!_parent.syncErrorThrowable) {
this.unsubscribe();
throw err;
}
else {
_parent.syncErrorValue = err;
_parent.syncErrorThrown = true;
this.unsubscribe();
}
}
};
SafeSubscriber.prototype.complete = function () {
if (!this.isStopped) {
var _parent = this._parent;
if (this._complete) {
if (!_parent.syncErrorThrowable) {
this.__tryOrUnsub(this._complete);
this.unsubscribe();
}
else {
this.__tryOrSetError(_parent, this._complete);
this.unsubscribe();
}
}
else {
this.unsubscribe();
}
}
};
SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {
try {
fn.call(this._context, value);
}
catch (err) {
this.unsubscribe();
throw err;
}
};
SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) {
try {
fn.call(this._context, value);
}
catch (err) {
parent.syncErrorValue = err;
parent.syncErrorThrown = true;
return true;
}
return false;
};
SafeSubscriber.prototype._unsubscribe = function () {
var _parent = this._parent;
this._context = null;
this._parent = null;
_parent.unsubscribe();
};
return SafeSubscriber;
}(Subscriber));
function toSubscriber(nextOrObserver, error, complete) {
if (nextOrObserver) {
if (nextOrObserver instanceof Subscriber) {
return nextOrObserver;
}
if (nextOrObserver[$$rxSubscriber]) {
return nextOrObserver[$$rxSubscriber]();
}
}
if (!nextOrObserver && !error && !complete) {
return new Subscriber(empty);
}
return new Subscriber(nextOrObserver, error, complete);
}
function getSymbolObservable(context) {
var $$observable;
var Symbol = context.Symbol;
if (typeof Symbol === 'function') {
if (Symbol.observable) {
$$observable = Symbol.observable;
}
else {
$$observable = Symbol('observable');
Symbol.observable = $$observable;
}
}
else {
$$observable = '@@observable';
}
return $$observable;
}
var $$observable = getSymbolObservable(root);
/**
* A representation of any set of values over any amount of time. This the most basic building block
* of RxJS.
*
* @class Observable<T>
*/
var Observable = (function () {
/**
* @constructor
* @param {Function} subscribe the function that is called when the Observable is
* initially subscribed to. This function is given a Subscriber, to which new values
* can be `next`ed, or an `error` method can be called to raise an error, or
* `complete` can be called to notify of a successful completion.
*/
function Observable(subscribe) {
this._isScalar = false;
if (subscribe) {
this._subscribe = subscribe;
}
}
/**
* Creates a new Observable, with this Observable as the source, and the passed
* operator defined as the new observable's operator.
* @method lift
* @param {Operator} operator the operator defining the operation to take on the observable
* @return {Observable} a new observable with the Operator applied
*/
Observable.prototype.lift = function (operator) {
var observable = new Observable();
observable.source = this;
observable.operator = operator;
return observable;
};
Observable.prototype.subscribe = function (observerOrNext, error, complete) {
var operator = this.operator;
var sink = toSubscriber(observerOrNext, error, complete);
if (operator) {
operator.call(sink, this);
}
else {
sink.add(this._subscribe(sink));
}
if (sink.syncErrorThrowable) {
sink.syncErrorThrowable = false;
if (sink.syncErrorThrown) {
throw sink.syncErrorValue;
}
}
return sink;
};
/**
* @method forEach
* @param {Function} next a handler for each value emitted by the observable
* @param {PromiseConstructor} [PromiseCtor] a constructor function used to instantiate the Promise
* @return {Promise} a promise that either resolves on observable completion or
* rejects with the handled error
*/
Observable.prototype.forEach = function (next, PromiseCtor) {
var _this = this;
if (!PromiseCtor) {
if (root.Rx && root.Rx.config && root.Rx.config.Promise) {
PromiseCtor = root.Rx.config.Promise;
}
else if (root.Promise) {
PromiseCtor = root.Promise;
}
}
if (!PromiseCtor) {
throw new Error('no Promise impl found');
}
return new PromiseCtor(function (resolve, reject) {
var subscription = _this.subscribe(function (value) {
if (subscription) {
// if there is a subscription, then we can surmise
// the next handling is asynchronous. Any errors thrown
// need to be rejected explicitly and unsubscribe must be
// called manually
try {
next(value);
}
catch (err) {
reject(err);
subscription.unsubscribe();
}
}
else {
// if there is NO subscription, then we're getting a nexted
// value synchronously during subscription. We can just call it.
// If it errors, Observable's `subscribe` will ensure the
// unsubscription logic is called, then synchronously rethrow the error.
// After that, Promise will trap the error and send it
// down the rejection path.
next(value);
}
}, reject, resolve);
});
};
Observable.prototype._subscribe = function (subscriber) {
return this.source.subscribe(subscriber);
};
/**
* An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable
* @method Symbol.observable
* @return {Observable} this instance of the observable
*/
Observable.prototype[$$observable] = function () {
return this;
};
// HACK: Since TypeScript inherits static properties too, we have to
// fight against TypeScript here so Subject can have a different static create signature
/**
* Creates a new cold Observable by calling the Observable constructor
* @static true
* @owner Observable
* @method create
* @param {Function} subscribe? the subscriber function to be passed to the Observable constructor
* @return {Observable} a new cold observable
*/
Observable.create = function (subscribe) {
return new Observable(subscribe);
};
return Observable;
}());
/**
* An error thrown when an action is invalid because the object has been
* unsubscribed.
*
* @see {@link Subject}
* @see {@link BehaviorSubject}
*
* @class ObjectUnsubscribedError
*/
var ObjectUnsubscribedError = (function (_super) {
__extends(ObjectUnsubscribedError, _super);
function ObjectUnsubscribedError() {
var err = _super.call(this, 'object unsubscribed');
this.name = err.name = 'ObjectUnsubscribedError';
this.stack = err.stack;
this.message = err.message;
}
return ObjectUnsubscribedError;
}(Error));
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var SubjectSubscription = (function (_super) {
__extends(SubjectSubscription, _super);
function SubjectSubscription(subject, subscriber) {
_super.call(this);
this.subject = subject;
this.subscriber = subscriber;
this.closed = false;
}
SubjectSubscription.prototype.unsubscribe = function () {
if (this.closed) {
return;
}
this.closed = true;
var subject = this.subject;
var observers = subject.observers;
this.subject = null;
if (!observers || observers.length === 0 || subject.isStopped || subject.closed) {
return;
}
var subscriberIndex = observers.indexOf(this.subscriber);
if (subscriberIndex !== -1) {
observers.splice(subscriberIndex, 1);
}
};
return SubjectSubscription;
}(Subscription));
/**
* @class SubjectSubscriber<T>
*/
var SubjectSubscriber = (function (_super) {
__extends(SubjectSubscriber, _super);
function SubjectSubscriber(destination) {
_super.call(this, destination);
this.destination = destination;
}
return SubjectSubscriber;
}(Subscriber));
/**
* @class Subject<T>
*/
var Subject = (function (_super) {
__extends(Subject, _super);
function Subject() {
_super.call(this);
this.observers = [];
this.closed = false;
this.isStopped = false;
this.hasError = false;
this.thrownError = null;
}
Subject.prototype[$$rxSubscriber] = function () {
return new SubjectSubscriber(this);
};
Subject.prototype.lift = function (operator) {
var subject = new AnonymousSubject(this, this);
subject.operator = operator;
return subject;
};
Subject.prototype.next = function (value) {
if (this.closed) {
throw new ObjectUnsubscribedError();
}
if (!this.isStopped) {
var observers = this.observers;
var len = observers.length;
var copy = observers.slice();
for (var i = 0; i < len; i++) {
copy[i].next(value);
}
}
};
Subject.prototype.error = function (err) {
if (this.closed) {
throw new ObjectUnsubscribedError();
}
this.hasError = true;
this.thrownError = err;
this.isStopped = true;
var observers = this.observers;
var len = observers.length;
var copy = observers.slice();
for (var i = 0; i < len; i++) {
copy[i].error(err);
}
this.observers.length = 0;
};
Subject.prototype.complete = function () {
if (this.closed) {
throw new ObjectUnsubscribedError();
}
this.isStopped = true;
var observers = this.observers;
var len = observers.length;
var copy = observers.slice();
for (var i = 0; i < len; i++) {
copy[i].complete();
}
this.observers.length = 0;
};
Subject.prototype.unsubscribe = function () {
this.isStopped = true;
this.closed = true;
this.observers = null;
};
Subject.prototype._subscribe = function (subscriber) {
if (this.closed) {
throw new ObjectUnsubscribedError();
}
else if (this.hasError) {
subscriber.error(this.thrownError);
return Subscription.EMPTY;
}
else if (this.isStopped) {
subscriber.complete();
return Subscription.EMPTY;
}
else {
this.observers.push(subscriber);
return new SubjectSubscription(this, subscriber);
}
};
Subject.prototype.asObservable = function () {
var observable = new Observable();
observable.source = this;
return observable;
};
Subject.create = function (destination, source) {
return new AnonymousSubject(destination, source);
};
return Subject;
}(Observable));
/**
* @class AnonymousSubject<T>
*/
var AnonymousSubject = (function (_super) {
__extends(AnonymousSubject, _super);
function AnonymousSubject(destination, source) {
_super.call(this);
this.destination = destination;
this.source = source;
}
AnonymousSubject.prototype.next = function (value) {
var destination = this.destination;
if (destination && destination.next) {
destination.next(value);
}
};
AnonymousSubject.prototype.error = function (err) {
var destination = this.destination;
if (destination && destination.error) {
this.destination.error(err);
}
};
AnonymousSubject.prototype.complete = function () {
var destination = this.destination;
if (destination && destination.complete) {
this.destination.complete();
}
};
AnonymousSubject.prototype._subscribe = function (subscriber) {
var source = this.source;
if (source) {
return this.source.subscribe(subscriber);
}
else {
return Subscription.EMPTY;
}
};
return AnonymousSubject;
}(Subject));
/**
* @class AsyncSubject<T>
*/
var AsyncSubject = (function (_super) {
__extends(AsyncSubject, _super);
function AsyncSubject() {
_super.apply(this, arguments);
this.value = null;
this.hasNext = false;
this.hasCompleted = false;
}
AsyncSubject.prototype._subscribe = function (subscriber) {
if (this.hasCompleted && this.hasNext) {
subscriber.next(this.value);
subscriber.complete();
return Subscription.EMPTY;
}
else if (this.hasError) {
subscriber.error(this.thrownError);
return Subscription.EMPTY;
}
return _super.prototype._subscribe.call(this, subscriber);
};
AsyncSubject.prototype.next = function (value) {
if (!this.hasCompleted) {
this.value = value;
this.hasNext = true;
}
};
AsyncSubject.prototype.complete = function () {
this.hasCompleted = true;
if (this.hasNext) {
_super.prototype.next.call(this, this.value);
}
_super.prototype.complete.call(this);
};
return AsyncSubject;
}(Subject));
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
var BoundCallbackObservable = (function (_super) {
__extends(BoundCallbackObservable, _super);
function BoundCallbackObservable(callbackFunc, selector, args, scheduler) {
_super.call(this);
this.callbackFunc = callbackFunc;
this.selector = selector;
this.args = args;
this.scheduler = scheduler;
}
/* tslint:enable:max-line-length */
/**
* Converts a callback API to a function that returns an Observable.
*
* <span class="informal">Give it a function `f` of type `f(x, callback)` and
* it will return a function `g` that when called as `g(x)` will output an
* Observable.</span>
*
* `bindCallback` is not an operator because its input and output are not
* Observables. The input is a function `func` with some parameters, but the
* last parameter must be a callback function that `func` calls when it is
* done. The output of `bindCallback` is a function that takes the same
* parameters as `func`, except the last one (the callback). When the output
* function is called with arguments, it will return an Observable where the
* results will be delivered to.
*
* @example <caption>Convert jQuery's getJSON to an Observable API</caption>
* // Suppose we have jQuery.getJSON('/my/url', callback)
* var getJSONAsObservable = Rx.Observable.bindCallback(jQuery.getJSON);
* var result = getJSONAsObservable('/my/url');
* result.subscribe(x => console.log(x), e => console.error(e));
*
* @see {@link bindNodeCallback}
* @see {@link from}
* @see {@link fromPromise}
*
* @param {function} func Function with a callback as the last parameter.
* @param {function} [selector] A function which takes the arguments from the
* callback and maps those a value to emit on the output Observable.
* @param {Scheduler} [scheduler] The scheduler on which to schedule the
* callbacks.
* @return {function(...params: *): Observable} A function which returns the
* Observable that delivers the same values the callback would deliver.
* @static true
* @name bindCallback
* @owner Observable
*/
BoundCallbackObservable.create = function (func, selector, scheduler) {
if (selector === void 0) { selector = undefined; }
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i - 0] = arguments[_i];
}
return new BoundCallbackObservable(func, selector, args, scheduler);
};
};
BoundCallbackObservable.prototype._subscribe = function (subscriber) {
var callbackFunc = this.callbackFunc;
var args = this.args;
var scheduler = this.scheduler;
var subject = this.subject;
if (!scheduler) {
if (!subject) {
subject = this.subject = new AsyncSubject();
var handler = function handlerFn() {
var innerArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
innerArgs[_i - 0] = arguments[_i];
}
var source = handlerFn.source;
var selector = source.selector, subject = source.subject;
if (selector) {
var result_1 = tryCatch(selector).apply(this, innerArgs);
if (result_1 === errorObject) {
subject.error(errorObject.e);
}
else {
subject.next(result_1);
subject.complete();
}
}
else {
subject.next(innerArgs.length === 1 ? innerArgs[0] : innerArgs);
subject.complete();
}
};
// use named function instance to avoid closure.
handler.source = this;
var result = tryCatch(callbackFunc).apply(this, args.concat(handler));
if (result === errorObject) {
subject.error(errorObject.e);
}
}
return subject.subscribe(subscriber);
}
else {
return scheduler.schedule(BoundCallbackObservable.dispatch, 0, { source: this, subscriber: subscriber });
}
};
BoundCallbackObservable.dispatch = function (state) {
var self = this;
var source = state.source, subscriber = state.subscriber;
var callbackFunc = source.callbackFunc, args = source.args, scheduler = source.scheduler;
var subject = source.subject;
if (!subject) {
subject = source.subject = new AsyncSubject();
var handler = function handlerFn() {
var innerArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
innerArgs[_i - 0] = arguments[_i];
}
var source = handlerFn.source;
var selector = source.selector, subject = source.subject;
if (selector) {
var result_2 = tryCatch(selector).apply(this, innerArgs);
if (result_2 === errorObject) {
self.add(scheduler.schedule(dispatchError, 0, { err: errorObject.e, subject: subject }));
}
else {
self.add(scheduler.schedule(dispatchNext, 0, { value: result_2, subject: subject }));
}
}
else {
var value = innerArgs.length === 1 ? innerArgs[0] : innerArgs;
self.add(scheduler.schedule(dispatchNext, 0, { value: value, subject: subject }));
}
};
// use named function to pass values in without closure
handler.source = source;
var result = tryCatch(callbackFunc).apply(this, args.concat(handler));
if (result === errorObject) {
subject.error(errorObject.e);
}
}
self.add(subject.subscribe(subscriber));
};
return BoundCallbackObservable;
}(Observable));
function dispatchNext(arg) {
var value = arg.value, subject = arg.subject;
subject.next(value);
subject.complete();
}
function dispatchError(arg) {
var err = arg.err, subject = arg.subject;
subject.error(err);
}
var bindCallback = BoundCallbackObservable.create;
Observable.bindCallback = bindCallback;
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
var BoundNodeCallbackObservable = (function (_super) {
__extends(BoundNodeCallbackObservable, _super);
function BoundNodeCallbackObservable(callbackFunc, selector, args, scheduler) {
_super.call(this);
this.callbackFunc = callbackFunc;
this.selector = selector;
this.args = args;
this.scheduler = scheduler;
}
/* tslint:enable:max-line-length */
/**
* Converts a Node.js-style callback API to a function that returns an
* Observable.
*
* <span class="informal">It's just like {@link bindCallback}, but the
* callback is expected to be of type `callback(error, result)`.</span>
*
* `bindNodeCallback` is not an operator because its input and output are not
* Observables. The input is a function `func` with some parameters, but the
* last parameter must be a callback function that `func` calls when it is
* done. The callback function is expected to follow Node.js conventions,
* where the first argument to the callback is an error, while remaining
* arguments are the callback result. The output of `bindNodeCallback` is a
* function that takes the same parameters as `func`, except the last one (the
* callback). When the output function is called with arguments, it will
* return an Observable where the results will be delivered to.
*
* @example <caption>Read a file from the filesystem and get the data as an Observable</caption>
* import * as fs from 'fs';
* var readFileAsObservable = Rx.Observable.bindNodeCallback(fs.readFile);
* var result = readFileAsObservable('./roadNames.txt', 'utf8');
* result.subscribe(x => console.log(x), e => console.error(e));
*
* @see {@link bindCallback}
* @see {@link from}
* @see {@link fromPromise}
*
* @param {function} func Function with a callback as the last parameter.
* @param {function} [selector] A function which takes the arguments from the
* callback and maps those a value to emit on the output Observable.
* @param {Scheduler} [scheduler] The scheduler on which to schedule the
* callbacks.
* @return {function(...params: *): Observable} A function which returns the
* Observable that delivers the same values the Node.js callback would
* deliver.
* @static true
* @name bindNodeCallback
* @owner Observable
*/
BoundNodeCallbackObservable.create = function (func, selector, scheduler) {
if (selector === void 0) { selector = undefined; }
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i - 0] = arguments[_i];
}
return new BoundNodeCallbackObservable(func, selector, args, scheduler);
};
};
BoundNodeCallbackObservable.prototype._subscribe = function (subscriber) {
var callbackFunc = this.callbackFunc;
var args = this.args;
var scheduler = this.scheduler;
var subject = this.subject;
if (!scheduler) {
if (!subject) {
subject = this.subject = new AsyncSubject();
var handler = function handlerFn() {
var innerArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
innerArgs[_i - 0] = arguments[_i];
}
var source = handlerFn.source;
var selector = source.selector, subject = source.subject;
var err = innerArgs.shift();
if (err) {
subject.error(err);
}
else if (selector) {
var result_1 = tryCatch(selector).apply(this, innerArgs);
if (result_1 === errorObject) {
subject.error(errorObject.e);
}
else {
subject.next(result_1);
subject.complete();
}
}
else {
subject.next(innerArgs.length === 1 ? innerArgs[0] : innerArgs);
subject.complete();
}
};
// use named function instance to avoid closure.
handler.source = this;
var result = tryCatch(callbackFunc).apply(this, args.concat(handler));
if (result === errorObject) {
subject.error(errorObject.e);
}
}
return subject.subscribe(subscriber);
}
else {
return scheduler.schedule(dispatch, 0, { source: this, subscriber: subscriber });
}
};
return BoundNodeCallbackObservable;
}(Observable));
function dispatch(state) {
var self = this;
var source = state.source, subscriber = state.subscriber;
// XXX: cast to `any` to access to the private field in `source`.
var _a = source, callbackFunc = _a.callbackFunc, args = _a.args, scheduler = _a.scheduler;
var subject = source.subject;
if (!subject) {
subject = source.subject = new AsyncSubject();
var handler = function handlerFn() {
var innerArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
innerArgs[_i - 0] = arguments[_i];
}
var source = handlerFn.source;
var selector = source.selector, subject = source.subject;
var err = innerArgs.shift();
if (err) {
subject.error(err);
}
else if (selector) {
var result_2 = tryCatch(selector).apply(this, innerArgs);
if (result_2 === errorObject) {
self.add(scheduler.schedule(dispatchError$1, 0, { err: errorObject.e, subject: subject }));
}
else {
self.add(scheduler.schedule(dispatchNext$1, 0, { value: result_2, subject: subject }));
}
}
else {
var value = innerArgs.length === 1 ? innerArgs[0] : innerArgs;
self.add(scheduler.schedule(dispatchNext$1, 0, { value: value, subject: subject }));
}
};
// use named function to pass values in without closure
handler.source = source;
var result = tryCatch(callbackFunc).apply(this, args.concat(handler));
if (result === errorObject) {
subject.error(errorObject.e);
}
}
self.add(subject.subscribe(subscriber));
}
function dispatchNext$1(arg) {
var value = arg.value, subject = arg.subject;
subject.next(value);
subject.complete();
}
function dispatchError$1(arg) {
var err = arg.err, subject = arg.subject;
subject.error(err);
}
var bindNodeCallback = BoundNodeCallbackObservable.create;
Observable.bindNodeCallback = bindNodeCallback;
function isScheduler(value) {
return value && typeof value.schedule === 'function';
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
var ScalarObservable = (function (_super) {
__extends(ScalarObservable, _super);
function ScalarObservable(value, scheduler) {
_super.call(this);
this.value = value;
this.scheduler = scheduler;
this._isScalar = true;
if (scheduler) {
this._isScalar = false;
}
}
ScalarObservable.create = function (value, scheduler) {
return new ScalarObservable(value, scheduler);
};
ScalarObservable.dispatch = function (state) {
var done = state.done, value = state.value, subscriber = state.subscriber;
if (done) {
subscriber.complete();
return;
}
subscriber.next(value);
if (subscriber.closed) {
return;
}
state.done = true;
this.schedule(state);
};
ScalarObservable.prototype._subscribe = function (subscriber) {
var value = this.value;
var scheduler = this.scheduler;
if (scheduler) {
return scheduler.schedule(ScalarObservable.dispatch, 0, {
done: false, value: value, subscriber: subscriber
});
}
else {
subscriber.next(value);
if (!subscriber.closed) {
subscriber.complete();
}
}
};
return ScalarObservable;
}(Observable));
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
var EmptyObservable = (function (_super) {
__extends(EmptyObservable, _super);
function EmptyObservable(scheduler) {
_super.call(this);
this.scheduler = scheduler;
}
/**
* Creates an Observable that emits no items to the Observer and immediately
* emits a complete notification.
*
* <span class="informal">Just emits 'complete', and nothing else.
* </span>
*
* <img src="./img/empty.png" width="100%">
*
* This static operator is useful for creating a simple Observable that only
* emits the complete notification. It can be used for composing with other
* Observables, such as in a {@link mergeMap}.
*
* @example <caption>Emit the number 7, then complete.</caption>
* var result = Rx.Observable.empty().startWith(7);
* result.subscribe(x => console.log(x));
*
* @example <caption>Map and flatten only odd numbers to the sequence 'a', 'b', 'c'</caption>
* var interval = Rx.Observable.interval(1000);
* var result = interval.mergeMap(x =>
* x % 2 === 1 ? Rx.Observable.of('a', 'b', 'c') : Rx.Observable.empty()
* );
* result.subscribe(x => console.log(x));
*
* @see {@link create}
* @see {@link never}
* @see {@link of}