/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { MatterError } from "#general";
import { ClusterType } from "../ClusterType.js";
export declare class IllegalClusterError extends MatterError {
}
/**
 * A "cluster composer" manages cluster configuration based on feature selection.
 */
export declare class ClusterComposer<const T extends ClusterType> {
    #private;
    cluster: T;
    constructor(cluster: T, allowInvalidFeatures?: boolean);
    /**
     * Build a cluster using selected feature flags.
     *
     * @param selection the name(s) of optional features to support
     * @throws {IllegalClusterError} if the feature combination is disallowed by the Matter specification
     */
    compose<const SelectionT extends ClusterComposer.FeatureSelection<T>>(selection: SelectionT): ClusterComposer.Of<T, SelectionT>;
    static injectElements(definition: Partial<ClusterType.Options>, component: Partial<ClusterType.Options>, original?: Partial<ClusterType>): void;
    /**
     * Throws an error if a feature combination is illegal per the Matter specification.
     */
    private reject;
}
export declare namespace ClusterComposer {
    type Component = Partial<ClusterType.Elements>;
    /**
     * An array of names indicating features to be injected.
     */
    type FeatureSelection<T extends ClusterType> = readonly Capitalize<string & keyof T["features"]>[];
    /**
     * A set of boolean values indicating whether a feature is enabled.
     */
    type FeatureFlags = Record<string, boolean | undefined>;
    /**
     * Describes the output of {@link ClusterComposer.compose}.
     */
    type Of<ClusterT extends ClusterType, FeaturesT extends FeatureSelection<ClusterT>> = WithFeatures<ClusterT, FeaturesT>;
    /**
     * The base of a cluster.
     */
    type BaseOf<T extends ClusterType> = T["base"] extends ClusterType ? T["base"] : T;
    /**
     * The result of composition.
     */
    type WithFeatures<ClusterT extends ClusterType, FeaturesT extends FeatureSelection<BaseOf<ClusterT>>> = Omit<BaseOf<ClusterT>, "supportedFeatures" | "base" | ElementType> & {
        supportedFeatures: FeaturesAsFlags<BaseOf<ClusterT>, FeaturesT>;
        base: BaseOf<ClusterT>;
    } & ExtendedElements<ClusterT, SelectedElements<FeaturesAsFlags<ClusterT, FeaturesT>, ClusterT["extensions"] extends object ? ClusterT["extensions"] : []>>;
    /**
     * Convert a {@link FeatureSelection} array into a {@link FeatureFlags} object.
     */
    type FeaturesAsFlags<ClusterT extends ClusterType, FlagsT extends FeatureSelection<ClusterT>> = {
        [K in keyof ClusterT["features"]]: K extends string ? Capitalize<K> extends `${FlagsT[number]}` ? true : false : never;
    };
    /**
     * Choose elements from applicable extensions.
     */
    type SelectedElements<FlagsT extends FeatureFlags, extensionsT extends readonly ClusterType.Extension[]> = extensionsT extends readonly [
        infer S extends ClusterType.Extension,
        ...infer R extends readonly ClusterType.Extension[]
    ] ? SelectorContribution<FlagsT, S> & SelectedElements<FlagsT, R> : {};
    /**
     * Determine the type contributed to feature selection by a specific selector.
     */
    type SelectorContribution<FlagsT extends FeatureFlags, SelectorT extends ClusterType.Extension> = FlagsT extends SelectorT["flags"] ? SelectorT["component"] extends false ? never : SelectorT["component"] & {
        attributes: {};
        commands: {};
        events: {};
    } : {
        attributes: {};
        commands: {};
        events: {};
    };
    /**
     * Cluster elements extended with .
     *
     * Note that we have to track the base separate from the originating cluster.  If we are removing features, we want
     * to maintain only those features present in the base or selected components.
     */
    type ExtendedElements<ClusterT extends ClusterType, ComponentT extends Component> = [ComponentT] extends [
        never
    ] ? never : {
        [TypeT in ElementType]: Pick<ClusterT[TypeT], keyof ClusterT[TypeT] & (keyof BaseOf<ClusterT>[TypeT] | keyof ComponentT[TypeT])> & Omit<ComponentT[TypeT], keyof ClusterT[TypeT]> & Omit<BaseOf<ClusterT>[TypeT], keyof ClusterT[TypeT] | keyof ComponentT[TypeT]>;
    };
    /**
     * A cluster extended by multiple components.
     */
    type WithComponents<ClusterT extends ClusterType, RestT extends Component[]> = RestT extends [
        infer ComponentT extends Component,
        ...infer RestT extends Component[]
    ] ? WithComponents<Omit<ClusterT, ElementType> & ExtendedElements<ClusterT, ComponentT>, RestT> : ClusterT;
    /**
     * A "WritableDefinition" is a Cluster with fields that may be modified.
     */
    type WritableDefinition = {
        -readonly [Key in keyof ClusterType]: ClusterType[Key];
    };
    type ElementType = "attributes" | "commands" | "events";
}
//# sourceMappingURL=ClusterComposer.d.ts.map