/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { type ClusterBehavior } from "#behavior/cluster/ClusterBehavior.js"; import { CommissioningClient } from "#behavior/system/commissioning/CommissioningClient.js"; import { RemoteDescriptor } from "#behavior/system/commissioning/RemoteDescriptor.js"; import { CommissioningDiscovery } from "#behavior/system/controller/discovery/CommissioningDiscovery.js"; import { ContinuousDiscovery } from "#behavior/system/controller/discovery/ContinuousDiscovery.js"; import { Discovery } from "#behavior/system/controller/discovery/Discovery.js"; import { InstanceDiscovery } from "#behavior/system/controller/discovery/InstanceDiscovery.js"; import { PaseDiscovery } from "#behavior/system/controller/discovery/PaseDiscovery.js"; import { Endpoint } from "#endpoint/Endpoint.js"; import { EndpointContainer } from "#endpoint/properties/EndpointContainer.js"; import { EndpointType } from "#endpoint/type/EndpointType.js"; import { MaybePromise, Observable } from "@matter/general"; import { CommissioningError, DiscoveryData, PeerAddress, SessionParameters } from "@matter/protocol"; import { NodeId } from "@matter/types"; import { ClientNode } from "../ClientNode.js"; import type { ServerNode } from "../ServerNode.js"; /** * Thrown when a commission or decommission of a {@link ClientNode} is requested while one is already in progress. */ export declare class FabricOperationInProgressError extends CommissioningError { } /** * Manages the set of known remote nodes. * * Remote nodes are either peers (commissioned into a fabric we share) or commissionable. */ export declare class Peers extends EndpointContainer { #private; constructor(owner: ServerNode); /** * Load nodes. Invoked automatically by owner. */ initialize(): void; /** * Find a specific commissionable node, or, if no discovery options are provided, returns the first discovered node. * TODO: Allow to provide an array of options for multiple discoveries (e.g. from a Multi QR code). */ locate(options?: Discovery.Options): InstanceDiscovery; /** * Employ discovery to find a set of commissionable nodes, the options can be used to limit the discovered devices * (e.g. just a specific vendor). * TODO: Allow to provide multiple identifiers for multiple discoveries (e.g. from a Multi QR code). * * If you do not provide a timeout value, will search until canceled, and you need to add a listener to * {@link Discovery#discovered} or {@link added} to receive discovered nodes. */ discover(options?: Discovery.Options): ContinuousDiscovery; /** * Find a specific commissionable node and commission. */ commission(options: CommissioningDiscovery.Options): CommissioningDiscovery; /** * Find a specific commissionable node and establish a PASE session without commissioning. * * Useful for split-commissioning scenarios where one controller establishes PASE and another * performs the commissioning flow, or for raw PASE channel establishment. */ pase(options: PaseDiscovery.Options): PaseDiscovery; /** * Complete a commissioning another commissioner started and handed off before the operational (CASE) step * (see {@link CommissioningClient.CommissioningOptions.finalizeCommissioning}). Operationally discovers and * connects the node, sends {@link GeneralCommissioning} `CommissioningComplete` to disarm the failsafe and * finalize, reads the node's structure and (unless `autoSubscribe` is false) subscribes — exactly as * {@link commission} does, so the peer is seeded rather than a blind commissioned node — then registers it. * `discoveryData` and `sessionParameters` (from the hand-off) seed operational discovery and the CASE session * establishment; `options` mirror the matching {@link commission} options. Throws {@link CommissioningError} and * removes the peer entry if discovery, connection, or `CommissioningComplete` fails; rejects as * {@link runCommissioning} describes if the node is gone or busy. */ completeCommissioning(nodeId: NodeId, discoveryData?: DiscoveryData, sessionParameters?: Partial, options?: Pick): Promise; /** * Find or create a {@link ClientNode} for a device described by {@link descriptor}. * * If a matching node already exists in the peer collection, returns it after refreshing its addresses and * discovery data from the supplied descriptor. Otherwise creates a new node using the descriptor. A matching node * that is being decommissioned is awaited first: if the decommission removes it, a new node is created, otherwise * the kept node is returned. * * After calling {@link forDescriptor}, commission the returned node via {@link ClientNode.commission}. */ forDescriptor(descriptor: RemoteDescriptor): Promise; /** * Obtain an {@link Observable} that emits when a specific type of endpoint initializes for a peer. * * This is useful for initializing general behavior on any peer endpoint of the specified type. */ endpointInstalled(type: T): Observable<[endpoint: Endpoint]>; /** * Obtain a {@link Observable} that emits when a specific type of cluster initializes for a peer. * * This is useful for initializing general behavior on any peer endpoint with the specified cluster. */ clusterInstalled(type: T): Observable<[endpoint: Endpoint, type: T], void>; /** Commissioned operational peers. Excludes commissionable discoveries and group nodes. */ get commissioned(): ClientNode[]; /** * Look up a peer by numeric/string id or {@link PeerAddress}. A {@link PeerAddress} matches the commissioned * peer whose {@link CommissioningClient} peer address equals it; otherwise the container's id lookup is used. * * Look up by {@link PeerAddress} for anything held while a peer is commissioned: a local id may be reissued to a * different device once the peer it named is gone, so the same string can resolve to a peer that never saw the * work it is being used for. An address is stable for as long as its peer stays commissioned; afterwards it * may name another device, under the rules `ControllerBehavior.allocatePeerAddress` documents. So a lookup * that *succeeds* is not proof this is the peer the caller meant. */ get(id: number | string | PeerAddress): ClientNode | undefined; get owner(): ServerNode; add(node: ClientNode): void; /** * Get or create a client node for the given peer address. * * This is mainly used to communicate to other known nodes on the fabric without having a formal commissioning * process. */ forAddress(peerAddress: PeerAddress, options?: Omit): Promise; /** * Delete every known node. * * A node we cannot tear down cleanly is closed and dropped instead, so it cannot block the factory reset this * serves; its persisted data outlives this call and is the caller's to discard. Failures are logged rather than * raised for the same reason. */ erase(): Promise; close(): Promise; /** * Run a commission attempt on {@link node} while protecting the node from the expired-node cull. * * Rejects with `DestroyedDependencyError` or `CrashedDependencyError` if the node is gone (its closing or deletion * began, or it crashed), so the attempt fails fast instead of crashing later when the closed backing is accessed, and with {@link FabricOperationInProgressError} if a commission or decommission attempt on it * is already in progress, as parallel attempts on the same {@link ClientNode} would race on device-side state. * Calling {@link ClientNode.commission} inside {@link fn} therefore rejects. */ runCommissioning(node: ClientNode, fn: () => MaybePromise): Promise; /** * Run a decommission attempt on {@link node}. While it runs, the expired-node cull and leave events do not delete * the node, and {@link forDescriptor} waits for it to end before handing out a node for the device. * * Rejects like {@link runCommissioning}: with `DestroyedDependencyError` or `CrashedDependencyError` if the node is * gone, with {@link FabricOperationInProgressError} if a commission or decommission of it is already in progress. */ runDecommissioning(node: ClientNode, fn: () => MaybePromise): Promise; } //# sourceMappingURL=Peers.d.ts.map