import { Arbitrary } from './definition/Arbitrary';
/** Define an item to be passed to `scheduleSequence` */
export declare type SchedulerSequenceItem<TMetaData = unknown> = {
    builder: () => Promise<any>;
    label: string;
    metadata?: TMetaData;
} | (() => Promise<any>);
/** Describe a task for the report produced by the scheduler */
export declare type SchedulerReportItem<TMetaData = unknown> = {
    /**
     * Execution status for this task
     * - resolved: task released by the scheduler and successful
     * - rejected: task released by the scheduler but with errors
     * - pending:  task still pending in the scheduler, not released yet
     */
    status: 'resolved' | 'rejected' | 'pending';
    /**
     * How was this task scheduled?
     * - promise: schedule
     * - function: scheduleFunction
     * - sequence: scheduleSequence
     */
    schedulingType: 'promise' | 'function' | 'sequence';
    /** Incremental id for the task, first received task has taskId = 1 */
    taskId: number;
    /** Label of the task */
    label: string;
    /** Metadata linked when scheduling the task */
    metadata?: TMetaData;
    /** Stringified version of the output or error computed using fc.stringify */
    outputValue?: string;
};
export interface SchedulerConstraints {
    /** Ensure that all scheduled tasks will be executed in the right context (for instance it can be the `act` of React) */
    act: (f: () => Promise<void>) => Promise<unknown>;
}
/**
 * Instance able to reschedule the ordering of promises
 * for a given app
 */
export interface Scheduler<TMetaData = unknown> {
    /** Wrap a new task using the Scheduler */
    schedule: <T>(task: Promise<T>, label?: string, metadata?: TMetaData) => Promise<T>;
    /** Automatically wrap function output using the Scheduler */
    scheduleFunction: <TArgs extends any[], T>(asyncFunction: (...args: TArgs) => Promise<T>) => (...args: TArgs) => Promise<T>;
    /**
     * Schedule a sequence of Promise to be executed sequencially.
     * Items within the sequence might be interleaved by other scheduled operations.
     *
     * Please note that whenever an item from the sequence has started,
     * the scheduler will wait until its end before moving to another scheduled task.
     *
     * A handle is returned by the function in order to monitor the state of the sequence.
     * Sequence will be marked:
     * - done if all the promises have been executed properly
     * - faulty if one of the promises within the sequence throws
     */
    scheduleSequence(sequenceBuilders: SchedulerSequenceItem<TMetaData>[]): {
        done: boolean;
        faulty: boolean;
        task: Promise<{
            done: boolean;
            faulty: boolean;
        }>;
    };
    /**
     * Count of pending scheduled tasks
     */
    count(): number;
    /**
     * Wait one scheduled task to be executed
     * @throws Whenever there is no task scheduled
     */
    waitOne: () => Promise<void>;
    /**
     * Wait all scheduled tasks,
     * including the ones that might be created by one of the resolved task
     */
    waitAll: () => Promise<void>;
    /**
     * Produce an array containing all the scheduled tasks so far with their execution status.
     * If the task has been executed, it includes a string representation of the associated output or error produced by the task if any.
     *
     * Tasks will be returned in the order they get executed by the scheduler.
     */
    report: () => SchedulerReportItem<TMetaData>[];
}
/**
 * For scheduler of promises
 */
declare function scheduler<TMetaData = unknown>(constraints?: SchedulerConstraints): Arbitrary<Scheduler<TMetaData>>;
/**
 * For custom scheduler with predefined resolution order
 *
 * Ordering is defined by using a template string like the one generated in case of failure of a {@link scheduler}
 *
 * It may be something like:
 * ```typescript
 * fc.schedulerFor()`
 *   -> [task\${2}] promise pending
 *   -> [task\${3}] promise pending
 *   -> [task\${1}] promise pending
 * `
 * ```
 *
 * Or more generally:
 * ```typescript
 * fc.schedulerFor()`
 *   This scheduler will resolve task ${2} first
 *   followed by ${3} and only then task ${1}
 * `
 * ```
 *
 * WARNING:
 * Custom scheduler will
 * neither check that all the referred promises have been scheduled
 * nor that they resolved with the same status and value.
 *
 *
 * WARNING:
 * If one the promises is wrongly defined it will fail - for instance asking to resolve 5 while 5 does not exist.
 */
declare function schedulerFor<TMetaData = unknown>(constraints?: SchedulerConstraints): (_strs: TemplateStringsArray, ...ordering: number[]) => Scheduler<TMetaData>;
/**
 * For custom scheduler with predefined resolution order
 *
 * WARNING:
 * Custom scheduler will not check that all the referred promises have been scheduled.
 *
 *
 * WARNING:
 * If one the promises is wrongly defined it will fail - for instance asking to resolve 5 while 5 does not exist.
 *
 * @param customOrdering - Array defining in which order the promises will be resolved.
 * Id of the promises start at 1. 1 means first scheduled promise, 2 second scheduled promise and so on.
 */
declare function schedulerFor<TMetaData = unknown>(customOrdering: number[], constraints?: SchedulerConstraints): Scheduler<TMetaData>;
export { scheduler, schedulerFor };
