123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 |
- // Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
- ;(function (factory) {
- 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')();
- // Because of build optimizers
- if (typeof define === 'function' && define.amd) {
- define(['./rx'], function (Rx, exports) {
- return factory(root, exports, Rx);
- });
- } else if (typeof module === 'object' && module && module.exports === freeExports) {
- module.exports = factory(root, module.exports, require('./rx'));
- } else {
- root.Rx = factory(root, {}, root.Rx);
- }
- }.call(this, function (root, exp, Rx, undefined) {
- // Aliases
- var Observable = Rx.Observable,
- observableProto = Observable.prototype,
- ObservableBase = Rx.ObservableBase,
- AbstractObserver = Rx.internals.AbstractObserver,
- FlatMapObservable = Rx.FlatMapObservable,
- observableConcat = Observable.concat,
- observableDefer = Observable.defer,
- observableEmpty = Observable.empty,
- disposableEmpty = Rx.Disposable.empty,
- CompositeDisposable = Rx.CompositeDisposable,
- SerialDisposable = Rx.SerialDisposable,
- SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
- Enumerable = Rx.internals.Enumerable,
- enumerableOf = Enumerable.of,
- currentThreadScheduler = Rx.Scheduler.currentThread,
- AsyncSubject = Rx.AsyncSubject,
- Observer = Rx.Observer,
- inherits = Rx.internals.inherits,
- addProperties = Rx.internals.addProperties,
- helpers = Rx.helpers,
- noop = helpers.noop,
- isPromise = helpers.isPromise,
- isFunction = helpers.isFunction,
- isIterable = Rx.helpers.isIterable,
- isArrayLike = Rx.helpers.isArrayLike,
- isScheduler = Rx.Scheduler.isScheduler,
- observableFromPromise = Observable.fromPromise;
- 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;
- }
- // 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 WhileEnumerable = (function(__super__) {
- inherits(WhileEnumerable, __super__);
- function WhileEnumerable(c, s) {
- this.c = c;
- this.s = s;
- }
- WhileEnumerable.prototype[$iterator$] = function () {
- var self = this;
- return {
- next: function () {
- return self.c() ?
- { done: false, value: self.s } :
- { done: true, value: void 0 };
- }
- };
- };
- return WhileEnumerable;
- }(Enumerable));
-
- function enumerableWhile(condition, source) {
- return new WhileEnumerable(condition, source);
- }
- /**
- * Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions.
- * This operator allows for a fluent style of writing queries that use the same sequence multiple times.
- *
- * @param {Function} selector Selector function which can use the source sequence as many times as needed, without sharing subscriptions to the source sequence.
- * @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
- */
- observableProto.letBind = observableProto['let'] = function (func) {
- return func(this);
- };
- /**
- * Determines whether an observable collection contains values.
- *
- * @example
- * 1 - res = Rx.Observable.if(condition, obs1);
- * 2 - res = Rx.Observable.if(condition, obs1, obs2);
- * 3 - res = Rx.Observable.if(condition, obs1, scheduler);
- * @param {Function} condition The condition which determines if the thenSource or elseSource will be run.
- * @param {Observable} thenSource The observable sequence or Promise that will be run if the condition function returns true.
- * @param {Observable} [elseSource] The observable sequence or Promise that will be run if the condition function returns false. If this is not provided, it defaults to Rx.Observabe.Empty with the specified scheduler.
- * @returns {Observable} An observable sequence which is either the thenSource or elseSource.
- */
- Observable['if'] = function (condition, thenSource, elseSourceOrScheduler) {
- return observableDefer(function () {
- elseSourceOrScheduler || (elseSourceOrScheduler = observableEmpty());
- isPromise(thenSource) && (thenSource = observableFromPromise(thenSource));
- isPromise(elseSourceOrScheduler) && (elseSourceOrScheduler = observableFromPromise(elseSourceOrScheduler));
- // Assume a scheduler for empty only
- typeof elseSourceOrScheduler.now === 'function' && (elseSourceOrScheduler = observableEmpty(elseSourceOrScheduler));
- return condition() ? thenSource : elseSourceOrScheduler;
- });
- };
- /**
- * Concatenates the observable sequences obtained by running the specified result selector for each element in source.
- * There is an alias for this method called 'forIn' for browsers <IE9
- * @param {Array} sources An array of values to turn into an observable sequence.
- * @param {Function} resultSelector A function to apply to each item in the sources array to turn it into an observable sequence.
- * @returns {Observable} An observable sequence from the concatenated observable sequences.
- */
- Observable['for'] = Observable.forIn = function (sources, resultSelector, thisArg) {
- return enumerableOf(sources, resultSelector, thisArg).concat();
- };
- /**
- * Repeats source as long as condition holds emulating a while loop.
- * There is an alias for this method called 'whileDo' for browsers <IE9
- *
- * @param {Function} condition The condition which determines if the source will be repeated.
- * @param {Observable} source The observable sequence that will be run if the condition function returns true.
- * @returns {Observable} An observable sequence which is repeated as long as the condition holds.
- */
- var observableWhileDo = Observable['while'] = Observable.whileDo = function (condition, source) {
- isPromise(source) && (source = observableFromPromise(source));
- return enumerableWhile(condition, source).concat();
- };
- /**
- * Repeats source as long as condition holds emulating a do while loop.
- *
- * @param {Function} condition The condition which determines if the source will be repeated.
- * @param {Observable} source The observable sequence that will be run if the condition function returns true.
- * @returns {Observable} An observable sequence which is repeated as long as the condition holds.
- */
- observableProto.doWhile = function (condition) {
- return observableConcat([this, observableWhileDo(condition, this)]);
- };
- /**
- * Uses selector to determine which source in sources to use.
- * @param {Function} selector The function which extracts the value for to test in a case statement.
- * @param {Array} sources A object which has keys which correspond to the case statement labels.
- * @param {Observable} [elseSource] The observable sequence or Promise that will be run if the sources are not matched. If this is not provided, it defaults to Rx.Observabe.empty with the specified scheduler.
- *
- * @returns {Observable} An observable sequence which is determined by a case statement.
- */
- Observable['case'] = function (selector, sources, defaultSourceOrScheduler) {
- return observableDefer(function () {
- isPromise(defaultSourceOrScheduler) && (defaultSourceOrScheduler = observableFromPromise(defaultSourceOrScheduler));
- defaultSourceOrScheduler || (defaultSourceOrScheduler = observableEmpty());
- isScheduler(defaultSourceOrScheduler) && (defaultSourceOrScheduler = observableEmpty(defaultSourceOrScheduler));
- var result = sources[selector()];
- isPromise(result) && (result = observableFromPromise(result));
- return result || defaultSourceOrScheduler;
- });
- };
- var ExpandObservable = (function(__super__) {
- inherits(ExpandObservable, __super__);
- function ExpandObservable(source, fn, scheduler) {
- this.source = source;
- this._fn = fn;
- this._scheduler = scheduler;
- __super__.call(this);
- }
- function scheduleRecursive(args, recurse) {
- var state = args[0], self = args[1];
- var work;
- if (state.q.length > 0) {
- work = state.q.shift();
- } else {
- state.isAcquired = false;
- return;
- }
- var m1 = new SingleAssignmentDisposable();
- state.d.add(m1);
- m1.setDisposable(work.subscribe(new ExpandObserver(state, self, m1)));
- recurse([state, self]);
- }
- ExpandObservable.prototype._ensureActive = function (state) {
- var isOwner = false;
- if (state.q.length > 0) {
- isOwner = !state.isAcquired;
- state.isAcquired = true;
- }
- isOwner && state.m.setDisposable(this._scheduler.scheduleRecursive([state, this], scheduleRecursive));
- };
- ExpandObservable.prototype.subscribeCore = function (o) {
- var m = new SerialDisposable(),
- d = new CompositeDisposable(m),
- state = {
- q: [],
- m: m,
- d: d,
- activeCount: 0,
- isAcquired: false,
- o: o
- };
- state.q.push(this.source);
- state.activeCount++;
- this._ensureActive(state);
- return d;
- };
- return ExpandObservable;
- }(ObservableBase));
- var ExpandObserver = (function(__super__) {
- inherits(ExpandObserver, __super__);
- function ExpandObserver(state, parent, m1) {
- this._s = state;
- this._p = parent;
- this._m1 = m1;
- __super__.call(this);
- }
- ExpandObserver.prototype.next = function (x) {
- this._s.o.onNext(x);
- var result = tryCatch(this._p._fn)(x);
- if (result === errorObj) { return this._s.o.onError(result.e); }
- this._s.q.push(result);
- this._s.activeCount++;
- this._p._ensureActive(this._s);
- };
- ExpandObserver.prototype.error = function (e) {
- this._s.o.onError(e);
- };
- ExpandObserver.prototype.completed = function () {
- this._s.d.remove(this._m1);
- this._s.activeCount--;
- this._s.activeCount === 0 && this._s.o.onCompleted();
- };
- return ExpandObserver;
- }(AbstractObserver));
- /**
- * Expands an observable sequence by recursively invoking selector.
- *
- * @param {Function} selector Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
- * @param {Scheduler} [scheduler] Scheduler on which to perform the expansion. If not provided, this defaults to the current thread scheduler.
- * @returns {Observable} An observable sequence containing all the elements produced by the recursive expansion.
- */
- observableProto.expand = function (selector, scheduler) {
- isScheduler(scheduler) || (scheduler = currentThreadScheduler);
- return new ExpandObservable(this, selector, scheduler);
- };
- function argumentsToArray() {
- var len = arguments.length, args = new Array(len);
- for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
- return args;
- }
- var ForkJoinObservable = (function (__super__) {
- inherits(ForkJoinObservable, __super__);
- function ForkJoinObservable(sources, cb) {
- this._sources = sources;
- this._cb = cb;
- __super__.call(this);
- }
- ForkJoinObservable.prototype.subscribeCore = function (o) {
- if (this._sources.length === 0) {
- o.onCompleted();
- return disposableEmpty;
- }
- var count = this._sources.length;
- var state = {
- finished: false,
- hasResults: new Array(count),
- hasCompleted: new Array(count),
- results: new Array(count)
- };
- var subscriptions = new CompositeDisposable();
- for (var i = 0, len = this._sources.length; i < len; i++) {
- var source = this._sources[i];
- isPromise(source) && (source = observableFromPromise(source));
- subscriptions.add(source.subscribe(new ForkJoinObserver(o, state, i, this._cb, subscriptions)));
- }
- return subscriptions;
- };
- return ForkJoinObservable;
- }(ObservableBase));
- var ForkJoinObserver = (function(__super__) {
- inherits(ForkJoinObserver, __super__);
- function ForkJoinObserver(o, s, i, cb, subs) {
- this._o = o;
- this._s = s;
- this._i = i;
- this._cb = cb;
- this._subs = subs;
- __super__.call(this);
- }
- ForkJoinObserver.prototype.next = function (x) {
- if (!this._s.finished) {
- this._s.hasResults[this._i] = true;
- this._s.results[this._i] = x;
- }
- };
- ForkJoinObserver.prototype.error = function (e) {
- this._s.finished = true;
- this._o.onError(e);
- this._subs.dispose();
- };
- ForkJoinObserver.prototype.completed = function () {
- if (!this._s.finished) {
- if (!this._s.hasResults[this._i]) {
- return this._o.onCompleted();
- }
- this._s.hasCompleted[this._i] = true;
- for (var i = 0; i < this._s.results.length; i++) {
- if (!this._s.hasCompleted[i]) { return; }
- }
- this._s.finished = true;
- var res = tryCatch(this._cb).apply(null, this._s.results);
- if (res === errorObj) { return this._o.onError(res.e); }
- this._o.onNext(res);
- this._o.onCompleted();
- }
- };
- return ForkJoinObserver;
- }(AbstractObserver));
- /**
- * Runs all observable sequences in parallel and collect their last elements.
- *
- * @example
- * 1 - res = Rx.Observable.forkJoin([obs1, obs2]);
- * 1 - res = Rx.Observable.forkJoin(obs1, obs2, ...);
- * @returns {Observable} An observable sequence with an array collecting the last elements of all the input sequences.
- */
- Observable.forkJoin = 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 ForkJoinObservable(args, resultSelector);
- };
- /**
- * Runs two observable sequences in parallel and combines their last elemenets.
- * @param {Observable} second Second observable sequence.
- * @param {Function} resultSelector Result selector function to invoke with the last elements of both sequences.
- * @returns {Observable} An observable sequence with the result of calling the selector function with the last elements of both input sequences.
- */
- observableProto.forkJoin = 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 Observable.forkJoin.apply(null, args);
- };
- /**
- * Comonadic bind operator.
- * @param {Function} selector A transform function to apply to each element.
- * @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler.
- * @returns {Observable} An observable sequence which results from the comonadic bind operation.
- */
- observableProto.manySelect = observableProto.extend = function (selector, scheduler) {
- isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
- var source = this;
- return observableDefer(function () {
- var chain;
- return source
- .map(function (x) {
- var curr = new ChainObservable(x);
- chain && chain.onNext(x);
- chain = curr;
- return curr;
- })
- .tap(
- noop,
- function (e) { chain && chain.onError(e); },
- function () { chain && chain.onCompleted(); }
- )
- .observeOn(scheduler)
- .map(selector);
- }, source);
- };
- var ChainObservable = (function (__super__) {
- inherits(ChainObservable, __super__);
- function ChainObservable(head) {
- __super__.call(this);
- this.head = head;
- this.tail = new AsyncSubject();
- }
- addProperties(ChainObservable.prototype, Observer, {
- _subscribe: function (o) {
- var g = new CompositeDisposable();
- g.add(currentThreadScheduler.schedule(this, function (_, self) {
- o.onNext(self.head);
- g.add(self.tail.mergeAll().subscribe(o));
- }));
- return g;
- },
- onCompleted: function () {
- this.onNext(Observable.empty());
- },
- onError: function (e) {
- this.onNext(Observable['throw'](e));
- },
- onNext: function (v) {
- this.tail.onNext(v);
- this.tail.onCompleted();
- }
- });
- return ChainObservable;
- }(Observable));
- var SwitchFirstObservable = (function (__super__) {
- inherits(SwitchFirstObservable, __super__);
- function SwitchFirstObservable(source) {
- this.source = source;
- __super__.call(this);
- }
- SwitchFirstObservable.prototype.subscribeCore = function (o) {
- var m = new SingleAssignmentDisposable(),
- g = new CompositeDisposable(),
- state = {
- hasCurrent: false,
- isStopped: false,
- o: o,
- g: g
- };
- g.add(m);
- m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
- return g;
- };
- return SwitchFirstObservable;
- }(ObservableBase));
- var SwitchFirstObserver = (function(__super__) {
- inherits(SwitchFirstObserver, __super__);
- function SwitchFirstObserver(state) {
- this._s = state;
- __super__.call(this);
- }
- SwitchFirstObserver.prototype.next = function (x) {
- if (!this._s.hasCurrent) {
- this._s.hasCurrent = true;
- isPromise(x) && (x = observableFromPromise(x));
- var inner = new SingleAssignmentDisposable();
- this._s.g.add(inner);
- inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
- }
- };
- SwitchFirstObserver.prototype.error = function (e) {
- this._s.o.onError(e);
- };
- SwitchFirstObserver.prototype.completed = function () {
- this._s.isStopped = true;
- !this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
- };
- inherits(InnerObserver, __super__);
- function InnerObserver(state, inner) {
- this._s = state;
- this._i = inner;
- __super__.call(this);
- }
- InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
- InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
- InnerObserver.prototype.completed = function () {
- this._s.g.remove(this._i);
- this._s.hasCurrent = false;
- this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
- };
- return SwitchFirstObserver;
- }(AbstractObserver));
- /**
- * Performs a exclusive waiting for the first to finish before subscribing to another observable.
- * Observables that come in between subscriptions will be dropped on the floor.
- * @returns {Observable} A exclusive observable with only the results that happen when subscribed.
- */
- observableProto.switchFirst = function () {
- return new SwitchFirstObservable(this);
- };
- observableProto.flatMapFirst = observableProto.exhaustMap = function(selector, resultSelector, thisArg) {
- return new FlatMapObservable(this, selector, resultSelector, thisArg).switchFirst();
- };
- observableProto.flatMapWithMaxConcurrent = observableProto.flatMapMaxConcurrent = function(limit, selector, resultSelector, thisArg) {
- return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(limit);
- };
- return Rx;
- }));
|