PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/rxjs/3.1.2/rx.joinpatterns.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 324 lines | 254 code | 35 blank | 35 comment | 59 complexity | d42a7444acd87d68584031e099d841a5 MD5 | raw file
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. ;(function (factory) {
  3. var objectTypes = {
  4. 'function': true,
  5. 'object': true
  6. };
  7. var
  8. freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
  9. freeSelf = objectTypes[typeof self] && self.Object && self,
  10. freeWindow = objectTypes[typeof window] && window && window.Object && window,
  11. freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
  12. moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
  13. freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
  14. var root = root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
  15. // Because of build optimizers
  16. if (typeof define === 'function' && define.amd) {
  17. define(['./rx'], function (Rx, exports) {
  18. return factory(root, exports, Rx);
  19. });
  20. } else if (typeof module === 'object' && module && module.exports === freeExports) {
  21. module.exports = factory(root, module.exports, require('./rx'));
  22. } else {
  23. root.Rx = factory(root, {}, root.Rx);
  24. }
  25. }.call(this, function (root, exp, Rx, undefined) {
  26. // Aliases
  27. var Observable = Rx.Observable,
  28. observableProto = Observable.prototype,
  29. AnonymousObservable = Rx.AnonymousObservable,
  30. observableThrow = Observable.throwError,
  31. observerCreate = Rx.Observer.create,
  32. SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
  33. CompositeDisposable = Rx.CompositeDisposable,
  34. AbstractObserver = Rx.internals.AbstractObserver,
  35. noop = Rx.helpers.noop,
  36. defaultComparer = Rx.internals.isEqual,
  37. inherits = Rx.internals.inherits,
  38. Enumerable = Rx.internals.Enumerable,
  39. Enumerator = Rx.internals.Enumerator,
  40. $iterator$ = Rx.iterator,
  41. doneEnumerator = Rx.doneEnumerator,
  42. bindCallback = Rx.internals.bindCallback;
  43. var Map = root.Map || (function () {
  44. function Map() {
  45. this.size = 0;
  46. this._values = [];
  47. this._keys = [];
  48. }
  49. Map.prototype['delete'] = function (key) {
  50. var i = this._keys.indexOf(key);
  51. if (i === -1) { return false }
  52. this._values.splice(i, 1);
  53. this._keys.splice(i, 1);
  54. this.size--;
  55. return true;
  56. };
  57. Map.prototype.get = function (key) {
  58. var i = this._keys.indexOf(key);
  59. return i === -1 ? undefined : this._values[i];
  60. };
  61. Map.prototype.set = function (key, value) {
  62. var i = this._keys.indexOf(key);
  63. if (i === -1) {
  64. this._keys.push(key);
  65. this._values.push(value);
  66. this.size++;
  67. } else {
  68. this._values[i] = value;
  69. }
  70. return this;
  71. };
  72. Map.prototype.forEach = function (cb, thisArg) {
  73. for (var i = 0; i < this.size; i++) {
  74. cb.call(thisArg, this._values[i], this._keys[i]);
  75. }
  76. };
  77. return Map;
  78. }());
  79. /**
  80. * @constructor
  81. * Represents a join pattern over observable sequences.
  82. */
  83. function Pattern(patterns) {
  84. this.patterns = patterns;
  85. }
  86. /**
  87. * Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
  88. * @param other Observable sequence to match in addition to the current pattern.
  89. * @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
  90. */
  91. Pattern.prototype.and = function (other) {
  92. return new Pattern(this.patterns.concat(other));
  93. };
  94. /**
  95. * Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
  96. * @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
  97. * @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
  98. */
  99. Pattern.prototype.thenDo = function (selector) {
  100. return new Plan(this, selector);
  101. };
  102. function Plan(expression, selector) {
  103. this.expression = expression;
  104. this.selector = selector;
  105. }
  106. Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
  107. var self = this;
  108. var joinObservers = [];
  109. for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
  110. joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], observer.onError.bind(observer)));
  111. }
  112. var activePlan = new ActivePlan(joinObservers, function () {
  113. var result;
  114. try {
  115. result = self.selector.apply(self, arguments);
  116. } catch (e) {
  117. observer.onError(e);
  118. return;
  119. }
  120. observer.onNext(result);
  121. }, function () {
  122. for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
  123. joinObservers[j].removeActivePlan(activePlan);
  124. }
  125. deactivate(activePlan);
  126. });
  127. for (i = 0, len = joinObservers.length; i < len; i++) {
  128. joinObservers[i].addActivePlan(activePlan);
  129. }
  130. return activePlan;
  131. };
  132. function planCreateObserver(externalSubscriptions, observable, onError) {
  133. var entry = externalSubscriptions.get(observable);
  134. if (!entry) {
  135. var observer = new JoinObserver(observable, onError);
  136. externalSubscriptions.set(observable, observer);
  137. return observer;
  138. }
  139. return entry;
  140. }
  141. function ActivePlan(joinObserverArray, onNext, onCompleted) {
  142. this.joinObserverArray = joinObserverArray;
  143. this.onNext = onNext;
  144. this.onCompleted = onCompleted;
  145. this.joinObservers = new Map();
  146. for (var i = 0, len = this.joinObserverArray.length; i < len; i++) {
  147. var joinObserver = this.joinObserverArray[i];
  148. this.joinObservers.set(joinObserver, joinObserver);
  149. }
  150. }
  151. ActivePlan.prototype.dequeue = function () {
  152. this.joinObservers.forEach(function (v) { v.queue.shift(); });
  153. };
  154. ActivePlan.prototype.match = function () {
  155. var i, len, hasValues = true;
  156. for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
  157. if (this.joinObserverArray[i].queue.length === 0) {
  158. hasValues = false;
  159. break;
  160. }
  161. }
  162. if (hasValues) {
  163. var firstValues = [],
  164. isCompleted = false;
  165. for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
  166. firstValues.push(this.joinObserverArray[i].queue[0]);
  167. this.joinObserverArray[i].queue[0].kind === 'C' && (isCompleted = true);
  168. }
  169. if (isCompleted) {
  170. this.onCompleted();
  171. } else {
  172. this.dequeue();
  173. var values = [];
  174. for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
  175. values.push(firstValues[i].value);
  176. }
  177. this.onNext.apply(this, values);
  178. }
  179. }
  180. };
  181. var JoinObserver = (function (__super__) {
  182. inherits(JoinObserver, __super__);
  183. function JoinObserver(source, onError) {
  184. __super__.call(this);
  185. this.source = source;
  186. this.onError = onError;
  187. this.queue = [];
  188. this.activePlans = [];
  189. this.subscription = new SingleAssignmentDisposable();
  190. this.isDisposed = false;
  191. }
  192. var JoinObserverPrototype = JoinObserver.prototype;
  193. JoinObserverPrototype.next = function (notification) {
  194. if (!this.isDisposed) {
  195. if (notification.kind === 'E') {
  196. return this.onError(notification.exception);
  197. }
  198. this.queue.push(notification);
  199. var activePlans = this.activePlans.slice(0);
  200. for (var i = 0, len = activePlans.length; i < len; i++) {
  201. activePlans[i].match();
  202. }
  203. }
  204. };
  205. JoinObserverPrototype.error = noop;
  206. JoinObserverPrototype.completed = noop;
  207. JoinObserverPrototype.addActivePlan = function (activePlan) {
  208. this.activePlans.push(activePlan);
  209. };
  210. JoinObserverPrototype.subscribe = function () {
  211. this.subscription.setDisposable(this.source.materialize().subscribe(this));
  212. };
  213. JoinObserverPrototype.removeActivePlan = function (activePlan) {
  214. this.activePlans.splice(this.activePlans.indexOf(activePlan), 1);
  215. this.activePlans.length === 0 && this.dispose();
  216. };
  217. JoinObserverPrototype.dispose = function () {
  218. __super__.prototype.dispose.call(this);
  219. if (!this.isDisposed) {
  220. this.isDisposed = true;
  221. this.subscription.dispose();
  222. }
  223. };
  224. return JoinObserver;
  225. } (AbstractObserver));
  226. /**
  227. * Creates a pattern that matches when both observable sequences have an available value.
  228. *
  229. * @param right Observable sequence to match with the current sequence.
  230. * @return {Pattern} Pattern object that matches when both observable sequences have an available value.
  231. */
  232. observableProto.and = function (right) {
  233. return new Pattern([this, right]);
  234. };
  235. /**
  236. * Matches when the observable sequence has an available value and projects the value.
  237. *
  238. * @param {Function} selector Selector that will be invoked for values in the source sequence.
  239. * @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
  240. */
  241. observableProto.thenDo = function (selector) {
  242. return new Pattern([this]).thenDo(selector);
  243. };
  244. /**
  245. * Joins together the results from several patterns.
  246. *
  247. * @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
  248. * @returns {Observable} Observable sequence with the results form matching several patterns.
  249. */
  250. Observable.when = function () {
  251. var len = arguments.length, plans;
  252. if (Array.isArray(arguments[0])) {
  253. plans = arguments[0];
  254. } else {
  255. plans = new Array(len);
  256. for(var i = 0; i < len; i++) { plans[i] = arguments[i]; }
  257. }
  258. return new AnonymousObservable(function (o) {
  259. var activePlans = [],
  260. externalSubscriptions = new Map();
  261. var outObserver = observerCreate(
  262. function (x) { o.onNext(x); },
  263. function (err) {
  264. externalSubscriptions.forEach(function (v) { v.onError(err); });
  265. o.onError(err);
  266. },
  267. function (x) { o.onCompleted(); }
  268. );
  269. try {
  270. for (var i = 0, len = plans.length; i < len; i++) {
  271. activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
  272. var idx = activePlans.indexOf(activePlan);
  273. activePlans.splice(idx, 1);
  274. activePlans.length === 0 && o.onCompleted();
  275. }));
  276. }
  277. } catch (e) {
  278. observableThrow(e).subscribe(o);
  279. }
  280. var group = new CompositeDisposable();
  281. externalSubscriptions.forEach(function (joinObserver) {
  282. joinObserver.subscribe();
  283. group.add(joinObserver);
  284. });
  285. return group;
  286. });
  287. };
  288. return Rx;
  289. }));