import { KeetaAnchorQueueRunner } from './index.js';
import type { KeetaAnchorQueueStorageDriver, KeetaAnchorQueueRequestID, KeetaAnchorQueueCommonOptions, KeetaAnchorQueueEntry } from './index.ts';
import type { Logger } from '../log/index.ts';
import type { JSONSerializable } from '../utils/json.js';
import type { KeetaAnchorQueueRunOptions } from './common.js';
/**
 * A KeetaAnchorQueueRunner that uses `any` for the user types
 * This is helpful for expressing pipelines where the inputs
 * and outputs of various stages are not known ahead of time
 */
declare class KeetaAnchorQueueRunnerAny<UserRequest = any, UserResult = any, QueueRequest extends JSONSerializable = JSONSerializable, QueueResult extends JSONSerializable = JSONSerializable> extends KeetaAnchorQueueRunner<UserRequest, UserResult, QueueRequest, QueueResult> {
    protected processor(): ReturnType<KeetaAnchorQueueRunner<UserRequest, UserResult, QueueRequest, QueueResult>['processor']>;
    protected decodeRequest(): UserRequest;
    protected decodeResponse(): UserResult | null;
    protected encodeRequest(): QueueRequest;
    protected encodeResponse(): QueueResult | null;
}
type KeetaAnchorQueuePipelineStage<QueueRequest, QueueResult> = {
    /**
     * Name of the stage (must be unique within the pipeline)
     */
    name: string;
    /**
     * Constructor of the runner to use for this stage
     */
    runner: typeof KeetaAnchorQueueRunner<QueueRequest, QueueResult, JSONSerializable, JSONSerializable>;
    /**
     * Arguments to pass to the runner constructor
     */
    args?: [{
        [key: string]: unknown;
    }?, ...unknown[]];
};
export interface KeetaAnchorQueuePipeline<QueueRequest, FINALQueueResult> {
    readonly id: string;
    /**
     * Add a new request to the queue pipeline at the first stage
     *
     * @param request The request to add
     * @returns The ID of the newly added request
     */
    add: (request: QueueRequest) => Promise<KeetaAnchorQueueRequestID>;
    /**
     * Get the entry of a request at the final stage of the pipeline
     * stage or `null` if not in the final stage
     *
     * The original request is also returned if available
     *
     * @param id The ID of the request to get
     * @returns The entry at the final stage or `null` if not found, with the original request (may be `null` if not available)
     */
    get: (id: KeetaAnchorQueueRequestID) => Promise<(Omit<KeetaAnchorQueueEntry<QueueRequest, FINALQueueResult>, 'request'> & {
        request: QueueRequest | null;
    }) | null>;
    /**
     * Run the pipeline processing jobs for up to the specified timeout (in milliseconds)
     * The process may take longer than the timeout if a job is already in progress
     * when the timeout is reached, in which case the process will complete the current job
     * before returning.
     *
     * @param timeoutMs The maximum time to run the processing jobs (in milliseconds). If not specified, runs until all available jobs are processed.
     * @returns `true` if there are more jobs to process, `false` otherwise
     */
    run: (options?: KeetaAnchorQueueRunOptions) => Promise<boolean>;
    /**
     * Run maintenance tasks for the pipeline -- this includes moving tasks from various states
     * and between stages of the pipeline
     */
    maintain: () => Promise<void>;
    /**
     * Destroy the pipeline and release any resources it allocated
     */
    destroy: () => Promise<void>;
    [Symbol.asyncDispose]: () => Promise<void>;
}
declare const symbolFirst: unique symbol;
declare const symbolLast: unique symbol;
/**
 * Abstract base class for queue advanced pipelines -- this provides
 * a standardized way to implement custom processing pipelines that
 * consist of multiple stages with custom behavior
 */
export declare abstract class KeetaAnchorQueuePipelineAdvanced<IN1 = unknown, FINALOUT = unknown> implements KeetaAnchorQueuePipeline<IN1, FINALOUT> {
    readonly id: string;
    protected readonly baseQueue: KeetaAnchorQueueStorageDriver<JSONSerializable, JSONSerializable>;
    protected readonly logger?: Logger | undefined;
    protected queues: KeetaAnchorQueueStorageDriver<JSONSerializable, JSONSerializable>[];
    protected initPromise?: Promise<void>;
    protected destroyed: boolean;
    static readonly StageID: {
        readonly first: typeof symbolFirst;
        readonly last: typeof symbolLast;
    };
    constructor(options: KeetaAnchorQueueCommonOptions & {
        baseQueue: KeetaAnchorQueueStorageDriver<JSONSerializable, JSONSerializable>;
    });
    protected methodLogger(method: string): Logger | undefined;
    /**
     * Create the pipeline stages -- will be called by the initialization process
     */
    protected abstract createPipeline(): Promise<void>;
    /**
     * Get the stage runner for the specified stage name, or the first/last stage
     */
    protected abstract getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.first): KeetaAnchorQueueRunner<IN1, unknown>;
    protected abstract getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.last): KeetaAnchorQueueRunner<unknown, FINALOUT>;
    protected abstract getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.first | typeof KeetaAnchorQueuePipelineAdvanced.StageID.last | string): KeetaAnchorQueueRunner<unknown, unknown> | null;
    /**
     * Create a new queue to use in a pipeline stage
     * It will be released when the pipeline is destroyed
     *
     * @param name The name of the queue
     * @returns The created queue
     */
    protected createQueue(name: string): Promise<KeetaAnchorQueueStorageDriver<JSONSerializable, JSONSerializable>>;
    protected init(): Promise<void>;
    add(request: IN1): ReturnType<KeetaAnchorQueueRunner<IN1, unknown>['add']>;
    get(id: KeetaAnchorQueueRequestID): Promise<(Omit<KeetaAnchorQueueEntry<IN1, FINALOUT>, 'request'> & {
        request: IN1 | null;
    }) | null>;
    run(options?: KeetaAnchorQueueRunOptions): Promise<boolean>;
    maintain(): Promise<void>;
    destroy(): Promise<void>;
    [Symbol.asyncDispose](): Promise<void>;
}
type MapKeetaAnchorQueuePipelineStages<In extends readonly [unknown, ...unknown[]]> = In extends [infer First, ...infer Rest extends [unknown, ...unknown[]]] ? readonly [KeetaAnchorQueuePipelineStage<First, Rest[0]>, ...MapKeetaAnchorQueuePipelineStages<Rest>] : [];
type MapKeetaAnchorQueueRunner<In extends readonly [unknown, ...unknown[]]> = In extends [infer First, ...infer Rest extends [unknown, ...unknown[]]] ? readonly [KeetaAnchorQueueRunner<First, Rest[0]>, ...MapKeetaAnchorQueueRunner<Rest>] : [];
type FirstElement<T extends readonly unknown[]> = T extends [infer First, ...unknown[]] ? First : never;
type LastElement<T extends readonly unknown[]> = T extends [...unknown[], infer Last] ? Last : never;
/**
 * Abstract base class for queue basic pipelines -- this provides
 * a standardized way to implement custom processing pipelines that
 * consist of multiple stages but do not require batching
 */
export declare abstract class KeetaAnchorQueuePipelineBasic<Stages extends readonly [unknown, ...unknown[]]> extends KeetaAnchorQueuePipelineAdvanced<FirstElement<Stages>, LastElement<Stages>> implements KeetaAnchorQueuePipeline<FirstElement<Stages>, LastElement<Stages>> {
    protected readonly abstract stages: MapKeetaAnchorQueuePipelineStages<Stages>;
    protected stageRunners: MapKeetaAnchorQueueRunner<Stages>;
    constructor(options: KeetaAnchorQueueCommonOptions & {
        baseQueue: KeetaAnchorQueueStorageDriver<JSONSerializable, JSONSerializable>;
    });
    protected methodLogger(method: string): Logger | undefined;
    protected getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.first): KeetaAnchorQueueRunner<FirstElement<Stages>, unknown>;
    protected getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.last): KeetaAnchorQueueRunner<unknown, LastElement<Stages>>;
    protected getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.first | typeof KeetaAnchorQueuePipelineAdvanced.StageID.last | string): KeetaAnchorQueueRunnerAny | null;
    /**
     * Create the pipeline from the user-defined stages
     */
    protected createPipeline(): Promise<void>;
    destroy(): Promise<void>;
}
export {};
//# sourceMappingURL=pipeline.d.ts.map