@matter/node 0.16.0-alpha.0-20251210-206ca2db7 → 0.16.0-alpha.0-20251211-0f80042cf

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.
Files changed (68) hide show
  1. package/dist/cjs/behavior/system/network/NetworkClient.d.ts +5 -1
  2. package/dist/cjs/behavior/system/network/NetworkClient.d.ts.map +1 -1
  3. package/dist/cjs/behavior/system/network/NetworkClient.js +19 -0
  4. package/dist/cjs/behavior/system/network/NetworkClient.js.map +1 -1
  5. package/dist/cjs/endpoint/properties/Behaviors.d.ts.map +1 -1
  6. package/dist/cjs/endpoint/properties/Behaviors.js +4 -3
  7. package/dist/cjs/endpoint/properties/Behaviors.js.map +1 -1
  8. package/dist/cjs/node/client/ClientEventEmitter.d.ts +2 -3
  9. package/dist/cjs/node/client/ClientEventEmitter.d.ts.map +1 -1
  10. package/dist/cjs/node/client/ClientEventEmitter.js +10 -2
  11. package/dist/cjs/node/client/ClientEventEmitter.js.map +1 -1
  12. package/dist/cjs/node/client/ClientGroupInteraction.d.ts +2 -2
  13. package/dist/cjs/node/client/ClientGroupInteraction.d.ts.map +1 -1
  14. package/dist/cjs/node/client/ClientGroupInteraction.js +1 -0
  15. package/dist/cjs/node/client/ClientGroupInteraction.js.map +1 -1
  16. package/dist/cjs/node/client/ClientNodeInteraction.js +1 -1
  17. package/dist/cjs/node/client/ClientNodeInteraction.js.map +1 -1
  18. package/dist/cjs/node/client/ClientStructure.d.ts +3 -1
  19. package/dist/cjs/node/client/ClientStructure.d.ts.map +1 -1
  20. package/dist/cjs/node/client/ClientStructure.js +20 -10
  21. package/dist/cjs/node/client/ClientStructure.js.map +1 -1
  22. package/dist/cjs/node/client/NodePeerAddressStore.d.ts.map +1 -1
  23. package/dist/cjs/node/client/NodePeerAddressStore.js +6 -3
  24. package/dist/cjs/node/client/NodePeerAddressStore.js.map +1 -1
  25. package/dist/cjs/node/client/PeerBehavior.d.ts.map +1 -1
  26. package/dist/cjs/node/client/PeerBehavior.js +13 -10
  27. package/dist/cjs/node/client/PeerBehavior.js.map +1 -1
  28. package/dist/cjs/node/server/InteractionServer.d.ts.map +1 -1
  29. package/dist/cjs/node/server/InteractionServer.js.map +1 -1
  30. package/dist/esm/behavior/system/network/NetworkClient.d.ts +5 -1
  31. package/dist/esm/behavior/system/network/NetworkClient.d.ts.map +1 -1
  32. package/dist/esm/behavior/system/network/NetworkClient.js +19 -0
  33. package/dist/esm/behavior/system/network/NetworkClient.js.map +1 -1
  34. package/dist/esm/endpoint/properties/Behaviors.d.ts.map +1 -1
  35. package/dist/esm/endpoint/properties/Behaviors.js +4 -3
  36. package/dist/esm/endpoint/properties/Behaviors.js.map +1 -1
  37. package/dist/esm/node/client/ClientEventEmitter.d.ts +2 -3
  38. package/dist/esm/node/client/ClientEventEmitter.d.ts.map +1 -1
  39. package/dist/esm/node/client/ClientEventEmitter.js +10 -2
  40. package/dist/esm/node/client/ClientEventEmitter.js.map +1 -1
  41. package/dist/esm/node/client/ClientGroupInteraction.d.ts +2 -2
  42. package/dist/esm/node/client/ClientGroupInteraction.d.ts.map +1 -1
  43. package/dist/esm/node/client/ClientGroupInteraction.js +1 -0
  44. package/dist/esm/node/client/ClientGroupInteraction.js.map +1 -1
  45. package/dist/esm/node/client/ClientNodeInteraction.js +1 -1
  46. package/dist/esm/node/client/ClientNodeInteraction.js.map +1 -1
  47. package/dist/esm/node/client/ClientStructure.d.ts +3 -1
  48. package/dist/esm/node/client/ClientStructure.d.ts.map +1 -1
  49. package/dist/esm/node/client/ClientStructure.js +20 -10
  50. package/dist/esm/node/client/ClientStructure.js.map +1 -1
  51. package/dist/esm/node/client/NodePeerAddressStore.d.ts.map +1 -1
  52. package/dist/esm/node/client/NodePeerAddressStore.js +6 -3
  53. package/dist/esm/node/client/NodePeerAddressStore.js.map +1 -1
  54. package/dist/esm/node/client/PeerBehavior.d.ts.map +1 -1
  55. package/dist/esm/node/client/PeerBehavior.js +13 -10
  56. package/dist/esm/node/client/PeerBehavior.js.map +1 -1
  57. package/dist/esm/node/server/InteractionServer.d.ts.map +1 -1
  58. package/dist/esm/node/server/InteractionServer.js.map +1 -1
  59. package/package.json +7 -7
  60. package/src/behavior/system/network/NetworkClient.ts +21 -1
  61. package/src/endpoint/properties/Behaviors.ts +3 -2
  62. package/src/node/client/ClientEventEmitter.ts +12 -4
  63. package/src/node/client/ClientGroupInteraction.ts +4 -2
  64. package/src/node/client/ClientNodeInteraction.ts +1 -1
  65. package/src/node/client/ClientStructure.ts +22 -10
  66. package/src/node/client/NodePeerAddressStore.ts +6 -3
  67. package/src/node/client/PeerBehavior.ts +23 -15
  68. package/src/node/server/InteractionServer.ts +1 -0
@@ -11,7 +11,7 @@ import { Descriptor } from "#clusters/descriptor";
11
11
  import { Endpoint } from "#endpoint/Endpoint.js";
12
12
  import { EndpointType } from "#endpoint/type/EndpointType.js";
13
13
  import { RootEndpoint } from "#endpoints/root";
14
- import { Diagnostic, InternalError, isDeepEqual, Logger } from "#general";
14
+ import { Diagnostic, InternalError, isDeepEqual, Logger, Observable } from "#general";
15
15
  import {
16
16
  AcceptedCommandList,
17
17
  AttributeList,
@@ -25,8 +25,8 @@ import {
25
25
  import type { ClientNode } from "#node/ClientNode.js";
26
26
  import type { Node } from "#node/Node.js";
27
27
  import { ReadScope, type Read, type ReadResult } from "#protocol";
28
+ import { ClientNodeStore } from "#storage/client/ClientNodeStore.js";
28
29
  import { DatasourceCache } from "#storage/client/DatasourceCache.js";
29
- import { ClientNodeStore } from "#storage/index.js";
30
30
  import type { AttributeId, ClusterId, ClusterType, CommandId, EndpointNumber } from "#types";
31
31
  import { Status } from "#types";
32
32
  import { ClientEventEmitter } from "./ClientEventEmitter.js";
@@ -52,6 +52,7 @@ export class ClientStructure {
52
52
  #pendingStructureEvents = Array<PendingEvent>();
53
53
  #delayedClusterEvents = new Array<ReadResult.EventValue>();
54
54
  #events: ClientStructureEvents;
55
+ #changed = Observable<[void]>();
55
56
 
56
57
  constructor(node: ClientNode) {
57
58
  this.#node = node;
@@ -64,6 +65,10 @@ export class ClientStructure {
64
65
  this.#events = this.#node.env.get(ClientStructureEvents);
65
66
  }
66
67
 
68
+ get changed() {
69
+ return this.#changed;
70
+ }
71
+
67
72
  /**
68
73
  * Load initial structure from cache.
69
74
  */
@@ -175,14 +180,16 @@ export class ClientStructure {
175
180
  // Apply changes
176
181
  const scope = ReadScope(request);
177
182
  for await (const chunk of changes) {
183
+ const chunkData = new Array<ReadResult.Report>();
178
184
  for (const change of chunk) {
185
+ chunkData.push(change);
179
186
  switch (change.kind) {
180
187
  case "attr-value":
181
188
  currentUpdates = await this.#mutateAttribute(change, scope, currentUpdates);
182
189
  break;
183
190
 
184
191
  case "event-value":
185
- this.#emitEvent(change, currentUpdates);
192
+ await this.#emitEvent(change, currentUpdates);
186
193
  break;
187
194
 
188
195
  case "attr-status":
@@ -197,7 +204,7 @@ export class ClientStructure {
197
204
  }
198
205
  }
199
206
 
200
- yield chunk;
207
+ yield chunkData;
201
208
  }
202
209
 
203
210
  // The last cluster still needs its changes applied
@@ -226,6 +233,7 @@ export class ClientStructure {
226
233
 
227
234
  // Likewise, we don't emit events until we've applied all structural changes
228
235
  this.#emitPendingStructureEvents();
236
+ await this.#emitPendingEvents();
229
237
  }
230
238
 
231
239
  /** Reference to the default subscription used when the node was started. */
@@ -280,7 +288,7 @@ export class ClientStructure {
280
288
  return currentUpdates;
281
289
  }
282
290
 
283
- #emitEvent(occurrence: ReadResult.EventValue, currentUpdates?: AttributeUpdates) {
291
+ async #emitEvent(occurrence: ReadResult.EventValue, currentUpdates?: AttributeUpdates) {
284
292
  const { endpointId, clusterId } = occurrence.path;
285
293
 
286
294
  const endpoint = this.#endpoints.get(endpointId);
@@ -291,7 +299,7 @@ export class ClientStructure {
291
299
  ) {
292
300
  this.#delayedClusterEvents.push(occurrence);
293
301
  } else {
294
- this.#eventEmitter(occurrence);
302
+ await this.#eventEmitter(occurrence);
295
303
  }
296
304
  }
297
305
 
@@ -628,7 +636,7 @@ export class ClientStructure {
628
636
  /**
629
637
  * Replace clusters after activation because fixed global attributes have changed.
630
638
  *
631
- * Currently we apply granular updates to clusters. This will possibly result in subtle errors if peers change in
639
+ * Currently, we apply granular updates to clusters. This will possibly result in subtle errors if peers change in
632
640
  * incompatible ways, but the backings are designed to be fairly resilient to this. This is simpler for API users
633
641
  * to deal with in the common case where they can just ignore. If it becomes problematic we can revert to replacing
634
642
  * entire endpoints or behaviors when there are structural changes.
@@ -742,8 +750,6 @@ export class ClientStructure {
742
750
  */
743
751
  #emitPendingStructureEvents() {
744
752
  const structureEvents = this.#pendingStructureEvents;
745
- const clusterEvents = this.#delayedClusterEvents;
746
- this.#delayedClusterEvents = [];
747
753
  this.#pendingStructureEvents = [];
748
754
  for (const event of structureEvents) {
749
755
  switch (event.kind) {
@@ -789,8 +795,14 @@ export class ClientStructure {
789
795
  }
790
796
  }
791
797
  }
798
+ this.#changed.emit();
799
+ }
800
+
801
+ async #emitPendingEvents() {
802
+ const clusterEvents = this.#delayedClusterEvents;
803
+ this.#delayedClusterEvents = [];
792
804
  for (const occurrence of clusterEvents) {
793
- this.#eventEmitter(occurrence);
805
+ await this.#eventEmitter(occurrence);
794
806
  }
795
807
  }
796
808
  }
@@ -5,12 +5,12 @@
5
5
  */
6
6
 
7
7
  import { RemoteDescriptor } from "#behavior/system/commissioning/RemoteDescriptor.js";
8
+ import { Crypto, ServerAddress, ServerAddressUdp } from "#general";
8
9
  import type { ClientNode } from "#node/ClientNode.js";
9
10
  import { IdentityService } from "#node/server/IdentityService.js";
10
11
  import type { ServerNode } from "#node/ServerNode.js";
11
12
  import { PeerAddress, PeerAddressMap, PeerAddressStore, PeerDescriptor } from "#protocol";
12
13
  import { FabricIndex, NodeId } from "#types";
13
- import { Crypto, ServerAddress, ServerAddressUdp } from "@matter/general";
14
14
 
15
15
  /**
16
16
  * This is an adapter for lower-level components in the protocol package.
@@ -74,17 +74,20 @@ export class NodePeerAddressStore extends PeerAddressStore {
74
74
 
75
75
  async updatePeer(peer: PeerDescriptor) {
76
76
  const node = this.#owner.peers.get(peer.address);
77
- if (!node) {
77
+ if (!node || !node.lifecycle.isInstalled) {
78
78
  return;
79
79
  }
80
80
 
81
- await node.act(agent => {
81
+ await node.act(async agent => {
82
+ await agent.context.transaction.addResources(agent.commissioning);
83
+ await agent.context.transaction.begin();
82
84
  const state = agent.commissioning.state;
83
85
  RemoteDescriptor.toLongForm(peer.discoveryData, state);
84
86
  if (peer.operationalAddress) {
85
87
  // TODO - modify lower tiers to pass along full set of operational addresses
86
88
  state.addresses = [peer.operationalAddress];
87
89
  }
90
+ await agent.context.transaction.commit();
88
91
  });
89
92
  }
90
93
 
@@ -25,6 +25,7 @@ import {
25
25
  ClusterComposer,
26
26
  ClusterId,
27
27
  ClusterRegistry,
28
+ ClusterType,
28
29
  Command,
29
30
  CommandId,
30
31
  MutableCluster,
@@ -103,12 +104,10 @@ function instrumentDiscoveredShape(shape: PeerBehavior.DiscoveredClusterShape) {
103
104
  return type;
104
105
  }
105
106
 
106
- let baseType: Behavior.Type;
107
+ let baseType: Behavior.Type | undefined;
107
108
  const standardCluster = ClusterRegistry.get(shape.id);
108
- if (standardCluster) {
109
+ if (standardCluster && !standardCluster.name.startsWith("Unknown cluster 0x")) {
109
110
  baseType = ClusterBehavior.for(standardCluster);
110
- } else {
111
- baseType = ClusterBehavior;
112
111
  }
113
112
 
114
113
  type = discoveredCache[fingerprint] = generateDiscoveredType(analysis, baseType);
@@ -138,22 +137,31 @@ function instrumentKnownShape(shape: PeerBehavior.KnownClusterShape) {
138
137
  return type;
139
138
  }
140
139
 
141
- function generateDiscoveredType(analysis: DiscoveredShapeAnalysis, baseType: Behavior.Type): ClusterBehavior.Type {
142
- // Ensure the input type is a ClusterBehavior
143
- if (!ClusterBehavior.is(baseType)) {
144
- throw new InternalError(`Base for cluster ${analysis.schema.name} is not a ClusterBehavior`);
145
- }
146
-
140
+ function generateDiscoveredType(analysis: DiscoveredShapeAnalysis, baseType?: Behavior.Type): ClusterBehavior.Type {
147
141
  let { schema } = analysis;
148
- let isExtended = false;
149
- const { attrSupportOverrides, extraAttrs, commandSupportOverrides, extraCommands } = analysis;
150
142
 
151
- // Obtain a ClusterType. This provides TLV for known elements
152
- let { cluster } = baseType;
153
- if (!cluster) {
143
+ let isExtended: boolean;
144
+ let cluster: ClusterType;
145
+
146
+ if (baseType) {
147
+ isExtended = false;
148
+
149
+ // Ensure the input type is a ClusterBehavior
150
+ if (!ClusterBehavior.is(baseType)) {
151
+ throw new InternalError(`Base for cluster ${analysis.schema.name} is not a ClusterBehavior`);
152
+ }
153
+
154
+ cluster = baseType.cluster;
155
+ } else {
156
+ isExtended = true;
157
+
154
158
  cluster = MutableCluster({ id: schema.id, name: schema.name, revision: schema.revision });
159
+
160
+ baseType = ClusterBehavior;
155
161
  }
156
162
 
163
+ const { attrSupportOverrides, extraAttrs, commandSupportOverrides, extraCommands } = analysis;
164
+
157
165
  // Identify known features the device supports
158
166
  let supportedFeatures = analysis.shape.features;
159
167
  if (typeof supportedFeatures === "number") {
@@ -449,6 +449,7 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
449
449
  if (fabric !== undefined && !keepSubscriptions) {
450
450
  let clearedCount = 0;
451
451
  for (const sess of this.#context.sessions.sessions) {
452
+ // TODO Adjust this filtering when subscriptions move to Peer
452
453
  if (!PeerAddress.is(sess.peerAddress, session.peerAddress)) {
453
454
  // Ignore subscriptions from other peers
454
455
  continue;