import { ConditionListener, ConditionOptions } from './cond.js';
import { DeepObjectPartial } from './object-utils.js';
import type { AbortSignalArgs } from './types.js';
export { matchAny } from './object-utils.js';
/**
 * Used to express a filter for {@link Matcher}.
 */
export type Filter<T> = DeepObjectPartial<T>;
/**
 * This can be added to a {@link Matcher} to recieve updates based on a filter.
 */
export interface MatcherSub<K> {
    add(k: K): any;
    delete(k: K): any;
}
/**
 * Matcher that allows us to observe groups of keyed objects as they transition through state.
 *
 * These objects must be cloneable via {@link structuredClone}.
 *
 * An `undefined` state is equivalent to blank/deleted: it does not exist.
 */
export declare class Matcher<K, T> {
    private objects;
    private groups;
    get(id: K): T | undefined;
    /**
     * Sets this value into the {@link Matcher}. This will trigger group state changes.
     */
    set(id: K, value: T | undefined): void;
    delete(id: K): boolean;
    /**
     * Does any object match this filter?
     */
    matchAny(filter: Filter<T>): boolean;
    /**
     * Matches objects immediately, without grouping.
     */
    matchAll(filter: Filter<T>): Generator<K, void, void>;
    /**
     * Returns the intersection of reading the given keys.
     */
    read(keys: Iterable<K>): DeepObjectPartial<T> | undefined;
    /**
     * Attaches a subscripton to this {@link Matcher} based on the given {@link Filter}. The filter
     * will be frozen before use, so you cannot change it later.
     *
     * This will add all initially matching objects to the {@link MatcherSub}. However, the current
     * matching set will not be cleared when the passed signal is aborted.
     */
    sub(filter: Filter<T>, g: MatcherSub<K>, options?: AbortSignalArgs): void;
}
export interface Group {
    active(): boolean;
    addListener(fn: (state: boolean) => any, options?: ConditionOptions): boolean;
    removeListener(fn: (state: boolean) => any): boolean;
}
/**
 * Provides a wrapper for a number of {@link Group} instances. By default, this is active when
 * all of the passed groups (including zero) are active, an AND filter.
 */
export declare class CombineGroup implements Group {
    private groups;
    private cond;
    private isActive;
    static create(groups: Group[], isActive?: (groups: Group[]) => boolean): CombineGroup;
    constructor(groups: Group[], isActive?: (groups: Group[]) => boolean);
    active(): boolean;
    addListener(fn: ConditionListener<boolean>, options?: ConditionOptions): boolean;
    removeListener(fn: ConditionListener<boolean>): boolean;
}
/**
 * Provides a wrapper to manage a {@link Filter} over a {@link Matcher}, both with matched keys
 * as well as a derived "active" state.
 *
 * By default, the group is active if any item matches the filter, however subclasses can change
 * this behavior by overriding {@link MatcherGroupprivate isActive}.
 */
export declare class MatcherGroup<K, T> implements Group {
    private filter;
    private matcher;
    private signal;
    private matchingSet;
    private cond;
    static create<K, T>(filter: Filter<T>, matcher: Matcher<K, T>, options?: AbortSignalArgs): MatcherGroup<K, T>;
    constructor(filter: Filter<T>, matcher: Matcher<K, T>, options?: AbortSignalArgs);
    protected isActive(matchingKeys: ReadonlySet<K>): boolean;
    active(): boolean;
    matching(): Iterable<K>;
    addListener(fn: ConditionListener<boolean>, options?: AbortSignalArgs): boolean;
    removeListener(fn: ConditionListener<boolean>): boolean;
}
