/// <reference types="chance" />
import { FiltersMap, RawFilters } from '../model';
import { ListIteratee } from 'lodash';
import { TypedEmitter } from '../util';
interface Order<T> {
    fieldName: ListIteratee<T>;
    order: 'asc' | 'desc';
}
interface IndexedItem<T> {
    item: T;
    index: number;
}
export type TransformPatch<T> = (item: T) => Partial<T>;
export interface BackendQuery<F extends FiltersMap = FiltersMap> {
    /**
     * Number of items to fetch for each page
     */
    limit: number;
    /**
     * The index of the item to start fetching items from.<br>
     * Relevant for APIs that support offset pagination.<br>
     * Not available on `CursorQuery`
     */
    offset?: number;
    page?: number;
    /**
     * Current search term (defaults to `undefined` for empty search)
     */
    search?: string;
    /**
     * The `cursor` returned from the server, to be sent back to it in the next call.<br>
     * Relevant for APIs that support cursor pagination.<br>
     * Not available on `OffsetQuery`
     */
    cursor?: string | null;
    /**
     * Current state of the filters. Each key holds the value of the filter, according to its type, defined in [CollectionConfig](./?path=/story/common-hooks--usecollection).
     */
    filters?: RawFilters<F>;
    /**
     * Current sort applied to the collection.
     */
    sort?: {
        fieldName: string;
        order: 'asc' | 'desc';
    }[];
    /**
     * Array of projected fields. A list of specific field names to return. If `fieldsets` are also specified, the union of `fieldsets` and `fields` is returned.
     */
    fields?: string[];
    /**
     * Array of named, predefined sets of projected fields. A array of predefined named sets of fields to be returned. Specifying multiple `fieldsets` will return the union of fields from all sets. If `fields` are also specified, the union of `fieldsets` and `fields` is returned.
     */
    fieldsset?: string[];
}
export interface Delay {
    min: number;
    max: number;
}
interface SubmitParams {
    delay?: Delay;
    throwError?: () => unknown;
}
interface MoveEvent<T, F extends FiltersMap> {
    from: IndexedItem<T>;
    after: IndexedItem<T> | null;
    over: IndexedItem<T>;
    filters: RawFilters<F>;
}
export interface InMemoryBackendParams<T, F extends FiltersMap = FiltersMap> {
    paginationMode?: 'offset' | 'cursor';
    /**
     * A callback function for each item creation
     */
    createOne: (index: number) => T;
    /**
     * A callback function that accepts an item and returns a unique ID of it. typically `item.id`.
     */
    itemKey: (item: T) => string;
    /**
     * A function that accepts a subset of [ComputedQuery](./?path=/story/common-types--computedquery) sent by the client and returns another function that accepts an item and should return a boolean that indicates whether the item passes the query filtering or not.
     */
    predicate?: (query: BackendQuery<F>) => (item: T) => boolean;
    /**
     * A function that accepts a subset of [ComputedQuery](./?path=/story/common-types--computedquery) sent by the client and returns another function that accepts an item and should returns a list of rules to order the items by
     */
    orderBy?: (query: BackendQuery<F>) => Order<T>[];
    /**
     * A function that accepts a subset of [ComputedQuery](./?path=/story/common-types--computedquery) sent by the client and returns a list of fields to project from the item
     */
    projection?: (query: BackendQuery<F>) => (item: T) => T;
    /**
     * Simulates API latency
     * @default { min: 0, max: 5 }
     */
    delay?: {
        min: number;
        max: number;
    };
    /**
     * Total number of items to store in the backend
     */
    total: number;
    /**
     * Enable total for the backend. Defaults to "true"
     */
    enableTotal?: boolean;
    excludeOrdinalFilters?: string[];
}
export declare class InMemoryBackend<T, F extends FiltersMap = FiltersMap> {
    readonly createOne: InMemoryBackendParams<T, F>['createOne'];
    readonly itemKey: InMemoryBackendParams<T, F>['itemKey'];
    readonly predicate: (query: BackendQuery<F>) => (item: T) => boolean;
    readonly orderBy?: (query: BackendQuery<F>) => Order<T>[];
    readonly projection: ((query: BackendQuery<F>) => (item: T) => T) | undefined;
    readonly initialTotal: number;
    readonly delay: {
        min: number;
        max: number;
    };
    readonly paginationMode: "cursor" | "offset" | undefined;
    readonly enableTotal?: boolean;
    readonly excludeOrdinalFilters: string[];
    readonly events: TypedEmitter<{
        updatedMany: () => void;
        updateAll: () => void;
        deleteAll: () => void;
        fetchDataStart: (query: BackendQuery<F>) => void | Promise<void>;
        fetchTotalStart: (query: BackendQuery<F>) => void | Promise<void>;
        moveStart: (events: MoveEvent<T, F>[]) => void | Promise<void>;
    }>;
    map: Map<string, T>;
    readonly chance: Chance.Chance;
    constructor(params: InMemoryBackendParams<T, F>);
    private simulateAsyncDelay;
    private newList;
    fetchDataSync(query: BackendQuery<F>): {
        cursor: string | undefined;
        total?: number | undefined;
        available?: number | undefined;
        items: T[];
    };
    fetchData: (query: BackendQuery<F>) => Promise<{
        cursor: string | undefined;
        total?: number | undefined;
        available?: number | undefined;
        items: T[];
    }>;
    fetchTotal: (query: BackendQuery<F>) => Promise<number>;
    deleteMany: (items: T[], params?: SubmitParams) => Promise<void>;
    deleteAll(params?: {
        delay?: Delay;
        throwError?: () => unknown;
        filters?: RawFilters<F>;
    }): Promise<void>;
    clear(): void;
    update: (item: T) => Promise<void>;
    updateMany(items: T[], params?: SubmitParams): Promise<void>;
    readonly categoriesOrdinal: Map<string, Map<string, number>>;
    _getOrdinal(filters: RawFilters<F>): Map<string, number>;
    move(events: MoveEvent<T, F>[], params?: {
        delay?: Delay;
        throwError?: () => unknown;
    }): Promise<void>;
    updateAll(patch: TransformPatch<T>, params?: {
        delay?: Delay;
        throwError?: () => unknown;
        filters?: RawFilters<F>;
    }): Promise<void>;
    unshift(newItems: T[]): Promise<void>;
    push(newItems: T[]): Promise<void>;
    elementAt: (index: number) => T;
    getRandomItems(count: number, { limit, page }: {
        limit: number;
        page: number;
    }): T[];
    randomItem: (predicate?: (_: T) => boolean) => {
        index: number;
        item: T | undefined;
    };
    get values(): T[];
    get available(): number;
    get(key?: string): T | undefined;
}
export {};
//# sourceMappingURL=InMemoryBackend.d.ts.map