import { Awaitable } from '../../libs/promises/promises.js';

declare class LockedError extends Error {
    #private;
    readonly name: string;
    constructor();
}
/**
 * A releasable object
 */
declare class Lock<T> {
    readonly inner: T;
    readonly release: () => void;
    constructor(inner: T, release: () => void);
    [Symbol.dispose](): void;
    get(): T;
}
/**
 * A semaphore with some reference and some capacity
 */
declare class Semaphore<T, N extends number = number> {
    #private;
    readonly inner: T;
    readonly capacity: N;
    constructor(inner: T, capacity: N);
    static void<N extends number>(capacity: N): Semaphore<void, N>;
    get locked(): boolean;
    get count(): number;
    get(): T;
    /**
     * Get and lock or throw
     * @returns
     */
    getOrThrow(): Promise<Lock<T>>;
    /**
     * Get and lock or wait
     * @returns
     */
    getOrWait(): Promise<Lock<T>>;
    /**
     * Run and lock or throw
     * @param callback
     */
    runOrThrow<R>(callback: (inner: T) => Awaitable<R>): Promise<R>;
    /**
     * Run and lock or wait
     * @param callback
     */
    runOrWait<R>(callback: (inner: T) => Awaitable<R>): Promise<R>;
}
/**
 * A semaphore but with a capacity of 1
 */
declare class Mutex<T> {
    #private;
    readonly inner: T;
    constructor(inner: T);
    static void(): Mutex<void>;
    get locked(): boolean;
    get(): T;
    getOrThrow(): Promise<Lock<T>>;
    getOrWait(): Promise<Lock<T>>;
    runOrThrow<R>(callback: (inner: T) => Awaitable<R>): Promise<R>;
    runOrWait<R>(callback: (inner: T) => Awaitable<R>): Promise<R>;
}

export { Lock, LockedError, Mutex, Semaphore };
