import type { Observable } from 'rxjs';
export interface Selector<T, R> {
    (state: T): R;
}
export interface SelectorOptions<T> {
    equals?: (a: T, b: T) => boolean;
    name?: string;
}
export interface Subscriber<T> {
    notify: (value: T) => void | Promise<void>;
}
export interface SelectorAPI<T> {
    select: () => T;
    selectSync: () => T;
    subscribe: (subscriber: Subscriber<T>) => VoidFunction;
    getId: () => string;
    /**
     * Observable-вид селектора: эмитит текущее значение при подписке и при каждом
     * реальном изменении (та же семантика, что у `subscribe`). Позволяет реактивно
     * трансформировать чтение прямо в компоненте — `selector.$.pipe(debounceTime(300))`.
     */
    readonly $: Observable<T>;
    /** @internal — проверка готовности источника данных */
    isSourceReady: () => boolean;
    /** @internal — подписка на изменение статуса источника */
    onSourceStatusChange: (callback: (isReady: boolean) => void) => VoidFunction;
}
/**
 * Интерфейс для модуля селекторов
 * Определяет контракт для работы с селекторами, который должен реализовывать SelectorModule
 */
export interface ISelectorModule<TStore extends Record<string, any>> {
    /**
     * Имя связанного хранилища
     */
    readonly storageName: string;
    /**
     * Создает простой селектор на основе функции выбора
     *
     * @param selector Функция, извлекающая данные из состояния
     * @param options Опции селектора
     * @returns API селектора
     *
     * @example
     * const isActive = selectorModule.createSelector(
     *   (state) => state.user.isActive,
     *   { name: 'userIsActive' }
     * );
     */
    createSelector<T>(selector: Selector<TStore, T>, options?: SelectorOptions<T>): SelectorAPI<T>;
    /**
     * Создает комбинированный селектор на основе других селекторов
     *
     * @param dependencies Массив селекторов, от которых зависит новый селектор
     * @param resultFn Функция, комбинирующая результаты зависимостей
     * @param options Опции селектора
     * @returns API селектора
     *
     * @example
     * const userWithStatus = selectorModule.createSelector(
     *   [userSelector, statusSelector],
     *   (user, status) => ({ ...user, status }),
     *   { name: 'userWithStatus' }
     * );
     */
    createSelector<Deps extends unknown[], T>(dependencies: {
        [K in keyof Deps]: SelectorAPI<Deps[K]>;
    }, resultFn: (...args: Deps) => T, options?: SelectorOptions<T>): SelectorAPI<T>;
    /**
     * Точечно удаляет один селектор по его id (`SelectorAPI.getId()`): снимает подписки
     * на хранилище и чистит кэш, не затрагивая остальные селекторы модуля. Нужен для
     * keyed-кэша и для `destroy()` class-селекторов, владеющих общим модулем.
     *
     * @param id Идентификатор селектора (`selector.getId()`)
     */
    removeSelector(id: string): void;
    /**
     * Освобождает ресурсы, связанные с модулем селекторов
     */
    destroy(): void;
}
