import type { Constructable } from '@furystack/inject';
import type { EventHub } from '@furystack/utils';
export declare const NumberComparisonOperators: readonly ["$gt", "$gte", "$lt", "$lte"];
export declare const StringComparisonOperators: readonly ["$startsWith", "$endsWith", "$like", "$regex"];
export declare const SingleComparisonOperators: readonly ["$eq", "$ne"];
export declare const ArrayComparisonOperators: readonly ["$in", "$nin"];
export declare const LogicalOperators: readonly ["$and", "$not", "$nor", "$or"];
export declare const allOperators: readonly ["$eq", "$ne", "$gt", "$gte", "$lt", "$lte", "$in", "$nin", "$and", "$not", "$nor", "$or", "$startsWith", "$endsWith", "$like", "$regex"];
export type FilterType<T> = {
    [K in keyof T]?: (T[K] extends string ? {
        [SCO in (typeof StringComparisonOperators)[number]]?: T[K];
    } : never) | (T[K] extends number ? {
        [SCO in (typeof NumberComparisonOperators)[number]]?: T[K];
    } : never) | {
        [SCO in (typeof SingleComparisonOperators)[number]]?: T[K];
    } | {
        [ACO in (typeof ArrayComparisonOperators)[number]]?: Array<T[K]>;
    };
} & {
    [LO in (typeof LogicalOperators)[number]]?: Array<FilterType<T>>;
};
export declare const isLogicalOperator: (propertyString: string) => propertyString is (typeof LogicalOperators)[number];
export declare const isOperator: (propertyString: string) => propertyString is (typeof allOperators)[number];
export declare const t: FilterType<{
    a: number;
    b: string;
    c: boolean;
}>;
export interface CreateResult<T> {
    created: T[];
}
export type WithOptionalId<T, TPrimaryKey extends keyof T> = Omit<T, TPrimaryKey> & {
    [K in TPrimaryKey]?: T[K];
};
/**
 * Type for default filtering model
 */
export interface FindOptions<T, TSelect extends Array<keyof T>> {
    /**
     * Limits the hits
     */
    top?: number;
    /**
     * Skips the first N hit
     */
    skip?: number;
    /**
     * Sets up an order by a field and a direction
     */
    order?: {
        [P in keyof T]?: 'ASC' | 'DESC';
    };
    /**
     * The result set will be limited to these fields
     */
    select?: TSelect;
    /**
     * The fields should match this filter
     */
    filter?: FilterType<T>;
}
export type PartialResult<T, TFields extends Array<keyof T>> = Pick<T, TFields[number]>;
export declare const selectFields: <T extends object, TField extends Array<keyof T>>(entry: T, ...fields: TField) => PartialResult<T, TField>;
/**
 * Interface that defines a physical store implementation
 */
export interface PhysicalStore<T, TPrimaryKey extends keyof T, TWriteableData = WithOptionalId<T, TPrimaryKey>> extends EventHub<{
    onEntityAdded: {
        entity: T;
    };
    onEntityUpdated: {
        id: T[TPrimaryKey];
        change: Partial<T>;
    };
    onEntityRemoved: {
        key: T[TPrimaryKey];
    };
}> {
    /**
     * The Primary key field name
     */
    readonly primaryKey: TPrimaryKey;
    /**
     * A constructable model
     */
    readonly model: Constructable<T>;
    /**
     * Adds an entry to the store, returns a promise that will be resolved with the added data
     * @param entries The data to be added
     */
    add(...entries: TWriteableData[]): Promise<CreateResult<T>>;
    /**
     * Updates an entry in the store, returns a promise that will be resolved once the update is done
     * @param id The primary key of the entry
     * @param data The data to be updated
     */
    update(id: T[TPrimaryKey], data: Partial<T>): Promise<void>;
    /**
     * Returns a promise that will be resolved with the count of the elements
     */
    count(filter?: FilterType<T>): Promise<number>;
    /**
     * Returns a promise that will be resolved with an array of elements that matches the filter
     * @param searchOptions An options object for the Search expression
     */
    find<TSelect extends Array<keyof T>>(findOptions: FindOptions<T, TSelect>): Promise<Array<PartialResult<T, TSelect>>>;
    /**
     * Returns a promise that will be resolved with an entry with the defined primary key or undefined
     * @param key The primary key of the entry
     */
    get<TSelect extends Array<keyof T>>(key: T[TPrimaryKey], select?: TSelect): Promise<PartialResult<T, TSelect> | undefined>;
    /**
     * Removes an entry with the defined primary key. Returns a promise that will be resolved once the operation is completed
     * @param key The primary key of the entry to remove
     */
    remove(...keys: Array<T[TPrimaryKey]>): Promise<void>;
}
//# sourceMappingURL=physical-store.d.ts.map