ngx-until-on-destroy
Version:
Allow you unsubscribe subscriptions when component was destroying. Can be used with Angular 5-10
122 lines (112 loc) • 3.46 kB
JavaScript
import { Subscription } from 'rxjs';
import { VERSION } from '@angular/core';
function decorateMethod({ target, hookName, oldName, wrappingFn }) {
const oldMethod = target[hookName];
target[oldName] = oldMethod;
return function () {
wrappingFn.call(this);
if (oldMethod) {
return oldMethod.call(this);
}
};
}
const componentDefKey = 'ɵcmp';
const factoryDefKey = 'ɵfac';
const directiveDefKey = 'ɵdir';
const isIvy = (target) => target.constructor[factoryDefKey];
function getIvyDef(target) {
return target.constructor[componentDefKey] || target.constructor[directiveDefKey];
}
function wrapIvyHook({ target, hookName, oldName, wrappingFn }) {
const ivyHookName = hookName.slice(0, 1).toLowerCase() + hookName.slice(1);
const ivyDef = getIvyDef(target);
ivyDef[ivyHookName] = decorateMethod({
target: ivyDef,
hookName: ivyHookName,
oldName,
wrappingFn,
});
}
function getViewEngineError(hookName, constructorName) {
return new Error(`You have to implements ${hookName} in component (or directive) ${constructorName}`);
}
function wrapViewEngineHook({ target, hookName, oldName, wrappingFn }) {
const veHookName = 'ng' + hookName;
if (!target[veHookName] && +VERSION.major < 9) {
throw getViewEngineError(veHookName, target.constructor.name);
}
target[veHookName] = decorateMethod({
target,
hookName: veHookName,
oldName,
wrappingFn
});
}
const subSymbol = Symbol('subscription');
const decoratedSymbol = Symbol('decorated');
const onInitSymbol = Symbol('onInit');
const onDestroySymbol = Symbol('onDestroy');
function markAsDecorated(target) {
target[decoratedSymbol] = true;
}
function isDecorated(target) {
return target.hasOwnProperty(decoratedSymbol);
}
function createMethodWrapper(originalMethod) {
return function (...args) {
const originalResult = originalMethod.apply(this, args);
if (originalResult instanceof Subscription) {
this[subSymbol].add(originalResult);
}
else if (Array.isArray(originalResult)) {
originalResult.forEach(s => this[subSymbol].add(s));
}
else {
throw new Error('Decorated method must return Subscription or Subscription[]');
}
return originalResult;
};
}
function wrapOneHook(wrapParams) {
if (isIvy(wrapParams.target)) {
wrapIvyHook(wrapParams);
}
wrapViewEngineHook(wrapParams);
}
function wrapHooks(target) {
if (!isDecorated(target)) {
markAsDecorated(target);
wrapOneHook({
target,
hookName: 'OnInit',
oldName: onInitSymbol,
wrappingFn() {
this[subSymbol] = new Subscription();
}
});
wrapOneHook({
target,
hookName: 'OnDestroy',
oldName: onDestroySymbol,
wrappingFn() {
this[subSymbol].unsubscribe();
}
});
}
}
function UntilOnDestroy() {
return function UntilOnDestroyDecorator(target, propertyKey) {
wrapHooks(target);
return {
value: createMethodWrapper(target[propertyKey]),
};
};
}
/*
* Public API Surface of ngx-until-on-destroy
*/
/**
* Generated bundle index. Do not edit.
*/
export { UntilOnDestroy };
//# sourceMappingURL=ngx-until-on-destroy.js.map