import { Observable, Subject, Subscription } from 'rxjs';
import { ModuleConfig } from './eui-config/eui-app-config';
import { EuiStoreServiceModel } from './eui-store/eui-store-service.model';
export interface EuiServiceModel<T> {
    init(t: T): Observable<EuiServiceStatus>;
    /**
     * retrieves the State of the service. If you don't pass anything it will retrieve the whole State
     * of that service. If you pass a selector or MapFunction it will retrieve a slice of the state. If
     * you pass a string that's a key of the Service State type it will retrieve that slice of the state.
     */
    getState<K = T>(): Observable<T>;
    getState<K>(mapFn: (state: T) => K): Observable<K>;
    getState<A extends keyof T>(key: A): Observable<T[A]>;
    getState<K>(keyOrMapFn?: ((state: T) => K) | string): Observable<K>;
    updateState(t: T): void;
}
export type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
export declare abstract class EuiService<T> implements EuiServiceModel<T> {
    protected stateInstance: T;
    protected prevStateInstance: T;
    protected $stateSubs: Subscription;
    protected $stateLazyLoadSubs: Subscription;
    onStateChange: Subject<T>;
    protected constructor(defaultState: T);
    initEuiService(): void;
    abstract init(t?: T): Observable<EuiServiceStatus>;
    abstract getState<K = T>(): Observable<T>;
    abstract getState<K>(mapFn?: (state: T) => K): Observable<K>;
    abstract getState<A extends keyof T>(key?: A): Observable<T[A]>;
    abstract getState<K>(keyOrMapFn?: ((state: T) => K) | string): Observable<K>;
    abstract updateState(t: DeepPartial<T>): void;
    protected unSubscribe(): void;
    /**
     * deep merge two objects
     * @param target the object that will be merged into
     * @param source the object that will be merged from
     */
    protected deepMerge<T>(target: T, source: DeepPartial<T>): T;
    /**
     * checks if the given item is an object
     * @param item the item that will be checked
     */
    private isObject;
    /**
     * returns a copy of the given value whether this value is object or primitive. For the arrays it will cover
     * multidimensional arrays, but it will not cover an object that contain functions. JSON.parse and JSON.stringify
     * might have performance issues on large scale objects but that's an edge case scenario. In case that happens in
     * the future follow the technique of NGRX with function caching.
     *
     * @param state
     */
    private copy;
}
export declare abstract class EuiLazyService<T> extends EuiService<T> {
    protected stateInstance: T;
    protected $stateSubs: Subscription;
    protected $stateLazyLoadSubs: Subscription;
    protected constructor(defaultState: T);
    abstract lazyLoadInit(moduleConfig: ModuleConfig, moduleName?: string): Observable<EuiServiceStatus>;
    initEuiService(storeForLazyLoad?: EuiStoreServiceModel<T>): void;
}
/**
 * EuiServiceStatus is a model that represents the status of the service. It has a boolean property that indicates
 * whether the service was successful or not. If the service was not successful it will have an error property that
 * contains the error message.
 * @param T the type of the error message
 * @property success a boolean property that indicates whether the service was successful or not
 * @property error an optional property that contains the error message
 */
export interface EuiServiceStatus<T = unknown> {
    success: boolean;
    error?: T;
}
//# sourceMappingURL=eui-service.model.d.ts.map