@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
JavaScript
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