@matter/node 0.16.0-alpha.0-20251205-dfb1e1556 → 0.16.0-alpha.0-20251209-d6072d23e

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 (366) hide show
  1. package/dist/cjs/behavior/Behavior.d.ts +5 -1
  2. package/dist/cjs/behavior/Behavior.d.ts.map +1 -1
  3. package/dist/cjs/behavior/Behavior.js +15 -5
  4. package/dist/cjs/behavior/Behavior.js.map +1 -1
  5. package/dist/cjs/behavior/Events.d.ts +7 -7
  6. package/dist/cjs/behavior/Events.d.ts.map +1 -1
  7. package/dist/cjs/behavior/Events.js +1 -1
  8. package/dist/cjs/behavior/Events.js.map +1 -1
  9. package/dist/cjs/behavior/Transitions.d.ts +2 -3
  10. package/dist/cjs/behavior/Transitions.d.ts.map +1 -1
  11. package/dist/cjs/behavior/Transitions.js +1 -2
  12. package/dist/cjs/behavior/Transitions.js.map +1 -1
  13. package/dist/cjs/behavior/cluster/ClusterBehaviorType.js +2 -2
  14. package/dist/cjs/behavior/cluster/ClusterBehaviorType.js.map +1 -1
  15. package/dist/cjs/behavior/cluster/ClusterEvents.d.ts +1 -1
  16. package/dist/cjs/behavior/cluster/ClusterEvents.d.ts.map +1 -1
  17. package/dist/cjs/behavior/cluster/cluster-behavior-utils.js +1 -1
  18. package/dist/cjs/behavior/cluster/cluster-behavior-utils.js.map +1 -1
  19. package/dist/cjs/behavior/context/Contextual.js +1 -1
  20. package/dist/cjs/behavior/context/Contextual.js.map +1 -1
  21. package/dist/cjs/behavior/context/NodeActivity.d.ts +2 -4
  22. package/dist/cjs/behavior/context/NodeActivity.d.ts.map +1 -1
  23. package/dist/cjs/behavior/context/NodeActivity.js +4 -11
  24. package/dist/cjs/behavior/context/NodeActivity.js.map +1 -1
  25. package/dist/cjs/behavior/context/server/LocalActorContext.d.ts +2 -3
  26. package/dist/cjs/behavior/context/server/LocalActorContext.d.ts.map +1 -1
  27. package/dist/cjs/behavior/context/server/LocalActorContext.js +3 -3
  28. package/dist/cjs/behavior/context/server/LocalActorContext.js.map +1 -1
  29. package/dist/cjs/behavior/context/server/RemoteActorContext.d.ts +2 -6
  30. package/dist/cjs/behavior/context/server/RemoteActorContext.d.ts.map +1 -1
  31. package/dist/cjs/behavior/context/server/RemoteActorContext.js +20 -22
  32. package/dist/cjs/behavior/context/server/RemoteActorContext.js.map +1 -1
  33. package/dist/cjs/behavior/internal/BackingEvents.js +2 -2
  34. package/dist/cjs/behavior/internal/BackingEvents.js.map +1 -1
  35. package/dist/cjs/behavior/internal/BehaviorBacking.d.ts +2 -1
  36. package/dist/cjs/behavior/internal/BehaviorBacking.d.ts.map +1 -1
  37. package/dist/cjs/behavior/internal/BehaviorBacking.js +3 -0
  38. package/dist/cjs/behavior/internal/BehaviorBacking.js.map +1 -1
  39. package/dist/cjs/behavior/internal/Reactors.d.ts.map +1 -1
  40. package/dist/cjs/behavior/internal/Reactors.js +2 -1
  41. package/dist/cjs/behavior/internal/Reactors.js.map +1 -1
  42. package/dist/cjs/behavior/state/managed/Datasource.d.ts.map +1 -1
  43. package/dist/cjs/behavior/state/managed/Datasource.js +1 -1
  44. package/dist/cjs/behavior/state/managed/Datasource.js.map +1 -1
  45. package/dist/cjs/behavior/state/managed/Internal.js +2 -2
  46. package/dist/cjs/behavior/state/managed/Internal.js.map +1 -1
  47. package/dist/cjs/behavior/state/managed/values/BitmapManager.js +1 -1
  48. package/dist/cjs/behavior/state/managed/values/BitmapManager.js.map +1 -1
  49. package/dist/cjs/behavior/state/managed/values/StructManager.js +1 -1
  50. package/dist/cjs/behavior/state/managed/values/StructManager.js.map +1 -1
  51. package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
  52. package/dist/cjs/behavior/system/commissioning/CommissioningClient.js +6 -12
  53. package/dist/cjs/behavior/system/commissioning/CommissioningClient.js.map +1 -1
  54. package/dist/cjs/behavior/system/commissioning/CommissioningServer.d.ts +3 -2
  55. package/dist/cjs/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  56. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js +3 -6
  57. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  58. package/dist/cjs/behavior/system/mqtt/MqttInterface.d.ts.map +1 -1
  59. package/dist/cjs/behavior/system/mqtt/MqttInterface.js +91 -30
  60. package/dist/cjs/behavior/system/mqtt/MqttInterface.js.map +1 -1
  61. package/dist/cjs/behavior/system/network/NetworkRuntime.d.ts.map +1 -1
  62. package/dist/cjs/behavior/system/network/NetworkRuntime.js +1 -3
  63. package/dist/cjs/behavior/system/network/NetworkRuntime.js.map +1 -1
  64. package/dist/cjs/behavior/system/network/ServerGroupNetworking.js +2 -2
  65. package/dist/cjs/behavior/system/network/ServerGroupNetworking.js.map +1 -1
  66. package/dist/cjs/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
  67. package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js +152 -13
  68. package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js.map +2 -2
  69. package/dist/cjs/behavior/system/remote/RemoteInterface.d.ts +3 -2
  70. package/dist/cjs/behavior/system/remote/RemoteInterface.d.ts.map +1 -1
  71. package/dist/cjs/behavior/system/remote/RemoteInterface.js +69 -10
  72. package/dist/cjs/behavior/system/remote/RemoteInterface.js.map +1 -1
  73. package/dist/cjs/behavior/system/remote/api/Api.d.ts.map +1 -1
  74. package/dist/cjs/behavior/system/remote/api/Api.js +4 -3
  75. package/dist/cjs/behavior/system/remote/api/Api.js.map +1 -1
  76. package/dist/cjs/behavior/system/sessions/SessionsBehavior.js +2 -2
  77. package/dist/cjs/behavior/system/sessions/SessionsBehavior.js.map +1 -1
  78. package/dist/cjs/behavior/system/subscriptions/SubscriptionsServer.d.ts.map +1 -1
  79. package/dist/cjs/behavior/system/subscriptions/SubscriptionsServer.js +14 -11
  80. package/dist/cjs/behavior/system/subscriptions/SubscriptionsServer.js.map +1 -1
  81. package/dist/cjs/behavior/system/websocket/WebSocketInterface.d.ts.map +1 -1
  82. package/dist/cjs/behavior/system/websocket/WebSocketInterface.js +12 -4
  83. package/dist/cjs/behavior/system/websocket/WebSocketInterface.js.map +1 -1
  84. package/dist/cjs/behaviors/access-control/AccessControlServer.js +1 -1
  85. package/dist/cjs/behaviors/access-control/AccessControlServer.js.map +1 -1
  86. package/dist/cjs/behaviors/administrator-commissioning/AdministratorCommissioningServer.d.ts.map +1 -1
  87. package/dist/cjs/behaviors/administrator-commissioning/AdministratorCommissioningServer.js +65 -7
  88. package/dist/cjs/behaviors/administrator-commissioning/AdministratorCommissioningServer.js.map +1 -1
  89. package/dist/cjs/behaviors/basic-information/BasicInformationServer.js +2 -2
  90. package/dist/cjs/behaviors/basic-information/BasicInformationServer.js.map +1 -1
  91. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.d.ts.map +1 -1
  92. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js +12 -8
  93. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
  94. package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts +2 -3
  95. package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
  96. package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.js +2 -10
  97. package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.js.map +1 -1
  98. package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.js +2 -2
  99. package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.js.map +1 -1
  100. package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.js +1 -1
  101. package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.js.map +1 -1
  102. package/dist/cjs/behaviors/operational-credentials/OperationalCredentialsServer.d.ts +0 -1
  103. package/dist/cjs/behaviors/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
  104. package/dist/cjs/behaviors/operational-credentials/OperationalCredentialsServer.js +15 -14
  105. package/dist/cjs/behaviors/operational-credentials/OperationalCredentialsServer.js.map +1 -1
  106. package/dist/cjs/behaviors/scenes-management/ScenesManagementServer.js +2 -2
  107. package/dist/cjs/behaviors/scenes-management/ScenesManagementServer.js.map +1 -1
  108. package/dist/cjs/behaviors/thermostat/AtomicWriteHandler.js +1 -1
  109. package/dist/cjs/behaviors/thermostat/AtomicWriteHandler.js.map +1 -1
  110. package/dist/cjs/behaviors/window-covering/WindowCoveringServer.d.ts.map +1 -1
  111. package/dist/cjs/behaviors/window-covering/WindowCoveringServer.js +21 -8
  112. package/dist/cjs/behaviors/window-covering/WindowCoveringServer.js.map +1 -1
  113. package/dist/cjs/endpoint/Agent.js +1 -1
  114. package/dist/cjs/endpoint/Agent.js.map +1 -1
  115. package/dist/cjs/endpoint/Endpoint.d.ts +2 -1
  116. package/dist/cjs/endpoint/Endpoint.d.ts.map +1 -1
  117. package/dist/cjs/endpoint/Endpoint.js +95 -8
  118. package/dist/cjs/endpoint/Endpoint.js.map +2 -2
  119. package/dist/cjs/endpoint/properties/Behaviors.d.ts.map +1 -1
  120. package/dist/cjs/endpoint/properties/Behaviors.js +11 -7
  121. package/dist/cjs/endpoint/properties/Behaviors.js.map +1 -1
  122. package/dist/cjs/endpoint/properties/Commands.js +1 -1
  123. package/dist/cjs/endpoint/properties/Commands.js.map +1 -1
  124. package/dist/cjs/endpoint/properties/EndpointLifecycle.d.ts.map +1 -1
  125. package/dist/cjs/endpoint/properties/EndpointLifecycle.js +3 -0
  126. package/dist/cjs/endpoint/properties/EndpointLifecycle.js.map +1 -1
  127. package/dist/cjs/node/ClientNode.d.ts.map +1 -1
  128. package/dist/cjs/node/ClientNode.js +2 -0
  129. package/dist/cjs/node/ClientNode.js.map +1 -1
  130. package/dist/cjs/node/Node.d.ts +2 -2
  131. package/dist/cjs/node/Node.d.ts.map +1 -1
  132. package/dist/cjs/node/Node.js +3 -2
  133. package/dist/cjs/node/Node.js.map +1 -1
  134. package/dist/cjs/node/ServerNode.d.ts.map +1 -1
  135. package/dist/cjs/node/ServerNode.js +54 -1
  136. package/dist/cjs/node/ServerNode.js.map +1 -1
  137. package/dist/cjs/node/client/ClientCommandMethod.d.ts.map +1 -1
  138. package/dist/cjs/node/client/ClientCommandMethod.js +26 -29
  139. package/dist/cjs/node/client/ClientCommandMethod.js.map +1 -1
  140. package/dist/cjs/node/client/NodePeerAddressStore.d.ts +3 -3
  141. package/dist/cjs/node/client/NodePeerAddressStore.d.ts.map +1 -1
  142. package/dist/cjs/node/client/NodePeerAddressStore.js.map +1 -1
  143. package/dist/cjs/node/client/PeerBehavior.js +1 -1
  144. package/dist/cjs/node/client/PeerBehavior.js.map +1 -1
  145. package/dist/cjs/node/client/Peers.d.ts.map +1 -1
  146. package/dist/cjs/node/client/Peers.js +14 -0
  147. package/dist/cjs/node/client/Peers.js.map +1 -1
  148. package/dist/cjs/node/integration/ProtocolService.d.ts.map +1 -1
  149. package/dist/cjs/node/integration/ProtocolService.js +3 -2
  150. package/dist/cjs/node/integration/ProtocolService.js.map +1 -1
  151. package/dist/cjs/node/server/InteractionServer.d.ts.map +1 -1
  152. package/dist/cjs/node/server/InteractionServer.js +55 -50
  153. package/dist/cjs/node/server/InteractionServer.js.map +2 -2
  154. package/dist/cjs/node/server/ServerEnvironment.js +1 -1
  155. package/dist/cjs/node/server/ServerEnvironment.js.map +1 -1
  156. package/dist/cjs/node/server/ServerSubscription.d.ts +61 -10
  157. package/dist/cjs/node/server/ServerSubscription.d.ts.map +1 -1
  158. package/dist/cjs/node/server/ServerSubscription.js +316 -157
  159. package/dist/cjs/node/server/ServerSubscription.js.map +2 -2
  160. package/dist/esm/behavior/Behavior.d.ts +5 -1
  161. package/dist/esm/behavior/Behavior.d.ts.map +1 -1
  162. package/dist/esm/behavior/Behavior.js +15 -5
  163. package/dist/esm/behavior/Behavior.js.map +1 -1
  164. package/dist/esm/behavior/Events.d.ts +7 -7
  165. package/dist/esm/behavior/Events.d.ts.map +1 -1
  166. package/dist/esm/behavior/Events.js +1 -1
  167. package/dist/esm/behavior/Events.js.map +1 -1
  168. package/dist/esm/behavior/Transitions.d.ts +2 -3
  169. package/dist/esm/behavior/Transitions.d.ts.map +1 -1
  170. package/dist/esm/behavior/Transitions.js +1 -2
  171. package/dist/esm/behavior/Transitions.js.map +1 -1
  172. package/dist/esm/behavior/cluster/ClusterBehaviorType.js +2 -2
  173. package/dist/esm/behavior/cluster/ClusterBehaviorType.js.map +1 -1
  174. package/dist/esm/behavior/cluster/ClusterEvents.d.ts +1 -1
  175. package/dist/esm/behavior/cluster/ClusterEvents.d.ts.map +1 -1
  176. package/dist/esm/behavior/cluster/cluster-behavior-utils.js +1 -1
  177. package/dist/esm/behavior/cluster/cluster-behavior-utils.js.map +1 -1
  178. package/dist/esm/behavior/context/Contextual.js +1 -1
  179. package/dist/esm/behavior/context/Contextual.js.map +1 -1
  180. package/dist/esm/behavior/context/NodeActivity.d.ts +2 -4
  181. package/dist/esm/behavior/context/NodeActivity.d.ts.map +1 -1
  182. package/dist/esm/behavior/context/NodeActivity.js +5 -12
  183. package/dist/esm/behavior/context/NodeActivity.js.map +1 -1
  184. package/dist/esm/behavior/context/server/LocalActorContext.d.ts +2 -3
  185. package/dist/esm/behavior/context/server/LocalActorContext.d.ts.map +1 -1
  186. package/dist/esm/behavior/context/server/LocalActorContext.js +5 -5
  187. package/dist/esm/behavior/context/server/LocalActorContext.js.map +1 -1
  188. package/dist/esm/behavior/context/server/RemoteActorContext.d.ts +2 -6
  189. package/dist/esm/behavior/context/server/RemoteActorContext.d.ts.map +1 -1
  190. package/dist/esm/behavior/context/server/RemoteActorContext.js +27 -24
  191. package/dist/esm/behavior/context/server/RemoteActorContext.js.map +1 -1
  192. package/dist/esm/behavior/internal/BackingEvents.js +2 -2
  193. package/dist/esm/behavior/internal/BackingEvents.js.map +1 -1
  194. package/dist/esm/behavior/internal/BehaviorBacking.d.ts +2 -1
  195. package/dist/esm/behavior/internal/BehaviorBacking.d.ts.map +1 -1
  196. package/dist/esm/behavior/internal/BehaviorBacking.js +4 -0
  197. package/dist/esm/behavior/internal/BehaviorBacking.js.map +1 -1
  198. package/dist/esm/behavior/internal/Reactors.d.ts.map +1 -1
  199. package/dist/esm/behavior/internal/Reactors.js +2 -1
  200. package/dist/esm/behavior/internal/Reactors.js.map +1 -1
  201. package/dist/esm/behavior/state/managed/Datasource.d.ts.map +1 -1
  202. package/dist/esm/behavior/state/managed/Datasource.js +2 -1
  203. package/dist/esm/behavior/state/managed/Datasource.js.map +1 -1
  204. package/dist/esm/behavior/state/managed/Internal.js +2 -2
  205. package/dist/esm/behavior/state/managed/Internal.js.map +1 -1
  206. package/dist/esm/behavior/state/managed/values/BitmapManager.js +1 -1
  207. package/dist/esm/behavior/state/managed/values/BitmapManager.js.map +1 -1
  208. package/dist/esm/behavior/state/managed/values/StructManager.js +1 -1
  209. package/dist/esm/behavior/state/managed/values/StructManager.js.map +1 -1
  210. package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
  211. package/dist/esm/behavior/system/commissioning/CommissioningClient.js +7 -14
  212. package/dist/esm/behavior/system/commissioning/CommissioningClient.js.map +1 -1
  213. package/dist/esm/behavior/system/commissioning/CommissioningServer.d.ts +3 -2
  214. package/dist/esm/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  215. package/dist/esm/behavior/system/commissioning/CommissioningServer.js +3 -7
  216. package/dist/esm/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  217. package/dist/esm/behavior/system/mqtt/MqttInterface.d.ts.map +1 -1
  218. package/dist/esm/behavior/system/mqtt/MqttInterface.js +91 -30
  219. package/dist/esm/behavior/system/mqtt/MqttInterface.js.map +1 -1
  220. package/dist/esm/behavior/system/network/NetworkRuntime.d.ts.map +1 -1
  221. package/dist/esm/behavior/system/network/NetworkRuntime.js +1 -3
  222. package/dist/esm/behavior/system/network/NetworkRuntime.js.map +1 -1
  223. package/dist/esm/behavior/system/network/ServerGroupNetworking.js +2 -2
  224. package/dist/esm/behavior/system/network/ServerGroupNetworking.js.map +1 -1
  225. package/dist/esm/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
  226. package/dist/esm/behavior/system/network/ServerNetworkRuntime.js +152 -14
  227. package/dist/esm/behavior/system/network/ServerNetworkRuntime.js.map +2 -2
  228. package/dist/esm/behavior/system/remote/RemoteInterface.d.ts +3 -2
  229. package/dist/esm/behavior/system/remote/RemoteInterface.d.ts.map +1 -1
  230. package/dist/esm/behavior/system/remote/RemoteInterface.js +76 -11
  231. package/dist/esm/behavior/system/remote/RemoteInterface.js.map +1 -1
  232. package/dist/esm/behavior/system/remote/api/Api.d.ts.map +1 -1
  233. package/dist/esm/behavior/system/remote/api/Api.js +4 -3
  234. package/dist/esm/behavior/system/remote/api/Api.js.map +1 -1
  235. package/dist/esm/behavior/system/sessions/SessionsBehavior.js +2 -2
  236. package/dist/esm/behavior/system/sessions/SessionsBehavior.js.map +1 -1
  237. package/dist/esm/behavior/system/subscriptions/SubscriptionsServer.d.ts.map +1 -1
  238. package/dist/esm/behavior/system/subscriptions/SubscriptionsServer.js +17 -14
  239. package/dist/esm/behavior/system/subscriptions/SubscriptionsServer.js.map +1 -1
  240. package/dist/esm/behavior/system/websocket/WebSocketInterface.d.ts.map +1 -1
  241. package/dist/esm/behavior/system/websocket/WebSocketInterface.js +12 -4
  242. package/dist/esm/behavior/system/websocket/WebSocketInterface.js.map +1 -1
  243. package/dist/esm/behaviors/access-control/AccessControlServer.js +1 -1
  244. package/dist/esm/behaviors/access-control/AccessControlServer.js.map +1 -1
  245. package/dist/esm/behaviors/administrator-commissioning/AdministratorCommissioningServer.d.ts.map +1 -1
  246. package/dist/esm/behaviors/administrator-commissioning/AdministratorCommissioningServer.js +66 -8
  247. package/dist/esm/behaviors/administrator-commissioning/AdministratorCommissioningServer.js.map +1 -1
  248. package/dist/esm/behaviors/basic-information/BasicInformationServer.js +2 -2
  249. package/dist/esm/behaviors/basic-information/BasicInformationServer.js.map +1 -1
  250. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.d.ts.map +1 -1
  251. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js +13 -9
  252. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
  253. package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts +2 -3
  254. package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
  255. package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.js +2 -10
  256. package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.js.map +1 -1
  257. package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.js +2 -2
  258. package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.js.map +1 -1
  259. package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.js +1 -1
  260. package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.js.map +1 -1
  261. package/dist/esm/behaviors/operational-credentials/OperationalCredentialsServer.d.ts +0 -1
  262. package/dist/esm/behaviors/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
  263. package/dist/esm/behaviors/operational-credentials/OperationalCredentialsServer.js +15 -15
  264. package/dist/esm/behaviors/operational-credentials/OperationalCredentialsServer.js.map +1 -1
  265. package/dist/esm/behaviors/scenes-management/ScenesManagementServer.js +2 -2
  266. package/dist/esm/behaviors/scenes-management/ScenesManagementServer.js.map +1 -1
  267. package/dist/esm/behaviors/thermostat/AtomicWriteHandler.js +1 -1
  268. package/dist/esm/behaviors/thermostat/AtomicWriteHandler.js.map +1 -1
  269. package/dist/esm/behaviors/window-covering/WindowCoveringServer.d.ts.map +1 -1
  270. package/dist/esm/behaviors/window-covering/WindowCoveringServer.js +22 -9
  271. package/dist/esm/behaviors/window-covering/WindowCoveringServer.js.map +1 -1
  272. package/dist/esm/endpoint/Agent.js +1 -1
  273. package/dist/esm/endpoint/Agent.js.map +1 -1
  274. package/dist/esm/endpoint/Endpoint.d.ts +2 -1
  275. package/dist/esm/endpoint/Endpoint.d.ts.map +1 -1
  276. package/dist/esm/endpoint/Endpoint.js +96 -8
  277. package/dist/esm/endpoint/Endpoint.js.map +2 -2
  278. package/dist/esm/endpoint/properties/Behaviors.d.ts.map +1 -1
  279. package/dist/esm/endpoint/properties/Behaviors.js +11 -7
  280. package/dist/esm/endpoint/properties/Behaviors.js.map +1 -1
  281. package/dist/esm/endpoint/properties/Commands.js +1 -1
  282. package/dist/esm/endpoint/properties/Commands.js.map +1 -1
  283. package/dist/esm/endpoint/properties/EndpointLifecycle.d.ts.map +1 -1
  284. package/dist/esm/endpoint/properties/EndpointLifecycle.js +3 -0
  285. package/dist/esm/endpoint/properties/EndpointLifecycle.js.map +1 -1
  286. package/dist/esm/node/ClientNode.d.ts.map +1 -1
  287. package/dist/esm/node/ClientNode.js +2 -0
  288. package/dist/esm/node/ClientNode.js.map +1 -1
  289. package/dist/esm/node/Node.d.ts +2 -2
  290. package/dist/esm/node/Node.d.ts.map +1 -1
  291. package/dist/esm/node/Node.js +5 -4
  292. package/dist/esm/node/Node.js.map +1 -1
  293. package/dist/esm/node/ServerNode.d.ts.map +1 -1
  294. package/dist/esm/node/ServerNode.js +54 -1
  295. package/dist/esm/node/ServerNode.js.map +1 -1
  296. package/dist/esm/node/client/ClientCommandMethod.d.ts.map +1 -1
  297. package/dist/esm/node/client/ClientCommandMethod.js +26 -29
  298. package/dist/esm/node/client/ClientCommandMethod.js.map +1 -1
  299. package/dist/esm/node/client/NodePeerAddressStore.d.ts +3 -3
  300. package/dist/esm/node/client/NodePeerAddressStore.d.ts.map +1 -1
  301. package/dist/esm/node/client/NodePeerAddressStore.js.map +1 -1
  302. package/dist/esm/node/client/PeerBehavior.js +1 -1
  303. package/dist/esm/node/client/PeerBehavior.js.map +1 -1
  304. package/dist/esm/node/client/Peers.d.ts.map +1 -1
  305. package/dist/esm/node/client/Peers.js +15 -1
  306. package/dist/esm/node/client/Peers.js.map +1 -1
  307. package/dist/esm/node/integration/ProtocolService.d.ts.map +1 -1
  308. package/dist/esm/node/integration/ProtocolService.js +4 -2
  309. package/dist/esm/node/integration/ProtocolService.js.map +1 -1
  310. package/dist/esm/node/server/InteractionServer.d.ts.map +1 -1
  311. package/dist/esm/node/server/InteractionServer.js +59 -51
  312. package/dist/esm/node/server/InteractionServer.js.map +2 -2
  313. package/dist/esm/node/server/ServerEnvironment.js +1 -1
  314. package/dist/esm/node/server/ServerEnvironment.js.map +1 -1
  315. package/dist/esm/node/server/ServerSubscription.d.ts +61 -10
  316. package/dist/esm/node/server/ServerSubscription.d.ts.map +1 -1
  317. package/dist/esm/node/server/ServerSubscription.js +321 -159
  318. package/dist/esm/node/server/ServerSubscription.js.map +2 -2
  319. package/package.json +7 -7
  320. package/src/behavior/Behavior.ts +12 -0
  321. package/src/behavior/Events.ts +12 -8
  322. package/src/behavior/Transitions.ts +3 -3
  323. package/src/behavior/cluster/ClusterBehaviorType.ts +2 -2
  324. package/src/behavior/cluster/ClusterEvents.ts +1 -1
  325. package/src/behavior/context/NodeActivity.ts +4 -13
  326. package/src/behavior/context/server/LocalActorContext.ts +6 -8
  327. package/src/behavior/context/server/RemoteActorContext.ts +34 -33
  328. package/src/behavior/internal/BehaviorBacking.ts +5 -0
  329. package/src/behavior/internal/Reactors.ts +1 -0
  330. package/src/behavior/state/managed/Datasource.ts +2 -1
  331. package/src/behavior/system/commissioning/CommissioningClient.ts +6 -13
  332. package/src/behavior/system/commissioning/CommissioningServer.ts +6 -8
  333. package/src/behavior/system/mqtt/MqttInterface.ts +6 -2
  334. package/src/behavior/system/network/NetworkRuntime.ts +1 -3
  335. package/src/behavior/system/network/ServerGroupNetworking.ts +2 -2
  336. package/src/behavior/system/network/ServerNetworkRuntime.ts +49 -15
  337. package/src/behavior/system/remote/RemoteInterface.ts +22 -4
  338. package/src/behavior/system/remote/api/Api.ts +4 -3
  339. package/src/behavior/system/sessions/SessionsBehavior.ts +2 -2
  340. package/src/behavior/system/subscriptions/SubscriptionsServer.ts +15 -13
  341. package/src/behavior/system/websocket/WebSocketInterface.ts +2 -1
  342. package/src/behaviors/access-control/AccessControlServer.ts +1 -1
  343. package/src/behaviors/administrator-commissioning/AdministratorCommissioningServer.ts +14 -7
  344. package/src/behaviors/basic-information/BasicInformationServer.ts +2 -2
  345. package/src/behaviors/general-commissioning/GeneralCommissioningServer.ts +14 -9
  346. package/src/behaviors/general-commissioning/ServerNodeFailsafeContext.ts +3 -15
  347. package/src/behaviors/general-diagnostics/GeneralDiagnosticsServer.ts +1 -1
  348. package/src/behaviors/group-key-management/GroupKeyManagementServer.ts +1 -1
  349. package/src/behaviors/operational-credentials/OperationalCredentialsServer.ts +22 -19
  350. package/src/behaviors/scenes-management/ScenesManagementServer.ts +1 -1
  351. package/src/behaviors/thermostat/AtomicWriteHandler.ts +1 -1
  352. package/src/behaviors/window-covering/WindowCoveringServer.ts +24 -9
  353. package/src/endpoint/Endpoint.ts +21 -4
  354. package/src/endpoint/properties/Behaviors.ts +11 -6
  355. package/src/endpoint/properties/Commands.ts +1 -1
  356. package/src/endpoint/properties/EndpointLifecycle.ts +4 -0
  357. package/src/node/ClientNode.ts +3 -0
  358. package/src/node/Node.ts +3 -2
  359. package/src/node/ServerNode.ts +1 -0
  360. package/src/node/client/ClientCommandMethod.ts +31 -38
  361. package/src/node/client/NodePeerAddressStore.ts +3 -3
  362. package/src/node/client/Peers.ts +19 -1
  363. package/src/node/integration/ProtocolService.ts +4 -2
  364. package/src/node/server/InteractionServer.ts +62 -51
  365. package/src/node/server/ServerEnvironment.ts +1 -1
  366. package/src/node/server/ServerSubscription.ts +225 -153
@@ -7,8 +7,13 @@
7
7
  import { NodeActivity } from "#behavior/context/NodeActivity.js";
8
8
  import { RemoteActorContext } from "#behavior/context/server/RemoteActorContext.js";
9
9
  import {
10
+ AsyncObservable,
11
+ Diagnostic,
10
12
  Duration,
13
+ hex,
11
14
  Hours,
15
+ InternalError,
16
+ Lifetime,
12
17
  Logger,
13
18
  MatterError,
14
19
  Millis,
@@ -23,19 +28,18 @@ import {
23
28
  } from "#general";
24
29
  import { Specification } from "#model";
25
30
  import type { ServerNode } from "#node/ServerNode.js";
26
- import type { DirtyState, Message, MessageExchange, NodeSession } from "#protocol";
31
+ import type { DirtyState, MessageExchange, NodeSession, Session, SubscriptionId } from "#protocol";
27
32
  import {
28
33
  AttributeReadResponse,
29
34
  AttributeSubscriptionResponse,
30
35
  EventReadResponse,
31
36
  InteractionServerMessenger,
32
- NoChannelError,
33
37
  NumberedOccurrence,
34
38
  PeerAddress,
35
39
  Read,
36
40
  ReadResult,
41
+ SessionClosedError,
37
42
  Subscription,
38
- SubscriptionCriteria,
39
43
  } from "#protocol";
40
44
  import {
41
45
  AttributeId,
@@ -45,6 +49,7 @@ import {
45
49
  INTERACTION_PROTOCOL_ID,
46
50
  StatusCode,
47
51
  StatusResponseError,
52
+ SubscribeRequest,
48
53
  } from "#types";
49
54
 
50
55
  const logger = Logger.get("ServerSubscription");
@@ -108,22 +113,29 @@ export namespace ServerSubscriptionConfig {
108
113
  * Interface between {@link ServerSubscription} and the local Matter environment.
109
114
  */
110
115
  export interface ServerSubscriptionContext {
116
+ // TODO - remove this. Subscriptions are associated with a peer, not a session
111
117
  session: NodeSession;
112
118
  node: ServerNode;
113
- initiateExchange(address: PeerAddress, protocolId: number): MessageExchange;
119
+ initiateExchange(addressOrSession: PeerAddress | Session, protocolId: number): MessageExchange;
114
120
  }
115
121
 
116
122
  /**
117
123
  * Implements the server side of a single subscription.
118
124
  */
119
- export class ServerSubscription extends Subscription {
125
+ export class ServerSubscription implements Subscription {
126
+ #lifetime?: Lifetime;
120
127
  readonly #context: ServerSubscriptionContext;
121
128
 
129
+ #id: SubscriptionId;
130
+ #isClosed = false;
131
+ #isCanceledByPeer = false;
132
+ #request: Omit<SubscribeRequest, "interactionModelRevision" | "keepSubscriptions">;
133
+ #cancelled = AsyncObservable<[subscription: Subscription]>();
134
+ #maxInterval?: Duration;
135
+
122
136
  #lastUpdateTime = Timestamp.zero;
123
137
  #updateTimer: Timer;
124
- readonly #sendDelayTimer: Timer = Time.getTimer(`Subscription ${this.id} delay`, Millis(50), () =>
125
- this.#triggerSendUpdate(),
126
- );
138
+ readonly #sendDelayTimer: Timer;
127
139
  #outstandingAttributeUpdates?: DirtyState.ForNode;
128
140
  #outstandingEventsMinNumber?: EventNumber;
129
141
  readonly #changeHandlers = new ObserverGroup();
@@ -132,8 +144,6 @@ export class ServerSubscription extends Subscription {
132
144
  #seededClusterDetails? = new Map<string, number>();
133
145
  #latestSeededEventNumber? = EventNumber(0);
134
146
  readonly #sendInterval: Duration;
135
- readonly #minIntervalFloor: Duration;
136
- readonly #maxIntervalCeiling: Duration;
137
147
  readonly #peerAddress: PeerAddress;
138
148
 
139
149
  #sendNextUpdateImmediately = false;
@@ -143,30 +153,19 @@ export class ServerSubscription extends Subscription {
143
153
  constructor(options: {
144
154
  id: number;
145
155
  context: ServerSubscriptionContext;
146
- criteria: SubscriptionCriteria;
147
- minIntervalFloor: Duration;
148
- maxIntervalCeiling: Duration;
156
+ request: Omit<SubscribeRequest, "interactionModelRevision" | "keepSubscriptions">;
149
157
  subscriptionOptions: ServerSubscriptionConfig;
150
158
  useAsMaxInterval?: Duration;
151
159
  useAsSendInterval?: Duration;
152
160
  }) {
153
- const {
154
- id,
155
- context,
156
- criteria,
157
- minIntervalFloor,
158
- maxIntervalCeiling,
159
- subscriptionOptions,
160
- useAsMaxInterval,
161
- useAsSendInterval,
162
- } = options;
163
-
164
- super(context.session, id, criteria);
161
+ const { id, context, request, subscriptionOptions, useAsMaxInterval, useAsSendInterval } = options;
162
+
163
+ this.#id = id;
164
+ this.#request = request;
165
+
165
166
  this.#context = context;
166
167
 
167
168
  this.#peerAddress = this.session.peerAddress;
168
- this.#minIntervalFloor = minIntervalFloor;
169
- this.#maxIntervalCeiling = maxIntervalCeiling;
170
169
 
171
170
  let maxInterval: Duration;
172
171
  let sendInterval: Duration;
@@ -183,9 +182,68 @@ export class ServerSubscription extends Subscription {
183
182
  this.maxInterval = maxInterval;
184
183
  this.#sendInterval = sendInterval;
185
184
 
186
- this.#updateTimer = Time.getTimer(`Subscription ${this.id} update`, this.#sendInterval, () =>
185
+ // These start later as needed
186
+ this.#sendDelayTimer = Time.getTimer(`Subscription ${this.idStr} delay`, Millis(50), () =>
187
+ this.#triggerSendUpdate(),
188
+ );
189
+ this.#updateTimer = Time.getTimer(`Subscription ${this.idStr} update`, this.#sendInterval, () =>
187
190
  this.#prepareDataUpdate(),
188
- ); // will be started later
191
+ );
192
+ }
193
+
194
+ get subscriptionId() {
195
+ return this.#id;
196
+ }
197
+
198
+ get idStr() {
199
+ return hex.fixed(this.#id, 8);
200
+ }
201
+
202
+ get session() {
203
+ return this.#context.session;
204
+ }
205
+
206
+ get isCanceledByPeer() {
207
+ return this.#isCanceledByPeer;
208
+ }
209
+
210
+ get request() {
211
+ return this.#request;
212
+ }
213
+
214
+ get cancelled() {
215
+ return this.#cancelled;
216
+ }
217
+
218
+ get maxInterval() {
219
+ if (this.#maxInterval === undefined) {
220
+ throw new InternalError("Subscription maxInterval accessed before it was set");
221
+ }
222
+ return this.#maxInterval;
223
+ }
224
+
225
+ get sendInterval() {
226
+ return this.#sendInterval;
227
+ }
228
+
229
+ get minIntervalFloor() {
230
+ return Seconds(this.request.minIntervalFloorSeconds);
231
+ }
232
+
233
+ get maxIntervalCeiling() {
234
+ return Seconds(this.request.maxIntervalCeilingSeconds);
235
+ }
236
+
237
+ set maxInterval(value: Duration) {
238
+ if (this.#maxInterval !== undefined) {
239
+ throw new InternalError("Subscription maxInterval set twice");
240
+ }
241
+ this.#maxInterval = value;
242
+ }
243
+
244
+ async handlePeerCancel() {
245
+ this.#isCanceledByPeer = true;
246
+ await this.close();
189
247
  }
190
248
 
191
249
  #determineSendingIntervals(
@@ -204,8 +262,8 @@ export class ServerSubscription extends Subscription {
204
262
  Duration.max(
205
263
  subscriptionMinInterval,
206
264
  Duration.max(
207
- this.#minIntervalFloor,
208
- Duration.min(subscriptionMaxInterval, this.#maxIntervalCeiling),
265
+ this.minIntervalFloor,
266
+ Duration.min(subscriptionMaxInterval, this.maxIntervalCeiling),
209
267
  ),
210
268
  ) +
211
269
  subscriptionRandomizationWindow * Math.random(),
@@ -218,7 +276,7 @@ export class ServerSubscription extends Subscription {
218
276
  // But if we have no chance of at least one full resubmission process we do like chip-tool.
219
277
  // One full resubmission process takes 33-45 seconds. So 60s means we reach at least first 2 retries of a
220
278
  // second subscription report after first failed.
221
- sendInterval = Duration.max(this.#minIntervalFloor, Millis.floor(Millis(maxInterval * 0.8)));
279
+ sendInterval = Duration.max(this.minIntervalFloor, Millis.floor(Millis(maxInterval * 0.8)));
222
280
  }
223
281
  if (sendInterval < subscriptionMinInterval) {
224
282
  // But not faster than once every 2s
@@ -249,7 +307,7 @@ export class ServerSubscription extends Subscription {
249
307
  changedAttrs: AttributeId[],
250
308
  version: number,
251
309
  ) {
252
- if (this.isClosed || !changedAttrs.length) {
310
+ if (this.#isClosed || !changedAttrs.length) {
253
311
  return;
254
312
  }
255
313
 
@@ -268,7 +326,7 @@ export class ServerSubscription extends Subscription {
268
326
  }
269
327
 
270
328
  #handleAddedEvents(occurrence: NumberedOccurrence) {
271
- if (this.isClosed) {
329
+ if (this.#isClosed) {
272
330
  return;
273
331
  }
274
332
 
@@ -284,7 +342,7 @@ export class ServerSubscription extends Subscription {
284
342
  }
285
343
 
286
344
  #sendEventUrgently({ endpointId, clusterId, eventId }: ReadResult.ConcreteEventPath): boolean {
287
- return (this.criteria.eventRequests ?? []).some(
345
+ return (this.request.eventRequests ?? []).some(
288
346
  ({ endpointId: reqEndpointId, clusterId: reqClusterId, eventId: reqEventId, isUrgent }) =>
289
347
  isUrgent &&
290
348
  (reqEndpointId === undefined || reqEndpointId === endpointId) &&
@@ -293,24 +351,14 @@ export class ServerSubscription extends Subscription {
293
351
  );
294
352
  }
295
353
 
296
- get sendInterval() {
297
- return this.#sendInterval;
298
- }
299
-
300
- get minIntervalFloor() {
301
- return this.#minIntervalFloor;
302
- }
303
-
304
- get maxIntervalCeiling() {
305
- return this.#maxIntervalCeiling;
306
- }
307
-
308
- override activate() {
309
- super.activate();
354
+ activate() {
355
+ this.session.subscriptions.add(this);
356
+ logger.debug(this.session.via, "New subscription", Diagnostic.strong(this.idStr));
357
+ this.#lifetime = this.#context.session.join("subscription", Diagnostic.strong(this.#id));
310
358
 
311
359
  // We do not need these data anymore, so we can free some memory
312
- if (this.criteria.eventFilters !== undefined) this.criteria.eventFilters.length = 0;
313
- if (this.criteria.dataVersionFilters !== undefined) this.criteria.dataVersionFilters.length = 0;
360
+ if (this.request.eventFilters !== undefined) this.request.eventFilters.length = 0;
361
+ if (this.request.dataVersionFilters !== undefined) this.request.dataVersionFilters.length = 0;
314
362
 
315
363
  this.#sendUpdatesActivated = true;
316
364
 
@@ -338,7 +386,7 @@ export class ServerSubscription extends Subscription {
338
386
  * sending by 50ms in any case to make sure to catch all updates.
339
387
  */
340
388
  #prepareDataUpdate() {
341
- if (this.#sendDelayTimer.isRunning || this.isClosed) {
389
+ if (this.#sendDelayTimer.isRunning || this.#isClosed) {
342
390
  // sending data is already scheduled, data updates go in there ... or we close down already
343
391
  return;
344
392
  }
@@ -350,29 +398,29 @@ export class ServerSubscription extends Subscription {
350
398
  this.#updateTimer.stop();
351
399
  const now = Time.nowMs;
352
400
  const timeSinceLastUpdate = Millis(now - this.#lastUpdateTime);
353
- if (timeSinceLastUpdate < this.#minIntervalFloor) {
401
+ if (timeSinceLastUpdate < this.minIntervalFloor) {
354
402
  // Respect minimum delay time between updates
355
403
  this.#updateTimer = Time.getTimer(
356
404
  "Subscription update",
357
- Millis(this.#minIntervalFloor - timeSinceLastUpdate),
405
+ Millis(this.minIntervalFloor - timeSinceLastUpdate),
358
406
  () => this.#prepareDataUpdate(),
359
407
  ).start();
360
408
  return;
361
409
  }
362
410
 
363
411
  this.#sendDelayTimer.start();
364
- this.#updateTimer = Time.getTimer(`Subscription update ${this.id}`, this.#sendInterval, () =>
412
+ this.#updateTimer = Time.getTimer(`Subscription update ${this.idStr}`, this.#sendInterval, () =>
365
413
  this.#prepareDataUpdate(),
366
414
  ).start();
367
415
  }
368
416
 
369
- #triggerSendUpdate(onlyWithData: boolean = false) {
417
+ #triggerSendUpdate(onlyWithData: boolean = false, session?: Session) {
370
418
  if (this.#currentUpdatePromise !== undefined) {
371
419
  logger.debug("Sending update already in progress, delaying update ...");
372
420
  this.#sendNextUpdateImmediately = true;
373
421
  return;
374
422
  }
375
- this.#currentUpdatePromise = this.#sendUpdate(onlyWithData)
423
+ this.#currentUpdatePromise = this.#sendUpdate(onlyWithData, session)
376
424
  .catch(error => logger.warn("Sending subscription update failed:", error))
377
425
  .finally(() => (this.#currentUpdatePromise = undefined));
378
426
  }
@@ -380,75 +428,85 @@ export class ServerSubscription extends Subscription {
380
428
  /**
381
429
  * Determine all attributes that have changed since the last update and send them out to the subscriber.
382
430
  */
383
- async #sendUpdate(onlyWithData = false) {
384
- // Get all outstanding updates, make sure the order is correct per endpoint and cluster
385
- const attributeFilter = this.#outstandingAttributeUpdates;
386
- this.#outstandingAttributeUpdates = undefined;
431
+ async #sendUpdate(onlyWithData = false, session?: Session) {
432
+ using updating = this.#lifetime?.join("updating");
387
433
 
388
- const eventsMinNumber = this.#outstandingEventsMinNumber;
389
- this.#outstandingEventsMinNumber = undefined;
390
-
391
- if (onlyWithData && attributeFilter === undefined && eventsMinNumber === undefined) {
392
- return;
393
- }
434
+ while (true) {
435
+ // Get all outstanding updates, make sure the order is correct per endpoint and cluster
436
+ const attributeFilter = this.#outstandingAttributeUpdates;
437
+ this.#outstandingAttributeUpdates = undefined;
394
438
 
395
- this.#lastUpdateTime = Time.nowMs;
439
+ const eventsMinNumber = this.#outstandingEventsMinNumber;
440
+ this.#outstandingEventsMinNumber = undefined;
396
441
 
397
- try {
398
- if (await this.#sendUpdateMessage(attributeFilter, eventsMinNumber, onlyWithData)) {
399
- this.#sendUpdateErrorCounter = 0;
400
- }
401
- } catch (error) {
402
- if (this.isClosed) {
403
- // No need to care about resubmissions when the server is closing
404
- return;
442
+ if (onlyWithData && attributeFilter === undefined && eventsMinNumber === undefined) {
443
+ break;
405
444
  }
406
445
 
407
- this.#sendUpdateErrorCounter++;
408
- logger.info(
409
- `Error sending subscription update message (error count=${this.#sendUpdateErrorCounter}):`,
410
- (error instanceof MatterError && error.message) || error,
411
- );
412
- if (this.#sendUpdateErrorCounter <= 2) {
413
- // fill the data back in the queue to resend with next try
414
- if (attributeFilter !== undefined) {
415
- for (const [endpointId, clusters] of Object.entries(attributeFilter)) {
416
- for (const [clusterId, attributes] of Object.entries(clusters)) {
417
- this.#addOutstandingAttributes(
418
- EndpointNumber(parseInt(endpointId)),
419
- ClusterId(parseInt(clusterId)),
420
- Array.from(attributes),
421
- );
422
- }
423
- }
446
+ this.#lastUpdateTime = Time.nowMs;
447
+
448
+ try {
449
+ using sending = updating?.join("sending");
450
+ if (await this.#sendUpdateMessage(sending, attributeFilter, eventsMinNumber, onlyWithData, session)) {
451
+ this.#sendUpdateErrorCounter = 0;
424
452
  }
425
- if (eventsMinNumber !== undefined) {
426
- this.#outstandingEventsMinNumber = eventsMinNumber; // newer number are always higher, so we can just set it
453
+ } catch (error) {
454
+ if (this.#isClosed) {
455
+ // No need to care about resubmissions when the server is closing
456
+ // TODO - implement proper abort so we don't need to ignore errors
457
+ return;
427
458
  }
428
- } else {
459
+
460
+ this.#sendUpdateErrorCounter++;
429
461
  logger.info(
430
- `Sending update failed 3 times in a row, canceling subscription ${this.id} and let controller subscribe again.`,
462
+ `Error sending subscription update message (error count=${this.#sendUpdateErrorCounter}):`,
463
+ (error instanceof MatterError && error.message) || error,
431
464
  );
432
- this.#sendNextUpdateImmediately = false;
433
- if (
434
- error instanceof NoResponseTimeoutError ||
435
- error instanceof NetworkError ||
436
- error instanceof NoChannelError
437
- ) {
438
- // Let's consider this subscription as dead and wait for a reconnect
439
- this.isCanceledByPeer = true; // We handle this case like if the controller canceled the subscription
440
- await this.destroy();
441
- return;
465
+ if (this.#sendUpdateErrorCounter <= 2) {
466
+ // fill the data back in the queue to resend with next try
467
+ if (attributeFilter !== undefined) {
468
+ for (const [endpointId, clusters] of Object.entries(attributeFilter)) {
469
+ for (const [clusterId, attributes] of Object.entries(clusters)) {
470
+ this.#addOutstandingAttributes(
471
+ EndpointNumber(parseInt(endpointId)),
472
+ ClusterId(parseInt(clusterId)),
473
+ Array.from(attributes),
474
+ );
475
+ }
476
+ }
477
+ }
478
+ if (eventsMinNumber !== undefined) {
479
+ this.#outstandingEventsMinNumber = eventsMinNumber; // newer number are always higher, so we can just set it
480
+ }
442
481
  } else {
443
- throw error;
482
+ logger.info(
483
+ `Sending update failed 3 times in a row, canceling subscription ${this.idStr} and let controller subscribe again.`,
484
+ );
485
+ this.#sendNextUpdateImmediately = false;
486
+ if (
487
+ error instanceof NoResponseTimeoutError ||
488
+ error instanceof NetworkError ||
489
+ error instanceof SessionClosedError
490
+ ) {
491
+ // Let's consider this subscription as dead and wait for a reconnect. We handle as if the
492
+ // controller cancelled
493
+ using _messaging = updating?.join("canceling");
494
+ this.#isCanceledByPeer = true;
495
+ await this.#cancel();
496
+ break;
497
+ } else {
498
+ throw error;
499
+ }
444
500
  }
445
501
  }
446
- }
447
502
 
448
- if (this.#sendNextUpdateImmediately) {
449
- logger.debug("Sending delayed update immediately after last one was sent.");
503
+ if (!this.#sendNextUpdateImmediately) {
504
+ break;
505
+ }
506
+
507
+ logger.debug("Sending delayed update immediately after last one was sent");
450
508
  this.#sendNextUpdateImmediately = false;
451
- await this.#sendUpdate(true); // Send but only if non-empty
509
+ onlyWithData = true; // In subsequent iterations only send if non-empty
452
510
  }
453
511
  }
454
512
 
@@ -457,7 +515,7 @@ export class ServerSubscription extends Subscription {
457
515
  */
458
516
  async *#processAttributesAndEventsReport(context: RemoteActorContext.Options, suppressStatusReports = false) {
459
517
  const request = {
460
- ...this.criteria,
518
+ ...this.request,
461
519
  interactionModelRevision: Specification.INTERACTION_MODEL_REVISION, // irrelevant here, set to our version
462
520
  };
463
521
 
@@ -558,68 +616,77 @@ export class ServerSubscription extends Subscription {
558
616
  this.#updateTimer.stop();
559
617
 
560
618
  // Register change handlers, so that we get changes directly
561
- if (this.criteria.attributeRequests?.length) {
619
+ if (this.request.attributeRequests?.length) {
562
620
  this.#changeHandlers.on(
563
621
  this.#context.node.protocol.attrsChanged,
564
622
  this.#handleClusterStateChanges.bind(this),
565
623
  );
566
624
  }
567
- if (this.criteria.eventRequests?.length) {
625
+ if (this.request.eventRequests?.length) {
568
626
  this.#changeHandlers.on(this.#context.node.protocol.eventHandler.added, this.#handleAddedEvents.bind(this));
569
627
  }
570
628
 
571
629
  await messenger.sendDataReport({
572
630
  baseDataReport: {
573
631
  suppressResponse: false, // we always need proper response for initial report
574
- subscriptionId: this.id,
632
+ subscriptionId: this.subscriptionId,
575
633
  interactionModelRevision: Specification.INTERACTION_MODEL_REVISION,
576
634
  },
577
- forFabricFilteredRead: this.criteria.isFabricFiltered,
635
+ forFabricFilteredRead: this.request.isFabricFiltered,
578
636
  payload: this.#processAttributesAndEventsReport(readContext, suppressStatusReports),
579
637
  });
580
638
  }
581
639
 
582
- async #flush() {
640
+ async #flush(flushViaSession?: Session) {
583
641
  this.#sendDelayTimer.stop();
584
642
  if (this.#outstandingAttributeUpdates !== undefined || this.#outstandingEventsMinNumber !== undefined) {
585
- logger.debug(`Flushing subscription ${this.id}${this.isClosed ? " (for closing)" : ""}`);
586
- this.#triggerSendUpdate(true);
643
+ logger.debug(`Flushing subscription ${this.idStr}${this.#isClosed ? " (for closing)" : ""}`);
644
+ this.#triggerSendUpdate(true, flushViaSession);
587
645
  if (this.#currentUpdatePromise) {
646
+ using _waiting = this.#lifetime?.join("waiting on flush");
588
647
  await this.#currentUpdatePromise;
589
648
  }
590
649
  }
591
650
  }
592
651
 
593
- protected override async destroy() {
594
- this.#sendUpdatesActivated = false;
595
-
596
- this.#changeHandlers.close();
597
-
598
- this.#updateTimer.stop();
599
- this.#sendDelayTimer.stop();
600
- await super.destroy();
601
- }
602
-
603
652
  /**
604
653
  * Closes the subscription and flushes all outstanding data updates if requested.
605
654
  */
606
- override async close(flush = false, cancelledByPeer = false) {
607
- if (this.isClosed) {
655
+ async close(flushViaSession?: Session) {
656
+ if (this.#isClosed) {
608
657
  return;
609
658
  }
610
- if (cancelledByPeer) {
611
- this.isCanceledByPeer = true;
612
- }
613
- await this.destroy();
659
+ this.#isClosed = true;
660
+
661
+ await this.#cancel(flushViaSession);
614
662
 
615
- if (flush) {
616
- await this.#flush();
617
- }
618
663
  if (this.#currentUpdatePromise) {
664
+ using _waiting = this.#lifetime?.closing()?.join("waiting on update");
619
665
  await this.#currentUpdatePromise;
620
666
  }
621
667
  }
622
668
 
669
+ async #cancel(flushViaSession?: Session) {
670
+ const closing = this.#lifetime?.closing();
671
+
672
+ this.#sendUpdatesActivated = false;
673
+
674
+ this.#changeHandlers.close();
675
+
676
+ if (flushViaSession !== undefined) {
677
+ using _flushing = closing?.join("flushing");
678
+ await this.#flush(flushViaSession);
679
+ }
680
+
681
+ this.#updateTimer.stop();
682
+ this.#sendDelayTimer.stop();
683
+
684
+ this.session.subscriptions.delete(this);
685
+ logger.debug(this.session.via, "Deleted subscription", hex.fixed(this.subscriptionId, 8));
686
+
687
+ this.cancelled.emit(this);
688
+ }
689
+
623
690
  /**
624
691
  * Iterates over all attributes and events that have changed since the last update and sends them to
625
692
  * the controller.
@@ -631,14 +698,13 @@ export class ServerSubscription extends Subscription {
631
698
  eventsMinNumber: EventNumber | undefined,
632
699
  ) {
633
700
  const request = {
634
- ...this.criteria,
701
+ ...this.request,
635
702
  interactionModelRevision: Specification.INTERACTION_MODEL_REVISION, // irrelevant here, set to our version
636
703
  };
637
704
 
638
705
  const session = RemoteActorContext({
639
706
  activity: (exchange as NodeActivity.WithActivity)[NodeActivity.activityKey],
640
707
  fabricFiltered: request.isFabricFiltered,
641
- message: {} as Message,
642
708
  exchange,
643
709
  node: this.#context.node,
644
710
  }).beginReadOnly();
@@ -678,53 +744,59 @@ export class ServerSubscription extends Subscription {
678
744
  }
679
745
 
680
746
  async #sendUpdateMessage(
747
+ lifetime: Lifetime | undefined,
681
748
  attributeFilter: DirtyState.ForCluster | undefined,
682
749
  eventsMinNumber: EventNumber | undefined,
683
750
  onlyWithData: boolean,
751
+ session?: Session,
684
752
  ) {
685
- const exchange = this.#context.initiateExchange(this.#peerAddress, INTERACTION_PROTOCOL_ID);
753
+ const exchange = this.#context.initiateExchange(session ?? this.#peerAddress, INTERACTION_PROTOCOL_ID);
686
754
  if (exchange === undefined) return false;
687
755
 
688
756
  const messenger = new InteractionServerMessenger(exchange);
689
757
 
690
758
  try {
691
759
  if (attributeFilter === undefined && eventsMinNumber === undefined) {
760
+ using _sending = lifetime?.join("sending keepalive");
692
761
  await messenger.sendDataReport({
693
762
  baseDataReport: {
694
763
  suppressResponse: true, // suppressResponse true for empty DataReports
695
- subscriptionId: this.id,
764
+ subscriptionId: this.subscriptionId,
696
765
  interactionModelRevision: Specification.INTERACTION_MODEL_REVISION,
697
766
  },
698
- forFabricFilteredRead: this.criteria.isFabricFiltered,
699
- waitForAck: !this.isClosed, // Do not wait for ack when closed
767
+ forFabricFilteredRead: this.request.isFabricFiltered,
768
+ waitForAck: !this.#isClosed, // Do not wait for ack when closed
700
769
  });
701
770
  } else {
771
+ using _sending = lifetime?.join("sending data");
702
772
  // TODO: Add correct handling for reports that would have data but in the end not send any because of
703
773
  // filtered out. Correct handling needs refactoring to create messenger and exchange on the fly
704
774
  // when data are there.
705
775
  await messenger.sendDataReport({
706
776
  baseDataReport: {
707
777
  suppressResponse: false, // Non-empty data reports always need to send response
708
- subscriptionId: this.id,
778
+ subscriptionId: this.subscriptionId,
709
779
  interactionModelRevision: Specification.INTERACTION_MODEL_REVISION,
710
780
  },
711
- forFabricFilteredRead: this.criteria.isFabricFiltered,
781
+ forFabricFilteredRead: this.request.isFabricFiltered,
712
782
  payload: this.#iterateDataUpdate(exchange, attributeFilter, eventsMinNumber),
713
- waitForAck: !this.isClosed, // Do not wait for ack when closed
783
+ waitForAck: !this.#isClosed, // Do not wait for ack when closed
714
784
  suppressEmptyReport: onlyWithData,
715
785
  });
716
786
  }
717
787
  } catch (error) {
718
788
  if (StatusResponseError.is(error, StatusCode.InvalidSubscription, StatusCode.Failure)) {
719
- logger.info(`Subscription ${this.id} cancelled by peer.`);
720
- this.isCanceledByPeer = true;
721
- await this.close(false);
789
+ logger.info(`Subscription ${this.idStr} cancelled by peer`);
790
+ this.#isCanceledByPeer = true;
722
791
  } else {
723
792
  StatusResponseError.accept(error);
724
- logger.info(`Subscription ${this.id} update failed:`, error);
725
- await this.close(false);
793
+ logger.info(`Subscription ${this.idStr} update failed:`, error);
726
794
  }
795
+
796
+ using _canceling = lifetime?.join("canceling");
797
+ await this.#cancel();
727
798
  } finally {
799
+ using _closing = lifetime?.join("closing messenger");
728
800
  await messenger.close();
729
801
  }
730
802
  return true;