/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { Behavior } from "#behavior/Behavior.js"; import { ClusterBehavior } from "#behavior/cluster/ClusterBehavior.js"; import type { GlobalAttributeState } from "#behavior/cluster/ClusterState.js"; import { ActionContext } from "#behavior/context/ActionContext.js"; import { Construction, Diagnostic, Environment, Immutable, Lifetime, MaybePromise, Observable } from "@matter/general"; import { DataModelPath } from "@matter/model"; import { InteractionSettings, Val } from "@matter/protocol"; import { EndpointNumber, FabricIndex } from "@matter/types"; import { Agent } from "./Agent.js"; import { Behaviors } from "./properties/Behaviors.js"; import { Commands } from "./properties/Commands.js"; import { EndpointContainer } from "./properties/EndpointContainer.js"; import { EndpointLifecycle } from "./properties/EndpointLifecycle.js"; import { Parts } from "./properties/Parts.js"; import { SupportedBehaviors } from "./properties/SupportedBehaviors.js"; import { EndpointType } from "./type/EndpointType.js"; /** * Endpoints consist of a hierarchy of parts. This class manages the current state of a single endpoint. * * You can interact with endpoints using an {@link Agent} created with {@link Endpoint.agentFor}. Agents are stateless and * designed for quick instantiation so you can create them as needed then discard. * * Most often direct access to {@link Agent} is transparent as Matter.js acquires an agent as necessary for * {@link Behavior} interactions. */ export declare class Endpoint { #private; [Diagnostic.value]: unknown; /** * A string that uniquely identifies an endpoint. * * This ID must be unique amongst all Parts with the same owner. */ get id(): string; /** * The endpoint ID or undefined if not yet assigned. */ get maybeId(): string | undefined; /** * The Matter {@link EndpointNumber} of the endpoint. This uniquely identifies the {@link Endpoint} in the scope of the * Matter node. */ get number(): EndpointNumber; /** * The endpoint number or undefined if not yet assigned. */ get maybeNumber(): EndpointNumber | undefined; /** * The owner of the endpoint. * * Every endpoint but the root endpoint (the "server node") is owned by another endpoint. */ get owner(): Endpoint | undefined; /** * Conditions this endpoint asserts, as stated at construction. * * @see {@link Endpoint.EndpointOptions.deviceConditions} */ get deviceConditions(): ReadonlySet; /** * Access an {@link Agent} for this endpoint. * * An {@link Agent} allows you to interact directly with the behaviors supported by the endpoint. Normally you * would use {@link act} to obtain an agent but {@link agentFor} is useful if you need to interact with multiple * endpoints in the same context. */ agentFor(this: Endpoint, context: ActionContext): Agent.Instance; get endpointProtocol(): import("@matter/protocol").EndpointProtocol | undefined; /** * Search for the owner of a specific type. * * Returns undefined if this owner is not found on the way up to the root endpoint. */ ownerOfType(type: T): Endpoint | undefined; /** * The endpoint's environment. Endpoint implementations use the environment to access platform components such as * storage and network components. */ get env(): Environment; /** * Access the pool of behaviors supported by this endpoint. */ get behaviors(): Behaviors; /** * Current state values for all behaviors, keyed by behavior ID. This view is read-only. */ get state(): Immutable>; /** * Current state for a specific behavior ID. * * Be aware that using a string type does not provide type checking and does not enforce the correctness of the used * Behavior type including all enabled features. Because of this the returned state is typed as a plain string * indexed record (Val.Struct). Please ensure to have proper checks in place when using this method with string type. */ stateOf(type: string): Immutable; /** * Current state for a specific behavior. * * This is the recommended way to access state for a specific behavior because it provides proper type checking * and enforces the correctness of the used Behavior type including all enabled features. */ stateOf(type: T): Immutable>; /** * Version of {@link stateOf} that returns undefined instead of throwing if the requested behavior unsupported. */ maybeStateOf(type: string): Immutable | undefined; /** * Version of {@link stateOf} that returns undefined instead of throwing if the requested behavior unsupported. */ maybeStateOf(type: T): Immutable> | undefined; /** * Update state values. This is a patch operation; it only modifies properties in {@link values}. * * {@link values} is an object with a {@link Behavior.id} as the key and state values as sub-objects. * * Input values must adhere to the {@link Behavior.schema} of the target {@link Behavior}. If not, set will throw * an error. * * This is a transactional operation. An error results in no change. The endpoint will wait for exclusive access * before applying changes. * * @param values the values to change */ set(values: SupportedBehaviors.StatePatchOf): Promise; /** * Update state values for a single behavior. * * The patch semantics used here are identical to {@link set}. * * This is the recommended way to set state for a single behavior because it provides proper type checking and * enforces the correctness of the used Behavior type including all enabled features. * * @param type the {@link Behavior} to patch * @param values the values to change */ setStateOf(type: T, values: Behavior.PatchStateOf): Promise; /** * Update state values for a single behavior ID. * * The patch semantics used here are identical to {@link set}. * * Be aware that using a string type does not provide type checking and does not enforce the correctness of the used * Behavior type including all enabled features. Expect runtime errors if the provided values are not compatible * with the actual Behavior type. * * @param type the {@link Behavior} to patch * @param values the values to change */ setStateOf(type: string, values: Val.Struct): Promise; /** * Typed read of a single behavior's state. * * Same client/server semantics as {@link get}, including the partial-state-on-failure contract. * * When a key-list selector is provided, each returned value may be `undefined` — absent on unsupported * attributes or those excluded by {@link EndpointReadFailedError}. */ getStateOf(type: B, selector?: true, options?: Endpoint.GetOptions): Promise>; getStateOf>(type: B, selector: readonly K[], options?: Endpoint.GetOptions): Promise<{ readonly [P in K]?: Behavior.StateOf[P]; }>; /** * Read of a single behavior's state by string id. * * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint. */ getStateOf(type: string, selector?: readonly string[], options?: Endpoint.GetOptions): Promise; /** * Reads the selected behavior state. * * @remarks * **Client endpoint.** Issues a single batched Matter Read for the selected attribute paths * and returns the fresh slice. State is updated as data arrives; reads whose fabric-filter * setting differs from the active subscription are not cached. * * **Partial-state contract on failure.** On any per-path failure status, rejects with * {@link EndpointReadFailedError}. The error carries both the failed paths and the assembled * partial slice for successful paths. * * **Server endpoint.** Returns a snapshot of local immutable state. `fabricFilter` is ignored. */ get(): Promise>>; get(selector: undefined, options?: Endpoint.GetOptions): Promise>>; get>(selector: S, options?: Endpoint.GetOptions): Promise>; /** * Commands for all behaviors keyed by behavior ID. */ get commands(): Commands; /** * Commands for a specific behavior id. Untyped: each command is `Commands.Command`. * * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint. */ commandsOf(type: string): Record; /** Typed variant of {@link commandsOf}; preserves the behavior's command interface. */ commandsOf(type: T): Commands.OfBehavior; /** * Events for all behaviors keyed by behavior ID. */ get events(): SupportedBehaviors.EventsOf; /** * Events for a specific behavior ID. * * Be aware that using a string type does not provide type checking and does not enforce the correctness of the used * Behavior type including all enabled features. Because of this each event is typed as Observable | undefined. * Please ensure to have proper checks in place when using this method with string type. */ eventsOf(type: string): Immutable>; /** * Events for a specific behavior. * * This is the recommended way to access events for a specific behavior because it provides proper type checking * and enforces the correctness of the used Behavior type including all enabled features. */ eventsOf(type: T): Behavior.EventsOf; /** * Activated cluster features for a behavior id, keyed by the camelCased feature title - same shape as the * static `features` map on cluster behavior types and as `this.features` inside a server cluster instance. * * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint. * @throws {@link EndpointBehaviorNotClusterError} if `type` is present but is not a cluster behavior. */ featuresOf(type: string): Immutable>; /** Typed variant of {@link featuresOf}; preserves the cluster's feature flag type from {@link ClusterBehavior.Type}. */ featuresOf(type: T): T["features"]; /** Returns undefined if `type` is unknown or not a cluster behavior; otherwise behaves like {@link featuresOf}. */ maybeFeaturesOf(type: string): Immutable> | undefined; maybeFeaturesOf(type: T): T["features"] | undefined; /** * Global attribute state (clusterRevision, featureMap, attributeList, acceptedCommandList, generatedCommandList) * for a behavior id. These attributes are managed automatically and omitted from the default {@link stateOf} * shape to reduce noise; this accessor exposes them when needed. * * For server clusters values are populated at construction. For client clusters values come from remote * subscription / read responses and may be empty arrays before the first read completes. * * @throws {@link EndpointBehaviorNotPresentError} if `type` is not present on the endpoint. * @throws {@link EndpointBehaviorNotClusterError} if `type` is present but is not a cluster behavior. */ globalsOf(type: string): Immutable; /** Typed variant of {@link globalsOf}; narrows `featureMap` to the cluster's per-feature flag type. */ globalsOf(type: T): Immutable & { featureMap: T["features"]; }>; /** Returns undefined if `type` is unknown or not a cluster behavior; otherwise behaves like {@link globalsOf}. */ maybeGlobalsOf(type: string): Immutable | undefined; maybeGlobalsOf(type: T): Immutable & { featureMap: T["features"]; }> | undefined; get construction(): Construction>; /** * Create new endpoint. * * The endpoint will not initialize fully until added to a {@link Node}. You can use {@link Endpoint.add} to * construct and initialize an {@link Endpoint} in one step. */ constructor(config: Endpoint.Configuration | T); /** * Create new endpoint. * * The endpoint will not initialize fully until added to a {@link Node}. You can use {@link Endpoint.add} to * construct and initialize an {@link Endpoint} in one step. */ constructor(type: T, options?: Endpoint.Options); set id(id: string); protected get container(): undefined | EndpointContainer; set number(number: number); set owner(owner: Endpoint | undefined); /** * Add a child endpoint. If this endpoint is initialized, awaits child initialization. * * If child initialization fails: * * - If the child is essential (@see {@link EndpointLifecycle#isEssential}), closes the child and rethrows * * - If the child is non-essential then logs the error but leaves the child in place. * * @param endpoint the {@link Endpoint} or {@link Endpoint.Configuration} */ add(endpoint: Endpoint | Endpoint.Configuration | T): Promise>; /** * Add a child endpoint with separate type and options arguments. * * @param type the {@link EndpointType} of the child endpoint * @param options settings for the new endpoint */ add(type: T, options?: Endpoint.Options): Promise>; /** * The type of endpoint this endpoint implements. */ get type(): EndpointType; /** * Access child parts. */ get parts(): Parts; /** * Is this a parent Endpoint? */ get hasParts(): boolean; /** * Endpoint information that varies as the endpoint initializes. */ get lifecycle(): EndpointLifecycle; protected createLifecycle(isEssential?: boolean): EndpointLifecycle; /** * Create an {@link Agent.Type} for the endpoint. */ get agentType(): Agent.Type; /** * Execute a function against an {@link Agent} for the endpoint. * * Agents provide the highest-leve API for interacting with endpoints. The agent is a composite object with * properties for each supported behavior. * * State changes made by {@link actor} are atomic and made permanent only when the actor exits unless you commit the * transaction manually. * * {@link actor} runs in an "offline" context where ACLs are ignored and all state is read/write. * * The {@link Agent} is destroyed after {@link actor} exits so you should not maintain references to the agent, its * behaviors or associated state. * * {@link actor} may be async. If so, the acting context will remain open until the returned {@link Promise} * resolves. * * @param purpose textual description of operation used for diagnostics * @param actor the function that performs the action * @param options settings of the acting context, see {@link Endpoint.ActOptions} */ act(purpose: string, actor: (agent: Agent.Instance) => MaybePromise, options?: Endpoint.ActOptions): MaybePromise; /** * Version of {@link act} without explicit diagnostic purpose. */ act(actor: (agent: Agent.Instance) => MaybePromise): MaybePromise; /** * The peer context for actions on this endpoint if it belongs to a client node, otherwise undefined. * * @internal */ get clientPeerContext(): { fabricIndexOnPeer?: FabricIndex; } | undefined; /** * Perform "soft" reset of the endpoint, reverting all in-memory structures to uninitialized. */ reset(): Promise; /** * Perform "hard" reset of the endpoint, reverting all in-memory and persistent state to uninitialized. */ erase(): Promise; /** * Erase all persisted data and destroy the endpoint. */ delete(): Promise; /** * Apply a depth-first visitor function to myself and all descendents. */ visit>(visitor: (endpoint: Endpoint) => T): T; /** * Destroy the endpoint and its parts. * * Every teardown step runs even when an earlier one fails. A failed deactivation rejects with a * {@link MatterAggregateError}; failures while destroying the endpoint, its parts and its behaviors are logged. */ close(): Promise; [Construction.destruct](): Promise; [Symbol.asyncDispose](): Promise; toString(): string; /** * Path identifying the endpoint in the Matter data model. */ get path(): DataModelPath; /** * Diagnostic identity. * * This is an unqualified path segment. */ get identity(): string | EndpointNumber; /** * Asynchronous initialization. * * Derivatives may override to perform async construction prior to full initialization. */ protected initialize(): MaybePromise; /** * Ensure requirements for construction are met. */ protected assertConstructable(): void; /** * Complete initialization. Invoked via {@link Construction#start} by the owner. */ [Construction.construct](): MaybePromise; get [Lifetime.owner](): Lifetime.Owner | undefined; /** * Diagnostic information regarding endpoint state. */ get diagnosticDict(): Record; } export declare namespace Endpoint { /** * Settings of the context {@link Endpoint.act} opens. `abort` ends the peer interactions of the commands the actor * invokes on a {@link ClientNode}, also while they wait for the peer. */ type ActOptions = Pick; type BehaviorOptions = { -readonly [K in keyof T["behaviors"] as K extends keyof O ? never : K]?: Behavior.Options; }; interface EndpointOptions { /** * The owner of the endpoint. * * If provided, takes ownership of the endpoint at construction. */ owner?: Endpoint | Agent; /** * The endpoint's string identifier. Must be unique within the parent. * * If you omit the identifier the node assigns a generated one for you. */ id?: string; /** * The endpoint number. Must be unique within the node. * * If you omit the endpoint number the node assigns a sequential one for you. */ number?: number; /** * Child endpoints. * * This is the inverse of setting {@link owner} above. The endpoint instantiates and takes ownership of child * endpoints at construction time. */ parts?: Iterable; /** * Designates whether an endpoint is essential. * * Endpoints are essential by default but you may disable by setting this to false. */ isEssential?: boolean; /** * Conditions of the product that this endpoint asserts, such as `PhysicalInputs` or `Cooler`. * * A device type's requirements may depend on a condition. matter.js derives the conditions that follow from * the endpoint tree and the node's configuration; state here only those that describe the product. A stated * condition holds in addition to the derived ones, and stating one never makes a condition false. An unknown * name is reported as a violation wherever the endpoint is judged, which in mode `off` of * `endpoint.validation` is only on request. * * @see {@link MatterSpecification.v161.Device} § 1.1.3 */ deviceConditions?: string[]; } type Options = BehaviorOptions & O; type Configuration = Options & { type: T; }; /** * Definition of an endpoint. May be an {@link EndpointType}, {@link Configuration}, or a {@link Endpoint} * instance. */ type Definition = T | Configuration | Endpoint; /** * Options for {@link Endpoint.get} and {@link Endpoint.getStateOf}. * * A read on a {@link ClientNode} does not run in the context of a surrounding {@link Endpoint.act}, so the abort of * that context does not reach it; pass `abort` to end the read, also while it waits for a sleeping ICD peer. */ interface GetOptions extends Pick { /** * When `false`, the underlying Matter Read is not fabric-filtered. Defaults to `true`. */ fabricFilter?: boolean; /** * When `true`, skips automatic data-version filter injection so the server returns all attribute values * regardless of whether they have changed since the last read or subscription. Defaults to `false`. */ includeKnownVersions?: boolean; } /** * Obtain a configuration from constructor parameters. */ function configurationFor(definition: T | Endpoint.Configuration, options?: Endpoint.Options): Configuration; /** * Obtain an endpoint for the given {@link Definition}. */ function partFor(definition: Definition): Endpoint; } export type BehaviorOf = T["behaviors"][keyof T["behaviors"]]; export type BehaviorAt = T["behaviors"][K]; export type BehaviorSelection = true | readonly (keyof Behavior.StateOf)[]; export type RawBehaviorSelection = true | readonly string[]; export type StateSelector = { [K in keyof T["behaviors"]]?: string extends K ? RawBehaviorSelection : T["behaviors"][K] extends Behavior.Type ? BehaviorSelection : RawBehaviorSelection; }; export type StateSliceOf = S extends undefined ? Immutable> : { [K in keyof S & keyof T["behaviors"]]: S[K] extends true ? Immutable>> : S[K] extends readonly (infer A)[] ? Immutable>, Extract>>>>> : never; }; //# sourceMappingURL=Endpoint.d.ts.map