@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
83 lines (82 loc) • 2.79 kB
JavaScript
import { _getTargetMethodSignature } from './decorator.util.js';
/**
* @example
* // decorators.ts
* export const BlockingLoader = () => _createPromiseDecorator({
* decoratorName: 'BlockingLoader',
* beforeFn: () => store.commit('setBlockingLoader'),
* finallyFn: () => store.commit('setBlockingLoader', false),
* })
*
* @experimental
*/
export function _createPromiseDecorator(cfg, decoratorParams = {}) {
const { decoratorName } = cfg;
return function decoratorFunction(target, propertyKey, pd) {
// console.log(`@Decorator.${cfg.decoratorName} called: ` + propertyKey, pd, target)
const originalMethod = pd.value;
const key = String(propertyKey);
const methodSignature = _getTargetMethodSignature(target, key);
pd.value = async function (...args) {
// console.log(`@${cfg.decoratorName} called inside function`)
const started = Date.now();
try {
// Before function
// console.log(`@${cfg.decoratorName} Before`)
if (cfg.beforeFn) {
await cfg.beforeFn({
decoratorParams,
args,
key,
target,
decoratorName,
started,
});
}
// Original function
let res = await originalMethod.apply(this, args);
// console.log(`${cfg.decoratorName} After`)
const resp = {
decoratorParams,
args,
key,
target,
decoratorName,
started,
};
if (cfg.thenFn) {
res = cfg.thenFn({
...resp,
res,
});
}
cfg.finallyFn?.(resp);
return res;
}
catch (err) {
console.error(`@${decoratorName} ${methodSignature} catch:`, err);
const resp = {
decoratorParams,
args,
key,
target,
decoratorName,
started,
};
let handled = false;
if (cfg.catchFn) {
cfg.catchFn({
...resp,
err,
});
handled = true;
}
cfg.finallyFn?.(resp);
if (!handled) {
throw err; // rethrow
}
}
};
return pd;
};
}