@matter/protocol 0.15.1 → 0.15.2-alpha.0-20250704-2715344f0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/action/Val.d.ts +4 -0
- package/dist/cjs/action/Val.d.ts.map +1 -1
- package/dist/cjs/action/Val.js.map +1 -1
- package/dist/cjs/action/client/ClientInteraction.d.ts +10 -8
- package/dist/cjs/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/cjs/action/client/ClientInteraction.js +152 -80
- package/dist/cjs/action/client/ClientInteraction.js.map +1 -1
- package/dist/cjs/action/client/ClientSubscription.d.ts +17 -0
- package/dist/cjs/action/client/ClientSubscription.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientSubscription.js +22 -0
- package/dist/cjs/action/client/ClientSubscription.js.map +6 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.d.ts +20 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.js +117 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.js.map +6 -0
- package/dist/cjs/action/client/ClientSubscriptions.d.ts +45 -0
- package/dist/cjs/action/client/ClientSubscriptions.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientSubscriptions.js +141 -0
- package/dist/cjs/action/client/ClientSubscriptions.js.map +6 -0
- package/dist/cjs/action/client/InputChunk.d.ts +12 -0
- package/dist/cjs/action/client/InputChunk.d.ts.map +1 -0
- package/dist/cjs/action/client/InputChunk.js +89 -0
- package/dist/cjs/action/client/InputChunk.js.map +6 -0
- package/dist/cjs/action/client/ReadScope.d.ts +26 -0
- package/dist/cjs/action/client/ReadScope.d.ts.map +1 -0
- package/dist/cjs/action/client/ReadScope.js +87 -0
- package/dist/cjs/action/client/ReadScope.js.map +6 -0
- package/dist/cjs/action/client/index.d.ts +5 -0
- package/dist/cjs/action/client/index.d.ts.map +1 -1
- package/dist/cjs/action/client/index.js +5 -0
- package/dist/cjs/action/client/index.js.map +1 -1
- package/dist/cjs/action/request/Invoke.d.ts.map +1 -1
- package/dist/cjs/action/request/Invoke.js +8 -2
- package/dist/cjs/action/request/Invoke.js.map +1 -1
- package/dist/cjs/action/request/Read.d.ts +0 -4
- package/dist/cjs/action/request/Read.d.ts.map +1 -1
- package/dist/cjs/action/request/Read.js.map +1 -1
- package/dist/cjs/action/request/Subscribe.d.ts +14 -1
- package/dist/cjs/action/request/Subscribe.d.ts.map +1 -1
- package/dist/cjs/action/request/Subscribe.js +2 -2
- package/dist/cjs/action/request/Subscribe.js.map +1 -1
- package/dist/cjs/action/response/SubscribeResult.d.ts +3 -5
- package/dist/cjs/action/response/SubscribeResult.d.ts.map +1 -1
- package/dist/cjs/action/server/AttributeReadResponse.d.ts +1 -1
- package/dist/cjs/action/server/AttributeReadResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/AttributeSubscriptionResponse.d.ts +1 -1
- package/dist/cjs/action/server/AttributeSubscriptionResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/AttributeSubscriptionResponse.js.map +1 -1
- package/dist/cjs/action/server/CommandInvokeResponse.d.ts +2 -1
- package/dist/cjs/action/server/CommandInvokeResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/CommandInvokeResponse.js +3 -3
- package/dist/cjs/action/server/CommandInvokeResponse.js.map +1 -1
- package/dist/cjs/action/server/EventReadResponse.d.ts +1 -1
- package/dist/cjs/action/server/EventReadResponse.d.ts.map +1 -1
- package/dist/cjs/codec/MessageCodec.d.ts +1 -1
- package/dist/cjs/codec/MessageCodec.d.ts.map +1 -1
- package/dist/cjs/common/FailsafeContext.d.ts.map +1 -1
- package/dist/cjs/common/FailsafeContext.js +0 -1
- package/dist/cjs/common/FailsafeContext.js.map +1 -1
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js +13 -10
- package/dist/cjs/fabric/Fabric.js.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts +6 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.js +16 -0
- package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
- package/dist/cjs/groups/FabricGroups.d.ts +1 -1
- package/dist/cjs/groups/FabricGroups.d.ts.map +1 -1
- package/dist/cjs/groups/Groups.d.ts +2 -2
- package/dist/cjs/groups/Groups.d.ts.map +1 -1
- package/dist/cjs/groups/Groups.js +2 -2
- package/dist/cjs/groups/Groups.js.map +1 -1
- package/dist/cjs/interaction/AttributeDataEncoder.d.ts +1 -1
- package/dist/cjs/interaction/FabricAccessControl.d.ts +1 -1
- package/dist/cjs/interaction/FabricAccessControl.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +8 -4
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts +21 -17
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +20 -12
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.d.ts +5 -6
- package/dist/cjs/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +4 -4
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +2 -2
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/peer/OperationalPeer.d.ts +1 -1
- package/dist/cjs/peer/OperationalPeer.d.ts.map +1 -1
- package/dist/cjs/peer/PeerAddress.d.ts.map +1 -1
- package/dist/cjs/peer/PeerAddress.js +1 -1
- package/dist/cjs/peer/PeerAddress.js.map +1 -1
- package/dist/cjs/peer/PeerAddressStore.d.ts +1 -1
- package/dist/cjs/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +5 -5
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/protocol/ChannelManager.d.ts +1 -3
- package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ChannelManager.js +3 -6
- package/dist/cjs/protocol/ChannelManager.js.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.d.ts +3 -2
- package/dist/cjs/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js +6 -8
- package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts +1 -3
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +7 -9
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.js +7 -8
- package/dist/cjs/protocol/ExchangeProvider.js.map +1 -1
- package/dist/cjs/protocol/MessageChannel.d.ts +17 -4
- package/dist/cjs/protocol/MessageChannel.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageChannel.js +15 -6
- package/dist/cjs/protocol/MessageChannel.js.map +1 -1
- package/dist/cjs/protocol/MessageExchange.d.ts +0 -6
- package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageExchange.js +5 -9
- package/dist/cjs/protocol/MessageExchange.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts +3 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.js +4 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.d.ts +0 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.js +0 -3
- package/dist/cjs/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/cjs/session/GroupSession.d.ts +1 -1
- package/dist/cjs/session/GroupSession.d.ts.map +1 -1
- package/dist/cjs/session/GroupSession.js +6 -6
- package/dist/cjs/session/GroupSession.js.map +1 -1
- package/dist/cjs/session/InsecureSession.d.ts +2 -1
- package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
- package/dist/cjs/session/InsecureSession.js +5 -4
- package/dist/cjs/session/InsecureSession.js.map +1 -1
- package/dist/cjs/session/NodeSession.d.ts +5 -3
- package/dist/cjs/session/NodeSession.d.ts.map +1 -1
- package/dist/cjs/session/NodeSession.js +4 -2
- package/dist/cjs/session/NodeSession.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts +2 -3
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +1 -3
- package/dist/cjs/session/SessionManager.js.map +1 -1
- package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseClient.js +6 -5
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +2 -2
- package/dist/cjs/session/case/CaseServer.js.map +1 -1
- package/dist/cjs/session/pase/PaseMessages.js +2 -2
- package/dist/cjs/session/pase/PaseMessages.js.map +1 -1
- package/dist/esm/action/Val.d.ts +4 -0
- package/dist/esm/action/Val.d.ts.map +1 -1
- package/dist/esm/action/Val.js.map +1 -1
- package/dist/esm/action/client/ClientInteraction.d.ts +10 -8
- package/dist/esm/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/esm/action/client/ClientInteraction.js +154 -82
- package/dist/esm/action/client/ClientInteraction.js.map +1 -1
- package/dist/esm/action/client/ClientSubscription.d.ts +17 -0
- package/dist/esm/action/client/ClientSubscription.d.ts.map +1 -0
- package/dist/esm/action/client/ClientSubscription.js +6 -0
- package/dist/esm/action/client/ClientSubscription.js.map +6 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.d.ts +20 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.d.ts.map +1 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.js +97 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.js.map +6 -0
- package/dist/esm/action/client/ClientSubscriptions.d.ts +45 -0
- package/dist/esm/action/client/ClientSubscriptions.d.ts.map +1 -0
- package/dist/esm/action/client/ClientSubscriptions.js +129 -0
- package/dist/esm/action/client/ClientSubscriptions.js.map +6 -0
- package/dist/esm/action/client/InputChunk.d.ts +12 -0
- package/dist/esm/action/client/InputChunk.d.ts.map +1 -0
- package/dist/esm/action/client/InputChunk.js +69 -0
- package/dist/esm/action/client/InputChunk.js.map +6 -0
- package/dist/esm/action/client/ReadScope.d.ts +26 -0
- package/dist/esm/action/client/ReadScope.d.ts.map +1 -0
- package/dist/esm/action/client/ReadScope.js +67 -0
- package/dist/esm/action/client/ReadScope.js.map +6 -0
- package/dist/esm/action/client/index.d.ts +5 -0
- package/dist/esm/action/client/index.d.ts.map +1 -1
- package/dist/esm/action/client/index.js +5 -0
- package/dist/esm/action/client/index.js.map +1 -1
- package/dist/esm/action/request/Invoke.d.ts.map +1 -1
- package/dist/esm/action/request/Invoke.js +8 -2
- package/dist/esm/action/request/Invoke.js.map +1 -1
- package/dist/esm/action/request/Read.d.ts +0 -4
- package/dist/esm/action/request/Read.d.ts.map +1 -1
- package/dist/esm/action/request/Read.js.map +1 -1
- package/dist/esm/action/request/Subscribe.d.ts +14 -1
- package/dist/esm/action/request/Subscribe.d.ts.map +1 -1
- package/dist/esm/action/request/Subscribe.js +2 -2
- package/dist/esm/action/request/Subscribe.js.map +1 -1
- package/dist/esm/action/response/SubscribeResult.d.ts +3 -5
- package/dist/esm/action/response/SubscribeResult.d.ts.map +1 -1
- package/dist/esm/action/server/AttributeReadResponse.d.ts +1 -1
- package/dist/esm/action/server/AttributeReadResponse.d.ts.map +1 -1
- package/dist/esm/action/server/AttributeSubscriptionResponse.d.ts +1 -1
- package/dist/esm/action/server/AttributeSubscriptionResponse.d.ts.map +1 -1
- package/dist/esm/action/server/AttributeSubscriptionResponse.js.map +1 -1
- package/dist/esm/action/server/CommandInvokeResponse.d.ts +2 -1
- package/dist/esm/action/server/CommandInvokeResponse.d.ts.map +1 -1
- package/dist/esm/action/server/CommandInvokeResponse.js +1 -1
- package/dist/esm/action/server/CommandInvokeResponse.js.map +1 -1
- package/dist/esm/action/server/EventReadResponse.d.ts +1 -1
- package/dist/esm/action/server/EventReadResponse.d.ts.map +1 -1
- package/dist/esm/codec/MessageCodec.d.ts +1 -1
- package/dist/esm/codec/MessageCodec.d.ts.map +1 -1
- package/dist/esm/common/FailsafeContext.d.ts.map +1 -1
- package/dist/esm/common/FailsafeContext.js +0 -1
- package/dist/esm/common/FailsafeContext.js.map +1 -1
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js +4 -1
- package/dist/esm/fabric/Fabric.js.map +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts +6 -1
- package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/esm/fabric/FabricAuthority.js +25 -1
- package/dist/esm/fabric/FabricAuthority.js.map +1 -1
- package/dist/esm/groups/FabricGroups.d.ts +1 -1
- package/dist/esm/groups/FabricGroups.d.ts.map +1 -1
- package/dist/esm/groups/Groups.d.ts +2 -2
- package/dist/esm/groups/Groups.d.ts.map +1 -1
- package/dist/esm/groups/Groups.js +1 -1
- package/dist/esm/groups/Groups.js.map +1 -1
- package/dist/esm/interaction/AttributeDataEncoder.d.ts +1 -1
- package/dist/esm/interaction/FabricAccessControl.d.ts +1 -1
- package/dist/esm/interaction/FabricAccessControl.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +8 -4
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts +21 -17
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +19 -11
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/mdns/MdnsScanner.d.ts +5 -6
- package/dist/esm/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsScanner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +2 -2
- package/dist/esm/peer/ControllerCommissioningFlow.js +1 -1
- package/dist/esm/peer/OperationalPeer.d.ts +1 -1
- package/dist/esm/peer/OperationalPeer.d.ts.map +1 -1
- package/dist/esm/peer/PeerAddress.d.ts.map +1 -1
- package/dist/esm/peer/PeerAddress.js +2 -2
- package/dist/esm/peer/PeerAddress.js.map +1 -1
- package/dist/esm/peer/PeerAddressStore.d.ts +1 -1
- package/dist/esm/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +4 -4
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/protocol/ChannelManager.d.ts +1 -3
- package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/esm/protocol/ChannelManager.js +3 -6
- package/dist/esm/protocol/ChannelManager.js.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.d.ts +3 -2
- package/dist/esm/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.js +4 -6
- package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts +1 -3
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +8 -7
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.js +4 -2
- package/dist/esm/protocol/ExchangeProvider.js.map +1 -1
- package/dist/esm/protocol/MessageChannel.d.ts +17 -4
- package/dist/esm/protocol/MessageChannel.d.ts.map +1 -1
- package/dist/esm/protocol/MessageChannel.js +12 -3
- package/dist/esm/protocol/MessageChannel.js.map +1 -1
- package/dist/esm/protocol/MessageExchange.d.ts +0 -6
- package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/esm/protocol/MessageExchange.js +7 -7
- package/dist/esm/protocol/MessageExchange.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts +3 -0
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.js +4 -0
- package/dist/esm/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.d.ts +0 -1
- package/dist/esm/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.js +0 -3
- package/dist/esm/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/esm/session/GroupSession.d.ts +1 -1
- package/dist/esm/session/GroupSession.d.ts.map +1 -1
- package/dist/esm/session/GroupSession.js +1 -1
- package/dist/esm/session/InsecureSession.d.ts +2 -1
- package/dist/esm/session/InsecureSession.d.ts.map +1 -1
- package/dist/esm/session/InsecureSession.js +3 -2
- package/dist/esm/session/InsecureSession.js.map +1 -1
- package/dist/esm/session/NodeSession.d.ts +5 -3
- package/dist/esm/session/NodeSession.d.ts.map +1 -1
- package/dist/esm/session/NodeSession.js +12 -2
- package/dist/esm/session/NodeSession.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts +2 -3
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +1 -3
- package/dist/esm/session/SessionManager.js.map +1 -1
- package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
- package/dist/esm/session/case/CaseClient.js +3 -2
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/case/CaseServer.js +1 -1
- package/dist/esm/session/pase/PaseMessages.js +1 -1
- package/package.json +6 -6
- package/src/action/Val.ts +5 -0
- package/src/action/client/ClientInteraction.ts +178 -90
- package/src/action/client/ClientSubscription.ts +18 -0
- package/src/action/client/ClientSubscriptionHandler.ts +137 -0
- package/src/action/client/ClientSubscriptions.ts +172 -0
- package/src/action/client/InputChunk.ts +79 -0
- package/src/action/client/ReadScope.ts +107 -0
- package/src/action/client/index.ts +5 -0
- package/src/action/request/Invoke.ts +11 -2
- package/src/action/request/Read.ts +0 -5
- package/src/action/request/Subscribe.ts +17 -3
- package/src/action/response/SubscribeResult.ts +3 -4
- package/src/action/server/AttributeReadResponse.ts +1 -1
- package/src/action/server/AttributeSubscriptionResponse.ts +2 -1
- package/src/action/server/CommandInvokeResponse.ts +4 -2
- package/src/action/server/EventReadResponse.ts +2 -2
- package/src/codec/MessageCodec.ts +1 -1
- package/src/common/FailsafeContext.ts +0 -1
- package/src/fabric/Fabric.ts +4 -1
- package/src/fabric/FabricAuthority.ts +29 -1
- package/src/groups/FabricGroups.ts +1 -1
- package/src/groups/Groups.ts +3 -2
- package/src/interaction/FabricAccessControl.ts +1 -1
- package/src/interaction/InteractionClient.ts +8 -4
- package/src/interaction/InteractionMessenger.ts +20 -13
- package/src/mdns/MdnsScanner.ts +5 -6
- package/src/peer/ControllerCommissioner.ts +2 -2
- package/src/peer/ControllerCommissioningFlow.ts +1 -1
- package/src/peer/OperationalPeer.ts +1 -1
- package/src/peer/PeerAddress.ts +2 -2
- package/src/peer/PeerAddressStore.ts +1 -1
- package/src/peer/PeerSet.ts +6 -4
- package/src/protocol/ChannelManager.ts +2 -4
- package/src/protocol/DeviceCommissioner.ts +4 -8
- package/src/protocol/ExchangeManager.ts +9 -7
- package/src/protocol/ExchangeProvider.ts +7 -3
- package/src/protocol/MessageChannel.ts +19 -4
- package/src/protocol/MessageExchange.ts +8 -12
- package/src/securechannel/SecureChannelMessenger.ts +4 -0
- package/src/securechannel/SecureChannelProtocol.ts +0 -4
- package/src/session/GroupSession.ts +1 -1
- package/src/session/InsecureSession.ts +3 -1
- package/src/session/NodeSession.ts +14 -4
- package/src/session/SessionManager.ts +1 -3
- package/src/session/case/CaseClient.ts +3 -2
- package/src/session/case/CaseServer.ts +1 -1
- package/src/session/pase/PaseMessages.ts +1 -1
|
@@ -13,34 +13,48 @@ import { InvokeResult } from "#action/response/InvokeResult.js";
|
|
|
13
13
|
import { ReadResult } from "#action/response/ReadResult.js";
|
|
14
14
|
import { SubscribeResult } from "#action/response/SubscribeResult.js";
|
|
15
15
|
import { WriteResult } from "#action/response/WriteResult.js";
|
|
16
|
-
import { Environment, Environmental,
|
|
17
|
-
import { InteractionClientMessenger } from "#interaction/InteractionMessenger.js";
|
|
18
|
-
import { SubscriptionClient } from "#interaction/SubscriptionClient.js";
|
|
16
|
+
import { BasicSet, Environment, Environmental, ImplementationError, PromiseQueue } from "#general";
|
|
17
|
+
import { InteractionClientMessenger, MessageType } from "#interaction/InteractionMessenger.js";
|
|
19
18
|
import { InteractionQueue } from "#peer/InteractionQueue.js";
|
|
20
19
|
import { ExchangeProvider } from "#protocol/ExchangeProvider.js";
|
|
20
|
+
import { TlvSubscribeResponse } from "#types";
|
|
21
|
+
import { ClientSubscriptions } from "./ClientSubscriptions.js";
|
|
22
|
+
import { InputChunk } from "./InputChunk.js";
|
|
21
23
|
|
|
22
|
-
export interface
|
|
24
|
+
export interface ClientInteractionContext {
|
|
23
25
|
exchanges: ExchangeProvider;
|
|
24
|
-
subscriptions:
|
|
26
|
+
subscriptions: ClientSubscriptions;
|
|
25
27
|
queue: PromiseQueue;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
export const DEFAULT_MIN_INTERVAL_FLOOR_SECONDS = 1;
|
|
31
|
+
|
|
28
32
|
/**
|
|
29
|
-
*
|
|
33
|
+
* Client-side implementation of the Matter protocol.
|
|
30
34
|
*/
|
|
31
35
|
export class ClientInteraction<SessionT extends InteractionSession = InteractionSession>
|
|
32
36
|
implements Interactable<SessionT>
|
|
33
37
|
{
|
|
34
38
|
readonly #exchanges: ExchangeProvider;
|
|
35
|
-
readonly #subscriptions:
|
|
39
|
+
readonly #subscriptions: ClientSubscriptions;
|
|
36
40
|
readonly #queue?: PromiseQueue;
|
|
41
|
+
readonly #interactions = new BasicSet<Read | Write | Invoke | Subscribe>();
|
|
42
|
+
#closed = false;
|
|
37
43
|
|
|
38
|
-
constructor(context:
|
|
44
|
+
constructor(context: ClientInteractionContext) {
|
|
39
45
|
this.#exchanges = context.exchanges;
|
|
40
46
|
this.#subscriptions = context.subscriptions;
|
|
41
47
|
this.#queue = context.queue;
|
|
42
48
|
}
|
|
43
49
|
|
|
50
|
+
async close() {
|
|
51
|
+
this.#closed = true;
|
|
52
|
+
|
|
53
|
+
while (this.#interactions.size) {
|
|
54
|
+
await this.#interactions.deleted;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
44
58
|
get subscriptions() {
|
|
45
59
|
return this.#subscriptions;
|
|
46
60
|
}
|
|
@@ -52,104 +66,178 @@ export class ClientInteraction<SessionT extends InteractionSession = Interaction
|
|
|
52
66
|
static [Environmental.create](env: Environment) {
|
|
53
67
|
const instance = new ClientInteraction({
|
|
54
68
|
exchanges: env.get(ExchangeProvider),
|
|
55
|
-
subscriptions: env.get(
|
|
69
|
+
subscriptions: env.get(ClientSubscriptions),
|
|
56
70
|
queue: env.get(InteractionQueue),
|
|
57
71
|
});
|
|
58
72
|
env.set(ClientInteraction, instance);
|
|
59
73
|
return instance;
|
|
60
74
|
}
|
|
61
75
|
|
|
62
|
-
read(
|
|
63
|
-
|
|
64
|
-
|
|
76
|
+
async *read(request: Read, _session?: SessionT): ReadResult {
|
|
77
|
+
try {
|
|
78
|
+
this.#begin(request);
|
|
79
|
+
const messenger = await InteractionClientMessenger.create(this.#exchanges);
|
|
80
|
+
|
|
81
|
+
await messenger.sendReadRequest(request);
|
|
82
|
+
|
|
83
|
+
for await (const report of messenger.readDataReports()) {
|
|
84
|
+
yield InputChunk(report);
|
|
85
|
+
}
|
|
86
|
+
} finally {
|
|
87
|
+
this.#end(request);
|
|
88
|
+
}
|
|
65
89
|
}
|
|
66
90
|
|
|
67
91
|
async write<T extends Write>(request: T, _session?: SessionT): WriteResult<T> {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
let messenger: undefined | InteractionClientMessenger;
|
|
93
|
+
try {
|
|
94
|
+
this.#begin(request);
|
|
95
|
+
messenger = await InteractionClientMessenger.create(this.#exchanges);
|
|
96
|
+
const response = await messenger.sendWriteCommand(request);
|
|
97
|
+
if (request.suppressResponse) {
|
|
98
|
+
return undefined as Awaited<WriteResult<T>>;
|
|
99
|
+
}
|
|
100
|
+
if (!response || !response.writeResponses?.length) {
|
|
101
|
+
return new Array<WriteResult.AttributeStatus>() as Awaited<WriteResult<T>>;
|
|
102
|
+
} else {
|
|
103
|
+
return response.writeResponses.map(
|
|
104
|
+
({
|
|
105
|
+
path: { nodeId, endpointId, clusterId, attributeId, listIndex },
|
|
106
|
+
status: { status, clusterStatus },
|
|
107
|
+
}) => ({
|
|
108
|
+
kind: "attr-status",
|
|
109
|
+
path: {
|
|
110
|
+
nodeId,
|
|
111
|
+
endpointId: endpointId!,
|
|
112
|
+
clusterId: clusterId!,
|
|
113
|
+
attributeId: attributeId!,
|
|
114
|
+
listIndex,
|
|
115
|
+
},
|
|
116
|
+
status,
|
|
117
|
+
clusterStatus,
|
|
118
|
+
}),
|
|
119
|
+
) as Awaited<WriteResult<T>>;
|
|
120
|
+
}
|
|
121
|
+
} finally {
|
|
122
|
+
await messenger?.close();
|
|
123
|
+
this.#end(request);
|
|
93
124
|
}
|
|
94
125
|
}
|
|
95
126
|
|
|
96
127
|
async *invoke(request: Invoke, _session?: SessionT): InvokeResult {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
128
|
+
let messenger: undefined | InteractionClientMessenger;
|
|
129
|
+
try {
|
|
130
|
+
this.#begin(request);
|
|
131
|
+
messenger = await InteractionClientMessenger.create(this.#exchanges);
|
|
132
|
+
const result = await messenger.sendInvokeCommand(request);
|
|
133
|
+
if (!request.suppressResponse) {
|
|
134
|
+
if (result && result.invokeResponses?.length) {
|
|
135
|
+
const chunk: InvokeResult.Chunk = result.invokeResponses
|
|
136
|
+
.map(response => {
|
|
137
|
+
if (response.command !== undefined) {
|
|
138
|
+
const {
|
|
139
|
+
commandPath: { endpointId, clusterId, commandId },
|
|
140
|
+
commandRef,
|
|
141
|
+
commandFields,
|
|
142
|
+
} = response.command;
|
|
143
|
+
const res: InvokeResult.CommandResponse = {
|
|
144
|
+
kind: "cmd-response",
|
|
145
|
+
path: {
|
|
146
|
+
endpointId: endpointId!,
|
|
147
|
+
clusterId: clusterId,
|
|
148
|
+
commandId: commandId,
|
|
149
|
+
},
|
|
150
|
+
commandRef,
|
|
151
|
+
data: commandFields!, // TODO add decoding
|
|
152
|
+
};
|
|
153
|
+
return res;
|
|
154
|
+
} else if (response.status !== undefined) {
|
|
155
|
+
const {
|
|
156
|
+
commandPath: { endpointId, clusterId, commandId },
|
|
157
|
+
commandRef,
|
|
158
|
+
status: { status, clusterStatus },
|
|
159
|
+
} = response.status;
|
|
160
|
+
const res: InvokeResult.CommandStatus = {
|
|
161
|
+
kind: "cmd-status",
|
|
162
|
+
path: {
|
|
163
|
+
endpointId: endpointId!,
|
|
164
|
+
clusterId: clusterId,
|
|
165
|
+
commandId: commandId,
|
|
166
|
+
},
|
|
167
|
+
commandRef,
|
|
168
|
+
status,
|
|
169
|
+
clusterStatus,
|
|
170
|
+
};
|
|
171
|
+
return res;
|
|
172
|
+
} else {
|
|
173
|
+
// Should not happen but if we ignore the response?
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
.filter(r => r !== undefined);
|
|
178
|
+
yield chunk;
|
|
179
|
+
} else {
|
|
180
|
+
yield [];
|
|
181
|
+
}
|
|
147
182
|
}
|
|
183
|
+
} finally {
|
|
184
|
+
await messenger?.close();
|
|
185
|
+
this.#end(request);
|
|
148
186
|
}
|
|
149
187
|
}
|
|
150
188
|
|
|
151
|
-
subscribe(
|
|
152
|
-
|
|
153
|
-
|
|
189
|
+
async subscribe(request: Subscribe, _session?: SessionT): SubscribeResult {
|
|
190
|
+
let messenger: undefined | InteractionClientMessenger;
|
|
191
|
+
try {
|
|
192
|
+
this.#begin(request);
|
|
193
|
+
|
|
194
|
+
messenger = await InteractionClientMessenger.create(this.#exchanges);
|
|
195
|
+
|
|
196
|
+
await messenger.sendSubscribeRequest({
|
|
197
|
+
...request,
|
|
198
|
+
minIntervalFloorSeconds: DEFAULT_MIN_INTERVAL_FLOOR_SECONDS,
|
|
199
|
+
maxIntervalCeilingSeconds: DEFAULT_MIN_INTERVAL_FLOOR_SECONDS,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
await this.#handleSubscriptionResponse(request, readChunks(messenger));
|
|
203
|
+
|
|
204
|
+
const responseMessage = await messenger.nextMessage(MessageType.SubscribeResponse);
|
|
205
|
+
const response = TlvSubscribeResponse.decode(responseMessage.payload);
|
|
206
|
+
|
|
207
|
+
return this.#subscriptions.add(request, response);
|
|
208
|
+
} finally {
|
|
209
|
+
await messenger?.close();
|
|
210
|
+
this.#end(request);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async #handleSubscriptionResponse(request: Subscribe, result: ReadResult) {
|
|
215
|
+
if (request.updated) {
|
|
216
|
+
await request.updated(result);
|
|
217
|
+
} else {
|
|
218
|
+
// It doesn't really make sense to subscribe without listening to the result, but higher-level Interactables
|
|
219
|
+
// may process responses so the subscriber doesn't need to. So "updated" may be omitted from the API, so
|
|
220
|
+
// we handle this case
|
|
221
|
+
//
|
|
222
|
+
// We need to await the generator or the interactable will hang
|
|
223
|
+
for await (const _chunk of result);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#begin(request: Read | Write | Invoke | Subscribe) {
|
|
228
|
+
if (this.#closed) {
|
|
229
|
+
throw new ImplementationError("Client interaction unavailable after close");
|
|
230
|
+
}
|
|
231
|
+
this.#interactions.add(request);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
#end(request: Read | Write | Invoke | Subscribe) {
|
|
235
|
+
this.#interactions.delete(request);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async function* readChunks(messenger: InteractionClientMessenger) {
|
|
240
|
+
for await (const report of messenger.readDataReports()) {
|
|
241
|
+
yield InputChunk(report);
|
|
154
242
|
}
|
|
155
243
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Subscribe } from "#action/request/Subscribe.js";
|
|
8
|
+
import { ActiveSubscription } from "#action/response/SubscribeResult.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The client view of an established Matter subscription.
|
|
12
|
+
*/
|
|
13
|
+
export interface ClientSubscription extends ActiveSubscription {
|
|
14
|
+
request: Subscribe;
|
|
15
|
+
timeoutAtMs?: number;
|
|
16
|
+
isClosed: boolean;
|
|
17
|
+
isReading: boolean;
|
|
18
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ReadResult } from "#action/response/ReadResult.js";
|
|
8
|
+
import { DecodedDataReport } from "#interaction/DecodedDataReport.js";
|
|
9
|
+
import { IncomingInteractionClientMessenger } from "#interaction/InteractionMessenger.js";
|
|
10
|
+
import { SubscriptionId } from "#interaction/Subscription.js";
|
|
11
|
+
import { MessageExchange } from "#protocol/MessageExchange.js";
|
|
12
|
+
import { ProtocolHandler } from "#protocol/ProtocolHandler.js";
|
|
13
|
+
import { DataReport, INTERACTION_PROTOCOL_ID, Status } from "#types";
|
|
14
|
+
import { Diagnostic, InternalError, Logger } from "@matter/general";
|
|
15
|
+
import { ClientSubscriptions } from "./ClientSubscriptions.js";
|
|
16
|
+
import { InputChunk } from "./InputChunk.js";
|
|
17
|
+
|
|
18
|
+
const logger = Logger.get("ClientSubscriptionHandler");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A protocol handler that informs {@link ClientSubscriptions} of new exchanges.
|
|
22
|
+
*/
|
|
23
|
+
export class ClientSubscriptionHandler implements ProtocolHandler {
|
|
24
|
+
id = INTERACTION_PROTOCOL_ID;
|
|
25
|
+
requiresSecureSession = true;
|
|
26
|
+
|
|
27
|
+
#subscriptions: ClientSubscriptions;
|
|
28
|
+
|
|
29
|
+
constructor(subscriptions: ClientSubscriptions) {
|
|
30
|
+
this.#subscriptions = subscriptions;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async onNewExchange(exchange: MessageExchange) {
|
|
34
|
+
const messenger = new IncomingInteractionClientMessenger(exchange);
|
|
35
|
+
// Read the initial report
|
|
36
|
+
const reports = messenger.readDataReports();
|
|
37
|
+
|
|
38
|
+
const initialIteration = await reports.next();
|
|
39
|
+
if (initialIteration.done) {
|
|
40
|
+
throw new InternalError("Exchange initiated with no initial message");
|
|
41
|
+
}
|
|
42
|
+
const initialReport = initialIteration.value;
|
|
43
|
+
|
|
44
|
+
// Ensure there is a subscription ID present
|
|
45
|
+
const { subscriptionId } = initialReport;
|
|
46
|
+
if (subscriptionId === undefined) {
|
|
47
|
+
logger.debug("Ignoring unsolicited data report with no subscription ID");
|
|
48
|
+
await sendInvalid(messenger, undefined);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Ensure the subscription ID is valid
|
|
53
|
+
const subscription = this.#subscriptions.get(subscriptionId);
|
|
54
|
+
if (subscription === undefined) {
|
|
55
|
+
logger.debug("Ignoring data report for unknown subscription ID", Diagnostic.strong(subscriptionId));
|
|
56
|
+
await sendInvalid(messenger, subscriptionId);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// If this is just a ping, only reset the timeout
|
|
61
|
+
if (!initialReport.attributeReports?.length && !initialReport.eventReports?.length) {
|
|
62
|
+
subscription.timeoutAtMs = undefined;
|
|
63
|
+
this.#subscriptions.resetTimer();
|
|
64
|
+
await exchange.close();
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Pass the data to the recipient
|
|
69
|
+
try {
|
|
70
|
+
subscription.isReading = true;
|
|
71
|
+
|
|
72
|
+
if (subscription.request.updated) {
|
|
73
|
+
await subscription.request.updated(processReports(initialReport, reports, messenger));
|
|
74
|
+
} else {
|
|
75
|
+
// It doesn't make sense to have the callback undefined but we allow it in the type because they may
|
|
76
|
+
// be handled by intermediate interactables. So we handle the case here too, but just iterate and throw
|
|
77
|
+
// away the reports
|
|
78
|
+
for await (const _chunk of reports);
|
|
79
|
+
}
|
|
80
|
+
} finally {
|
|
81
|
+
subscription.isReading = false;
|
|
82
|
+
subscription.timeoutAtMs = undefined;
|
|
83
|
+
this.#subscriptions.resetTimer();
|
|
84
|
+
await exchange.close();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async close() {}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function sendInvalid(messenger: IncomingInteractionClientMessenger, subscriptionId?: SubscriptionId) {
|
|
92
|
+
await messenger.sendStatus(Status.InvalidSubscription, {
|
|
93
|
+
multipleMessageInteraction: true,
|
|
94
|
+
logContext: {
|
|
95
|
+
subId: subscriptionId,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
await messenger.close();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Convert incoming data reports into a {@link ReadResult}.
|
|
103
|
+
*
|
|
104
|
+
* Parses incoming reports and validates subscription IDs.
|
|
105
|
+
*/
|
|
106
|
+
async function* processReports(
|
|
107
|
+
initialReport: DataReport,
|
|
108
|
+
otherReports: AsyncIterable<DataReport>,
|
|
109
|
+
messenger: IncomingInteractionClientMessenger,
|
|
110
|
+
): ReadResult {
|
|
111
|
+
yield InputChunk(initialReport);
|
|
112
|
+
|
|
113
|
+
const { subscriptionId } = initialReport;
|
|
114
|
+
|
|
115
|
+
for await (const report of otherReports) {
|
|
116
|
+
const decoded = DecodedDataReport(report);
|
|
117
|
+
|
|
118
|
+
if (decoded.subscriptionId === undefined) {
|
|
119
|
+
logger.debug(
|
|
120
|
+
"Ignoring data report for incorrect subscription id",
|
|
121
|
+
Diagnostic.strong(decoded.subscriptionId),
|
|
122
|
+
);
|
|
123
|
+
await sendInvalid(messenger, decoded.subscriptionId);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (decoded.subscriptionId !== subscriptionId) {
|
|
127
|
+
logger.debug(
|
|
128
|
+
"Ignoring data report for incorrect subscription id",
|
|
129
|
+
Diagnostic.strong(decoded.subscriptionId),
|
|
130
|
+
);
|
|
131
|
+
await sendInvalid(messenger, decoded.subscriptionId);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
yield InputChunk(report);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Subscribe } from "#action/request/Subscribe.js";
|
|
8
|
+
import { ReadResult } from "#action/response/ReadResult.js";
|
|
9
|
+
import { ActiveSubscription } from "#action/response/SubscribeResult.js";
|
|
10
|
+
import {
|
|
11
|
+
BasicSet,
|
|
12
|
+
CanceledError,
|
|
13
|
+
Diagnostic,
|
|
14
|
+
Environment,
|
|
15
|
+
Environmental,
|
|
16
|
+
Logger,
|
|
17
|
+
Time,
|
|
18
|
+
TimeoutError,
|
|
19
|
+
Timer,
|
|
20
|
+
} from "#general";
|
|
21
|
+
import { SubscriptionId } from "#interaction/Subscription.js";
|
|
22
|
+
import { SubscribeResponse } from "#types";
|
|
23
|
+
import { ClientSubscription } from "./ClientSubscription.js";
|
|
24
|
+
|
|
25
|
+
const logger = Logger.get("ClientSubscriptions");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A managed set of {@link ClientSubscription} instances.
|
|
29
|
+
*/
|
|
30
|
+
export class ClientSubscriptions {
|
|
31
|
+
#subscriptions = new BasicSet<ClientSubscription>();
|
|
32
|
+
#timeout?: Timer;
|
|
33
|
+
#nextTimeoutAt?: number;
|
|
34
|
+
|
|
35
|
+
static [Environmental.create](env: Environment) {
|
|
36
|
+
const instance = new ClientSubscriptions();
|
|
37
|
+
env.set(ClientSubscriptions, instance);
|
|
38
|
+
return instance;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Register an active subscription.
|
|
43
|
+
*/
|
|
44
|
+
add(request: Subscribe, response: SubscribeResponse): ActiveSubscription {
|
|
45
|
+
const subscription: ClientSubscription = {
|
|
46
|
+
...response,
|
|
47
|
+
request,
|
|
48
|
+
close: () => this.#closeOne(subscription, new CanceledError()),
|
|
49
|
+
timeoutAtMs: undefined,
|
|
50
|
+
isClosed: false,
|
|
51
|
+
isReading: true,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
this.#subscriptions.add(subscription);
|
|
55
|
+
this.resetTimer();
|
|
56
|
+
|
|
57
|
+
return subscription;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Retrieve a subscription by ID.
|
|
62
|
+
*/
|
|
63
|
+
get(id: SubscriptionId) {
|
|
64
|
+
return this.#subscriptions.get("subscriptionId", id);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Iterate over active subscriptions.
|
|
69
|
+
*/
|
|
70
|
+
[Symbol.iterator]() {
|
|
71
|
+
return this.#subscriptions[Symbol.iterator]();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Terminate all subscriptions.
|
|
76
|
+
*/
|
|
77
|
+
async close() {
|
|
78
|
+
if (this.#timeout) {
|
|
79
|
+
this.#timeout.stop();
|
|
80
|
+
this.#timeout = undefined;
|
|
81
|
+
}
|
|
82
|
+
for (const subscription of this.#subscriptions) {
|
|
83
|
+
subscription.close();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Restart the timeout timer for the current set of active subscriptions.
|
|
89
|
+
*/
|
|
90
|
+
resetTimer() {
|
|
91
|
+
const now = Time.nowMs();
|
|
92
|
+
let nextTimeoutAt: number | undefined;
|
|
93
|
+
|
|
94
|
+
// Process each subscription
|
|
95
|
+
for (const subscription of this.#subscriptions) {
|
|
96
|
+
// If reading data reports, ignore for timeout purposes
|
|
97
|
+
if (subscription.isReading) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Update timeout or expire if timed out
|
|
102
|
+
let { timeoutAtMs } = subscription;
|
|
103
|
+
if (timeoutAtMs === undefined) {
|
|
104
|
+
// Set timeout time
|
|
105
|
+
timeoutAtMs = subscription.timeoutAtMs = timeoutFor(subscription);
|
|
106
|
+
} else if (timeoutAtMs < now) {
|
|
107
|
+
// Timeout
|
|
108
|
+
this.#timeOut(subscription);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// If this is the earliest timeout, record
|
|
113
|
+
if (nextTimeoutAt === undefined || nextTimeoutAt > timeoutAtMs) {
|
|
114
|
+
nextTimeoutAt = timeoutAtMs;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// If no subscriptions require timeout, disable timer
|
|
119
|
+
if (nextTimeoutAt === undefined) {
|
|
120
|
+
this.#nextTimeoutAt = undefined;
|
|
121
|
+
this.#timeout?.stop();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Create or update timer if not set for correct interval
|
|
126
|
+
if (nextTimeoutAt !== this.#nextTimeoutAt) {
|
|
127
|
+
this.#nextTimeoutAt = nextTimeoutAt;
|
|
128
|
+
if (this.#timeout) {
|
|
129
|
+
this.#timeout?.stop();
|
|
130
|
+
this.#timeout.intervalMs = nextTimeoutAt - now;
|
|
131
|
+
} else {
|
|
132
|
+
this.#timeout = Time.getTimer("SubscriptionTimeout", nextTimeoutAt - now, this.resetTimer.bind(this));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
#closeOne(subscription: ClientSubscription, cause: CanceledError | TimeoutError) {
|
|
138
|
+
if (subscription.isClosed) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
subscription.isClosed = true;
|
|
142
|
+
this.#subscriptions.delete(subscription);
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
subscription.request.closed?.(cause);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
logger.error("Error canceling subscription", Diagnostic.strong(subscription.subscriptionId), e);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
#timeOut(registration: ClientSubscription) {
|
|
152
|
+
logger.info(
|
|
153
|
+
"Subscription",
|
|
154
|
+
Diagnostic.strong(registration.subscriptionId),
|
|
155
|
+
"timed out after",
|
|
156
|
+
Diagnostic.strong(`${timeoutFor(registration)}ms`),
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
// TODO - rather than closing, put into dormant state and resubscribe when connection reestablishes
|
|
160
|
+
this.#closeOne(registration, new TimeoutError());
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function timeoutFor(subscription: ClientSubscription) {
|
|
165
|
+
return subscription.maxInterval * 1000 + (subscription.request.maxPeerResponseTime ?? 0);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export namespace ClientSubscriptions {
|
|
169
|
+
export interface Listener {
|
|
170
|
+
(reports: AsyncIterable<ReadResult.Chunk>): Promise<void>;
|
|
171
|
+
}
|
|
172
|
+
}
|