import type { UUID } from 'node:crypto';
import type { Concrete } from 'utilium';
import type { CreationOptions, FileSystem, StreamOptions, UsageInfo } from '../internal/filesystem.js';
import type { InodeLike } from '../internal/inode.js';
import '../polyfills.js';
/**
 * @category Internals
 * @internal
 */
export declare class MutexLock {
    protected readonly previous?: MutexLock | undefined;
    protected current: PromiseWithResolvers<void>;
    protected _isLocked: boolean;
    get isLocked(): boolean;
    constructor(previous?: MutexLock | undefined);
    done(): Promise<void>;
    unlock(): void;
    [Symbol.dispose](): void;
}
/**
 * @hidden
 * @category Internals
 */
export declare class _MutexedFS<T extends FileSystem> implements FileSystem {
    /**
     * @internal
     */
    _fs: T;
    get type(): number;
    get name(): string;
    get label(): string | undefined;
    set label(value: string | undefined);
    get attributes(): import("utilium").ConstMap<import("../internal/filesystem.js").FileSystemAttributes, keyof import("../internal/filesystem.js").FileSystemAttributes, void | import("../internal/filesystem.js").CaseFold | undefined> & Map<string, any>;
    get _uuid(): UUID;
    set _uuid(value: UUID);
    get uuid(): UUID;
    ready(): Promise<void>;
    readySync(): void;
    usage(): UsageInfo;
    /**
     * The current locks
     */
    private currentLock?;
    /**
     * Adds a lock for a path
     */
    protected addLock(): MutexLock;
    /**
     * Locks `path` asynchronously.
     * If the path is currently locked, waits for it to be unlocked.
     * @internal
     */
    lock(timeout?: number): Promise<MutexLock>;
    /**
     * Locks `path` asynchronously.
     * If the path is currently locked, an error will be thrown
     * @internal
     */
    lockSync(): MutexLock;
    /**
     * Whether `path` is locked
     * @internal
     */
    get isLocked(): boolean;
    rename(oldPath: string, newPath: string): Promise<void>;
    renameSync(oldPath: string, newPath: string): void;
    stat(path: string): Promise<InodeLike>;
    statSync(path: string): InodeLike;
    touch(path: string, metadata: InodeLike): Promise<void>;
    touchSync(path: string, metadata: InodeLike): void;
    createFile(path: string, options: CreationOptions): Promise<InodeLike>;
    createFileSync(path: string, options: CreationOptions): InodeLike;
    unlink(path: string): Promise<void>;
    unlinkSync(path: string): void;
    rmdir(path: string): Promise<void>;
    rmdirSync(path: string): void;
    mkdir(path: string, options: CreationOptions): Promise<InodeLike>;
    mkdirSync(path: string, options: CreationOptions): InodeLike;
    readdir(path: string): Promise<string[]>;
    readdirSync(path: string): string[];
    exists(path: string): Promise<boolean>;
    existsSync(path: string): boolean;
    link(srcpath: string, dstpath: string): Promise<void>;
    linkSync(srcpath: string, dstpath: string): void;
    sync(): Promise<void>;
    syncSync(): void;
    read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
    readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
    write(path: string, buffer: Uint8Array, offset: number): Promise<void>;
    writeSync(path: string, buffer: Uint8Array, offset: number): void;
    streamRead(path: string, options: StreamOptions): ReadableStream;
    streamWrite(path: string, options: StreamOptions): WritableStream;
}
/**
 * This serializes access to an underlying async filesystem.
 * For example, on an OverlayFS instance with an async lower
 * directory operations like rename and rmdir may involve multiple
 * requests involving both the upper and lower file systems -- they
 * are not executed in a single atomic step. OverlayFS used to use this
 * to avoid having to reason about the correctness of
 * multiple requests interleaving.
 *
 * @privateRemarks
 * Instead of extending the passed class, `MutexedFS` stores it internally.
 * This is to avoid a deadlock caused when a method calls another one
 * The problem is discussed extensively in [#78](https://github.com/zen-fs/core/issues/78)
 * Instead of extending `FileSystem`,
 * `MutexedFS` implements it in order to make sure all of the methods are passed through
 *
 * @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
 * @category Internals
 * @internal
 */
export declare function Mutexed<const T extends Concrete<typeof FileSystem>>(FS: T): typeof _MutexedFS<InstanceType<T>> & {
    new (...args: ConstructorParameters<T>): _MutexedFS<InstanceType<T>>;
};
