import type { IStorage } from '../storage';
import type { ISelectorModule, SelectorAPI, SelectorOptions } from './selector.interface';
/**
 * Публичный class-based слой селекторов. Селекторы объявляются как поля класса через
 * фабрики `this.select` / `this.combine` / `this.keyed` — поля сразу настоящие
 * `SelectorAPI` (eager-материализация, никаких рецептов).
 *
 * Внешние селекторы (cross-store) передаются параметрами конструктора подкласса:
 * parameter properties присваиваются ДО инициализаторов полей, поэтому `this.core`
 * в полях доступен корректно.
 *
 * Внутреннее состояние базы — hard-private (`#`-поля/методы): их имена в отдельном
 * namespace и НЕ конфликтуют с полями-селекторами подкласса (можно объявить селектор
 * `track`, `module` и т.п.). Зарезервированы лишь `protected`/публичные члены
 * (`select`/`combine`/`keyed`/`destroy`) — их именами селекторы называть нельзя.
 *
 * @example
 * ```ts
 * class PostsSelectors extends Selectors<PostsState> {
 *   constructor(storage: IStorage<PostsState>, private readonly core: CoreSelectors) {
 *     super(storage)
 *   }
 *
 *   private readonly api = this.select((s) => s.api)
 *   readonly list           = this.select((s) => s.list)
 *   readonly isPostsLoading = this.combine([this.api], (a) => a.postsRequest.status === 'loading')
 *   // cross-store: пересчитывается при изменении чужого стора
 *   readonly currentUserId  = this.combine([this.core.profile], (p) => p?.user_info?.id ?? null)
 * }
 * ```
 */
export declare abstract class Selectors<TState extends Record<string, any>> {
    #private;
    /** Принимает `storage` (создаёт и владеет своим `SelectorModule`) либо готовый модуль. */
    constructor(source: IStorage<TState> | ISelectorModule<TState>);
    /** Простой селектор: мемоизация по ссылке стейта + трекинг затронутых ключей. */
    protected select<R>(selector: (state: TState) => R, options?: SelectorOptions<R>): SelectorAPI<R>;
    /** Combined-селектор; зависимости — любые `SelectorAPI`, в т.ч. из других сторов. */
    protected combine<Deps extends unknown[], R>(deps: {
        [K in keyof Deps]: SelectorAPI<Deps[K]>;
    }, fn: (...args: Deps) => R, options?: SelectorOptions<R>): SelectorAPI<R>;
    /**
     * Параметрический (keyed) селектор: один `SelectorAPI` на ключ (кэш по ключу).
     *
     * Слайсы соседних ключей живут под общим родителем (`s.byTarget[key]`), а storage при
     * обновлении пере-клонирует всю ветку — поэтому ссылка соседнего ключа не сохраняется.
     * Чтобы обновление ключа A не уведомляло подписчиков ключа B, keyed-селекторы по
     * умолчанию сравнивают значения структурно (`deepEquals`). Опции можно переопределить.
     */
    protected keyed<K extends string | number, R>(fn: (key: K) => (state: TState) => R, options?: SelectorOptions<R>): (key: K) => SelectorAPI<R>;
    /**
     * Уничтожает свой модуль (только если владеет им). Если модуль передан снаружи —
     * удаляет из него лишь свои селекторы, чужие не трогает.
     */
    destroy(): void;
}
