| import { isArray } from './util/isArray'; |
| import { isObject } from './util/isObject'; |
| import { isFunction } from './util/isFunction'; |
| import { UnsubscriptionError } from './util/UnsubscriptionError'; |
| export class Subscription { |
| constructor(unsubscribe) { |
| this.closed = false; |
| this._parentOrParents = null; |
| this._subscriptions = null; |
| if (unsubscribe) { |
| this._unsubscribe = unsubscribe; |
| } |
| } |
| unsubscribe() { |
| let errors; |
| if (this.closed) { |
| return; |
| } |
| let { _parentOrParents, _unsubscribe, _subscriptions } = this; |
| this.closed = true; |
| this._parentOrParents = null; |
| this._subscriptions = null; |
| if (_parentOrParents instanceof Subscription) { |
| _parentOrParents.remove(this); |
| } |
| else if (_parentOrParents !== null) { |
| for (let index = 0; index < _parentOrParents.length; ++index) { |
| const parent = _parentOrParents[index]; |
| parent.remove(this); |
| } |
| } |
| if (isFunction(_unsubscribe)) { |
| try { |
| _unsubscribe.call(this); |
| } |
| catch (e) { |
| errors = e instanceof UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e]; |
| } |
| } |
| if (isArray(_subscriptions)) { |
| let index = -1; |
| let len = _subscriptions.length; |
| while (++index < len) { |
| const sub = _subscriptions[index]; |
| if (isObject(sub)) { |
| try { |
| sub.unsubscribe(); |
| } |
| catch (e) { |
| errors = errors || []; |
| if (e instanceof UnsubscriptionError) { |
| errors = errors.concat(flattenUnsubscriptionErrors(e.errors)); |
| } |
| else { |
| errors.push(e); |
| } |
| } |
| } |
| } |
| } |
| if (errors) { |
| throw new UnsubscriptionError(errors); |
| } |
| } |
| add(teardown) { |
| let subscription = teardown; |
| if (!teardown) { |
| return Subscription.EMPTY; |
| } |
| switch (typeof teardown) { |
| case 'function': |
| subscription = new Subscription(teardown); |
| case 'object': |
| if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') { |
| return subscription; |
| } |
| else if (this.closed) { |
| subscription.unsubscribe(); |
| return subscription; |
| } |
| else if (!(subscription instanceof Subscription)) { |
| const tmp = subscription; |
| subscription = new Subscription(); |
| subscription._subscriptions = [tmp]; |
| } |
| break; |
| default: { |
| throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); |
| } |
| } |
| let { _parentOrParents } = subscription; |
| if (_parentOrParents === null) { |
| subscription._parentOrParents = this; |
| } |
| else if (_parentOrParents instanceof Subscription) { |
| if (_parentOrParents === this) { |
| return subscription; |
| } |
| subscription._parentOrParents = [_parentOrParents, this]; |
| } |
| else if (_parentOrParents.indexOf(this) === -1) { |
| _parentOrParents.push(this); |
| } |
| else { |
| return subscription; |
| } |
| const subscriptions = this._subscriptions; |
| if (subscriptions === null) { |
| this._subscriptions = [subscription]; |
| } |
| else { |
| subscriptions.push(subscription); |
| } |
| return subscription; |
| } |
| remove(subscription) { |
| const subscriptions = this._subscriptions; |
| if (subscriptions) { |
| const subscriptionIndex = subscriptions.indexOf(subscription); |
| if (subscriptionIndex !== -1) { |
| subscriptions.splice(subscriptionIndex, 1); |
| } |
| } |
| } |
| } |
| Subscription.EMPTY = (function (empty) { |
| empty.closed = true; |
| return empty; |
| }(new Subscription())); |
| function flattenUnsubscriptionErrors(errors) { |
| return errors.reduce((errs, err) => errs.concat((err instanceof UnsubscriptionError) ? err.errors : err), []); |
| } |
| //# sourceMappingURL=Subscription.js.map |