UNPKG

@code-art/rx-helpers

Version:

A library with Rxjs operators that can be used in your Angular 8 projects.

191 lines (183 loc) 5.87 kB
import { Subject, Subscriber, defer } from 'rxjs'; import { takeUntil, startWith, switchMap, shareReplay } from 'rxjs/operators'; const DESTROY_SUBJECT_SYMBOL = Symbol(); const DECORATOR_APPLIED_SYMBOL = Symbol(); function isComponentType(type) { return type && !!type.ɵcmp; } function isDirectiveType(type) { return type && !!type.ɵdir; } function isPipeType(type) { return type && !!type.ɵpipe; } function isProviderType(type) { return type && !!type.ɵprov; } function doOnDestroy() { const subject = this[DESTROY_SUBJECT_SYMBOL]; if (subject) { subject.next(0); subject.complete(); this[DESTROY_SUBJECT_SYMBOL] = undefined; } } function applyOnDestroyHook(def, handler) { const oldOnDestroy = def.onDestroy; def.onDestroy = function () { if (oldOnDestroy) { oldOnDestroy.apply(this); } handler.apply(this); }; } function applyOnDestroyToProvider(def, handler) { const oldOnDestroy = def.prototype.ngOnDestroy; def.prototype.ngOnDestroy = function (...args) { if (oldOnDestroy) { oldOnDestroy.apply(this, args); } handler.apply(this); }; } function applyOnDestroyToInstance(instance) { if (!instance[DESTROY_SUBJECT_SYMBOL]) { instance[DESTROY_SUBJECT_SYMBOL] = new Subject(); const constructor = instance.constructor; if (typeof constructor === 'function') { if (constructor[DECORATOR_APPLIED_SYMBOL]) { return; } if (isPipeType(constructor) || isComponentType(constructor) || isDirectiveType(constructor) || isProviderType(constructor)) { throw new Error(`To use ${takeUntilDestroyed.name} with Components, Pipes, Directives and Services add the @${TakeUntilDestroyed.name}.`); } } if (typeof instance.ngOnDestroy !== 'function') { throw new Error(`${takeUntilDestroyed.name} can only be applied to Components, Pipes, Directives and Services with @Injectable decorator or ` + ` to object instance implementing OnDestroy interface.`); } const oldOnDestroy = instance.ngOnDestroy; instance.ngOnDestroy = function (...args) { oldOnDestroy.apply(instance, args); doOnDestroy.apply(this); }; } } function applyOnDestroyToClass(target) { if (isComponentType(target)) { applyOnDestroyHook(target.ɵcmp, doOnDestroy); } else if (isDirectiveType(target)) { applyOnDestroyHook(target.ɵdir, doOnDestroy); } else if (isPipeType(target)) { applyOnDestroyHook(target.ɵpipe, doOnDestroy); } else { applyOnDestroyToProvider(target, doOnDestroy); } target[DECORATOR_APPLIED_SYMBOL] = true; } function TakeUntilDestroyed() { return applyOnDestroyToClass; } function takeUntilDestroyed(instance) { return (source) => { const c = instance; // const c = (component as any) as ComponentWithTakeUntilDestroy; applyOnDestroyToInstance(c); return source.pipe(takeUntil(c[DESTROY_SUBJECT_SYMBOL])); }; } class ZoneSubscriber extends Subscriber { constructor(_zone, destination) { super(destination); this._zone = _zone; } _next(value) { this._zone.run(() => { if (typeof this.destination.next === 'function') { this.destination.next(value); } }); } _error(error) { this._zone.run(() => { if (typeof this.destination.error === 'function') { this.destination.error(error); } }); } _complete() { this._zone.run(() => { if (typeof this.destination.complete === 'function') { this.destination.complete(); } }); } } class ZoneOperator { constructor(_zone) { this._zone = _zone; } call(subscriber, source) { return source.subscribe(new ZoneSubscriber(this._zone, subscriber)); } } function withZone(zone) { return (source) => source.lift(new ZoneOperator(zone)); } class OutsideZoneSubscriber extends Subscriber { constructor(_zone, destination) { super(destination); this._zone = _zone; } _next(value) { this._zone.runOutsideAngular(() => { if (typeof this.destination.next === 'function') { this.destination.next(value); } }); } _error(error) { this._zone.runOutsideAngular(() => { if (typeof this.destination.error === 'function') { this.destination.error(error); } }); } _complete() { this._zone.runOutsideAngular(() => { if (typeof this.destination.complete === 'function') { this.destination.complete(); } }); } } class OutsideZoneOperator { constructor(_zone) { this._zone = _zone; } call(subscriber, source) { return source.subscribe(new OutsideZoneSubscriber(this._zone, subscriber)); } } function outsideZone(zone) { return (source) => source.lift(new OutsideZoneOperator(zone)); } function cacheUntil(observable) { return (source) => { return observable.pipe(startWith(0), switchMap(() => defer(() => source)), shareReplay(1)); }; } /* * Public API Surface of rx-helpers */ /** * Generated bundle index. Do not edit. */ export { TakeUntilDestroyed, cacheUntil, outsideZone, takeUntilDestroyed, withZone }; //# sourceMappingURL=code-art-rx-helpers.js.map