import NodeFire from 'nodefire';
import { FireleaseStats, type QueueSourceMode } from './stats';
export declare const TESTABLES: {
    resetBetweenTests: typeof resetBetweenTests;
    waitUntilDeleted: typeof waitUntilDeleted;
    getQueueCheckCooldown: typeof getQueueCheckCooldown;
};
declare const RETRY_DIRECTIVE: unique symbol;
export type Duration = number | string;
export interface Lease {
    expiry?: number;
    time?: number;
    attempts?: number;
    initial?: number;
    busy?: boolean;
    timeNeeded?: number;
    extendLeasePromise?: Promise<void>;
}
export type AcquiredLease = Lease & {
    expiry: number;
    time: number;
    attempts: number;
    initial: number;
    readonly firstAcquisition?: true;
};
export interface LeaseItem {
    _lease?: Lease;
    [key: string]: any;
}
export interface RetryDirective {
    readonly [RETRY_DIRECTIVE]: true;
}
export interface WorkerItem extends LeaseItem {
    _lease: AcquiredLease;
    readonly $ref: NodeFire;
    readonly $leaseTimeRemaining: number;
}
export type FireleaseErrorLevel = 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug';
export interface FireleaseErrorDetails {
    cause?: string;
    code?: string;
    count?: number;
    delta?: number;
    description?: string;
    itemKey?: string;
    listenerLimit?: number;
    liveCount?: number;
    mode?: QueueSourceMode;
    phase?: string;
    queue?: string;
    reason?: string;
    source?: string;
    timeNeeded?: Duration;
    timeout?: Duration;
}
export interface FireleaseError extends Error {
    firelease?: FireleaseErrorDetails;
    level?: FireleaseErrorLevel;
}
export type LeaseTransactionOutcome = 'acquired' | 'contended' | 'failed';
export type CaptureLeaseTransactionMetrics = (outcome: LeaseTransactionOutcome, tries: number, duration: number) => undefined;
export interface QueueOptions {
    maxConcurrent?: number;
    bufferSize?: number;
    minLease?: Duration;
    maxLease?: Duration;
    healthyPingLatency?: Duration;
    preprocess?: (item: LeaseItem) => LeaseItem;
    captureLeaseTransactionMetrics?: CaptureLeaseTransactionMetrics;
}
export type PingReport = FireleaseStats;
export type QueueRef = NodeFire | NodeFire[];
export type WorkerResult = RetryDirective | Duration | Lease | null | void | ((item: LeaseItem) => RetryDirective | Duration | Lease | null | void);
export type Worker = (item: WorkerItem) => WorkerResult | PromiseLike<WorkerResult>;
export interface FireleaseSettings {
    globalMaxConcurrent: number;
    safeQueueSize: number;
    queueCheckInterval: Duration;
    queueLoadTimeout: Duration;
    captureError: (error: FireleaseError) => void;
}
export interface FireleaseApi {
    readonly RETRY: RetryDirective;
    readonly settings: FireleaseSettings;
    readonly defaults: QueueOptions;
    readonly stats: FireleaseStats;
    attachWorker: {
        (refOrRefs: QueueRef, worker: Worker): void;
        (refOrRefs: QueueRef, options: QueueOptions, worker: Worker): void;
    };
    pingQueues(callback?: ((report: PingReport) => void) | null, interval?: Duration): void;
    extendLease(item: WorkerItem, timeNeeded: Duration): Promise<void>;
    blacklist(taskKey: string): boolean;
    shutdown(): Promise<void>;
    listTasksInProgress(): string[];
}
/**
 * Return this from a worker to retry after the current lease expires, and to reset the lease
 * backoff to zero.
 */
export declare const RETRY: RetryDirective;
/** Default option values for all subsequent attachWorker calls. */
export declare const defaults: QueueOptions;
export declare const stats: FireleaseStats;
export declare const settings: FireleaseSettings;
declare const firelease: FireleaseApi;
declare function getQueueCheckCooldown(previousDuration: number): number;
/**
 * Attaches a worker function to consume tasks from a queue.  You should normally attach no more
 * than one worker per path in any given process, but it's OK to run multiple processes on the same
 * paths concurrently.
 *
 * All durations can be specified as either a human-readable string, or a number of milliseconds.
 *
 * @param {NodeFire | NodeFire[]} refOrRefs One or more NodeFire refs to queue roots in Firebase.
 *        Individual tasks will be children of these roots and must be objects.  All refs form one
 *        logical queue and share the same worker and concurrency limits.  The '_lease' key is
 *        reserved for use by Firelease in each task.
 * @param {Object} options Optional options, supporting the following values:
 *        maxConcurrent: {number} max number of tasks to handle concurrently for this worker.
 *        bufferSize: {number} upper bound on how many tasks to keep buffered from each source and
 *          potentially go through leasing transactions in parallel.  It defaults to `Infinity`,
 *          which is preferred for efficiency and correctness unless the queue will usually remain
 *          above `settings.safeQueueSize`.  `Infinity` adapts between a full listener and a safe
 *          listener limited to `settings.safeQueueSize` tasks.  Use a finite value only to keep an
 *          ordinarily large queue permanently on a limited listener.  An explicit finite value is
 *          used as-is and may be greater than `settings.safeQueueSize`.
 *        minLease: {number | string} minimum duration of each lease, which should equal the maximum
 *          expected time a worker will take to handle a task.
 *        maxLease: {number | string} maximum duration of each lease; the lease duration is doubled
 *          each time a task fails until it reaches maxLease.
 *        preprocess: {function(Object):Object} a function to use to preprocess each item during the
 *          leasing transaction.  This function must be fast, synchronous, idempotent, and
 *          should return the modified item (passed as the sole argument, OK to mutate).  One use
 *          for preprocessing is to clean up items written to a queue by a process outside your
 *          control (e.g., webhooks).
 *        healthyPingLatency: {number | string} the maximum response latency to pings that is
 *          considered "healthy" for this queue.
 *        captureLeaseTransactionMetrics: {function(string, number, number)} a callback invoked
 *          after each acquired, contended, or failed task lease transaction with its outcome,
 *          NodeFire transaction tries, and duration in milliseconds.  The callback must be
 *          synchronous.
 * @param {function(Object):RETRY | number | string | undefined} worker The worker function that
 *        handles enqueued tasks.  It will be given a task object as argument, with a special $ref
 *        attribute set to the Nodefire ref of that task.  On a task's first acquisition its _lease
 *        also has a non-enumerable firstAcquisition property set to true; it is not saved to
 *        Firebase and is absent on subsequent acquisitions.  The worker can perform arbitrary
 *        computation whose duration should not exceed the queue's minLease value.  It can
 *        manipulate the task itself in Firebase as well, e.g. to delete it (to get at-most-once
 *        queue semantics) or otherwise modify it.  The worker can return any of the following:
 *        * undefined or null to cause the task to be retired from the queue.
 *        * firelease.RETRY to cause the task to be retried after the current lease expires (and
 *          reset the lease backoff counter).
 *        * A duration after which the task should be retried relative to when it was started.
 *        * An epoch in milliseconds greater than 1000000000000 at which the task should be tried.
 *        * A complete _lease object, to be saved as-is.
 *        * A function that takes the task as argument and returns one of the values above.  This
 *          function will be executed in a transaction to ensure atomicity.
 *        All of these values can also be wrapped in a promise.
 */
export declare function attachWorker(refOrRefs: QueueRef, worker: Worker): void;
export declare function attachWorker(refOrRefs: QueueRef, options: QueueOptions, worker: Worker): void;
/**
 * Sets up regular pinging of all queues.  Can be called either before or after workers are
 * attached, and will always ping all queues.  Can be called more than once to change the
 * parameters.
 *
 * All durations can be specified as either a human-readable string, or a number of milliseconds.
 *
 * @param {Function(Object) | null} callback The callback to invoke with the live `stats` object
 *        each time we ping all the queues.  It retains the existing global fields and adds
 *        structured results for every logical queue and physical source.  If not specified,
 *        reports are silently dropped.
 * @param {number | string} interval The interval at which to ping queues, to both check the
 *        current response latency and make sure no tasks are stuck.  Defaults to 1 minute.
 */
export declare function pingQueues(callback?: ((report: PingReport) => void) | null, interval?: Duration): void;
declare function waitUntilDeleted(ref: NodeFire, timeout: number): Promise<void>;
/**
 * Extends the lease on a task to give the worker more time to finish.  Checks a bunch of validity
 * constraints along the way and throws an error if the worker needs to abort.
 *
 * All durations can be specified as either a human-readable string, or a number of milliseconds.
 *
 * @param {Object} item The original task object provided to a worker function.
 * @param {number | string} timeNeeded The minimum time needed counting from the current time.  The
          actual lease may be extended by up to twice this amount, to prevent excessive churn.
 * @return {Promise} A promise that will be resolved when the lease has been extended, and rejected
 *         if something went wrong and the worker should abort.
 */
export declare function extendLease(item: WorkerItem, timeNeeded: Duration): Promise<void>;
/**
 * Blacklist the given task key from ever being processed again.
 * @param {string} taskKey The task key to blacklist.  This is the full Firebase URL of the task and
 *        can be obtained from an error using `error.firelease.itemKey`.
 * @return {boolean} True if the task key was added to the list, false if it was already present.
 */
export declare function blacklist(taskKey: string): boolean;
/**
 * Shuts down firelease by refusing to take new tasks.
 * @return {Promise<void>} A promise that resolves when the shutdown is complete.
 */
export declare function shutdown(): Promise<void>;
/**
 * Lists the URLs of all tasks that are currently being worked on.
 */
export declare function listTasksInProgress(): string[];
declare function resetBetweenTests(): void;
export default firelease;
