/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Callable } from "@matter/general";
import { Model } from "../models/Model.js";
/**
 * A collection of models with support for efficient lookup by name and ID.
 *
 * Callable as a function to look up models by key:
 *
 *     clusters("OnOff")           // equivalent to clusters.for("OnOff")
 *
 * Name search uses canonical camel case, so "FooBar", "fooBar" and "foo-bar" are considered equivalent.
 */
export interface ModelIndex<T extends Model = Model> {
    /**
     * Look up a model by ID or name.
     *
     * If `key` is `undefined`, returns `undefined`.
     */
    (key: number | string | undefined): T | undefined;
    /**
     * Retrieve a model for the given ID or name.
     *
     * If `key` is `undefined`, returns `undefined`.
     *
     * Use the two-parameter version for indices that contain multiple model types.
     *
     * @deprecated Use the call signature instead: `index(key)` rather than `index.for(key)`.
     */
    for(key: undefined): undefined;
    for(key: number | string): T | undefined;
    for(key: number | string | undefined): T | undefined;
    /**
     * Retrieve a model of the specific type for the given ID or name.
     *
     * Name search uses canonical camel case.
     *
     * @deprecated Use the call signature instead: `index(key)` rather than `index.for(key)`.
     */
    for<M extends T>(key: number | string, type: Model.Type<M>): M | undefined;
    /**
     * Retrieve a model for the given ID or name, throwing if not found.
     *
     * If `key` is `undefined`, returns `undefined` without throwing.
     */
    require(key: undefined): undefined;
    require(key: number | string): T;
    require(key: number | string | undefined): T | undefined;
    /**
     * Retrieve a model of the specific type for the given ID or name, throwing if not found.
     */
    require<M extends T>(key: number | string, type: Model.Type<M>): M;
    /**
     * Retrieve a model by key and create an operational extension of it.
     *
     * Shorthand for `index.require(key).extend(properties, ...children)`.
     */
    extend(key: number | string, properties?: Partial<Model.Definition<T>>, ...children: Model.ChildDefinition<Model>[]): T;
    /**
     * Filter to a specific model subtype.
     */
    ofType<M extends T>(type: Model.Type<M>): M[];
    /**
     * Iterate over all models.
     */
    [Symbol.iterator](): IterableIterator<T>;
    /**
     * Execute a function for each model.
     */
    forEach(fn: (model: T, index: number) => void): void;
    /**
     * Map models to a new array.
     */
    map<U>(fn: (model: T, index: number) => U): U[];
    /**
     * Filter models.
     */
    filter(fn: (model: T, index: number) => boolean): T[];
    /**
     * Find the first model matching a predicate.
     */
    find(fn: (model: T, index: number) => boolean): T | undefined;
    /**
     * Test whether any model matches a predicate.
     */
    some(fn: (model: T, index: number) => boolean): boolean;
    /**
     * Test whether all models match a predicate.
     */
    every(fn: (model: T, index: number) => boolean): boolean;
    /**
     * Reduce models to a single value.
     */
    reduce<U>(fn: (accumulator: U, model: T, index: number) => U, initialValue: U): U;
    /**
     * The number of models in this index.
     */
    readonly length: number;
    /**
     * Access a model by position.
     */
    at(index: number): T | undefined;
}
/**
 * Implementation of {@link ModelIndex} used for initial creation.
 */
export declare class MutableModelIndex<T extends Model = Model> extends Callable<[key: number | string | undefined], T | undefined> implements ModelIndex<T> {
    #private;
    constructor(items?: T[]);
    /**
     * Add items.  Used during construction only.
     */
    push(...items: T[]): void;
    get length(): number;
    at(index: number): T | undefined;
    [Symbol.iterator](): IterableIterator<T>;
    forEach(fn: (model: T, index: number) => void): void;
    map<U>(fn: (model: T, index: number) => U): U[];
    filter(fn: (model: T, index: number) => boolean): T[];
    find(fn: (model: T, index: number) => boolean): T | undefined;
    some(fn: (model: T, index: number) => boolean): boolean;
    every(fn: (model: T, index: number) => boolean): boolean;
    reduce<U>(fn: (accumulator: U, model: T, index: number) => U, initialValue: U): U;
    for(key: undefined): undefined;
    for(key: number | string): T;
    for<M extends T>(key: number | string, type: Model.Type<M>): M;
    require(key: undefined): undefined;
    require(key: number | string): T;
    require<M extends T>(key: number | string, type: Model.Type<M>): M;
    extend(key: number | string, properties?: Partial<Model.Definition<T>>, ...children: Model.ChildDefinition<Model>[]): T;
    ofType<T extends Model.Type>(type: T): InstanceType<T>[];
}
//# sourceMappingURL=ModelIndex.d.ts.map