just-build
Version:
A simple task runner that doesn't bloat your package
1,426 lines (1,363 loc) • 71.3 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var objectTypes = {
'boolean': false,
'function': true,
'object': true,
'number': false,
'string': false,
'undefined': false
};
var root = (objectTypes[typeof self] && self) || (objectTypes[typeof window] && window);
var freeGlobal = objectTypes[typeof global] && global;
if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
root = freeGlobal;
}
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 (Error) {
function UnsubscriptionError(errors) {
Error.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;
}
if ( Error ) UnsubscriptionError.__proto__ = Error;
UnsubscriptionError.prototype = Object.create( Error && Error.prototype );
UnsubscriptionError.prototype.constructor = UnsubscriptionError;
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 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 unsubscribe () {
var hasErrors = false;
var errors;
if (this.closed) {
return;
}
this.closed = true;
var ref = this;
var _unsubscribe = ref._unsubscribe;
var _subscriptions = ref._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$1 = tryCatch(sub.unsubscribe).call(sub);
if (trial$1 === 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 add (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 remove (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()));
var empty = {
closed: true,
next: function next(value) { },
error: function error(err) { throw err; },
complete: function complete() { }
};
var Symbol = root.Symbol;
var $$rxSubscriber = (typeof Symbol === 'function' && typeof Symbol.for === 'function') ?
Symbol.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 (Subscription$$1) {
function Subscriber(destinationOrNext, error, complete) {
Subscription$$1.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;
}
}
if ( Subscription$$1 ) Subscriber.__proto__ = Subscription$$1;
Subscriber.prototype = Object.create( Subscription$$1 && Subscription$$1.prototype );
Subscriber.prototype.constructor = Subscriber;
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 create (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 next (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 error (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 complete () {
if (!this.isStopped) {
this.isStopped = true;
this._complete();
}
};
Subscriber.prototype.unsubscribe = function unsubscribe () {
if (this.closed) {
return;
}
this.isStopped = true;
Subscription$$1.prototype.unsubscribe.call(this);
};
Subscriber.prototype._next = function _next (value) {
this.destination.next(value);
};
Subscriber.prototype._error = function _error (err) {
this.destination.error(err);
this.unsubscribe();
};
Subscriber.prototype._complete = function _complete () {
this.destination.complete();
this.unsubscribe();
};
return Subscriber;
}(Subscription));
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var SafeSubscriber = (function (Subscriber) {
function SafeSubscriber(_parent, observerOrNext, error, complete) {
Subscriber.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;
}
if ( Subscriber ) SafeSubscriber.__proto__ = Subscriber;
SafeSubscriber.prototype = Object.create( Subscriber && Subscriber.prototype );
SafeSubscriber.prototype.constructor = SafeSubscriber;
SafeSubscriber.prototype.next = function next (value) {
if (!this.isStopped && this._next) {
var ref = this;
var _parent = ref._parent;
if (!_parent.syncErrorThrowable) {
this.__tryOrUnsub(this._next, value);
}
else if (this.__tryOrSetError(_parent, this._next, value)) {
this.unsubscribe();
}
}
};
SafeSubscriber.prototype.error = function error (err) {
if (!this.isStopped) {
var ref = this;
var _parent = ref._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 complete () {
if (!this.isStopped) {
var ref = this;
var _parent = ref._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 __tryOrUnsub (fn, value) {
try {
fn.call(this._context, value);
}
catch (err) {
this.unsubscribe();
throw err;
}
};
SafeSubscriber.prototype.__tryOrSetError = function __tryOrSetError (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 _unsubscribe () {
var ref = this;
var _parent = ref._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();
}
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 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 lift (operator) {
var observable = new Observable();
observable.source = this;
observable.operator = operator;
return observable;
};
/**
* Registers handlers for handling emitted values, error and completions from the observable, and
* executes the observable's subscriber function, which will take action to set up the underlying data stream
* @method subscribe
* @param {PartialObserver|Function} observerOrNext (optional) either an observer defining all functions to be called,
* or the first of three possible handlers, which is the handler for each value emitted from the observable.
* @param {Function} error (optional) a handler for a terminal event resulting from an error. If no error handler is provided,
* the error will be thrown as unhandled
* @param {Function} complete (optional) a handler for a terminal event resulting from successful completion.
* @return {ISubscription} a subscription reference to the registered handlers
*/
Observable.prototype.subscribe = function subscribe (observerOrNext, error, complete) {
var ref = this;
var operator = ref.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 forEach (next, PromiseCtor) {
var this$1 = 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$1.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 _subscribe (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);
};
/**
* Applies a given `project` function to each value emitted by the source
* Observable, and emits the resulting values as an Observable.
*
* <span class="informal">Like [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),
* it passes each source value through a transformation function to get
* corresponding output values.</span>
*
* <img src="./img/map.png" width="100%">
*
* Similar to the well known `Array.prototype.map` function, this operator
* applies a projection to each value and emits that projection in the output
* Observable.
*
* @example <caption>Map every every click to the clientX position of that click</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var positions = clicks.map(ev => ev.clientX);
* positions.subscribe(x => console.log(x));
*
* @see {@link mapTo}
* @see {@link pluck}
*
* @param {function(value: T, index: number): R} project The function to apply
* to each `value` emitted by the source Observable. The `index` parameter is
* the number `i` for the i-th emission that has happened since the
* subscription, starting from the number `0`.
* @param {any} [thisArg] An optional argument to define what `this` is in the
* `project` function.
* @return {Observable<R>} An Observable that emits the values from the source
* Observable transformed by the given `project` function.
* @method map
* @owner Observable
*/
function map(project, thisArg) {
if (typeof project !== 'function') {
throw new TypeError('argument is not a function. Are you looking for `mapTo()`?');
}
return this.lift(new MapOperator(project, thisArg));
}
var MapOperator = function MapOperator(project, thisArg) {
this.project = project;
this.thisArg = thisArg;
};
MapOperator.prototype.call = function call (subscriber, source) {
return source._subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));
};
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var MapSubscriber = (function (Subscriber$$1) {
function MapSubscriber(destination, project, thisArg) {
Subscriber$$1.call(this, destination);
this.project = project;
this.count = 0;
this.thisArg = thisArg || this;
}
if ( Subscriber$$1 ) MapSubscriber.__proto__ = Subscriber$$1;
MapSubscriber.prototype = Object.create( Subscriber$$1 && Subscriber$$1.prototype );
MapSubscriber.prototype.constructor = MapSubscriber;
// NOTE: This looks unoptimized, but it's actually purposefully NOT
// using try/catch optimizations.
MapSubscriber.prototype._next = function _next (value) {
var result;
try {
result = this.project.call(this.thisArg, value, this.count++);
}
catch (err) {
this.destination.error(err);
return;
}
this.destination.next(result);
};
return MapSubscriber;
}(Subscriber));
Observable.prototype.map = map;
function isScheduler(value) {
return value && typeof value.schedule === 'function';
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
var ScalarObservable = (function (Observable$$1) {
function ScalarObservable(value, scheduler) {
Observable$$1.call(this);
this.value = value;
this.scheduler = scheduler;
this._isScalar = true;
if (scheduler) {
this._isScalar = false;
}
}
if ( Observable$$1 ) ScalarObservable.__proto__ = Observable$$1;
ScalarObservable.prototype = Object.create( Observable$$1 && Observable$$1.prototype );
ScalarObservable.prototype.constructor = ScalarObservable;
ScalarObservable.create = function create (value, scheduler) {
return new ScalarObservable(value, scheduler);
};
ScalarObservable.dispatch = function dispatch (state) {
var done = state.done;
var value = state.value;
var 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 _subscribe (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 (Observable$$1) {
function EmptyObservable(scheduler) {
Observable$$1.call(this);
this.scheduler = scheduler;
}
if ( Observable$$1 ) EmptyObservable.__proto__ = Observable$$1;
EmptyObservable.prototype = Object.create( Observable$$1 && Observable$$1.prototype );
EmptyObservable.prototype.constructor = EmptyObservable;
/**
* 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}
* @see {@link throw}
*
* @param {Scheduler} [scheduler] A {@link Scheduler} to use for scheduling
* the emission of the complete notification.
* @return {Observable} An "empty" Observable: emits only the complete
* notification.
* @static true
* @name empty
* @owner Observable
*/
EmptyObservable.create = function create (scheduler) {
return new EmptyObservable(scheduler);
};
EmptyObservable.dispatch = function dispatch (arg) {
var subscriber = arg.subscriber;
subscriber.complete();
};
EmptyObservable.prototype._subscribe = function _subscribe (subscriber) {
var scheduler = this.scheduler;
if (scheduler) {
return scheduler.schedule(EmptyObservable.dispatch, 0, { subscriber: subscriber });
}
else {
subscriber.complete();
}
};
return EmptyObservable;
}(Observable));
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
var ArrayObservable = (function (Observable$$1) {
function ArrayObservable(array, scheduler) {
Observable$$1.call(this);
this.array = array;
this.scheduler = scheduler;
if (!scheduler && array.length === 1) {
this._isScalar = true;
this.value = array[0];
}
}
if ( Observable$$1 ) ArrayObservable.__proto__ = Observable$$1;
ArrayObservable.prototype = Object.create( Observable$$1 && Observable$$1.prototype );
ArrayObservable.prototype.constructor = ArrayObservable;
ArrayObservable.create = function create (array, scheduler) {
return new ArrayObservable(array, scheduler);
};
/**
* Creates an Observable that emits some values you specify as arguments,
* immediately one after the other, and then emits a complete notification.
*
* <span class="informal">Emits the arguments you provide, then completes.
* </span>
*
* <img src="./img/of.png" width="100%">
*
* This static operator is useful for creating a simple Observable that only
* emits the arguments given, and the complete notification thereafter. It can
* be used for composing with other Observables, such as with {@link concat}.
* By default, it uses a `null` Scheduler, which means the `next`
* notifications are sent synchronously, although with a different Scheduler
* it is possible to determine when those notifications will be delivered.
*
* @example <caption>Emit 10, 20, 30, then 'a', 'b', 'c', then start ticking every second.</caption>
* var numbers = Rx.Observable.of(10, 20, 30);
* var letters = Rx.Observable.of('a', 'b', 'c');
* var interval = Rx.Observable.interval(1000);
* var result = numbers.concat(letters).concat(interval);
* result.subscribe(x => console.log(x));
*
* @see {@link create}
* @see {@link empty}
* @see {@link never}
* @see {@link throw}
*
* @param {...T} values Arguments that represent `next` values to be emitted.
* @param {Scheduler} [scheduler] A {@link Scheduler} to use for scheduling
* the emissions of the `next` notifications.
* @return {Observable<T>} An Observable that emits each given input value.
* @static true
* @name of
* @owner Observable
*/
ArrayObservable.of = function of () {
var array = [], len$1 = arguments.length;
while ( len$1-- ) array[ len$1 ] = arguments[ len$1 ];
var scheduler = array[array.length - 1];
if (isScheduler(scheduler)) {
array.pop();
}
else {
scheduler = null;
}
var len = array.length;
if (len > 1) {
return new ArrayObservable(array, scheduler);
}
else if (len === 1) {
return new ScalarObservable(array[0], scheduler);
}
else {
return new EmptyObservable(scheduler);
}
};
ArrayObservable.dispatch = function dispatch (state) {
var array = state.array;
var index = state.index;
var count = state.count;
var subscriber = state.subscriber;
if (index >= count) {
subscriber.complete();
return;
}
subscriber.next(array[index]);
if (subscriber.closed) {
return;
}
state.index = index + 1;
this.schedule(state);
};
ArrayObservable.prototype._subscribe = function _subscribe (subscriber) {
var index = 0;
var array = this.array;
var count = array.length;
var scheduler = this.scheduler;
if (scheduler) {
return scheduler.schedule(ArrayObservable.dispatch, 0, {
array: array, index: index, count: count, subscriber: subscriber
});
}
else {
for (var i = 0; i < count && !subscriber.closed; i++) {
subscriber.next(array[i]);
}
subscriber.complete();
}
};
return ArrayObservable;
}(Observable));
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var OuterSubscriber = (function (Subscriber$$1) {
function OuterSubscriber () {
Subscriber$$1.apply(this, arguments);
}
if ( Subscriber$$1 ) OuterSubscriber.__proto__ = Subscriber$$1;
OuterSubscriber.prototype = Object.create( Subscriber$$1 && Subscriber$$1.prototype );
OuterSubscriber.prototype.constructor = OuterSubscriber;
OuterSubscriber.prototype.notifyNext = function notifyNext (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
this.destination.next(innerValue);
};
OuterSubscriber.prototype.notifyError = function notifyError (error, innerSub) {
this.destination.error(error);
};
OuterSubscriber.prototype.notifyComplete = function notifyComplete (innerSub) {
this.destination.complete();
};
return OuterSubscriber;
}(Subscriber));
function isPromise(value) {
return value && typeof value.subscribe !== 'function' && typeof value.then === 'function';
}
var $$iterator;
var Symbol$1 = root.Symbol;
if (typeof Symbol$1 === 'function') {
if (Symbol$1.iterator) {
$$iterator = Symbol$1.iterator;
}
else if (typeof Symbol$1.for === 'function') {
$$iterator = Symbol$1.for('iterator');
}
}
else {
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
// Bug for mozilla version
$$iterator = '@@iterator';
}
else if (root.Map) {
// es6-shim specific logic
var keys = Object.getOwnPropertyNames(root.Map.prototype);
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
if (key !== 'entries' && key !== 'size' && root.Map.prototype[key] === root.Map.prototype['entries']) {
$$iterator = key;
break;
}
}
}
else {
$$iterator = '@@iterator';
}
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var InnerSubscriber = (function (Subscriber$$1) {
function InnerSubscriber(parent, outerValue, outerIndex) {
Subscriber$$1.call(this);
this.parent = parent;
this.outerValue = outerValue;
this.outerIndex = outerIndex;
this.index = 0;
}
if ( Subscriber$$1 ) InnerSubscriber.__proto__ = Subscriber$$1;
InnerSubscriber.prototype = Object.create( Subscriber$$1 && Subscriber$$1.prototype );
InnerSubscriber.prototype.constructor = InnerSubscriber;
InnerSubscriber.prototype._next = function _next (value) {
this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this);
};
InnerSubscriber.prototype._error = function _error (error) {
this.parent.notifyError(error, this);
this.unsubscribe();
};
InnerSubscriber.prototype._complete = function _complete () {
this.parent.notifyComplete(this);
this.unsubscribe();
};
return InnerSubscriber;
}(Subscriber));
function subscribeToResult(outerSubscriber, result, outerValue, outerIndex) {
var destination = new InnerSubscriber(outerSubscriber, outerValue, outerIndex);
if (destination.closed) {
return null;
}
if (result instanceof Observable) {
if (result._isScalar) {
destination.next(result.value);
destination.complete();
return null;
}
else {
return result.subscribe(destination);
}
}
if (isArray(result)) {
for (var i = 0, len = result.length; i < len && !destination.closed; i++) {
destination.next(result[i]);
}
if (!destination.closed) {
destination.complete();
}
}
else if (isPromise(result)) {
result.then(function (value) {
if (!destination.closed) {
destination.next(value);
destination.complete();
}
}, function (err) { return destination.error(err); })
.then(null, function (err) {
// Escaping the Promise trap: globally throw unhandled errors
root.setTimeout(function () { throw err; });
});
return destination;
}
else if (typeof result[$$iterator] === 'function') {
var iterator = result[$$iterator]();
do {
var item = iterator.next();
if (item.done) {
destination.complete();
break;
}
destination.next(item.value);
if (destination.closed) {
break;
}
} while (true);
}
else if (typeof result[$$observable] === 'function') {
var obs = result[$$observable]();
if (typeof obs.subscribe !== 'function') {
destination.error(new Error('invalid observable'));
}
else {
return obs.subscribe(new InnerSubscriber(outerSubscriber, outerValue, outerIndex));
}
}
else {
destination.error(new TypeError('unknown type returned'));
}
return null;
}
/**
* Converts a higher-order Observable into a first-order Observable which
* concurrently delivers all values that are emitted on the inner Observables.
*
* <span class="informal">Flattens an Observable-of-Observables.</span>
*
* <img src="./img/mergeAll.png" width="100%">
*
* `mergeAll` subscribes to an Observable that emits Observables, also known as
* a higher-order Observable. Each time it observes one of these emitted inner
* Observables, it subscribes to that and delivers all the values from the
* inner Observable on the output Observable. The output Observable only
* completes once all inner Observables have completed. Any error delivered by
* a inner Observable will be immediately emitted on the output Observable.
*
* @example <caption>Spawn a new interval Observable for each click event, and blend their outputs as one Observable</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000));
* var firstOrder = higherOrder.mergeAll();
* firstOrder.subscribe(x => console.log(x));
*
* @example <caption>Count from 0 to 9 every second for each click, but only allow 2 concurrent timers</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000).take(10));
* var firstOrder = higherOrder.mergeAll(2);
* firstOrder.subscribe(x => console.log(x));
*
* @see {@link combineAll}
* @see {@link concatAll}
* @see {@link exhaust}
* @see {@link merge}
* @see {@link mergeMap}
* @see {@link mergeMapTo}
* @see {@link mergeScan}
* @see {@link switch}
* @see {@link zipAll}
*
* @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of inner
* Observables being subscribed to concurrently.
* @return {Observable} An Observable that emits values coming from all the
* inner Observables emitted by the source Observable.
* @method mergeAll
* @owner Observable
*/
var MergeAllOperator = function MergeAllOperator(concurrent) {
this.concurrent = concurrent;
};
MergeAllOperator.prototype.call = function call (observer, source) {
return source._subscribe(new MergeAllSubscriber(observer, this.concurrent));
};
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var MergeAllSubscriber = (function (OuterSubscriber$$1) {
function MergeAllSubscriber(destination, concurrent) {
OuterSubscriber$$1.call(this, destination);
this.concurrent = concurrent;
this.hasCompleted = false;
this.buffer = [];
this.active = 0;
}
if ( OuterSubscriber$$1 ) MergeAllSubscriber.__proto__ = OuterSubscriber$$1;
MergeAllSubscriber.prototype = Object.create( OuterSubscriber$$1 && OuterSubscriber$$1.prototype );
MergeAllSubscriber.prototype.constructor = MergeAllSubscriber;
MergeAllSubscriber.prototype._next = function _next (observable) {
if (this.active < this.concurrent) {
this.active++;
this.add(subscribeToResult(this, observable));
}
else {
this.buffer.push(observable);
}
};
MergeAllSubscriber.prototype._complete = function _complete () {
this.hasCompleted = true;
if (this.active === 0 && this.buffer.length === 0) {
this.destination.complete();
}
};
MergeAllSubscriber.prototype.notifyComplete = function notifyComplete (innerSub) {
var buffer = this.buffer;
this.remove(innerSub);
this.active--;
if (buffer.length > 0) {
this._next(buffer.shift());
}
else if (this.active === 0 && this.hasCompleted) {
this.destination.complete();
}
};
return MergeAllSubscriber;
}(OuterSubscriber));
/**
* Creates an output Observable which sequentially emits all values from every
* given input Observable after the current Observable.
*
* <span class="informal">Concatenates multiple Observables together by
* sequentially emitting their values, one Observable after the other.</span>
*
* <img src="./img/concat.png" width="100%">
*
* Joins this Observable with multiple other Observables by subscribing to them
* one at a time, starting with the source, and merging their results into the
* output Observable. Will wait for each Observable to complete before moving
* on to the next.
*
* @example <caption>Concatenate a timer counting from 0 to 3 with a synchronous sequence from 1 to 10</caption>
* var timer = Rx.Observable.interval(1000).take(4);
* var sequence = Rx.Observable.range(1, 10);
* var result = timer.concat(sequence);
* result.subscribe(x => console.log(x));
*
* @example <caption>Concatenate 3 Observables</caption>
* var timer1 = Rx.Observable.interval(1000).take(10);
* var timer2 = Rx.Observable.interval(2000).take(6);
* var timer3 = Rx.Observable.interval(500).take(10);
* var result = timer1.concat(timer2, timer3);
* result.subscribe(x => console.log(x));
*
* @see {@link concatAll}
* @see {@link concatMap}
* @see {@link concatMapTo}
*
* @param {Observable} other An input Observable to concatenate after the source
* Observable. More than one input Observables may be given as argument.
* @param {Scheduler} [scheduler=null] An optional Scheduler to schedule each
* Observable subscription on.
* @return {Observable} All values of each passed Observable merged into a
* single Observable, in order, in serial fashion.
* @method concat
* @owner Observable
*/
function concat() {
var observables = [], len = arguments.length;
while ( len-- ) observables[ len ] = arguments[ len ];
return concatStatic.apply(void 0, [ this ].concat( observables ));
}
/* tslint:enable:max-line-length */
/**
* Creates an output Observable which sequentially emits all values from every
* given input Observable after the current Observable.
*
* <span class="informal">Concatenates multiple Observables together by
* sequentially emitting their values, one Observable after the other.</span>
*
* <img src="./img/concat.png" width="100%">
*
* Joins multiple Observables together by subscribing to them one at a time and
* merging their results into the output Observable. Will wait for each
* Observable to complete before moving on to the next.
*
* @example <caption>Concatenate a timer counting from 0 to 3 with a synchronous sequence from 1 to 10</caption>
* var timer = Rx.Observable.interval(1000).take(4);
* var sequence = Rx.Observable.range(1, 10);
* var result = Rx.Observable.concat(timer, sequence);
* result.subscribe(x => console.log(x));
*
* @example <caption>Concatenate 3 Observables</caption>
* var timer1 = Rx.Observable.interval(1000).take(10);
* var timer2 = Rx.Observable.interval(2000).take(6);
* var timer3 = Rx.Observable.interval(500).take(10);
* var result = Rx.Observable.concat(timer1, timer2, timer3);
* result.subscribe(x => console.log(x));
*
* @see {@link concatAll}
* @see {@link concatMap}
* @see {@link concatMapTo}
*
* @param {Observable} input1 An input Observable to concatenate with others.
* @param {Observable} input2 An input Observable to concatenate with others.
* More than one input Observables may be given as argument.
* @param {Scheduler} [scheduler=null] An optional Scheduler to schedule each
* Observable subscription on.
* @return {Observable} All values of each passed Observable merged into a
* single Observable, in order, in serial fashion.
* @static true
* @name concat
* @owner Observable
*/
function concatStatic() {
var observables = [], len = arguments.length;
while ( len-- ) observables[ len ] = arguments[ len ];
var scheduler = null;
var args = observables;
if (isScheduler(args[observables.length - 1])) {
scheduler = args.pop();
}
return new ArrayObservable(observables, scheduler).lift(new MergeAllOperator(1));
}
Observable.prototype.concat = concat;
/**
* Applies an accumulator function over the source Observable, and returns each
* intermediate result, with an optional seed value.
*
* <span class="informal">It's like {@link reduce}, but emits the current
* accumulation whenever the source emits a value.</span>
*
* <img src="./img/scan.png" width="100%">
*
* Combines together all values emitted on the source, using an accumulator
* function that knows how to join a new source value into the accumulation from
* the past. Is similar to {@link reduce}, but emits the intermediate
* accumulations.
*
* Returns an Observable that applies a specified `accumulator` function to each
* item emitted by the source Observable. If a `seed` value is specified, then
* that value will be used as the initial value for the accumulator. If no seed
* value is specified, the first item of the source is used as the seed.
*
* @example <caption>Count the number of click events</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var ones = clicks.mapTo(1);
* var seed = 0;
* var count = ones.scan((acc, one) => acc + one, seed);
* count.subscribe(x => console.log(x));
*
* @see {@link expand}
* @see {@link mergeScan}
* @see {@link reduce}
*
* @param {function(acc: R, value: T, index: number): R} accumulator
* The accumulator function called on each source value.
* @param {T|R} [seed] The initial accumulation value.
* @return {Observable<R>} An observable of the accumulated values.
* @method scan
* @owner Observable
*/
function scan(accumulator, seed) {
return this.lift(new ScanOperator(accumulator, seed));
}
var ScanOperator = function ScanOperator(accumulator, seed) {
this.accumulator = accumulator;
this.seed = seed;
};
ScanOperator.prototype.call = function call (subscriber, source) {
return source._subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed));
};
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var ScanSubscriber = (function (Subscriber$$1) {
function ScanSubscriber(destination, accumulator, seed) {
Subscriber$$1.call(this, destination);
this.accumulator = accumulator;
this.index = 0;
this.accumulatorSet = false;
this.seed = seed;
this.accumulatorSet = typeof seed !== 'undefined';
}
if ( Subscriber$$1 ) ScanSubscriber.__proto__ = Subscriber$$1;
ScanSubscriber.prototype = Object.create( Subscriber$$1 && Subscriber$$1.prototype );
ScanSubscriber.prototype.constructor = ScanSubscriber;
var prototypeAccessors = { seed: {} };
prototypeAccessors.seed.get = function () {
return this._seed;
};
prototypeAccessors.seed.set = function (value) {
this.accumulatorSet = true;
this._seed = value;
};
ScanSubscriber.prototype._next = function _next (value) {
if (!this.accumulatorSet) {
this.seed = value;
this.destination.next(value);
}
else {
return this._tryNext(value);
}
};
ScanSubscriber.prototype._tryNext = function _tryNext (value) {
var index = this.index++;
var result;
try {
result = this.accumulator(this.seed, value, index);
}
catch (err) {
this.destination.error(err);
}
this.seed = result;
this.destination.next(result);
};
Object.defineProperties( ScanSubscriber.prototype, prototypeAccessors );
return ScanSubscriber;
}(Subscriber));
Observable.prototype.scan = scan;
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
var PromiseObservable = (function (Observable$$1) {
function PromiseObservable(promise, scheduler) {
Observable$$1.call(this);
this.promise = promise;
this.scheduler = scheduler;
}
if (