@matter/node 0.16.0-alpha.0-20251212-4dde71be3 → 0.16.0-alpha.0-20251216-71c21f901
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts +1 -1
- package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
- package/dist/cjs/behavior/system/commissioning/CommissioningClient.js +31 -14
- package/dist/cjs/behavior/system/commissioning/CommissioningClient.js.map +2 -2
- package/dist/cjs/behavior/system/network/ClientNetworkRuntime.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/ClientNetworkRuntime.js +12 -1
- package/dist/cjs/behavior/system/network/ClientNetworkRuntime.js.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkClient.d.ts +8 -4
- package/dist/cjs/behavior/system/network/NetworkClient.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkClient.js +32 -4
- package/dist/cjs/behavior/system/network/NetworkClient.js.map +1 -1
- package/dist/cjs/endpoint/properties/Behaviors.d.ts.map +1 -1
- package/dist/cjs/endpoint/properties/Behaviors.js +31 -1
- package/dist/cjs/endpoint/properties/Behaviors.js.map +1 -1
- package/dist/cjs/node/ClientNode.d.ts +3 -3
- package/dist/cjs/node/ClientNode.d.ts.map +1 -1
- package/dist/cjs/node/ClientNode.js +5 -4
- package/dist/cjs/node/ClientNode.js.map +1 -1
- package/dist/cjs/node/Node.d.ts.map +1 -1
- package/dist/cjs/node/Node.js +14 -0
- package/dist/cjs/node/Node.js.map +1 -1
- package/dist/cjs/node/client/ClientNodeInteraction.d.ts +25 -6
- package/dist/cjs/node/client/ClientNodeInteraction.d.ts.map +1 -1
- package/dist/cjs/node/client/ClientNodeInteraction.js +45 -9
- package/dist/cjs/node/client/ClientNodeInteraction.js.map +1 -1
- package/dist/cjs/node/client/ClientStructure.d.ts +1 -1
- package/dist/cjs/node/client/ClientStructure.d.ts.map +1 -1
- package/dist/cjs/node/client/ClientStructure.js +4 -3
- package/dist/cjs/node/client/ClientStructure.js.map +1 -1
- package/dist/cjs/node/client/Peers.d.ts +6 -3
- package/dist/cjs/node/client/Peers.d.ts.map +1 -1
- package/dist/cjs/node/client/Peers.js +40 -15
- package/dist/cjs/node/client/Peers.js.map +2 -2
- package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts +1 -1
- package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
- package/dist/esm/behavior/system/commissioning/CommissioningClient.js +32 -14
- package/dist/esm/behavior/system/commissioning/CommissioningClient.js.map +2 -2
- package/dist/esm/behavior/system/network/ClientNetworkRuntime.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/ClientNetworkRuntime.js +21 -2
- package/dist/esm/behavior/system/network/ClientNetworkRuntime.js.map +1 -1
- package/dist/esm/behavior/system/network/NetworkClient.d.ts +8 -4
- package/dist/esm/behavior/system/network/NetworkClient.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/NetworkClient.js +33 -5
- package/dist/esm/behavior/system/network/NetworkClient.js.map +1 -1
- package/dist/esm/endpoint/properties/Behaviors.d.ts.map +1 -1
- package/dist/esm/endpoint/properties/Behaviors.js +31 -1
- package/dist/esm/endpoint/properties/Behaviors.js.map +1 -1
- package/dist/esm/node/ClientNode.d.ts +3 -3
- package/dist/esm/node/ClientNode.d.ts.map +1 -1
- package/dist/esm/node/ClientNode.js +5 -4
- package/dist/esm/node/ClientNode.js.map +1 -1
- package/dist/esm/node/Node.d.ts.map +1 -1
- package/dist/esm/node/Node.js +16 -1
- package/dist/esm/node/Node.js.map +1 -1
- package/dist/esm/node/client/ClientNodeInteraction.d.ts +25 -6
- package/dist/esm/node/client/ClientNodeInteraction.d.ts.map +1 -1
- package/dist/esm/node/client/ClientNodeInteraction.js +47 -10
- package/dist/esm/node/client/ClientNodeInteraction.js.map +1 -1
- package/dist/esm/node/client/ClientStructure.d.ts +1 -1
- package/dist/esm/node/client/ClientStructure.d.ts.map +1 -1
- package/dist/esm/node/client/ClientStructure.js +4 -3
- package/dist/esm/node/client/ClientStructure.js.map +1 -1
- package/dist/esm/node/client/Peers.d.ts +6 -3
- package/dist/esm/node/client/Peers.d.ts.map +1 -1
- package/dist/esm/node/client/Peers.js +49 -16
- package/dist/esm/node/client/Peers.js.map +2 -2
- package/package.json +7 -7
- package/src/behavior/system/commissioning/CommissioningClient.ts +32 -10
- package/src/behavior/system/network/ClientNetworkRuntime.ts +20 -2
- package/src/behavior/system/network/NetworkClient.ts +39 -8
- package/src/endpoint/properties/Behaviors.ts +39 -1
- package/src/endpoint/properties/Commands.ts +1 -1
- package/src/node/ClientNode.ts +10 -4
- package/src/node/Node.ts +17 -0
- package/src/node/client/ClientNodeInteraction.ts +65 -16
- package/src/node/client/ClientStructure.ts +13 -5
- package/src/node/client/Peers.ts +56 -19
|
@@ -198,7 +198,7 @@ export class ClientStructure {
|
|
|
198
198
|
logger.debug(
|
|
199
199
|
"Received status for",
|
|
200
200
|
change.kind === "attr-status" ? "attribute" : "event",
|
|
201
|
-
Diagnostic.strong(change.path
|
|
201
|
+
Diagnostic.strong(Diagnostic.dict(change.path)),
|
|
202
202
|
`: ${Status[change.status]}#${change.status}${change.clusterStatus !== undefined ? `/${Status[change.clusterStatus]}#${change.clusterStatus}` : ""}`,
|
|
203
203
|
);
|
|
204
204
|
break;
|
|
@@ -237,10 +237,18 @@ export class ClientStructure {
|
|
|
237
237
|
await this.#emitPendingEvents();
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
/**
|
|
241
|
-
protected get subscribedFabricFiltered() {
|
|
240
|
+
/** Determines if the subscription is fabric filtered */
|
|
241
|
+
protected get subscribedFabricFiltered(): boolean {
|
|
242
242
|
if (this.#subscribedFabricFiltered === undefined) {
|
|
243
|
-
|
|
243
|
+
const defaultSubscription =
|
|
244
|
+
this.#node.state.network.defaultSubscription ??
|
|
245
|
+
({} as { isFabricFiltered?: boolean; fabricFiltered?: boolean }); // Either Subscribe or Options
|
|
246
|
+
this.#subscribedFabricFiltered =
|
|
247
|
+
("isFabricFiltered" in defaultSubscription
|
|
248
|
+
? defaultSubscription.isFabricFiltered
|
|
249
|
+
: "fabricFiltered" in defaultSubscription
|
|
250
|
+
? defaultSubscription.fabricFiltered
|
|
251
|
+
: true) ?? true;
|
|
244
252
|
this.#node.events.network.defaultSubscription$Changed.on(newSubscription => {
|
|
245
253
|
this.#subscribedFabricFiltered = newSubscription?.isFabricFiltered ?? true;
|
|
246
254
|
});
|
|
@@ -293,7 +301,7 @@ export class ClientStructure {
|
|
|
293
301
|
const { endpointId, clusterId } = occurrence.path;
|
|
294
302
|
|
|
295
303
|
const endpoint = this.#endpoints.get(endpointId);
|
|
296
|
-
// If we are building updates on current cluster or endpoint has pending changes, delay event emission
|
|
304
|
+
// If we are building updates on the current cluster or endpoint has pending changes, delay event emission
|
|
297
305
|
if (
|
|
298
306
|
(currentUpdates && (currentUpdates.endpointId === endpointId || currentUpdates.clusterId === clusterId)) ||
|
|
299
307
|
(endpoint !== undefined && this.#pendingChanges?.has(endpoint))
|
package/src/node/client/Peers.ts
CHANGED
|
@@ -33,7 +33,15 @@ import {
|
|
|
33
33
|
} from "#general";
|
|
34
34
|
import { ClientGroup } from "#node/ClientGroup.js";
|
|
35
35
|
import { InteractionServer } from "#node/server/InteractionServer.js";
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
ClientSubscriptionHandler,
|
|
38
|
+
ClientSubscriptions,
|
|
39
|
+
FabricManager,
|
|
40
|
+
InteractionQueue,
|
|
41
|
+
PeerAddress,
|
|
42
|
+
PeerSet,
|
|
43
|
+
SessionManager,
|
|
44
|
+
} from "#protocol";
|
|
37
45
|
import { ServerNodeStore } from "#storage/server/ServerNodeStore.js";
|
|
38
46
|
import { FabricIndex } from "@matter/types";
|
|
39
47
|
import { ClientNode } from "../ClientNode.js";
|
|
@@ -53,9 +61,10 @@ const EXPIRATION_INTERVAL = Minutes.one;
|
|
|
53
61
|
*/
|
|
54
62
|
export class Peers extends EndpointContainer<ClientNode> {
|
|
55
63
|
#expirationInterval?: CancelablePromise;
|
|
56
|
-
#
|
|
64
|
+
#installedSubscriptionHandler?: ClientSubscriptionHandler;
|
|
57
65
|
#mutex = new Mutex(this);
|
|
58
66
|
#closed = false;
|
|
67
|
+
#queue: InteractionQueue;
|
|
59
68
|
|
|
60
69
|
constructor(owner: ServerNode) {
|
|
61
70
|
super(owner);
|
|
@@ -66,6 +75,8 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
66
75
|
|
|
67
76
|
owner.env.applyTo(InteractionServer, this.#configureInteractionServer.bind(this));
|
|
68
77
|
|
|
78
|
+
this.#queue = this.owner.env.get(InteractionQueue); // Queue is Node wide
|
|
79
|
+
|
|
69
80
|
this.added.on(this.#handlePeerAdded.bind(this));
|
|
70
81
|
this.deleted.on(this.#manageExpiration.bind(this));
|
|
71
82
|
|
|
@@ -117,16 +128,19 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
117
128
|
}
|
|
118
129
|
|
|
119
130
|
/**
|
|
120
|
-
* Find a specific commissionable node.
|
|
131
|
+
* Find a specific commissionable node, or, if no discovery options are provided, returns the first discovered node.
|
|
132
|
+
* TODO: Allow to provide an array of options for multiple discoveries (e.g. from a Multi QR code).
|
|
121
133
|
*/
|
|
122
134
|
locate(options?: Discovery.Options) {
|
|
123
135
|
return new InstanceDiscovery(this.owner, options);
|
|
124
136
|
}
|
|
125
137
|
|
|
126
138
|
/**
|
|
127
|
-
* Employ discovery to find a set of commissionable nodes
|
|
139
|
+
* Employ discovery to find a set of commissionable nodes, the options can be used to limit the discovered devices
|
|
140
|
+
* (e.g. just a specific vendor).
|
|
141
|
+
* TODO: Allow to provide multiple identifiers for multiple discoveries (e.g. from a Multi QR code).
|
|
128
142
|
*
|
|
129
|
-
* If you do not provide a timeout value, will search until canceled and you need to add a listener to
|
|
143
|
+
* If you do not provide a timeout value, will search until canceled, and you need to add a listener to
|
|
130
144
|
* {@link Discovery#discovered} or {@link added} to receive discovered nodes.
|
|
131
145
|
*/
|
|
132
146
|
discover(options?: Discovery.Options) {
|
|
@@ -161,14 +175,15 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
161
175
|
/**
|
|
162
176
|
* Emits when fixed attributes
|
|
163
177
|
*/
|
|
164
|
-
|
|
165
178
|
override get(id: number | string | PeerAddress) {
|
|
166
179
|
if (typeof id !== "string" && typeof id !== "number") {
|
|
167
180
|
const address = PeerAddress(id);
|
|
168
181
|
for (const node of this) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
182
|
+
if (node.behaviors.active.some(({ id }) => id === "commissioning")) {
|
|
183
|
+
const nodeAddress = node.maybeStateOf("commissioning")?.peerAddress as PeerAddress | undefined;
|
|
184
|
+
if (nodeAddress !== undefined && PeerAddress.is(nodeAddress, address)) {
|
|
185
|
+
return node;
|
|
186
|
+
}
|
|
172
187
|
}
|
|
173
188
|
}
|
|
174
189
|
return undefined;
|
|
@@ -218,7 +233,8 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
218
233
|
|
|
219
234
|
override async close() {
|
|
220
235
|
this.#closed = true;
|
|
221
|
-
|
|
236
|
+
this.#queue.close();
|
|
237
|
+
await this.#installedSubscriptionHandler?.close();
|
|
222
238
|
this.#cancelExpiration();
|
|
223
239
|
await this.#mutex;
|
|
224
240
|
await super.close();
|
|
@@ -242,18 +258,19 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
242
258
|
* If required, installs a listener in the environment's {@link InteractionServer} to handle subscription responses.
|
|
243
259
|
*/
|
|
244
260
|
#configureInteractionServer() {
|
|
245
|
-
if (
|
|
261
|
+
if (
|
|
262
|
+
this.#closed ||
|
|
263
|
+
this.#installedSubscriptionHandler !== undefined ||
|
|
264
|
+
!this.owner.env.has(InteractionServer)
|
|
265
|
+
) {
|
|
246
266
|
return;
|
|
247
267
|
}
|
|
248
268
|
|
|
249
269
|
const subscriptions = this.owner.env.get(ClientSubscriptions);
|
|
250
270
|
const interactionServer = this.owner.env.get(InteractionServer);
|
|
251
271
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
interactionServer.clientHandler = this.#subscriptionHandler;
|
|
272
|
+
this.#installedSubscriptionHandler = new ClientSubscriptionHandler(subscriptions);
|
|
273
|
+
interactionServer.clientHandler = this.#installedSubscriptionHandler;
|
|
257
274
|
}
|
|
258
275
|
|
|
259
276
|
/**
|
|
@@ -281,6 +298,9 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
281
298
|
}
|
|
282
299
|
|
|
283
300
|
#onExpirationIntervalElapsed() {
|
|
301
|
+
if (this.#closed) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
284
304
|
this.#mutex.run(() =>
|
|
285
305
|
this.#cullExpiredNodesAndAddresses()
|
|
286
306
|
.catch(error => {
|
|
@@ -297,7 +317,13 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
297
317
|
const now = Time.nowMs;
|
|
298
318
|
|
|
299
319
|
for (const node of this) {
|
|
300
|
-
|
|
320
|
+
if (!node.lifecycle.isReady) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
const state = node.maybeStateOf(CommissioningClient);
|
|
324
|
+
if (state === undefined) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
301
327
|
const { addresses } = state;
|
|
302
328
|
const isCommissioned = state.peerAddress !== undefined;
|
|
303
329
|
|
|
@@ -358,6 +384,10 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
358
384
|
node.eventsOf(type).capabilityMinima$Changed.on(setPeerLimits);
|
|
359
385
|
|
|
360
386
|
function setPeerLimits() {
|
|
387
|
+
if (!node.env.has(PeerSet)) {
|
|
388
|
+
// Node is not yet online, delay setting limits
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
361
391
|
const peerAddress = node.maybeStateOf(CommissioningClient)?.peerAddress;
|
|
362
392
|
if (peerAddress) {
|
|
363
393
|
node.env.get(PeerSet).for(peerAddress).limits = node.stateOf(type).capabilityMinima;
|
|
@@ -398,8 +428,15 @@ export class Peers extends EndpointContainer<ClientNode> {
|
|
|
398
428
|
});
|
|
399
429
|
}
|
|
400
430
|
|
|
401
|
-
#onShutdown(
|
|
402
|
-
|
|
431
|
+
async #onShutdown(node: ClientNode) {
|
|
432
|
+
if (!node.lifecycle.isReady || !node.lifecycle.isOnline) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const peerAddress = node.maybeStateOf(CommissioningClient)?.peerAddress;
|
|
436
|
+
if (peerAddress !== undefined) {
|
|
437
|
+
// Shutdown event means the device reboots, handle it like a peer loss and remove all sessions
|
|
438
|
+
await this.owner.env.get(SessionManager).handlePeerShutdown(peerAddress);
|
|
439
|
+
}
|
|
403
440
|
}
|
|
404
441
|
}
|
|
405
442
|
|