/**
 * Represents a Promiseable type.
 */
type Promiseable<T> = T | Promise<T>;
/**
 * A string type that represents a pipe alias.
 */
type PipeAlias = string;
/**
 * A class type that represents a pipe.
 */
type PipeClass<T = unknown, R = T, Args extends any[] = any[]> = new (...args: Args) => PipeInstance<T, R>;
/**
 * A function type that represents a pipe.
 */
type FunctionalPipe<T = unknown, R = T> = (passable: T, next: PipeExecutor<T, R>, ...params: any[]) => Promiseable<R>;
/**
 * A factory function type that represents a pipe.
 */
type FactoryPipe<T = unknown, R = T, Args extends any[] = any[]> = (...args: Args) => FunctionalPipe<T, R>;
/**
 * A type that can either be a function or a string, representing a pipeline step.
 *
 * A pipe can either be a function that performs an action or a string identifier to be resolved.
 */
type PipeType<T = unknown, R = T, Args extends any[] = any[]> = PipeAlias | PipeClass<T, R, Args> | FunctionalPipe<T, R> | FactoryPipe<T, R, Args>;
/**
 * A mixed type that can be either a simple Pipe or a MetaPipe configuration.
 */
type MixedPipe<T = unknown, R = T, Args extends any[] = any[]> = PipeType<T, R, Args> | MetaPipe<T, R, Args>;
/**
 * Pipe Executor function type.
 *
 * @param passable - The passable objects being sent through the pipeline.
 * @returns The result of the execution, which could be a synchronous or asynchronous response.
 *
 * @template T - The type of the passable object.
 * @template R - The type of the return value from the pipeline execution, defaulting to `T`.
 */
type PipeExecutor<T = unknown, R = T> = (passable: T) => Promiseable<R>;
/**
 * Next Pipe Executor function type.
 *
 * @param passable - The passable objects being sent through the pipeline.
 * @returns The result of the execution, which could be a synchronous or asynchronous response.
 *
 * @template T - The type of the passable object.
 * @template R - The type of the return value from the pipeline execution, defaulting to `T`.
 */
type NextPipe<T = unknown, R = T> = PipeExecutor<T, R>;
/**
 * Reducer callback function type used to build a sequence of pipe executions.
 *
 * @param previousPipeExecutor - The executor from the previous step in the pipeline.
 * @param currentPipe - The current pipe being added to the sequence.
 * @returns The combined executor function.
 *
 * @template T - The type of the passable object.
 * @template R - The type of the return value from the pipeline execution, defaulting to `T`.
 */
type ReducerCallback<T = unknown, R = T, Args extends any[] = any[]> = (previousPipeExecutor: PipeExecutor<T, R>, currentPipe: MetaPipe<T, R, Args>) => PipeExecutor<T, R>;
/**
 * A function type that represents a resolver for a given pipe.
 *
 * @typeParam T - The type of the passable object in the pipeline.
 * @typeParam R - The type of the return value from the resolved pipe, which defaults to `T`.
 * @param pipe - The pipe that needs to be resolved, which can be either a simple pipe or a MetaPipe.
 * @returns The resolved pipe instance of type `PipeInstance<T, R> | undefined`.
 *
 * This type is used to provide a custom mechanism for resolving pipes before they are executed in the pipeline.
 */
type PipeResolver<T = unknown, R = T, Args extends any[] = any[]> = (pipe: MetaPipe<T, R, Args>) => PipeInstance<T, R> | undefined;
/**
 * ConfigContextOptions.
 */
interface PipelineOptions<T = unknown, R = T, Args extends any[] = any[]> {
    hooks?: PipelineHook<T, R, Args>;
    resolver?: PipeResolver<T, R, Args>;
}
/**
 * Represents a pipe instance that contains different pipe functions.
 *
 * @template T - The type of the passable object.
 * @template R - The type of the return value from the pipeline execution, defaulting to `T`.
 *
 * An object representing a set of functions used as part of the pipeline.
 * The keys represent function names, and the values are functions that take specific arguments.
 */
type PipeInstance<T = unknown, R = T> = PipeDefaultInstance<T, R> | PipeCustomInstance<T, R>;
/**
 * Represents a pipe instance that contains a default pipe function.
 *
 * @template T - The type of the passable object.
 * @template R - The type of the return value from the pipeline execution, defaulting to `T`.
 *
 * An object representing a default function used as part of the pipeline.
 * The key is the `handle` property, which is a function that takes specific arguments.
 */
interface PipeDefaultInstance<T = unknown, R = T> {
    handle: FunctionalPipe<T, R>;
}
/**
 * Represents a pipe instance that contains different pipe functions.
 *
 * @template T - The type of the passable object.
 * @template R - The type of the return value from the pipeline execution, defaulting to `T`.
 *
 * An object representing a set of functions used as part of the pipeline.
 * The keys represent function names, and the values are functions that take specific arguments.
 */
interface PipeCustomInstance<T = unknown, R = T> {
    [key: string]: FunctionalPipe<T, R> | any;
}
/**
 * Represents a MetaPipe configuration item, with a pipe, parameters, and priority level.
 *
 * A configuration object used for managing pipes in the pipeline.
 */
interface MetaPipe<T = unknown, R = T, Args extends any[] = any[]> {
    /** The pipe to execute, which can be a function or a string identifier. */
    module: PipeType<T, R, Args>;
    /** An optional array of parameters to pass to the pipe. */
    params?: any[];
    /** An optional priority level of the pipe. */
    priority?: number;
    /** An optional flag indicating whether the pipe is a class. */
    isClass?: boolean;
    /** An optional flag indicating whether the pipe is a container alias. */
    isAlias?: boolean;
    /** An optional flag indicating whether the pipe is a factory. */
    isFactory?: boolean;
}
/**
 * HookName Type.
 */
type HookName = 'onProcessingPipe' | 'onPipeProcessed';
/**
 * Hook Type.
 *
 * Represents a hook that can either be synchronous or asynchronous.
 */
type PipelineHook<T = unknown, R = T, Args extends any[] = any[]> = Record<HookName, Array<PipelineHookListener<T, R, Args>>>;
/**
 * PipelineHookContext Type.
 */
interface PipelineHookContext<T = unknown, R = T, Args extends any[] = any[]> {
    passable: T;
    pipe: PipeCustomInstance<T, R>;
    instance: PipeCustomInstance<T, R>;
    pipes: Array<MetaPipe<T, R, Args>>;
}
/**
 * PipelineHookListener Type.
 *
 * Represents a listener hook that can either be synchronous or asynchronous.
 */
type PipelineHookListener<T = unknown, R = T, Args extends any[] = any[]> = (context: PipelineHookContext<T, R, Args>) => Promiseable<void>;

/**
 * Class representing a Pipeline.
 *
 * @template T - The type of the passable object in the pipeline.
 * @template R - The type of the return value from the pipeline execution.
 *
 * This class is responsible for managing and executing a series of operations
 * on a set of passable values through multiple configurable pipes.
 */
declare class Pipeline<T = unknown, R = T, Args extends any[] = any[]> {
    /** The passable objects sent through the pipeline */
    private passable?;
    /** The method name to call on each pipe */
    private method;
    /** Flag indicating whether the pipeline should run synchronously or asynchronously */
    private isSync;
    /** The default priority for the pipes in the pipeline */
    private _defaultPriority;
    /** The sorted metadata pipes that will be executed */
    private sortedMetaPipes;
    /** The pipeline hooks */
    private readonly hooks;
    /** The resolver function used to resolve pipes before they are executed in the pipeline. */
    private readonly resolver?;
    /**
     * Create a pipeline instance.
     *
     * @param options - Optional Pipeline options.
     * @returns The pipeline instance.
     */
    static create<T = unknown, R = T, Args extends any[] = any[]>(options?: PipelineOptions<T, R, Args>): Pipeline<T, R>;
    /**
     * Initialize a new Pipeline instance.
     *
     * @param options - Optional Pipeline options.
     */
    protected constructor(options?: PipelineOptions<T, R, Args>);
    /**
     * Set the default priority for pipes in the pipeline.
     *
     * @param value - The priority value to set.
     * @returns The current Pipeline instance.
     */
    defaultPriority(value: number): this;
    /**
     * Set the passable objects being sent through the pipeline.
     *
     * @param passable - The object to pass through the pipeline.
     * @returns The current Pipeline instance.
     */
    send(passable: T): this;
    /**
     * Set the pipes for the pipeline.
     *
     * @param pipes - The pipes or MetaPipe instances.
     * @returns The current Pipeline instance.
     */
    through(...pipes: Array<MixedPipe<T, R, Args>>): this;
    /**
     * Add additional pipes to the pipeline.
     *
     * @param {...MixedPipe} pipe - A single pipe or a list of pipes to add.
     * @returns The current Pipeline instance.
     */
    pipe(...pipe: Array<MixedPipe<T, R, Args>>): this;
    /**
     * Set the method to call on each pipe.
     *
     * @param method - The method name to use on each pipe.
     * @returns The current Pipeline instance.
     */
    via(method: string): this;
    /**
     * Configure the pipeline to run synchronously or asynchronously.
     *
     * @param value - Set true for sync, false for async (default is true).
     * @returns The current Pipeline instance.
     */
    sync(value?: boolean): this;
    /**
     * Add a hook to the pipeline.
     *
     * @param name - The name of the hook.
     * @param listener - The hook listener function.
     * @returns The current Pipeline instance.
     */
    on(name: HookName, listener: PipelineHookListener<T, R, Args> | Array<PipelineHookListener<T, R, Args>>): this;
    /**
     * Run the pipeline with a final destination callback.
     *
     * @param destination - The final function to execute.
     * @returns The result of the pipeline, either synchronously or as a Promise.
     */
    then(destination: PipeExecutor<T, R>): Promiseable<R>;
    /**
     * Run the pipeline and return the result.
     *
     * @returns The result of the pipeline, either synchronously or as a Promise.
     */
    thenReturn(): Promiseable<R>;
    /**
     * Get the asynchronous reducer to iterate over the pipes.
     *
     * @returns The asynchronous reducer callback.
     */
    private asyncReducer;
    /**
     * Get the synchronous reducer to iterate over the pipes.
     *
     * @returns The synchronous reducer callback.
     */
    private reducer;
    /**
     * Resolve and execute async pipe.
     *
     * @param currentPipe - The current pipe to execute (class or service alias string).
     * @param passable - The passable object to send through the pipe.
     * @param previousPipeExecutor - The previous pipe executor in the sequence.
     * @returns The result of the pipe execution.
     * @throws PipelineError If the pipe cannot be resolved or the method is missing.
     */
    private executeAsyncPipe;
    /**
     * Resolve and execute a pipe.
     *
     * @param currentPipe - The current pipe to execute (class or service alias string).
     * @param passable - The passable object to send through the pipe.
     * @param previousPipeExecutor - The previous pipe executor in the sequence.
     * @returns The result of the pipe execution.
     * @throws PipelineError If the pipe cannot be resolved or the method is missing.
     */
    private executePipe;
    /**
     * Resolve pipe.
     *
     * @param currentPipe - The current pipe to execute (class or service alias string).
     * @returns The resolved pipe instance.
     * @throws PipelineError If the pipe cannot be resolved or the method is missing.
     */
    private resolvePipe;
    /**
     * Create an instance from the provided pipe.
     *
     * @param currentPipe - The pipe function to create an instance from.
     * @returns The created instance or an object with the method.
     */
    private createInstanceFromPipe;
    /**
     * Validate that the required method exists on the instance.
     *
     * @param instance - The instance to validate.
     * @param currentPipe - The current pipe being executed.
     * @throws {PipelineError} If the method does not exist on the instance.
     */
    private validatePipeMethod;
    /**
     * Execute lifecycle async hooks.
     *
     * @param name - The hook's name.
     * @param pipe - The current pipe instance.
     */
    private executeAsyncHooks;
    /**
     * Execute lifecycle hooks.
     *
     * @param name - The hook's name.
     * @param pipe - The current pipe instance.
     */
    private executeHooks;
}

/**
 * Define a new middleware for the pipeline.
 *
 * @param module - The pipe module to add to the pipeline.
 * @param options - Additional options for the middleware.
 * @returns The metadata for the middleware.
 */
declare const defineMiddleware: <T = unknown, R = T, Args extends any[] = any[]>(module: PipeType<T, R, Args>, options?: Omit<MetaPipe<T, R, Args>, "module">) => MetaPipe<T, R, Args>;
/**
 * Check if the value is a string.
 *
 * @param value - The value to check.
 * @returns `true` if the value is an string, otherwise `false`.
 */
declare const isString: (value: unknown) => value is string;
/**
 * Check if the value is a function.
 *
 * @param value - The value to check.
 * @returns `true` if the value is a function, otherwise `false`.
 */
declare const isFunction: (value: unknown) => value is Function;
/**
 * Checks if the given value is a constructor function.
 *
 * @param value - The value to be checked.
 * @returns True if the value is a constructor function, false otherwise.
 */
declare const isConstructor: <ClassType = any>(value: unknown) => value is new (...args: any[]) => ClassType;
/**
 * Check if the meta pipe is a function pipe.
 *
 * @param metaPipe - The meta pipe to check.
 * @returns `true` if the meta pipe is a function pipe, otherwise `false`.
 */
declare const isFunctionPipe: <T = unknown, R = T, Args extends any[] = any[]>(metaPipe: MetaPipe<T, R, Args>) => metaPipe is {
    module: FunctionalPipe<T, R>;
};
/**
 * Check if the meta pipe is an alias pipe.
 *
 * @param metaPipe - The meta pipe to check.
 * @returns `true` if the meta pipe is an alias pipe, otherwise `false`.
 */
declare const isAliasPipe: <T = unknown, R = T, Args extends any[] = any[]>(metaPipe: MetaPipe<T, R, Args>) => metaPipe is {
    module: PipeAlias;
};
/**
 * Check if the meta pipe is a class pipe.
 *
 * @param metaPipe - The meta pipe to check.
 * @returns `true` if the meta pipe is a class pipe, otherwise `false`.
 */
declare const isClassPipe: <T = unknown, R = T, Args extends any[] = any[]>(metaPipe: MetaPipe<T, R, Args>) => metaPipe is {
    module: PipeClass<T, R, Args>;
};
/**
 * Check if the meta pipe is a factory pipe.
 *
 * @param metaPipe - The meta pipe to check.
 * @returns `true` if the meta pipe is a factory pipe, otherwise `false`.
 */
declare const isFactoryPipe: <T = unknown, R = T, Args extends any[] = any[]>(metaPipe: MetaPipe<T, R, Args>) => metaPipe is {
    module: FactoryPipe<T, R, Args>;
};

/**
 * Custom error for pipeline operations.
 */
declare class PipelineError extends Error {
    constructor(message: string);
}

export { Pipeline, PipelineError, defineMiddleware, isAliasPipe, isClassPipe, isConstructor, isFactoryPipe, isFunction, isFunctionPipe, isString };
export type { FactoryPipe, FunctionalPipe, HookName, MetaPipe, MixedPipe, NextPipe, PipeAlias, PipeClass, PipeCustomInstance, PipeDefaultInstance, PipeExecutor, PipeInstance, PipeResolver, PipeType, PipelineHook, PipelineHookContext, PipelineHookListener, PipelineOptions, Promiseable, ReducerCallback };
