export interface PromiseDecoratorCfg<RES = any, PARAMS = any> {
    decoratorName: string;
    /**
     * Called BEFORE the original function.
     * If Promise is returned - it will be awaited.
     */
    beforeFn?: (r: PromiseDecoratorResp<PARAMS>) => void | Promise<void>;
    /**
     * Called just AFTER the original function.
     * The output of this hook will be passed further,
     * so, pay attention to pass through (or modify) the result.
     */
    thenFn?: (r: PromiseDecoratorResp<PARAMS> & {
        res: RES;
    }) => RES;
    /**
     * Called on Promise.reject.
     * If `catchFn` is not present - will re-throw the error,
     * which will most likely be "unhandledRejection" (unless there's another higher-level @Decorator that will catch it).
     * If `catchFn` is present - it's responsible for handling or re-throwing the error.
     * Whatever `catchFn` returns - passed to the original output.
     */
    catchFn?: (r: PromiseDecoratorResp<PARAMS> & {
        err: any;
    }) => RES;
    /**
     * Fires AFTER thenFn / catchFn, like a usual Promise.finally().
     * Doesn't have access to neither res nor err (same as Promise.finally).
     */
    finallyFn?: (r: PromiseDecoratorResp<PARAMS>) => any;
}
export interface PromiseDecoratorResp<PARAMS> {
    decoratorParams: PARAMS;
    args: any[];
    started: number;
    target: any;
    key: string;
    decoratorName: string;
}
/**
 * @example
 * // decorators.ts
 * export const BlockingLoader = () => _createPromiseDecorator({
 *   decoratorName: 'BlockingLoader',
 *   beforeFn: () => store.commit('setBlockingLoader'),
 *   finallyFn: () => store.commit('setBlockingLoader', false),
 * })
 *
 * @experimental
 */
export declare function _createPromiseDecorator<RES = any, PARAMS = any>(cfg: PromiseDecoratorCfg<RES, PARAMS>, decoratorParams?: PARAMS): MethodDecorator;
