import { RemoteDataStatus } from "./RemoteDataStatus.js";
import { Optional } from "./Optional.js";
/**
 * This class represents data from a remote source that takes time to load.
 *
 * This data can be a single value or an array of values. Since there's no way to
 * infer the shape of the data, the caller is expected to know and to make the
 * appropriate calls
 *
 *
 * @template D A type representing the shape of data that is being requested
 * @template E A type representing the shape of errors that can be returned
 */
export declare class AsyncData<D, E = {}> {
    #private;
    protected status: RemoteDataStatus;
    private constructor();
    /**
     * Create an instance of this type that indicates that the request for async data
     * has not yet been made
     */
    static notAsked<ND, NE = {}>(): AsyncData<ND, NE>;
    /**
     * Create an instance of this type that indicates that a request is in flight but has not
     * yet completed
     */
    static loading<LD, LE = {}>(): AsyncData<LD, LE>;
    /**
     * Create an instance of this type that indicates that some data has been returned by the request.
     *
     * NB: There is nothing here that asserts that the request is complete. This factory method can
     * be called multiple times to indicate loading data in progress.
     *
     * @param data
     */
    static loaded<LD, LE = {}>(data: readonly LD[]): AsyncData<LD, LE>;
    /**
     * Create an instance of this type that indicates that the requests has errored.
     * @param error
     */
    static errored<ED, EE = {}>(error: EE): AsyncData<ED, EE>;
    private cloneWithNewData;
    /**
     *
     * @returns true if this object currently contains retrievable data, i.e. not an error and not an inflight request
     */
    containsData(): boolean;
    /**
     * Check the status of the data request
     *
     * @param status
     */
    is(status: RemoteDataStatus): boolean;
    /**
     * Check whether data has been requested
     */
    isAsked(): boolean;
    /**
     * Check whether data is currently loading
     */
    isLoading(): boolean;
    /**
     * Check whether any data has loaded (or that the request has failed)
     */
    isLoaded(): boolean;
    /**
     * Check whether the data errored out
     */
    isErrored(): boolean;
    /**
     * Checks whether the data that was loaded is empty.
     *
     * This will throw an error if the data is not loaded yet
     *
     * @throws {NoSuchElementException}
     */
    isEmpty(): boolean;
    /**
     *
     */
    value(): ReadonlyArray<D>;
    loadMore(): AsyncData<D, E>;
    /**
     * Get the data as an optional and treat it as an array
     *
     * This will return any internal data that exists. As a result, it will
     * return data after a call to `loadMore`.
     */
    getOptional(): Optional<readonly D[]>;
    /**
     * Treats the data as an Optional and returns the internal
     * value or the provided value.
     *
     * @param v
     */
    orElse(v: readonly D[]): typeof v;
    append(v: D[]): AsyncData<D>;
    /**
     * Standard response for mapping this AsyncData to a new one
     * when no data is loaded
     */
    private getNonLoadedResult;
    map<U>(callbackfn: (value: D, index: number, array?: ReadonlyArray<D>) => U): AsyncData<U, E>;
    mapValue<U>(callbackfn: (value: D, index: number, array?: ReadonlyArray<D>) => U): ReadonlyArray<U>;
    filter(callbackfn: (value: D, index?: number, array?: ReadonlyArray<D>) => boolean): AsyncData<D, E>;
    reduce<U>(callbackfn: (previousValue: U, currentValue: D, currentIndex: number, array: ReadonlyArray<D>) => U, initialValue: U): AsyncData<U, E>;
    find(predicate: (value: D, index: number, obj: ReadonlyArray<D>) => boolean, thisArg?: unknown): D | undefined;
    findIndex(predicate: (value: D, index: number, obj: ReadonlyArray<D>) => boolean, thisArg?: unknown): number;
    update(index: number, value: D): AsyncData<D, E>;
    concat(...items: (D | ConcatArray<D>)[]): AsyncData<D, E>;
    /**
     * Sorts the elements of data, according to `compareFn`
     *
     * Note that this does not sort the elements in place
     *
     * @param compareFn The comparison function to be applied to the data elements. See [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) documentation for more detail
     *
     *
     * @throws an error if no response has been received
     */
    sort(compareFn?: (a: D, b: D) => number): D[];
    get(index: number): D;
    remove(index: number): AsyncData<D, E>;
    /**
     * This returns `true` if the `predicate` returns `true` for every element of data.
     *
     * It is synonymous with {@link every}
     *
     * @throws an error if no response has been received
     */
    all(predicate: (value: D, index: number, array: D[]) => boolean): boolean;
    /**
     * This returns `true` if the `predicate` returns `true` for every element of data.
     *
     * It is synonymous with {@link all}
     *
     * @throws an error if no response has been received
     */
    every(predicate: (value: D, index: number, array: D[]) => boolean): boolean;
    /**
     * This returns `true` if the `predicate` returns `true` for any element of data.
     *
     * It is synonymous with {@link some}
     *
     * @throws an error if no response has been received
     */
    any(predicate: (value: D, index: number, array: D[]) => boolean): boolean;
    /**
     * This returns `true` if the `predicate` returns `true` for any element of data.
     *
     * It is synonymous with {@link any}
     *
     * @throws an error if no response has been received
     */
    some(predicate: (value: D, index: number, array: D[]) => boolean): boolean;
}
