@matter/node 0.16.0-alpha.0-20251209-d6072d23e → 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 (219) hide show
  1. package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts +6 -2
  2. package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
  3. package/dist/cjs/behavior/system/commissioning/CommissioningClient.js +12 -3
  4. package/dist/cjs/behavior/system/commissioning/CommissioningClient.js.map +2 -2
  5. package/dist/cjs/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  6. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js +1 -1
  7. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  8. package/dist/cjs/behavior/system/commissioning/RemoteDescriptor.d.ts +1 -1
  9. package/dist/cjs/behavior/system/commissioning/RemoteDescriptor.d.ts.map +1 -1
  10. package/dist/cjs/behavior/system/commissioning/RemoteDescriptor.js +3 -2
  11. package/dist/cjs/behavior/system/commissioning/RemoteDescriptor.js.map +1 -1
  12. package/dist/cjs/behavior/system/commissioning/index.d.ts +1 -0
  13. package/dist/cjs/behavior/system/commissioning/index.d.ts.map +1 -1
  14. package/dist/cjs/behavior/system/commissioning/index.js +1 -0
  15. package/dist/cjs/behavior/system/commissioning/index.js.map +1 -1
  16. package/dist/cjs/behavior/system/controller/ControllerBehavior.d.ts.map +1 -1
  17. package/dist/cjs/behavior/system/controller/ControllerBehavior.js +5 -2
  18. package/dist/cjs/behavior/system/controller/ControllerBehavior.js.map +1 -1
  19. package/dist/cjs/behavior/system/controller/discovery/CommissioningDiscovery.d.ts +1 -1
  20. package/dist/cjs/behavior/system/network/NetworkClient.d.ts +5 -1
  21. package/dist/cjs/behavior/system/network/NetworkClient.d.ts.map +1 -1
  22. package/dist/cjs/behavior/system/network/NetworkClient.js +19 -0
  23. package/dist/cjs/behavior/system/network/NetworkClient.js.map +1 -1
  24. package/dist/cjs/behavior/system/network/index.d.ts +1 -0
  25. package/dist/cjs/behavior/system/network/index.d.ts.map +1 -1
  26. package/dist/cjs/behavior/system/network/index.js +1 -0
  27. package/dist/cjs/behavior/system/network/index.js.map +1 -1
  28. package/dist/cjs/behaviors/access-control/AccessControlServer.d.ts +1 -2
  29. package/dist/cjs/behaviors/access-control/AccessControlServer.d.ts.map +1 -1
  30. package/dist/cjs/behaviors/access-control/AccessControlServer.js.map +1 -1
  31. package/dist/cjs/behaviors/basic-information/BasicInformationServer.d.ts +1 -2
  32. package/dist/cjs/behaviors/basic-information/BasicInformationServer.d.ts.map +1 -1
  33. package/dist/cjs/behaviors/basic-information/BasicInformationServer.js.map +1 -1
  34. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.d.ts.map +1 -1
  35. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js +2 -1
  36. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
  37. package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts +1 -1
  38. package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts.map +1 -1
  39. package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.js.map +1 -1
  40. package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.d.ts +1 -2
  41. package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.d.ts.map +1 -1
  42. package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.js.map +1 -1
  43. package/dist/cjs/endpoint/properties/Behaviors.d.ts +8 -0
  44. package/dist/cjs/endpoint/properties/Behaviors.d.ts.map +1 -1
  45. package/dist/cjs/endpoint/properties/Behaviors.js +11 -20
  46. package/dist/cjs/endpoint/properties/Behaviors.js.map +2 -2
  47. package/dist/cjs/endpoint/properties/EndpointInitializer.d.ts +2 -1
  48. package/dist/cjs/endpoint/properties/EndpointInitializer.d.ts.map +1 -1
  49. package/dist/cjs/endpoint/properties/EndpointInitializer.js.map +1 -1
  50. package/dist/cjs/endpoint/properties/Endpoints.d.ts +1 -1
  51. package/dist/cjs/endpoint/properties/Endpoints.d.ts.map +1 -1
  52. package/dist/cjs/endpoint/properties/Endpoints.js +4 -4
  53. package/dist/cjs/endpoint/properties/Endpoints.js.map +1 -1
  54. package/dist/cjs/node/Node.d.ts.map +1 -1
  55. package/dist/cjs/node/Node.js +12 -3
  56. package/dist/cjs/node/Node.js.map +1 -1
  57. package/dist/cjs/node/NodePhysicalProperties.d.ts.map +1 -1
  58. package/dist/cjs/node/NodePhysicalProperties.js +6 -4
  59. package/dist/cjs/node/NodePhysicalProperties.js.map +1 -1
  60. package/dist/cjs/node/client/ClientEventEmitter.d.ts +2 -3
  61. package/dist/cjs/node/client/ClientEventEmitter.d.ts.map +1 -1
  62. package/dist/cjs/node/client/ClientEventEmitter.js +10 -2
  63. package/dist/cjs/node/client/ClientEventEmitter.js.map +1 -1
  64. package/dist/cjs/node/client/ClientGroupInteraction.d.ts +2 -2
  65. package/dist/cjs/node/client/ClientGroupInteraction.d.ts.map +1 -1
  66. package/dist/cjs/node/client/ClientGroupInteraction.js +1 -0
  67. package/dist/cjs/node/client/ClientGroupInteraction.js.map +1 -1
  68. package/dist/cjs/node/client/ClientNodeInteraction.js +1 -1
  69. package/dist/cjs/node/client/ClientNodeInteraction.js.map +1 -1
  70. package/dist/cjs/node/client/ClientStructure.d.ts +3 -1
  71. package/dist/cjs/node/client/ClientStructure.d.ts.map +1 -1
  72. package/dist/cjs/node/client/ClientStructure.js +20 -10
  73. package/dist/cjs/node/client/ClientStructure.js.map +1 -1
  74. package/dist/cjs/node/client/NodePeerAddressStore.d.ts.map +1 -1
  75. package/dist/cjs/node/client/NodePeerAddressStore.js +6 -3
  76. package/dist/cjs/node/client/NodePeerAddressStore.js.map +1 -1
  77. package/dist/cjs/node/client/PeerBehavior.d.ts.map +1 -1
  78. package/dist/cjs/node/client/PeerBehavior.js +13 -10
  79. package/dist/cjs/node/client/PeerBehavior.js.map +1 -1
  80. package/dist/cjs/node/client/index.d.ts +1 -0
  81. package/dist/cjs/node/client/index.d.ts.map +1 -1
  82. package/dist/cjs/node/client/index.js +1 -0
  83. package/dist/cjs/node/client/index.js.map +1 -1
  84. package/dist/cjs/node/index.d.ts +1 -0
  85. package/dist/cjs/node/index.d.ts.map +1 -1
  86. package/dist/cjs/node/index.js +1 -0
  87. package/dist/cjs/node/index.js.map +1 -1
  88. package/dist/cjs/node/server/InteractionServer.d.ts.map +1 -1
  89. package/dist/cjs/node/server/InteractionServer.js +6 -3
  90. package/dist/cjs/node/server/InteractionServer.js.map +2 -2
  91. package/dist/cjs/node/server/ServerEndpointInitializer.d.ts +3 -1
  92. package/dist/cjs/node/server/ServerEndpointInitializer.d.ts.map +1 -1
  93. package/dist/cjs/node/server/ServerEndpointInitializer.js +10 -0
  94. package/dist/cjs/node/server/ServerEndpointInitializer.js.map +1 -1
  95. package/dist/cjs/node/server/ServerSubscription.d.ts +1 -1
  96. package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts +6 -2
  97. package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
  98. package/dist/esm/behavior/system/commissioning/CommissioningClient.js +13 -3
  99. package/dist/esm/behavior/system/commissioning/CommissioningClient.js.map +1 -1
  100. package/dist/esm/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  101. package/dist/esm/behavior/system/commissioning/CommissioningServer.js +1 -1
  102. package/dist/esm/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  103. package/dist/esm/behavior/system/commissioning/RemoteDescriptor.d.ts +1 -1
  104. package/dist/esm/behavior/system/commissioning/RemoteDescriptor.d.ts.map +1 -1
  105. package/dist/esm/behavior/system/commissioning/RemoteDescriptor.js +3 -2
  106. package/dist/esm/behavior/system/commissioning/RemoteDescriptor.js.map +1 -1
  107. package/dist/esm/behavior/system/commissioning/index.d.ts +1 -0
  108. package/dist/esm/behavior/system/commissioning/index.d.ts.map +1 -1
  109. package/dist/esm/behavior/system/commissioning/index.js +1 -0
  110. package/dist/esm/behavior/system/commissioning/index.js.map +1 -1
  111. package/dist/esm/behavior/system/controller/ControllerBehavior.d.ts.map +1 -1
  112. package/dist/esm/behavior/system/controller/ControllerBehavior.js +5 -2
  113. package/dist/esm/behavior/system/controller/ControllerBehavior.js.map +1 -1
  114. package/dist/esm/behavior/system/controller/discovery/CommissioningDiscovery.d.ts +1 -1
  115. package/dist/esm/behavior/system/network/NetworkClient.d.ts +5 -1
  116. package/dist/esm/behavior/system/network/NetworkClient.d.ts.map +1 -1
  117. package/dist/esm/behavior/system/network/NetworkClient.js +19 -0
  118. package/dist/esm/behavior/system/network/NetworkClient.js.map +1 -1
  119. package/dist/esm/behavior/system/network/index.d.ts +1 -0
  120. package/dist/esm/behavior/system/network/index.d.ts.map +1 -1
  121. package/dist/esm/behavior/system/network/index.js +1 -0
  122. package/dist/esm/behavior/system/network/index.js.map +1 -1
  123. package/dist/esm/behaviors/access-control/AccessControlServer.d.ts +1 -2
  124. package/dist/esm/behaviors/access-control/AccessControlServer.d.ts.map +1 -1
  125. package/dist/esm/behaviors/access-control/AccessControlServer.js.map +1 -1
  126. package/dist/esm/behaviors/basic-information/BasicInformationServer.d.ts +1 -2
  127. package/dist/esm/behaviors/basic-information/BasicInformationServer.d.ts.map +1 -1
  128. package/dist/esm/behaviors/basic-information/BasicInformationServer.js.map +1 -1
  129. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.d.ts.map +1 -1
  130. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js +2 -1
  131. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
  132. package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts +1 -1
  133. package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts.map +1 -1
  134. package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.js.map +1 -1
  135. package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.d.ts +1 -2
  136. package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.d.ts.map +1 -1
  137. package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.js.map +1 -1
  138. package/dist/esm/endpoint/properties/Behaviors.d.ts +8 -0
  139. package/dist/esm/endpoint/properties/Behaviors.d.ts.map +1 -1
  140. package/dist/esm/endpoint/properties/Behaviors.js +11 -20
  141. package/dist/esm/endpoint/properties/Behaviors.js.map +2 -2
  142. package/dist/esm/endpoint/properties/EndpointInitializer.d.ts +2 -1
  143. package/dist/esm/endpoint/properties/EndpointInitializer.d.ts.map +1 -1
  144. package/dist/esm/endpoint/properties/EndpointInitializer.js.map +1 -1
  145. package/dist/esm/endpoint/properties/Endpoints.d.ts +1 -1
  146. package/dist/esm/endpoint/properties/Endpoints.d.ts.map +1 -1
  147. package/dist/esm/endpoint/properties/Endpoints.js +4 -4
  148. package/dist/esm/endpoint/properties/Endpoints.js.map +1 -1
  149. package/dist/esm/node/Node.d.ts.map +1 -1
  150. package/dist/esm/node/Node.js +12 -3
  151. package/dist/esm/node/Node.js.map +1 -1
  152. package/dist/esm/node/NodePhysicalProperties.d.ts.map +1 -1
  153. package/dist/esm/node/NodePhysicalProperties.js +6 -4
  154. package/dist/esm/node/NodePhysicalProperties.js.map +1 -1
  155. package/dist/esm/node/client/ClientEventEmitter.d.ts +2 -3
  156. package/dist/esm/node/client/ClientEventEmitter.d.ts.map +1 -1
  157. package/dist/esm/node/client/ClientEventEmitter.js +10 -2
  158. package/dist/esm/node/client/ClientEventEmitter.js.map +1 -1
  159. package/dist/esm/node/client/ClientGroupInteraction.d.ts +2 -2
  160. package/dist/esm/node/client/ClientGroupInteraction.d.ts.map +1 -1
  161. package/dist/esm/node/client/ClientGroupInteraction.js +1 -0
  162. package/dist/esm/node/client/ClientGroupInteraction.js.map +1 -1
  163. package/dist/esm/node/client/ClientNodeInteraction.js +1 -1
  164. package/dist/esm/node/client/ClientNodeInteraction.js.map +1 -1
  165. package/dist/esm/node/client/ClientStructure.d.ts +3 -1
  166. package/dist/esm/node/client/ClientStructure.d.ts.map +1 -1
  167. package/dist/esm/node/client/ClientStructure.js +20 -10
  168. package/dist/esm/node/client/ClientStructure.js.map +1 -1
  169. package/dist/esm/node/client/NodePeerAddressStore.d.ts.map +1 -1
  170. package/dist/esm/node/client/NodePeerAddressStore.js +6 -3
  171. package/dist/esm/node/client/NodePeerAddressStore.js.map +1 -1
  172. package/dist/esm/node/client/PeerBehavior.d.ts.map +1 -1
  173. package/dist/esm/node/client/PeerBehavior.js +13 -10
  174. package/dist/esm/node/client/PeerBehavior.js.map +1 -1
  175. package/dist/esm/node/client/index.d.ts +1 -0
  176. package/dist/esm/node/client/index.d.ts.map +1 -1
  177. package/dist/esm/node/client/index.js +1 -0
  178. package/dist/esm/node/client/index.js.map +1 -1
  179. package/dist/esm/node/index.d.ts +1 -0
  180. package/dist/esm/node/index.d.ts.map +1 -1
  181. package/dist/esm/node/index.js +1 -0
  182. package/dist/esm/node/index.js.map +1 -1
  183. package/dist/esm/node/server/InteractionServer.d.ts.map +1 -1
  184. package/dist/esm/node/server/InteractionServer.js +7 -3
  185. package/dist/esm/node/server/InteractionServer.js.map +2 -2
  186. package/dist/esm/node/server/ServerEndpointInitializer.d.ts +3 -1
  187. package/dist/esm/node/server/ServerEndpointInitializer.d.ts.map +1 -1
  188. package/dist/esm/node/server/ServerEndpointInitializer.js +10 -0
  189. package/dist/esm/node/server/ServerEndpointInitializer.js.map +1 -1
  190. package/dist/esm/node/server/ServerSubscription.d.ts +1 -1
  191. package/package.json +7 -7
  192. package/src/behavior/system/commissioning/CommissioningClient.ts +21 -2
  193. package/src/behavior/system/commissioning/CommissioningServer.ts +2 -2
  194. package/src/behavior/system/commissioning/RemoteDescriptor.ts +3 -2
  195. package/src/behavior/system/commissioning/index.ts +1 -0
  196. package/src/behavior/system/controller/ControllerBehavior.ts +6 -3
  197. package/src/behavior/system/network/NetworkClient.ts +21 -1
  198. package/src/behavior/system/network/index.ts +1 -0
  199. package/src/behaviors/access-control/AccessControlServer.ts +2 -2
  200. package/src/behaviors/basic-information/BasicInformationServer.ts +2 -3
  201. package/src/behaviors/general-commissioning/GeneralCommissioningServer.ts +1 -0
  202. package/src/behaviors/general-diagnostics/GeneralDiagnosticsServer.ts +1 -1
  203. package/src/behaviors/group-key-management/GroupKeyManagementServer.ts +2 -2
  204. package/src/endpoint/properties/Behaviors.ts +27 -16
  205. package/src/endpoint/properties/EndpointInitializer.ts +2 -1
  206. package/src/endpoint/properties/Endpoints.ts +4 -4
  207. package/src/node/Node.ts +12 -3
  208. package/src/node/NodePhysicalProperties.ts +6 -4
  209. package/src/node/client/ClientEventEmitter.ts +12 -4
  210. package/src/node/client/ClientGroupInteraction.ts +4 -2
  211. package/src/node/client/ClientNodeInteraction.ts +1 -1
  212. package/src/node/client/ClientStructure.ts +22 -10
  213. package/src/node/client/NodePeerAddressStore.ts +6 -3
  214. package/src/node/client/PeerBehavior.ts +23 -15
  215. package/src/node/client/index.ts +1 -0
  216. package/src/node/index.ts +1 -0
  217. package/src/node/server/InteractionServer.ts +8 -3
  218. package/src/node/server/ServerEndpointInitializer.ts +14 -1
  219. package/src/node/server/ServerSubscription.ts +1 -1
@@ -64,7 +64,7 @@ export class GeneralDiagnosticsServer extends Base {
64
64
  declare state: GeneralDiagnosticsServer.State;
65
65
  static override readonly schema = schema;
66
66
 
67
- override initialize(): MaybePromise {
67
+ override initialize() {
68
68
  if (this.state.testEventTriggersEnabled === undefined) {
69
69
  this.state.testEventTriggersEnabled = false;
70
70
  } else if (this.state.testEventTriggersEnabled) {
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { ActionContext } from "#behavior/context/ActionContext.js";
8
8
  import { GroupKeyManagement } from "#clusters/group-key-management";
9
- import { deepCopy, ImplementationError, Logger, MaybePromise } from "#general";
9
+ import { deepCopy, ImplementationError, Logger } from "#general";
10
10
  import { DatatypeModel, FieldElement } from "#model";
11
11
  import { NodeLifecycle } from "#node/NodeLifecycle.js";
12
12
  import { assertRemoteActor, Fabric, FabricManager, hasRemoteActor, IPK_DEFAULT_EPOCH_START_TIME } from "#protocol";
@@ -47,7 +47,7 @@ export class GroupKeyManagementServer extends GroupKeyManagementBehavior {
47
47
  declare state: GroupKeyManagementServer.State;
48
48
  static override readonly schema = schema;
49
49
 
50
- override initialize(): MaybePromise {
50
+ override initialize() {
51
51
  if (this.features.cacheAndSync) {
52
52
  throw new ImplementationError("The CacheAndSync feature is provisional. Do not use it.");
53
53
  }
@@ -6,7 +6,6 @@
6
6
 
7
7
  import { Behavior } from "#behavior/Behavior.js";
8
8
  import type { ClusterBehavior } from "#behavior/cluster/ClusterBehavior.js";
9
- import { limitEndpointAttributeDataToAllowedFabrics } from "#behavior/cluster/FabricScopedDataHandler.js";
10
9
  import { ActionContext } from "#behavior/context/ActionContext.js";
11
10
  import { NodeActivity } from "#behavior/context/NodeActivity.js";
12
11
  import { LocalActorContext } from "#behavior/context/server/LocalActorContext.js";
@@ -28,7 +27,7 @@ import {
28
27
  } from "#general";
29
28
  import { FeatureSet } from "#model";
30
29
  import { ProtocolService } from "#node/integration/ProtocolService.js";
31
- import { ClusterTypeProtocol, FabricManager, Val } from "#protocol";
30
+ import { ClusterTypeProtocol, Val } from "#protocol";
32
31
  import { ClusterType, VoidSchema } from "#types";
33
32
  import type { Agent } from "../Agent.js";
34
33
  import type { Endpoint } from "../Endpoint.js";
@@ -243,16 +242,6 @@ export class Behaviors {
243
242
  promise = endpointInitializer.behaviorsInitialized(agent);
244
243
  }
245
244
 
246
- if (this.#endpoint.env.has(FabricManager)) {
247
- const fabricIndices = this.#endpoint.env.get(FabricManager).fabrics.map(fabric => fabric.fabricIndex);
248
- if (fabricIndices.length > 0) {
249
- // Make sure the state on startup only includes allowed Fabric scoped data
250
- return MaybePromise.then(promise, () =>
251
- limitEndpointAttributeDataToAllowedFabrics(this.#endpoint, fabricIndices),
252
- );
253
- }
254
- }
255
-
256
245
  return promise;
257
246
  };
258
247
 
@@ -281,7 +270,17 @@ export class Behaviors {
281
270
  /**
282
271
  * Does the {@link Endpoint} support a specified behavior?
283
272
  */
284
- has<T extends Behavior.Type>(type: T) {
273
+ has<T extends Behavior.Type>(type: T): boolean;
274
+
275
+ /**
276
+ * Does the {@link Endpoint} support a specified behavior by its behavior Id?
277
+ */
278
+ has(typeId: string): boolean;
279
+
280
+ has(type: Behavior.Type | string): boolean {
281
+ if (typeof type === "string") {
282
+ return !!this.#supported[type];
283
+ }
285
284
  const myType = this.#supported[type.id];
286
285
  return myType === type || myType?.supports(type);
287
286
  }
@@ -609,7 +608,18 @@ export class Behaviors {
609
608
  /**
610
609
  * Obtain current data version of behavior.
611
610
  */
612
- versionOf(type: Behavior.Type) {
611
+ versionOf(type: Behavior.Type): number;
612
+
613
+ /**
614
+ * Obtain current data version of behavior by its behavior Id, if existing
615
+ */
616
+ versionOf(typeId: string): number | undefined;
617
+
618
+ versionOf(type: Behavior.Type | string) {
619
+ if (typeof type === "string") {
620
+ const backing = this.#backings[type];
621
+ return backing?.maybeDatasource?.version;
622
+ }
613
623
  const backing = this.#backingFor(type);
614
624
  return backing.datasource.version;
615
625
  }
@@ -751,9 +761,9 @@ export class Behaviors {
751
761
  const { id, Events } = type;
752
762
 
753
763
  const get = () => this.#backingFor(type).stateView;
754
- Object.defineProperty(this.#endpoint.state, id, { get, enumerable: true });
764
+ Object.defineProperty(this.#endpoint.state, id, { get, enumerable: true, configurable: true });
755
765
  if (type.schema.id !== undefined) {
756
- Object.defineProperty(this.#endpoint.state, type.schema.id, { get });
766
+ Object.defineProperty(this.#endpoint.state, type.schema.id, { get, configurable: true });
757
767
  }
758
768
 
759
769
  Object.defineProperty(this.#endpoint.events, id, {
@@ -770,6 +780,7 @@ export class Behaviors {
770
780
  },
771
781
 
772
782
  enumerable: true,
783
+ configurable: true,
773
784
  });
774
785
  }
775
786
  }
@@ -7,6 +7,7 @@
7
7
  import type { Behavior } from "#behavior/Behavior.js";
8
8
  import type { BehaviorBacking } from "#behavior/internal/BehaviorBacking.js";
9
9
  import type { Agent } from "#endpoint/Agent.js";
10
+ import { MaybePromise } from "#general";
10
11
  import type { Endpoint } from "../Endpoint.js";
11
12
 
12
13
  /**
@@ -40,5 +41,5 @@ export abstract class EndpointInitializer {
40
41
  /**
41
42
  * Invoked after behaviors are initialized but before the initialization transaction commits.
42
43
  */
43
- behaviorsInitialized(_agent: Agent) {}
44
+ behaviorsInitialized(_agent: Agent): MaybePromise {}
44
45
  }
@@ -61,14 +61,14 @@ export class Endpoints implements ImmutableSet<Endpoint> {
61
61
  return this.#list[Symbol.iterator]();
62
62
  }
63
63
 
64
- for(number: number | string): Endpoint {
65
- if (number === 0) {
64
+ for(id: number | string): Endpoint {
65
+ if (id === 0) {
66
66
  return this.#node;
67
67
  }
68
68
 
69
- const endpoint = typeof number === "string" ? this.#idIndex[number] : this.#index[number];
69
+ const endpoint = typeof id === "string" ? this.#idIndex[id] : this.#index[id];
70
70
  if (endpoint === undefined) {
71
- throw new StatusResponse.NotFoundError(`Endpoint ${number} does not exist`);
71
+ throw new StatusResponse.NotFoundError(`Endpoint ${id} does not exist`);
72
72
  }
73
73
  return endpoint;
74
74
  }
package/src/node/Node.ts CHANGED
@@ -41,6 +41,7 @@ export abstract class Node<T extends Node.CommonRootEndpoint = Node.CommonRootEn
41
41
  #environment: Environment;
42
42
  #runtime?: NetworkRuntime;
43
43
  #startInProgress = false;
44
+ #closeInProgress = false;
44
45
 
45
46
  constructor(config: Node.Configuration<T>) {
46
47
  const parentEnvironment = config.environment ?? config.owner?.env ?? Environment.default;
@@ -183,9 +184,17 @@ export abstract class Node<T extends Node.CommonRootEndpoint = Node.CommonRootEn
183
184
  }
184
185
 
185
186
  override async close() {
186
- this.lifecycle.targetState = "offline";
187
- await this.lifecycle.mutex.close();
188
- await this.closeWithMutex();
187
+ if (this.#closeInProgress) {
188
+ return;
189
+ }
190
+ this.#closeInProgress = true;
191
+ try {
192
+ this.lifecycle.targetState = "offline";
193
+ await this.lifecycle.mutex.close();
194
+ await this.closeWithMutex();
195
+ } finally {
196
+ this.#closeInProgress = false;
197
+ }
189
198
  }
190
199
 
191
200
  protected async closeWithMutex() {
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import { DescriptorClient } from "#behaviors/descriptor";
7
8
  import { NetworkCommissioningClient } from "#behaviors/network-commissioning";
8
9
  import { PowerSourceClient } from "#behaviors/power-source";
9
10
  import { ThreadNetworkDiagnosticsClient } from "#behaviors/thread-network-diagnostics";
@@ -20,7 +21,7 @@ import { ClusterId } from "#types";
20
21
  * Inspects a node to generate {@link PhysicalDeviceProperties}.
21
22
  */
22
23
  export function NodePhysicalProperties(node: Node) {
23
- const rootEndpointServerList = [...node.state.descriptor.serverList];
24
+ const rootEndpointServerList = [...(node.maybeStateOf(DescriptorClient)?.serverList ?? [])];
24
25
 
25
26
  const properties: PhysicalDeviceProperties = {
26
27
  threadConnected: false,
@@ -58,8 +59,9 @@ function inspectEndpoint(endpoint: Endpoint, properties: PhysicalDevicePropertie
58
59
  const powerSource = endpoint.behaviors.typeFor(PowerSourceClient);
59
60
  if (powerSource) {
60
61
  const features = powerSource.schema.supportedFeatures;
62
+ const status = endpoint.stateOf(PowerSourceClient).status;
61
63
  if (features.has("WIRED")) {
62
- if (endpoint.stateOf(PowerSourceClient).status === PowerSource.PowerSourceStatus.Active) {
64
+ if (status === PowerSource.PowerSourceStatus.Active) {
63
65
  // Should we only consider A/C "mains" powered? What is a DC adapter? What is an external battery?
64
66
  // For now assuming "wired" means "don't worry about power consumption"
65
67
  properties.isMainsPowered = true;
@@ -71,9 +73,9 @@ function inspectEndpoint(endpoint: Endpoint, properties: PhysicalDevicePropertie
71
73
  endpoint.behaviors.elementsOf(powerSource).attributes.has("batChargeLevel")
72
74
  ) {
73
75
  if (
74
- endpoint.stateOf(PowerSourceClient).status === PowerSource.PowerSourceStatus.Active ||
76
+ status === PowerSource.PowerSourceStatus.Active ||
75
77
  // Some devices do not properly specify state as active
76
- endpoint.stateOf(PowerSourceClient).status === PowerSource.PowerSourceStatus.Unspecified
78
+ status === PowerSource.PowerSourceStatus.Unspecified
77
79
  ) {
78
80
  properties.isBatteryPowered = true;
79
81
  }
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import type { ElementEvent, Events } from "#behavior/Events.js";
8
+ import { NetworkClient } from "#behavior/system/network/NetworkClient.js";
8
9
  import { camelize, Diagnostic, isObject, Logger } from "#general";
9
10
  import { ClusterModel, EventModel, MatterModel } from "#model";
10
11
  import type { ClientNode } from "#node/ClientNode.js";
@@ -18,10 +19,9 @@ const logger = Logger.get("ClientEventEmitter");
18
19
  * Event handler for Matter events transmitted by a peer.
19
20
  *
20
21
  * TODO - set priority on context when split for server vs. client
21
- * TODO - record latest event number for each subscription shape (or just wildcard?)
22
22
  */
23
23
  export interface ClientEventEmitter {
24
- (event: ReadResult.EventValue): void;
24
+ (event: ReadResult.EventValue): Promise<void>;
25
25
  }
26
26
 
27
27
  /**
@@ -40,7 +40,7 @@ const warnedForUnknown = new Set<ClusterId | `${ClusterId}-${EventId}`>();
40
40
  export function ClientEventEmitter(node: ClientNode, structure: ClientStructure) {
41
41
  return emitClientEvent;
42
42
 
43
- function emitClientEvent(occurrence: ReadResult.EventValue) {
43
+ async function emitClientEvent(occurrence: ReadResult.EventValue) {
44
44
  const names = getNames(node.matter, occurrence);
45
45
  if (!names) {
46
46
  return;
@@ -48,10 +48,18 @@ export function ClientEventEmitter(node: ClientNode, structure: ClientStructure)
48
48
 
49
49
  const event = getEvent(node, occurrence, names.cluster, names.event);
50
50
  if (event) {
51
- node.act(agent => {
51
+ await node.act(async agent => {
52
52
  // Current ActionContext is not writable, could skip act() but meh, see TODO above
53
53
  //agent.context.priority = occurrence.priority;
54
54
  event.emit(occurrence.value, agent.context);
55
+
56
+ const network = agent.get(NetworkClient);
57
+ if (occurrence.number > network.state.maxEventNumber) {
58
+ await agent.context.transaction.addResources(network);
59
+ await agent.context.transaction.begin();
60
+ network.state.maxEventNumber = occurrence.number;
61
+ await agent.context.transaction.commit();
62
+ }
55
63
  });
56
64
  }
57
65
  }
@@ -8,11 +8,11 @@ import type { ActionContext } from "#behavior/index.js";
8
8
  import { ImplementationError } from "#general";
9
9
  import {
10
10
  ClientInvoke,
11
+ ClientSubscription,
11
12
  DecodedInvokeResult,
12
13
  Read,
13
14
  ReadResult,
14
15
  Subscribe,
15
- SubscribeResult,
16
16
  Write,
17
17
  WriteResult,
18
18
  } from "#protocol";
@@ -27,7 +27,7 @@ export class ClientGroupInteraction extends ClientNodeInteraction {
27
27
  }
28
28
 
29
29
  /** Groups do not support reading or subscribing to attributes */
30
- override async subscribe(_request: Subscribe, _context?: ActionContext): SubscribeResult {
30
+ override async subscribe(_request: Subscribe, _context?: ActionContext): Promise<ClientSubscription> {
31
31
  throw new InvalidGroupOperationError("Groups do not support subscribing to attributes");
32
32
  }
33
33
 
@@ -65,6 +65,8 @@ export class ClientGroupInteraction extends ClientNodeInteraction {
65
65
  throw new InvalidGroupOperationError("Timed requests are not supported for group address invokes.");
66
66
  }
67
67
 
68
+ request.suppressResponse = true; // Invoking on a group does not yield a response by definition
69
+
68
70
  return super.invoke(request, context);
69
71
  }
70
72
  }
@@ -74,7 +74,7 @@ export class ClientNodeInteraction implements Interactable<ActionContext> {
74
74
  request,
75
75
  }),
76
76
 
77
- sustain: request.sustain === undefined ? true : request.sustain,
77
+ sustain: request.sustain !== false,
78
78
 
79
79
  updated: async data => {
80
80
  const result = this.structure.mutate(request, data);
@@ -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") {
@@ -5,5 +5,6 @@
5
5
  */
6
6
 
7
7
  export * from "./ClientEndpointInitializer.js";
8
+ export * from "./ClientNodeInteraction.js";
8
9
  export * from "./NodePeerAddressStore.js";
9
10
  export * from "./Peers.js";
package/src/node/index.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  export * from "./client/index.js";
8
+ export * from "./ClientNode.js";
8
9
  export * from "./integration/index.js";
9
10
  export * from "./Node.js";
10
11
  export * from "./NodeLifecycle.js";
@@ -448,11 +448,16 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
448
448
 
449
449
  if (fabric !== undefined && !keepSubscriptions) {
450
450
  let clearedCount = 0;
451
- for (const session of this.#context.sessions.sessions) {
452
- for (const subscription of session.subscriptions) {
451
+ for (const sess of this.#context.sessions.sessions) {
452
+ // TODO Adjust this filtering when subscriptions move to Peer
453
+ if (!PeerAddress.is(sess.peerAddress, session.peerAddress)) {
454
+ // Ignore subscriptions from other peers
455
+ continue;
456
+ }
457
+ for (const subscription of sess.subscriptions) {
453
458
  await subscription.handlePeerCancel();
459
+ clearedCount++;
454
460
  }
455
- clearedCount++;
456
461
  }
457
462
  if (clearedCount > 0) {
458
463
  logger.debug(
@@ -5,11 +5,14 @@
5
5
  */
6
6
 
7
7
  import { Behavior } from "#behavior/Behavior.js";
8
+ import { limitEndpointAttributeDataToAllowedFabrics } from "#behavior/cluster/FabricScopedDataHandler.js";
8
9
  import { BehaviorBacking } from "#behavior/internal/BehaviorBacking.js";
9
10
  import { ServerBehaviorBacking } from "#behavior/internal/ServerBehaviorBacking.js";
10
11
  import { Endpoint } from "#endpoint/Endpoint.js";
12
+ import type { Agent } from "#endpoint/index.js";
11
13
  import { EndpointInitializer } from "#endpoint/properties/EndpointInitializer.js";
12
- import { Environment, InternalError, Logger } from "#general";
14
+ import { Environment, InternalError, Logger, MaybePromise } from "#general";
15
+ import { FabricManager } from "#protocol";
13
16
  import { ServerNodeStore } from "#storage/server/ServerNodeStore.js";
14
17
  import { DescriptorServer } from "../../behaviors/descriptor/DescriptorServer.js";
15
18
 
@@ -105,4 +108,14 @@ export class ServerEndpointInitializer extends EndpointInitializer {
105
108
 
106
109
  return id;
107
110
  }
111
+
112
+ override behaviorsInitialized(agent: Agent): MaybePromise {
113
+ // Make sure the state only includes allowed Fabric scoped data when an endpoint is added after node is online
114
+ if (agent.env.has(FabricManager)) {
115
+ const fabricIndices = agent.env.get(FabricManager).fabrics.map(fabric => fabric.fabricIndex);
116
+ if (fabricIndices.length > 0) {
117
+ return limitEndpointAttributeDataToAllowedFabrics(agent.endpoint, fabricIndices);
118
+ }
119
+ }
120
+ }
108
121
  }
@@ -443,7 +443,7 @@ export class ServerSubscription implements Subscription {
443
443
  break;
444
444
  }
445
445
 
446
- this.#lastUpdateTime = Time.nowMs;
446
+ this.#lastUpdateTime = Time.nowMs; // TODO Count time from here or from "receive of the ack"?
447
447
 
448
448
  try {
449
449
  using sending = updating?.join("sending");