/**
 * @license
 * Copyright 2022-2024 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Agent } from "#endpoint/Agent.js";
import { EventEmitter, MaybePromise, Observable } from "#general";
import type { ClusterType } from "#types";
import { Reactor } from "./Reactor.js";
import type { BehaviorBacking } from "./internal/BehaviorBacking.js";
import { Resource } from "./state/transaction/Resource.js";
import { RootSupervisor } from "./supervision/RootSupervisor.js";
import { Schema } from "./supervision/Schema.js";
/**
 * Behavior implements functionality for an Endpoint.  Endpoint agents are implemented as a composition of behaviors.
 *
 * Most behaviors associated 1:1 with a Matter cluster type as implemented by ClusterBehavior.  But you can also extend
 * Behavior directly to add other types of composable logic to an endpoint.
 *
 * You probably want to build your behavior using one of the standard implementations offered by Matter.js.
 */
export declare abstract class Behavior {
    #private;
    /**
     * Each behavior implementation has an ID that uniquely identifies the type of behavior.  An Endpoint may only have
     * one behavior with the specified ID.
     *
     * Endpoint instances store each behavior in a property with the same name as the behavior's ID.
     *
     * EndpointBuilder also uses the ID when replacing behaviors using the with() builder method.
     */
    static readonly id: string;
    /**
     * A behavior's schema controls access to data, commands and events.
     *
     * Schema is inferred from the methods and properties of the behavior but you can specify explicitly for additional
     * control.
     */
    static readonly schema?: Schema;
    /**
     * By default behaviors load lazily as they are accessed.  You can set this flag to true to force behaviors to load
     * immediately when the endpoint initializes.
     */
    static readonly early: boolean;
    /**
     * The agent that owns the behavior.
     */
    get agent(): Agent;
    /**
     * The endpoint that owns behavior's agent.
     */
    get endpoint(): import("../index.js").Endpoint<import("../index.js").EndpointType.Empty>;
    /**
     * The context in which the behavior operates.
     */
    get context(): import("./index.js").ActionContext;
    /**
     * The endpoint's environment.
     */
    get env(): import("#general").Environment;
    /**
     * The session in which the behavior has been invoked.
     */
    get session(): import("@matter.js/protocol").SecureSession;
    /**
     * Execute logic with elevated privileges.
     *
     * The provided function executes with privileges escalated to offline mode.  This is not commonly necessary.
     *
     * Elevated logic effectively ignores ACLs so should be used with care.
     *
     * Note that interactions with the behavior will remain elevated until the synchronous completion of this call.
     * You should only elevate privileges for synchronous logic.
     *
     * @param fn the elevated logic
     */
    asAdmin(fn: () => void): void;
    /**
     * Access the behavior's state.
     */
    readonly state: {};
    /**
     * Access the behavior's events.
     */
    readonly events: EventEmitter;
    constructor(agent: Agent, backing: BehaviorBacking);
    /**
     * The data supervisor for the behavior.  The supervisor controls validation and access to behavior data.
     */
    static get supervisor(): RootSupervisor;
    /**
     * Implementation of endpoint-scoped state.  Subclasses may override to extend.
     */
    static State: new () => {};
    /**
     * Implementation of internal state.  Subclasses may override to extend.
     */
    static Internal: new () => {};
    /**
     * Implementation of the events property.  Subclasses may override to extend.
     */
    static Events: typeof EventEmitter;
    /**
     * Behaviors are ephemeral and should not perform initialization in their constructor.  They can override this
     * method instead.
     *
     * This method may be synchronous or asyncronous.  If asynchronous, the behavior will not be available for external
     * use until initialization completes.
     */
    initialize(_options?: {}): MaybePromise;
    /**
     * Release resources.  This is the public API for releasing application resources held by behaviors in internal
     * state.
     */
    [Symbol.asyncDispose](): MaybePromise;
    /**
     * Description used in diagnostic messages.
     */
    toString(): string;
    /**
     * Install a {@link Reactor}.
     *
     * Important: The reactor MUST be a real JS function - arrow functions will not work!
     */
    protected reactTo<O extends Observable<any[], any>>(observable: O, reactor: Reactor<Parameters<O["emit"]>, ReturnType<O["emit"]>>, options?: Reactor.Options): void;
    /**
     * Create a generic callback function that has the same properties as a {@link Reactor}.
     *
     * Like a reactor, the callback's "this" will be bound to an active Behavior instance.
     * Because of this: The reactor MUST be a real JS function - arrow functions will not work!
     */
    protected callback<A extends any[], R>(reactor: Reactor<A, R>, options?: Reactor.Options): (...args: A) => R | undefined;
    /**
     * Does this behavior support functionality of a specific implementation?
     */
    static supports(other: Behavior.Type): boolean;
    /**
     * Default state values.
     */
    static get defaults(): Record<string, any>;
    /**
     * Create a new behavior with different default state values.
     */
    static set<This extends Behavior.Type>(this: This, defaults: Behavior.InputStateOf<This>): This;
    /**
     * Explicitly reference other {@link Behavior}s as dependencies, ensuring this behavior is destroyed first.
     *
     * This probably won't be commonly necessary.  If it is we can instrument Agent to collect dependencies
     * automatically.
     */
    static dependencies?: Iterable<Behavior.Type>;
    get [Resource.reference](): import("./state/managed/Datasource.js").Datasource<import("./state/StateType.js").StateType>;
}
export declare namespace Behavior {
    /**
     * Static properties supported by all behaviors.
     */
    interface Type {
        new (agent: Agent, backing: BehaviorBacking): Behavior;
        readonly name: string;
        readonly id: typeof Behavior.id;
        readonly set: typeof Behavior.set;
        readonly supports: typeof Behavior.supports;
        readonly defaults: Record<string, any>;
        readonly schema?: Schema;
        readonly early: boolean;
        readonly supervisor: RootSupervisor;
        readonly dependencies?: Iterable<Behavior.Type>;
        readonly State: new () => {};
        readonly Internal: new () => {};
        readonly Events: typeof EventEmitter;
    }
    /**
     * This function simply throws NotImplementedError.  More importantly, its presence in any command implementation
     * method informs the endpoint that the command is not implemented.
     */
    function unimplemented(..._args: any[]): Promise<any>;
    /**
     * The state type of a behavior {@link Type}.
     */
    type StateOf<B extends Type> = InstanceType<B["State"]>;
    /**
     * Input variant of StateOf.
     */
    type InputStateOf<B extends Type> = Partial<ClusterType.RelaxTypes<StateOf<B>>>;
    /**
     * Patch variant of StateOf.
     */
    type PatchStateOf<B extends Type> = ClusterType.PatchType<StateOf<B>>;
    /**
     * The events type of a behavior {@link Type}.
     */
    type EventsOf<B extends Type> = InstanceType<B["Events"]>;
    /**
     * Initialization options.
     */
    type InitializationOptionsOf<B extends Type> = Parameters<InstanceType<B>["initialize"]> extends [infer P extends object] ? P : {};
    /**
     * Configuration options you may set when adding a {@link Behavior} to an endpoint.
     */
    type Options<T extends Behavior.Type = Behavior.Type> = Behavior.InputStateOf<T> & Behavior.InitializationOptionsOf<T>;
}
//# sourceMappingURL=Behavior.d.ts.map