import {accept, Filter} from '../decorators';
import {internal} from '../internal';
import {Providers} from '../providers';
import {joinFqn, orUseSupplier} from '../util';
import {Profiler} from './profiler';
const { logger, MSG_FMT } = internal;
export type ProfileOptions = {
label?: string;
filter?: Filter;
profiler?: Profiler;
}
export function Profile(options: ProfileOptions = {}): MethodDecorator {
return function (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor {
const original = descriptor.value;
const fqn = options?.label || joinFqn(propertyKey, target.constructor.name);
const log = logger('@Profile');
log.debug(MSG_FMT.annotatingMethod, target.constructor.name, propertyKey, 'Profile', options);
descriptor.value = function (...args: unknown[]): unknown {
let result;
if (accept(options.filter)) {
const profiler = Providers.useOrProvide(Profiler, options.profiler);
profiler.profile(fqn);
result = original.apply(this, ...args);
if (result instanceof Promise) {
result.then(() => profiler.profileEnd(fqn))
}
else {
profiler.profileEnd(fqn);
}
}
else {
result = original.apply(this, ...args);
}
return result;
};
return descriptor;
}
}
export function ProfileTimestamp(options: ProfileOptions = {}): MethodDecorator {
return function (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor {
const log = logger('@ProfileTimestamp');
log.debug(MSG_FMT.annotatingMethod, target.constructor.name, propertyKey, 'ProfileTimestamp', options);
const original = descriptor.value;
const _label = options.label || `${target.constructor.name}.${String(propertyKey)}`;
descriptor.value = function (...args: unknown[]): unknown {
if (accept(options.filter)) {
orUseSupplier(options.profiler, () => Providers.provide(Profiler)).timeStamp(_label);
}
return original.apply(this, ...args);
};
return descriptor;
}
}
|