/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { ImplementationError } from "#MatterError.js";
import { Observable, ObservableValue } from "./Observable.js";
/**
 * A read-only set.
 */
export interface ImmutableSet<T> {
    [Symbol.iterator]: () => Iterator<T, undefined>;
    has(item: T): boolean;
    get size(): number;
    map<R>(mapper: (item: T) => R): R[];
    find(predicate: (item: T) => boolean | undefined): T | undefined;
    filter(predicate: (item: T) => boolean | undefined): T[];
}
/**
 * A write-only set.
 */
export interface MutableSet<T, AddT = T> {
    add(definition: AddT): void;
    delete(definition: T): boolean;
    clear(): void;
}
/**
 * Set change events.
 */
export interface ObservableSet<T> {
    get added(): Observable<[T]>;
    get deleted(): Observable<[T]>;
    get empty(): ObservableValue;
}
/**
 * An interface for index set lookup.
 *
 * Note that this interface only supports a single item for each key.  If multiple items associate with a key only the
 * first is returned.
 */
export interface IndexedSet<T> {
    /**
     * Retrieve an item with the named {@link field} set to {@link value}.
     */
    get<F extends keyof T>(field: F, value: T[F]): T | undefined;
    /**
     * Obtain a {@link Map} of values in {@link field} to the associated item in the set.
     */
    mapOf<F extends keyof T>(field: F): Map<T[F], T>;
}
/**
 * A generic set implementation supporting all interfaces in this module.
 *
 * Unused features have minimal performance impact.
 */
export declare class BasicSet<T, AddT = T> implements ImmutableSet<T>, MutableSet<T, AddT>, ObservableSet<T>, IndexedSet<T> {
    #private;
    constructor(...initialItems: AddT[]);
    [Symbol.iterator](): SetIterator<T>;
    get size(): number;
    map<R>(mapper: (item: T) => R): R[];
    find(predicate: (item: T) => boolean | undefined): T | undefined;
    filter(predicate: (item: T) => boolean | undefined): T[];
    has(item: T): boolean;
    add(item: AddT): void;
    get<F extends keyof T>(field: F, value: T[F]): T | undefined;
    /**
     * Obtain key/value map using specific field as key.
     *
     * Note we use {@link This} to constrain usage to sets where {@link T} === {@link AddT} as required by {@link Map}.
     */
    mapOf<This extends BasicSet<T, T>, F extends keyof T>(this: This, field: F): Map<T[F], T>;
    delete(item: T): boolean;
    delete<F extends keyof T>(field: keyof T, value: T[F]): boolean;
    clear(): void;
    get added(): Observable<[T], void>;
    get deleted(): Observable<[T], void>;
    get empty(): ObservableValue<[boolean], void>;
    protected create(definition: AddT): T;
}
/**
 * A {@link Map} backed by an {@link IndexedSet}.
 *
 * This supports the common case where sets must be looked up by key.  Implementations like {@link BasicSet} offer
 * efficient lookup by key using {@link IndexedSet#get}, but usage like a {@link Map} is still cumbersome.  This class
 * works as an adapter to make key/value access patterns more natural.
 */
export declare class MapOfIndexedSet<T, S extends ImmutableSet<T> & MutableSet<T> & IndexedSet<T>, K extends keyof T> implements Map<T[K], T> {
    #private;
    /**
     * Create a new map.
     *
     * @param set the backing data
     * @param key a property of {@link T} used as the key
     * @param index optional index that optimizes lookup by bypassing {@link IndexedSet#get}
     */
    constructor(set: S, key: K, index?: Map<T[K], T>);
    clear(): void;
    delete(key: T[K]): boolean;
    forEach(callbackfn: (value: T, key: T[K], map: Map<T[K], T>) => void, thisArg?: any): void;
    get(key: T[K]): T | undefined;
    has(key: T[K]): boolean;
    set(key: T[K], value: T): this;
    get size(): number;
    entries(): MapIterator<[T[K], T]>;
    keys(): MapIterator<T[K]>;
    values(): MapIterator<T>;
    [Symbol.iterator](): MapIterator<[T[K], T]>;
    [Symbol.toStringTag]: string;
}
export declare namespace MapOfIndexedSet {
    class KeyValueMismatchError extends ImplementationError {
    }
}
//# sourceMappingURL=Set.d.ts.map