PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://gitlab.com/Mirros/cdnjs
JavaScript | 415 lines | 270 code | 40 blank | 105 comment | 47 complexity | 638b96945f7910b35ddae66d79cf0d4b 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. 'boolean': false,
  5. 'function': true,
  6. 'object': true,
  7. 'number': false,
  8. 'string': false,
  9. 'undefined': false
  10. };
  11. var root = (objectTypes[typeof window] && window) || this,
  12. freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
  13. freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
  14. moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
  15. freeGlobal = objectTypes[typeof global] && global;
  16. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  17. root = freeGlobal;
  18. }
  19. // Because of build optimizers
  20. if (typeof define === 'function' && define.amd) {
  21. define(['rx', 'exports'], function (Rx, exports) {
  22. root.Rx = factory(root, exports, Rx);
  23. return root.Rx;
  24. });
  25. } else if (typeof module === 'object' && module && module.exports === freeExports) {
  26. module.exports = factory(root, module.exports, require('./rx'));
  27. } else {
  28. root.Rx = factory(root, {}, root.Rx);
  29. }
  30. }.call(this, function (root, exp, Rx, undefined) {
  31. // Aliases
  32. var Observable = Rx.Observable,
  33. observableProto = Observable.prototype,
  34. AnonymousObservable = Rx.AnonymousObservable,
  35. observableThrow = Observable.throwException,
  36. observerCreate = Rx.Observer.create,
  37. SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
  38. CompositeDisposable = Rx.CompositeDisposable,
  39. AbstractObserver = Rx.internals.AbstractObserver,
  40. noop = Rx.helpers.noop,
  41. defaultComparer = Rx.internals.isEqual,
  42. inherits = Rx.internals.inherits,
  43. slice = Array.prototype.slice;
  44. // Utilities
  45. function argsOrArray(args, idx) {
  46. return args.length === 1 && Array.isArray(args[idx]) ?
  47. args[idx] :
  48. slice.call(args);
  49. }
  50. /** @private */
  51. var Map = (function () {
  52. /**
  53. * @constructor
  54. * @private
  55. */
  56. function Map() {
  57. this.keys = [];
  58. this.values = [];
  59. }
  60. /**
  61. * @private
  62. * @memberOf Map#
  63. */
  64. Map.prototype['delete'] = function (key) {
  65. var i = this.keys.indexOf(key);
  66. if (i !== -1) {
  67. this.keys.splice(i, 1);
  68. this.values.splice(i, 1);
  69. }
  70. return i !== -1;
  71. };
  72. /**
  73. * @private
  74. * @memberOf Map#
  75. */
  76. Map.prototype.get = function (key, fallback) {
  77. var i = this.keys.indexOf(key);
  78. return i !== -1 ? this.values[i] : fallback;
  79. };
  80. /**
  81. * @private
  82. * @memberOf Map#
  83. */
  84. Map.prototype.set = function (key, value) {
  85. var i = this.keys.indexOf(key);
  86. if (i !== -1) {
  87. this.values[i] = value;
  88. }
  89. this.values[this.keys.push(key) - 1] = value;
  90. };
  91. /**
  92. * @private
  93. * @memberOf Map#
  94. */
  95. Map.prototype.size = function () { return this.keys.length; };
  96. /**
  97. * @private
  98. * @memberOf Map#
  99. */
  100. Map.prototype.has = function (key) {
  101. return this.keys.indexOf(key) !== -1;
  102. };
  103. /**
  104. * @private
  105. * @memberOf Map#
  106. */
  107. Map.prototype.getKeys = function () { return this.keys.slice(0); };
  108. /**
  109. * @private
  110. * @memberOf Map#
  111. */
  112. Map.prototype.getValues = function () { return this.values.slice(0); };
  113. return Map;
  114. }());
  115. /**
  116. * @constructor
  117. * Represents a join pattern over observable sequences.
  118. */
  119. function Pattern(patterns) {
  120. this.patterns = patterns;
  121. }
  122. /**
  123. * Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
  124. *
  125. * @param other Observable sequence to match in addition to the current pattern.
  126. * @return Pattern object that matches when all observable sequences in the pattern have an available value.
  127. */
  128. Pattern.prototype.and = function (other) {
  129. var patterns = this.patterns.slice(0);
  130. patterns.push(other);
  131. return new Pattern(patterns);
  132. };
  133. /**
  134. * Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
  135. *
  136. * @param selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
  137. * @return Plan that produces the projected values, to be fed (with other plans) to the when operator.
  138. */
  139. Pattern.prototype.then = function (selector) {
  140. return new Plan(this, selector);
  141. };
  142. function Plan(expression, selector) {
  143. this.expression = expression;
  144. this.selector = selector;
  145. }
  146. Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
  147. var self = this;
  148. var joinObservers = [];
  149. for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
  150. joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], observer.onError.bind(observer)));
  151. }
  152. var activePlan = new ActivePlan(joinObservers, function () {
  153. var result;
  154. try {
  155. result = self.selector.apply(self, arguments);
  156. } catch (exception) {
  157. observer.onError(exception);
  158. return;
  159. }
  160. observer.onNext(result);
  161. }, function () {
  162. for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
  163. joinObservers[j].removeActivePlan(activePlan);
  164. }
  165. deactivate(activePlan);
  166. });
  167. for (i = 0, len = joinObservers.length; i < len; i++) {
  168. joinObservers[i].addActivePlan(activePlan);
  169. }
  170. return activePlan;
  171. };
  172. function planCreateObserver(externalSubscriptions, observable, onError) {
  173. var entry = externalSubscriptions.get(observable);
  174. if (!entry) {
  175. var observer = new JoinObserver(observable, onError);
  176. externalSubscriptions.set(observable, observer);
  177. return observer;
  178. }
  179. return entry;
  180. }
  181. // Active Plan
  182. function ActivePlan(joinObserverArray, onNext, onCompleted) {
  183. var i, joinObserver;
  184. this.joinObserverArray = joinObserverArray;
  185. this.onNext = onNext;
  186. this.onCompleted = onCompleted;
  187. this.joinObservers = new Map();
  188. for (i = 0; i < this.joinObserverArray.length; i++) {
  189. joinObserver = this.joinObserverArray[i];
  190. this.joinObservers.set(joinObserver, joinObserver);
  191. }
  192. }
  193. ActivePlan.prototype.dequeue = function () {
  194. var values = this.joinObservers.getValues();
  195. for (var i = 0, len = values.length; i < len; i++) {
  196. values[i].queue.shift();
  197. }
  198. };
  199. ActivePlan.prototype.match = function () {
  200. var firstValues, i, len, isCompleted, values, hasValues = true;
  201. for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
  202. if (this.joinObserverArray[i].queue.length === 0) {
  203. hasValues = false;
  204. break;
  205. }
  206. }
  207. if (hasValues) {
  208. firstValues = [];
  209. isCompleted = false;
  210. for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
  211. firstValues.push(this.joinObserverArray[i].queue[0]);
  212. if (this.joinObserverArray[i].queue[0].kind === 'C') {
  213. isCompleted = true;
  214. }
  215. }
  216. if (isCompleted) {
  217. this.onCompleted();
  218. } else {
  219. this.dequeue();
  220. values = [];
  221. for (i = 0; i < firstValues.length; i++) {
  222. values.push(firstValues[i].value);
  223. }
  224. this.onNext.apply(this, values);
  225. }
  226. }
  227. };
  228. /** @private */
  229. var JoinObserver = (function (_super) {
  230. inherits(JoinObserver, _super);
  231. /**
  232. * @constructor
  233. * @private
  234. */
  235. function JoinObserver(source, onError) {
  236. _super.call(this);
  237. this.source = source;
  238. this.onError = onError;
  239. this.queue = [];
  240. this.activePlans = [];
  241. this.subscription = new SingleAssignmentDisposable();
  242. this.isDisposed = false;
  243. }
  244. var JoinObserverPrototype = JoinObserver.prototype;
  245. /**
  246. * @memberOf JoinObserver#
  247. * @private
  248. */
  249. JoinObserverPrototype.next = function (notification) {
  250. if (!this.isDisposed) {
  251. if (notification.kind === 'E') {
  252. this.onError(notification.exception);
  253. return;
  254. }
  255. this.queue.push(notification);
  256. var activePlans = this.activePlans.slice(0);
  257. for (var i = 0, len = activePlans.length; i < len; i++) {
  258. activePlans[i].match();
  259. }
  260. }
  261. };
  262. /**
  263. * @memberOf JoinObserver#
  264. * @private
  265. */
  266. JoinObserverPrototype.error = noop;
  267. /**
  268. * @memberOf JoinObserver#
  269. * @private
  270. */
  271. JoinObserverPrototype.completed = noop;
  272. /**
  273. * @memberOf JoinObserver#
  274. * @private
  275. */
  276. JoinObserverPrototype.addActivePlan = function (activePlan) {
  277. this.activePlans.push(activePlan);
  278. };
  279. /**
  280. * @memberOf JoinObserver#
  281. * @private
  282. */
  283. JoinObserverPrototype.subscribe = function () {
  284. this.subscription.setDisposable(this.source.materialize().subscribe(this));
  285. };
  286. /**
  287. * @memberOf JoinObserver#
  288. * @private
  289. */
  290. JoinObserverPrototype.removeActivePlan = function (activePlan) {
  291. var idx = this.activePlans.indexOf(activePlan);
  292. this.activePlans.splice(idx, 1);
  293. if (this.activePlans.length === 0) {
  294. this.dispose();
  295. }
  296. };
  297. /**
  298. * @memberOf JoinObserver#
  299. * @private
  300. */
  301. JoinObserverPrototype.dispose = function () {
  302. _super.prototype.dispose.call(this);
  303. if (!this.isDisposed) {
  304. this.isDisposed = true;
  305. this.subscription.dispose();
  306. }
  307. };
  308. return JoinObserver;
  309. } (AbstractObserver));
  310. /**
  311. * Creates a pattern that matches when both observable sequences have an available value.
  312. *
  313. * @param right Observable sequence to match with the current sequence.
  314. * @return {Pattern} Pattern object that matches when both observable sequences have an available value.
  315. */
  316. observableProto.and = function (right) {
  317. return new Pattern([this, right]);
  318. };
  319. /**
  320. * Matches when the observable sequence has an available value and projects the value.
  321. *
  322. * @param selector Selector that will be invoked for values in the source sequence.
  323. * @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
  324. */
  325. observableProto.then = function (selector) {
  326. return new Pattern([this]).then(selector);
  327. };
  328. /**
  329. * Joins together the results from several patterns.
  330. *
  331. * @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.
  332. * @returns {Observable} Observable sequence with the results form matching several patterns.
  333. */
  334. Observable.when = function () {
  335. var plans = argsOrArray(arguments, 0);
  336. return new AnonymousObservable(function (observer) {
  337. var activePlans = [],
  338. externalSubscriptions = new Map(),
  339. group,
  340. i, len,
  341. joinObserver,
  342. joinValues,
  343. outObserver;
  344. outObserver = observerCreate(observer.onNext.bind(observer), function (exception) {
  345. var values = externalSubscriptions.getValues();
  346. for (var j = 0, jlen = values.length; j < jlen; j++) {
  347. values[j].onError(exception);
  348. }
  349. observer.onError(exception);
  350. }, observer.onCompleted.bind(observer));
  351. try {
  352. for (i = 0, len = plans.length; i < len; i++) {
  353. activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
  354. var idx = activePlans.indexOf(activePlan);
  355. activePlans.splice(idx, 1);
  356. if (activePlans.length === 0) {
  357. outObserver.onCompleted();
  358. }
  359. }));
  360. }
  361. } catch (e) {
  362. observableThrow(e).subscribe(observer);
  363. }
  364. group = new CompositeDisposable();
  365. joinValues = externalSubscriptions.getValues();
  366. for (i = 0, len = joinValues.length; i < len; i++) {
  367. joinObserver = joinValues[i];
  368. joinObserver.subscribe();
  369. group.add(joinObserver);
  370. }
  371. return group;
  372. });
  373. };
  374. return Rx;
  375. }));