@project-chip/matter.js 0.9.2 → 0.9.4
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/CommissioningServer.d.ts.map +1 -1
- package/dist/cjs/CommissioningServer.js +0 -1
- package/dist/cjs/CommissioningServer.js.map +2 -2
- package/dist/cjs/MatterDevice.d.ts +3 -0
- package/dist/cjs/MatterDevice.d.ts.map +1 -1
- package/dist/cjs/MatterDevice.js +21 -7
- package/dist/cjs/MatterDevice.js.map +2 -2
- package/dist/cjs/behavior/AccessControl.js +2 -2
- package/dist/cjs/behavior/AccessControl.js.map +2 -2
- package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts +1 -0
- package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
- package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js +14 -0
- package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js.map +2 -2
- package/dist/cjs/behavior/definitions/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
- package/dist/cjs/behavior/definitions/operational-credentials/OperationalCredentialsServer.js +11 -2
- package/dist/cjs/behavior/definitions/operational-credentials/OperationalCredentialsServer.js.map +2 -2
- package/dist/cjs/behavior/state/transaction/Transaction.d.ts +18 -18
- package/dist/cjs/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateManager.js +1 -0
- package/dist/cjs/certificate/CertificateManager.js.map +2 -2
- package/dist/cjs/certificate/CertificationDeclarationManager.d.ts +1 -1
- package/dist/cjs/certificate/CertificationDeclarationManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificationDeclarationManager.js +3 -2
- package/dist/cjs/certificate/CertificationDeclarationManager.js.map +2 -2
- package/dist/cjs/cluster/server/AccessControlServer.js.map +1 -1
- package/dist/cjs/cluster/server/AttributeServer.d.ts +9 -0
- package/dist/cjs/cluster/server/AttributeServer.d.ts.map +1 -1
- package/dist/cjs/cluster/server/AttributeServer.js +62 -0
- package/dist/cjs/cluster/server/AttributeServer.js.map +3 -3
- package/dist/cjs/cluster/server/ClusterServer.d.ts.map +1 -1
- package/dist/cjs/cluster/server/ClusterServer.js +8 -1
- package/dist/cjs/cluster/server/ClusterServer.js.map +2 -2
- package/dist/cjs/cluster/server/ClusterServerTypes.d.ts +3 -3
- package/dist/cjs/cluster/server/ClusterServerTypes.d.ts.map +1 -1
- package/dist/cjs/cluster/server/ClusterServerTypes.js.map +1 -1
- package/dist/cjs/cluster/server/EventServer.d.ts +8 -2
- package/dist/cjs/cluster/server/EventServer.d.ts.map +1 -1
- package/dist/cjs/cluster/server/EventServer.js +33 -7
- package/dist/cjs/cluster/server/EventServer.js.map +2 -2
- package/dist/cjs/cluster/server/OperationalCredentialsServer.d.ts.map +1 -1
- package/dist/cjs/cluster/server/OperationalCredentialsServer.js +31 -8
- package/dist/cjs/cluster/server/OperationalCredentialsServer.js.map +2 -2
- package/dist/cjs/common/FailsafeContext.d.ts +1 -0
- package/dist/cjs/common/FailsafeContext.d.ts.map +1 -1
- package/dist/cjs/common/FailsafeContext.js +16 -2
- package/dist/cjs/common/FailsafeContext.js.map +2 -2
- package/dist/cjs/crypto/Crypto.d.ts +1 -1
- package/dist/cjs/crypto/Crypto.d.ts.map +1 -1
- package/dist/cjs/crypto/Crypto.js +2 -2
- package/dist/cjs/crypto/Crypto.js.map +2 -2
- package/dist/cjs/device/LegacyInteractionServer.d.ts +2 -2
- package/dist/cjs/device/LegacyInteractionServer.d.ts.map +1 -1
- package/dist/cjs/device/LegacyInteractionServer.js +13 -1
- package/dist/cjs/device/LegacyInteractionServer.js.map +2 -2
- package/dist/cjs/fabric/Fabric.d.ts +1 -0
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js +5 -0
- package/dist/cjs/fabric/Fabric.js.map +2 -2
- package/dist/cjs/fabric/FabricManager.d.ts +1 -0
- package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricManager.js +2 -1
- package/dist/cjs/fabric/FabricManager.js.map +2 -2
- package/dist/cjs/model/models/EventModel.d.ts +1 -0
- package/dist/cjs/model/models/EventModel.d.ts.map +1 -1
- package/dist/cjs/model/models/EventModel.js +3 -0
- package/dist/cjs/model/models/EventModel.js.map +2 -2
- package/dist/cjs/model/models/FieldModel.d.ts +1 -0
- package/dist/cjs/model/models/FieldModel.d.ts.map +1 -1
- package/dist/cjs/model/models/FieldModel.js +3 -0
- package/dist/cjs/model/models/FieldModel.js.map +2 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.d.ts +2 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/cjs/node/server/TransactionalInteractionServer.js +0 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/cjs/protocol/interaction/AttributeDataEncoder.d.ts +6 -3
- package/dist/cjs/protocol/interaction/AttributeDataEncoder.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/AttributeDataEncoder.js +14 -8
- package/dist/cjs/protocol/interaction/AttributeDataEncoder.js.map +2 -2
- package/dist/cjs/protocol/interaction/EventHandler.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/EventHandler.js +1 -3
- package/dist/cjs/protocol/interaction/EventHandler.js.map +2 -2
- package/dist/cjs/protocol/interaction/InteractionClient.js +1 -1
- package/dist/cjs/protocol/interaction/InteractionClient.js.map +2 -2
- package/dist/cjs/protocol/interaction/InteractionEndpointStructure.d.ts +3 -3
- package/dist/cjs/protocol/interaction/InteractionEndpointStructure.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/InteractionEndpointStructure.js +1 -0
- package/dist/cjs/protocol/interaction/InteractionEndpointStructure.js.map +2 -2
- package/dist/cjs/protocol/interaction/InteractionMessenger.d.ts +1 -1
- package/dist/cjs/protocol/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/InteractionMessenger.js +11 -4
- package/dist/cjs/protocol/interaction/InteractionMessenger.js.map +2 -2
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts +5 -6
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/InteractionServer.js +44 -37
- package/dist/cjs/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/cjs/protocol/interaction/SubscriptionHandler.d.ts +31 -12
- package/dist/cjs/protocol/interaction/SubscriptionHandler.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/SubscriptionHandler.js +161 -69
- package/dist/cjs/protocol/interaction/SubscriptionHandler.js.map +3 -3
- package/dist/cjs/session/SecureSession.d.ts.map +1 -1
- package/dist/cjs/session/SecureSession.js +2 -1
- package/dist/cjs/session/SecureSession.js.map +2 -2
- package/dist/cjs/session/SessionManager.d.ts +2 -0
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +7 -0
- package/dist/cjs/session/SessionManager.js.map +2 -2
- package/dist/cjs/tlv/TlvArray.d.ts +2 -2
- package/dist/cjs/tlv/TlvArray.d.ts.map +1 -1
- package/dist/cjs/tlv/TlvArray.js +2 -2
- package/dist/cjs/tlv/TlvArray.js.map +2 -2
- package/dist/cjs/tlv/TlvNullable.d.ts +2 -2
- package/dist/cjs/tlv/TlvNullable.d.ts.map +1 -1
- package/dist/cjs/tlv/TlvNullable.js +2 -2
- package/dist/cjs/tlv/TlvNullable.js.map +2 -2
- package/dist/cjs/tlv/TlvObject.d.ts +2 -2
- package/dist/cjs/tlv/TlvObject.d.ts.map +1 -1
- package/dist/cjs/tlv/TlvObject.js +18 -12
- package/dist/cjs/tlv/TlvObject.js.map +2 -2
- package/dist/cjs/tlv/TlvSchema.d.ts +14 -2
- package/dist/cjs/tlv/TlvSchema.d.ts.map +1 -1
- package/dist/cjs/tlv/TlvSchema.js +2 -2
- package/dist/cjs/tlv/TlvSchema.js.map +2 -2
- package/dist/cjs/tlv/TlvWrapper.d.ts +2 -2
- package/dist/cjs/tlv/TlvWrapper.d.ts.map +1 -1
- package/dist/cjs/tlv/TlvWrapper.js +2 -2
- package/dist/cjs/tlv/TlvWrapper.js.map +2 -2
- package/dist/esm/CommissioningServer.d.ts.map +1 -1
- package/dist/esm/CommissioningServer.js +0 -1
- package/dist/esm/CommissioningServer.js.map +2 -2
- package/dist/esm/MatterDevice.d.ts +3 -0
- package/dist/esm/MatterDevice.d.ts.map +1 -1
- package/dist/esm/MatterDevice.js +21 -7
- package/dist/esm/MatterDevice.js.map +2 -2
- package/dist/esm/behavior/AccessControl.js +2 -2
- package/dist/esm/behavior/AccessControl.js.map +2 -2
- package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts +1 -0
- package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
- package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js +15 -1
- package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js.map +2 -2
- package/dist/esm/behavior/definitions/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
- package/dist/esm/behavior/definitions/operational-credentials/OperationalCredentialsServer.js +11 -2
- package/dist/esm/behavior/definitions/operational-credentials/OperationalCredentialsServer.js.map +2 -2
- package/dist/esm/behavior/state/transaction/Transaction.d.ts +18 -18
- package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateManager.js +1 -0
- package/dist/esm/certificate/CertificateManager.js.map +2 -2
- package/dist/esm/certificate/CertificationDeclarationManager.d.ts +1 -1
- package/dist/esm/certificate/CertificationDeclarationManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificationDeclarationManager.js +3 -2
- package/dist/esm/certificate/CertificationDeclarationManager.js.map +2 -2
- package/dist/esm/cluster/server/AccessControlServer.js.map +1 -1
- package/dist/esm/cluster/server/AttributeServer.d.ts +9 -0
- package/dist/esm/cluster/server/AttributeServer.d.ts.map +1 -1
- package/dist/esm/cluster/server/AttributeServer.js +69 -1
- package/dist/esm/cluster/server/AttributeServer.js.map +2 -2
- package/dist/esm/cluster/server/ClusterServer.d.ts.map +1 -1
- package/dist/esm/cluster/server/ClusterServer.js +9 -2
- package/dist/esm/cluster/server/ClusterServer.js.map +2 -2
- package/dist/esm/cluster/server/ClusterServerTypes.d.ts +3 -3
- package/dist/esm/cluster/server/ClusterServerTypes.d.ts.map +1 -1
- package/dist/esm/cluster/server/ClusterServerTypes.js.map +1 -1
- package/dist/esm/cluster/server/EventServer.d.ts +8 -2
- package/dist/esm/cluster/server/EventServer.d.ts.map +1 -1
- package/dist/esm/cluster/server/EventServer.js +33 -7
- package/dist/esm/cluster/server/EventServer.js.map +2 -2
- package/dist/esm/cluster/server/OperationalCredentialsServer.d.ts.map +1 -1
- package/dist/esm/cluster/server/OperationalCredentialsServer.js +31 -8
- package/dist/esm/cluster/server/OperationalCredentialsServer.js.map +2 -2
- package/dist/esm/common/FailsafeContext.d.ts +1 -0
- package/dist/esm/common/FailsafeContext.d.ts.map +1 -1
- package/dist/esm/common/FailsafeContext.js +17 -3
- package/dist/esm/common/FailsafeContext.js.map +2 -2
- package/dist/esm/crypto/Crypto.d.ts +1 -1
- package/dist/esm/crypto/Crypto.d.ts.map +1 -1
- package/dist/esm/crypto/Crypto.js +2 -2
- package/dist/esm/crypto/Crypto.js.map +2 -2
- package/dist/esm/device/LegacyInteractionServer.d.ts +2 -2
- package/dist/esm/device/LegacyInteractionServer.d.ts.map +1 -1
- package/dist/esm/device/LegacyInteractionServer.js +13 -1
- package/dist/esm/device/LegacyInteractionServer.js.map +2 -2
- package/dist/esm/fabric/Fabric.d.ts +1 -0
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js +5 -0
- package/dist/esm/fabric/Fabric.js.map +2 -2
- package/dist/esm/fabric/FabricManager.d.ts +1 -0
- package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
- package/dist/esm/fabric/FabricManager.js +2 -1
- package/dist/esm/fabric/FabricManager.js.map +2 -2
- package/dist/esm/model/models/EventModel.d.ts +1 -0
- package/dist/esm/model/models/EventModel.d.ts.map +1 -1
- package/dist/esm/model/models/EventModel.js +3 -0
- package/dist/esm/model/models/EventModel.js.map +2 -2
- package/dist/esm/model/models/FieldModel.d.ts +1 -0
- package/dist/esm/model/models/FieldModel.d.ts.map +1 -1
- package/dist/esm/model/models/FieldModel.js +3 -0
- package/dist/esm/model/models/FieldModel.js.map +2 -2
- package/dist/esm/node/server/TransactionalInteractionServer.d.ts +2 -2
- package/dist/esm/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/esm/node/server/TransactionalInteractionServer.js +0 -2
- package/dist/esm/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/esm/protocol/interaction/AttributeDataEncoder.d.ts +6 -3
- package/dist/esm/protocol/interaction/AttributeDataEncoder.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/AttributeDataEncoder.js +14 -8
- package/dist/esm/protocol/interaction/AttributeDataEncoder.js.map +2 -2
- package/dist/esm/protocol/interaction/EventHandler.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/EventHandler.js +1 -3
- package/dist/esm/protocol/interaction/EventHandler.js.map +2 -2
- package/dist/esm/protocol/interaction/InteractionClient.js +1 -1
- package/dist/esm/protocol/interaction/InteractionClient.js.map +2 -2
- package/dist/esm/protocol/interaction/InteractionEndpointStructure.d.ts +3 -3
- package/dist/esm/protocol/interaction/InteractionEndpointStructure.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/InteractionEndpointStructure.js +1 -0
- package/dist/esm/protocol/interaction/InteractionEndpointStructure.js.map +2 -2
- package/dist/esm/protocol/interaction/InteractionMessenger.d.ts +1 -1
- package/dist/esm/protocol/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/InteractionMessenger.js +11 -4
- package/dist/esm/protocol/interaction/InteractionMessenger.js.map +2 -2
- package/dist/esm/protocol/interaction/InteractionServer.d.ts +5 -6
- package/dist/esm/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/InteractionServer.js +44 -37
- package/dist/esm/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/esm/protocol/interaction/SubscriptionHandler.d.ts +31 -12
- package/dist/esm/protocol/interaction/SubscriptionHandler.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/SubscriptionHandler.js +161 -69
- package/dist/esm/protocol/interaction/SubscriptionHandler.js.map +3 -3
- package/dist/esm/session/SecureSession.d.ts.map +1 -1
- package/dist/esm/session/SecureSession.js +2 -1
- package/dist/esm/session/SecureSession.js.map +2 -2
- package/dist/esm/session/SessionManager.d.ts +2 -0
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +7 -0
- package/dist/esm/session/SessionManager.js.map +2 -2
- package/dist/esm/tlv/TlvArray.d.ts +2 -2
- package/dist/esm/tlv/TlvArray.d.ts.map +1 -1
- package/dist/esm/tlv/TlvArray.js +2 -2
- package/dist/esm/tlv/TlvArray.js.map +2 -2
- package/dist/esm/tlv/TlvNullable.d.ts +2 -2
- package/dist/esm/tlv/TlvNullable.d.ts.map +1 -1
- package/dist/esm/tlv/TlvNullable.js +2 -2
- package/dist/esm/tlv/TlvNullable.js.map +2 -2
- package/dist/esm/tlv/TlvObject.d.ts +2 -2
- package/dist/esm/tlv/TlvObject.d.ts.map +1 -1
- package/dist/esm/tlv/TlvObject.js +19 -13
- package/dist/esm/tlv/TlvObject.js.map +2 -2
- package/dist/esm/tlv/TlvSchema.d.ts +14 -2
- package/dist/esm/tlv/TlvSchema.d.ts.map +1 -1
- package/dist/esm/tlv/TlvSchema.js +2 -2
- package/dist/esm/tlv/TlvSchema.js.map +2 -2
- package/dist/esm/tlv/TlvWrapper.d.ts +2 -2
- package/dist/esm/tlv/TlvWrapper.d.ts.map +1 -1
- package/dist/esm/tlv/TlvWrapper.js +2 -2
- package/dist/esm/tlv/TlvWrapper.js.map +2 -2
- package/package.json +3 -3
- package/src/CommissioningServer.ts +0 -1
- package/src/MatterDevice.ts +34 -7
- package/src/behavior/AccessControl.ts +2 -2
- package/src/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.ts +21 -1
- package/src/behavior/definitions/operational-credentials/OperationalCredentialsServer.ts +13 -0
- package/src/certificate/CertificateManager.ts +1 -2
- package/src/certificate/CertificationDeclarationManager.ts +2 -2
- package/src/cluster/server/AccessControlServer.ts +3 -3
- package/src/cluster/server/AttributeServer.ts +79 -1
- package/src/cluster/server/ClusterServer.ts +9 -2
- package/src/cluster/server/ClusterServerTypes.ts +3 -3
- package/src/cluster/server/EventServer.ts +57 -10
- package/src/cluster/server/OperationalCredentialsServer.ts +35 -5
- package/src/common/FailsafeContext.ts +19 -7
- package/src/crypto/Crypto.ts +1 -1
- package/src/device/LegacyInteractionServer.ts +15 -4
- package/src/fabric/Fabric.ts +6 -0
- package/src/fabric/FabricManager.ts +1 -0
- package/src/model/models/EventModel.ts +4 -0
- package/src/model/models/FieldModel.ts +4 -0
- package/src/node/server/TransactionalInteractionServer.ts +2 -4
- package/src/protocol/interaction/AttributeDataEncoder.ts +20 -9
- package/src/protocol/interaction/EventHandler.ts +1 -3
- package/src/protocol/interaction/InteractionClient.ts +1 -1
- package/src/protocol/interaction/InteractionEndpointStructure.ts +4 -4
- package/src/protocol/interaction/InteractionMessenger.ts +12 -3
- package/src/protocol/interaction/InteractionServer.ts +53 -52
- package/src/protocol/interaction/SubscriptionHandler.ts +215 -92
- package/src/session/SecureSession.ts +2 -1
- package/src/session/SessionManager.ts +9 -0
- package/src/tlv/TlvArray.ts +3 -3
- package/src/tlv/TlvNullable.ts +3 -3
- package/src/tlv/TlvObject.ts +20 -14
- package/src/tlv/TlvSchema.ts +17 -3
- package/src/tlv/TlvWrapper.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/fabric/FabricManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { InternalError, MatterError, MatterFlowError } from \"../common/MatterError.js\";\nimport { Key } from \"../crypto/Key.js\";\nimport { FabricIndex } from \"../datatype/FabricIndex.js\";\nimport { StorageContext } from \"../storage/StorageContext.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { Observable } from \"../util/Observable.js\";\nimport { MaybePromise } from \"../util/Promises.js\";\nimport { Fabric, FabricJsonObject } from \"./Fabric.js\";\n\n/** Specific Error for when a fabric is not found. */\nexport class FabricNotFoundError extends MatterError {}\nexport class FabricTableFullError extends MatterError {}\n\nexport enum FabricAction {\n Added,\n Removed,\n Updated,\n}\n\nexport class FabricManager {\n #nextFabricIndex = 1;\n readonly #fabrics = new Map<FabricIndex, Fabric>();\n #initializationDone = false;\n #fabricStorage: StorageContext;\n #events = {\n added: Observable<[fabric: Fabric]>(),\n updated: Observable<[fabric: Fabric]>(),\n deleted: Observable<[fabric: Fabric]>(),\n };\n\n constructor(fabricStorage: StorageContext) {\n this.#fabricStorage = fabricStorage;\n }\n\n async initFromStorage() {\n const fabrics = await this.#fabricStorage.get<FabricJsonObject[]>(\"fabrics\", []);\n fabrics.forEach(fabric => this.addFabric(Fabric.createFromStorageObject(fabric)));\n this.#nextFabricIndex = await this.#fabricStorage.get(\"nextFabricIndex\", this.#nextFabricIndex);\n this.#initializationDone = true;\n }\n\n get events() {\n return this.#events;\n }\n\n getNextFabricIndex() {\n for (let i = 0; i < 254; i++) {\n const fabricIndex = this.#nextFabricIndex++;\n if (this.#nextFabricIndex > 254) this.#nextFabricIndex = 1;\n if (!this.#fabrics.has(FabricIndex(fabricIndex))) {\n return FabricIndex(fabricIndex);\n }\n }\n throw new FabricTableFullError(\"No free fabric index available.\");\n }\n\n persistFabrics(): MaybePromise<void> {\n const storeResult = this.#fabricStorage.set(\n \"fabrics\",\n Array.from(this.#fabrics.values()).map(fabric => fabric.toStorageObject()),\n );\n if (MaybePromise.is(storeResult)) {\n return storeResult.then(() => this.#fabricStorage.set(\"nextFabricIndex\", this.#nextFabricIndex));\n }\n return this.#fabricStorage.set(\"nextFabricIndex\", this.#nextFabricIndex);\n }\n\n addFabric(fabric: Fabric) {\n const { fabricIndex } = fabric;\n if (this.#fabrics.has(fabricIndex)) {\n throw new MatterFlowError(`Fabric with index ${fabricIndex} already exists.`);\n }\n this.#fabrics.set(fabricIndex, fabric);\n fabric.addRemoveCallback(async () => this.removeFabric(fabricIndex));\n fabric.persistCallback = (isUpdate = true) => {\n const persistResult = this.persistFabrics();\n return MaybePromise.then(persistResult, () => {\n if (isUpdate) {\n this.#events.updated.emit(fabric); // Assume Fabric got updated when persist callback is called\n }\n });\n };\n if (this.#initializationDone) {\n this.#events.added.emit(fabric);\n }\n }\n\n async removeFabric(fabricIndex: FabricIndex) {\n const fabric = this.#fabrics.get(fabricIndex);\n if (fabric === undefined)\n throw new FabricNotFoundError(\n `Fabric with index ${fabricIndex} cannot be removed because it does not exist.`,\n );\n this.#fabrics.delete(fabricIndex);\n await this.persistFabrics();\n this.#events.deleted.emit(fabric);\n }\n\n getFabrics() {\n return Array.from(this.#fabrics.values());\n }\n\n findFabricFromDestinationId(destinationId: ByteArray, initiatorRandom: ByteArray) {\n for (const fabric of this.#fabrics.values()) {\n const candidateDestinationId = fabric.getDestinationId(fabric.nodeId, initiatorRandom);\n if (!candidateDestinationId.equals(destinationId)) continue;\n return fabric;\n }\n\n throw new InternalError(\"Fabric cannot be found from destinationId\");\n }\n\n findByKeypair(keypair: Key) {\n for (const fabric of this.#fabrics.values()) {\n if (fabric.matchesKeyPair(keypair)) {\n return fabric;\n }\n }\n return undefined;\n }\n\n async updateFabric(fabric: Fabric) {\n const { fabricIndex } = fabric;\n if (!this.#fabrics.has(fabricIndex)) {\n throw new FabricNotFoundError(\n `Fabric with index ${fabricIndex} cannot be updated because it does not exist.`,\n );\n }\n this.#fabrics.set(fabricIndex, fabric);\n await this.persistFabrics();\n this.#events.updated.emit(fabric);\n }\n\n async revokeFabric(fabricIndex: FabricIndex) {\n const fabric = this.#fabrics.get(fabricIndex);\n if (fabric === undefined) {\n throw new MatterFlowError(`Fabric with index ${fabricIndex} does not exist to revoke.`);\n }\n await fabric.remove();\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,eAAe,aAAa,uBAAuB;AAE5D,SAAS,mBAAmB;AAG5B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,cAAgC;AAGlC,MAAM,4BAA4B,YAAY;AAAC;AAC/C,MAAM,6BAA6B,YAAY;AAAC;AAEhD,IAAK,eAAL,kBAAKA,kBAAL;AACH,EAAAA,4BAAA;AACA,EAAAA,4BAAA;AACA,EAAAA,4BAAA;AAHQ,SAAAA;AAAA,GAAA;AAML,MAAM,cAAc;AAAA,EACvB,mBAAmB;AAAA,EACV,WAAW,oBAAI,IAAyB;AAAA,EACjD,sBAAsB;AAAA,EACtB;AAAA,EACA,UAAU;AAAA,IACN,OAAO,WAA6B;AAAA,IACpC,SAAS,WAA6B;AAAA,IACtC,SAAS,WAA6B;AAAA,
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { InternalError, MatterError, MatterFlowError } from \"../common/MatterError.js\";\nimport { Key } from \"../crypto/Key.js\";\nimport { FabricIndex } from \"../datatype/FabricIndex.js\";\nimport { StorageContext } from \"../storage/StorageContext.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { Observable } from \"../util/Observable.js\";\nimport { MaybePromise } from \"../util/Promises.js\";\nimport { Fabric, FabricJsonObject } from \"./Fabric.js\";\n\n/** Specific Error for when a fabric is not found. */\nexport class FabricNotFoundError extends MatterError {}\nexport class FabricTableFullError extends MatterError {}\n\nexport enum FabricAction {\n Added,\n Removed,\n Updated,\n}\n\nexport class FabricManager {\n #nextFabricIndex = 1;\n readonly #fabrics = new Map<FabricIndex, Fabric>();\n #initializationDone = false;\n #fabricStorage: StorageContext;\n #events = {\n added: Observable<[fabric: Fabric]>(),\n updated: Observable<[fabric: Fabric]>(),\n deleted: Observable<[fabric: Fabric]>(),\n failsafeClosed: Observable<[]>(),\n };\n\n constructor(fabricStorage: StorageContext) {\n this.#fabricStorage = fabricStorage;\n }\n\n async initFromStorage() {\n const fabrics = await this.#fabricStorage.get<FabricJsonObject[]>(\"fabrics\", []);\n fabrics.forEach(fabric => this.addFabric(Fabric.createFromStorageObject(fabric)));\n this.#nextFabricIndex = await this.#fabricStorage.get(\"nextFabricIndex\", this.#nextFabricIndex);\n this.#initializationDone = true;\n }\n\n get events() {\n return this.#events;\n }\n\n getNextFabricIndex() {\n for (let i = 0; i < 254; i++) {\n const fabricIndex = this.#nextFabricIndex++;\n if (this.#nextFabricIndex > 254) this.#nextFabricIndex = 1;\n if (!this.#fabrics.has(FabricIndex(fabricIndex))) {\n return FabricIndex(fabricIndex);\n }\n }\n throw new FabricTableFullError(\"No free fabric index available.\");\n }\n\n persistFabrics(): MaybePromise<void> {\n const storeResult = this.#fabricStorage.set(\n \"fabrics\",\n Array.from(this.#fabrics.values()).map(fabric => fabric.toStorageObject()),\n );\n if (MaybePromise.is(storeResult)) {\n return storeResult.then(() => this.#fabricStorage.set(\"nextFabricIndex\", this.#nextFabricIndex));\n }\n return this.#fabricStorage.set(\"nextFabricIndex\", this.#nextFabricIndex);\n }\n\n addFabric(fabric: Fabric) {\n const { fabricIndex } = fabric;\n if (this.#fabrics.has(fabricIndex)) {\n throw new MatterFlowError(`Fabric with index ${fabricIndex} already exists.`);\n }\n this.#fabrics.set(fabricIndex, fabric);\n fabric.addRemoveCallback(async () => this.removeFabric(fabricIndex));\n fabric.persistCallback = (isUpdate = true) => {\n const persistResult = this.persistFabrics();\n return MaybePromise.then(persistResult, () => {\n if (isUpdate) {\n this.#events.updated.emit(fabric); // Assume Fabric got updated when persist callback is called\n }\n });\n };\n if (this.#initializationDone) {\n this.#events.added.emit(fabric);\n }\n }\n\n async removeFabric(fabricIndex: FabricIndex) {\n const fabric = this.#fabrics.get(fabricIndex);\n if (fabric === undefined)\n throw new FabricNotFoundError(\n `Fabric with index ${fabricIndex} cannot be removed because it does not exist.`,\n );\n this.#fabrics.delete(fabricIndex);\n await this.persistFabrics();\n this.#events.deleted.emit(fabric);\n }\n\n getFabrics() {\n return Array.from(this.#fabrics.values());\n }\n\n findFabricFromDestinationId(destinationId: ByteArray, initiatorRandom: ByteArray) {\n for (const fabric of this.#fabrics.values()) {\n const candidateDestinationId = fabric.getDestinationId(fabric.nodeId, initiatorRandom);\n if (!candidateDestinationId.equals(destinationId)) continue;\n return fabric;\n }\n\n throw new InternalError(\"Fabric cannot be found from destinationId\");\n }\n\n findByKeypair(keypair: Key) {\n for (const fabric of this.#fabrics.values()) {\n if (fabric.matchesKeyPair(keypair)) {\n return fabric;\n }\n }\n return undefined;\n }\n\n async updateFabric(fabric: Fabric) {\n const { fabricIndex } = fabric;\n if (!this.#fabrics.has(fabricIndex)) {\n throw new FabricNotFoundError(\n `Fabric with index ${fabricIndex} cannot be updated because it does not exist.`,\n );\n }\n this.#fabrics.set(fabricIndex, fabric);\n await this.persistFabrics();\n this.#events.updated.emit(fabric);\n }\n\n async revokeFabric(fabricIndex: FabricIndex) {\n const fabric = this.#fabrics.get(fabricIndex);\n if (fabric === undefined) {\n throw new MatterFlowError(`Fabric with index ${fabricIndex} does not exist to revoke.`);\n }\n await fabric.remove();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["FabricAction"]
|
|
7
7
|
}
|
|
@@ -11,6 +11,7 @@ export declare class EventModel extends ValueModel implements EventElement {
|
|
|
11
11
|
id: Mei;
|
|
12
12
|
priority?: EventElement.Priority;
|
|
13
13
|
constructor(definition: EventElement.Properties);
|
|
14
|
+
get fabricSensitive(): boolean;
|
|
14
15
|
static Tag: import("../index.js").ElementTag;
|
|
15
16
|
}
|
|
16
17
|
//# sourceMappingURL=EventModel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/EventModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,qBAAa,UAAW,SAAQ,UAAW,YAAW,YAAY;IACrD,GAAG,EAAE,YAAY,CAAC,GAAG,CAAoB;IACzC,EAAE,EAAG,GAAG,CAAC;IAClB,QAAQ,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC;gBAErB,UAAU,EAAE,YAAY,CAAC,UAAU;
|
|
1
|
+
{"version":3,"file":"EventModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/EventModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,qBAAa,UAAW,SAAQ,UAAW,YAAW,YAAY;IACrD,GAAG,EAAE,YAAY,CAAC,GAAG,CAAoB;IACzC,EAAE,EAAG,GAAG,CAAC;IAClB,QAAQ,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC;gBAErB,UAAU,EAAE,YAAY,CAAC,UAAU;IAI/C,IAAI,eAAe,IAAI,OAAO,CAE7B;IAMD,MAAM,CAAC,GAAG,mCAAoB;CACjC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/model/models/EventModel.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { EventElement } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { ValueModel } from \"./ValueModel.js\";\n\nexport class EventModel extends ValueModel implements EventElement {\n override tag: EventElement.Tag = EventElement.Tag;\n override id!: Mei;\n priority?: EventElement.Priority;\n\n constructor(definition: EventElement.Properties) {\n super(definition);\n }\n\n static {\n Model.types[EventElement.Tag] = this;\n }\n\n static Tag = EventElement.Tag;\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,oBAAoB;AAC7B,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAEpB,MAAM,mBAAmB,WAAmC;AAAA,EAK/D,YAAY,YAAqC;AAC7C,UAAM,UAAU;AALpB,SAAS,MAAwB,aAAa;AAAA,EAM9C;AAAA,EAEA,OAAO;AACH,UAAM,MAAM,aAAa,GAAG,IAAI;AAAA,EACpC;AAAA,EAEA;AAAA,SAAO,MAAM,aAAa;AAAA;AAC9B;",
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { EventElement } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { ValueModel } from \"./ValueModel.js\";\n\nexport class EventModel extends ValueModel implements EventElement {\n override tag: EventElement.Tag = EventElement.Tag;\n override id!: Mei;\n priority?: EventElement.Priority;\n\n constructor(definition: EventElement.Properties) {\n super(definition);\n }\n\n get fabricSensitive(): boolean {\n return this.effectiveAccess.fabricSensitive;\n }\n\n static {\n Model.types[EventElement.Tag] = this;\n }\n\n static Tag = EventElement.Tag;\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,oBAAoB;AAC7B,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAEpB,MAAM,mBAAmB,WAAmC;AAAA,EAK/D,YAAY,YAAqC;AAC7C,UAAM,UAAU;AALpB,SAAS,MAAwB,aAAa;AAAA,EAM9C;AAAA,EAEA,IAAI,kBAA2B;AAC3B,WAAO,KAAK,gBAAgB;AAAA,EAChC;AAAA,EAEA,OAAO;AACH,UAAM,MAAM,aAAa,GAAG,IAAI;AAAA,EACpC;AAAA,EAEA;AAAA,SAAO,MAAM,aAAa;AAAA;AAC9B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -11,6 +11,7 @@ export declare class FieldModel extends PropertyModel implements FieldElement {
|
|
|
11
11
|
id?: Mei;
|
|
12
12
|
isGlobalAttribute?: boolean;
|
|
13
13
|
constructor(definition: FieldElement.Properties);
|
|
14
|
+
get fabricSensitive(): boolean;
|
|
14
15
|
/**
|
|
15
16
|
* Fields may omit their ID. In this case we use their index within the parent as the ID.
|
|
16
17
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/FieldModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,qBAAa,UAAW,SAAQ,aAAc,YAAW,YAAY;IACxD,GAAG,EAAE,YAAY,CAAC,GAAG,CAAoB;IACzC,EAAE,CAAC,EAAE,GAAG,CAAC;IACT,iBAAiB,CAAC,EAAE,OAAO,CAAC;gBAEzB,UAAU,EAAE,YAAY,CAAC,UAAU;IAI/C;;OAEG;IACH,IAAa,WAAW,uBAUvB;IAED;;;OAGG;IACH,IAAa,GAAG,uBAKf;CAKJ"}
|
|
1
|
+
{"version":3,"file":"FieldModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/FieldModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,qBAAa,UAAW,SAAQ,aAAc,YAAW,YAAY;IACxD,GAAG,EAAE,YAAY,CAAC,GAAG,CAAoB;IACzC,EAAE,CAAC,EAAE,GAAG,CAAC;IACT,iBAAiB,CAAC,EAAE,OAAO,CAAC;gBAEzB,UAAU,EAAE,YAAY,CAAC,UAAU;IAI/C,IAAI,eAAe,YAElB;IAED;;OAEG;IACH,IAAa,WAAW,uBAUvB;IAED;;;OAGG;IACH,IAAa,GAAG,uBAKf;CAKJ"}
|
|
@@ -13,6 +13,9 @@ class FieldModel extends PropertyModel {
|
|
|
13
13
|
super(definition);
|
|
14
14
|
this.tag = FieldElement.Tag;
|
|
15
15
|
}
|
|
16
|
+
get fabricSensitive() {
|
|
17
|
+
return this.effectiveAccess.fabricSensitive;
|
|
18
|
+
}
|
|
16
19
|
/**
|
|
17
20
|
* Fields may omit their ID. In this case we use their index within the parent as the ID.
|
|
18
21
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/model/models/FieldModel.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { Metatype } from \"../definitions/index.js\";\nimport { FieldElement } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { PropertyModel } from \"./PropertyModel.js\";\nimport { ValueModel } from \"./ValueModel.js\";\n\nexport class FieldModel extends PropertyModel implements FieldElement {\n override tag: FieldElement.Tag = FieldElement.Tag;\n override id?: Mei;\n override isGlobalAttribute?: boolean;\n\n constructor(definition: FieldElement.Properties) {\n super(definition);\n }\n\n /**\n * Fields may omit their ID. In this case we use their index within the parent as the ID.\n */\n override get effectiveId() {\n if (this.id !== undefined) {\n return this.id;\n }\n if (this.parent instanceof ValueModel) {\n const index = this.parent.children.indexOf(this);\n if (index !== -1) {\n return index;\n }\n }\n }\n\n /**\n * The key for bitmap fields is actually the constraint which defines the bit range. All other datatypes use the\n * default key.\n */\n override get key() {\n if (this.parent instanceof ValueModel && this.parent.effectiveMetatype === Metatype.bitmap) {\n return this.constraint.toString();\n }\n return super.key;\n }\n\n static {\n Model.types[FieldElement.Tag] = this;\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAC7B,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAEpB,MAAM,mBAAmB,cAAsC;AAAA,EAKlE,YAAY,YAAqC;AAC7C,UAAM,UAAU;AALpB,SAAS,MAAwB,aAAa;AAAA,EAM9C;AAAA;AAAA;AAAA;AAAA,EAKA,IAAa,cAAc;AACvB,QAAI,KAAK,OAAO,QAAW;AACvB,aAAO,KAAK;AAAA,IAChB;AACA,QAAI,KAAK,kBAAkB,YAAY;AACnC,YAAM,QAAQ,KAAK,OAAO,SAAS,QAAQ,IAAI;AAC/C,UAAI,UAAU,IAAI;AACd,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAa,MAAM;AACf,QAAI,KAAK,kBAAkB,cAAc,KAAK,OAAO,sBAAsB,SAAS,QAAQ;AACxF,aAAO,KAAK,WAAW,SAAS;AAAA,IACpC;AACA,WAAO,MAAM;AAAA,EACjB;AAAA,EAEA,OAAO;AACH,UAAM,MAAM,aAAa,GAAG,IAAI;AAAA,EACpC;AACJ;",
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { Metatype } from \"../definitions/index.js\";\nimport { FieldElement } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { PropertyModel } from \"./PropertyModel.js\";\nimport { ValueModel } from \"./ValueModel.js\";\n\nexport class FieldModel extends PropertyModel implements FieldElement {\n override tag: FieldElement.Tag = FieldElement.Tag;\n override id?: Mei;\n override isGlobalAttribute?: boolean;\n\n constructor(definition: FieldElement.Properties) {\n super(definition);\n }\n\n get fabricSensitive() {\n return this.effectiveAccess.fabricSensitive;\n }\n\n /**\n * Fields may omit their ID. In this case we use their index within the parent as the ID.\n */\n override get effectiveId() {\n if (this.id !== undefined) {\n return this.id;\n }\n if (this.parent instanceof ValueModel) {\n const index = this.parent.children.indexOf(this);\n if (index !== -1) {\n return index;\n }\n }\n }\n\n /**\n * The key for bitmap fields is actually the constraint which defines the bit range. All other datatypes use the\n * default key.\n */\n override get key() {\n if (this.parent instanceof ValueModel && this.parent.effectiveMetatype === Metatype.bitmap) {\n return this.constraint.toString();\n }\n return super.key;\n }\n\n static {\n Model.types[FieldElement.Tag] = this;\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAC7B,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAEpB,MAAM,mBAAmB,cAAsC;AAAA,EAKlE,YAAY,YAAqC;AAC7C,UAAM,UAAU;AALpB,SAAS,MAAwB,aAAa;AAAA,EAM9C;AAAA,EAEA,IAAI,kBAAkB;AAClB,WAAO,KAAK,gBAAgB;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAa,cAAc;AACvB,QAAI,KAAK,OAAO,QAAW;AACvB,aAAO,KAAK;AAAA,IAChB;AACA,QAAI,KAAK,kBAAkB,YAAY;AACnC,YAAM,QAAQ,KAAK,OAAO,SAAS,QAAQ,IAAI;AAC/C,UAAI,UAAU,IAAI;AACd,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAa,MAAM;AACf,QAAI,KAAK,kBAAkB,cAAc,KAAK,OAAO,sBAAsB,SAAS,QAAQ;AACxF,aAAO,KAAK,WAAW,SAAS;AAAA,IACpC;AACA,WAAO,MAAM;AAAA,EACjB;AAAA,EAEA,OAAO;AACH,UAAM,MAAM,aAAa,GAAG,IAAI;AAAA,EACpC;AACJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,7 +7,7 @@ import { MatterDevice } from "../../MatterDevice.js";
|
|
|
7
7
|
import { AccessControlServer } from "../../behavior/definitions/access-control/AccessControlServer.js";
|
|
8
8
|
import { AnyAttributeServer, AttributeServer } from "../../cluster/server/AttributeServer.js";
|
|
9
9
|
import { CommandServer } from "../../cluster/server/CommandServer.js";
|
|
10
|
-
import {
|
|
10
|
+
import { AnyEventServer } from "../../cluster/server/EventServer.js";
|
|
11
11
|
import { Message } from "../../codec/MessageCodec.js";
|
|
12
12
|
import { Endpoint } from "../../endpoint/Endpoint.js";
|
|
13
13
|
import { EndpointInterface } from "../../endpoint/EndpointInterface.js";
|
|
@@ -41,7 +41,7 @@ export declare class TransactionalInteractionServer extends InteractionServer {
|
|
|
41
41
|
version: number;
|
|
42
42
|
value: any;
|
|
43
43
|
}>;
|
|
44
|
-
protected readEvent(path: EventPath, eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined, event:
|
|
44
|
+
protected readEvent(path: EventPath, eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined, event: AnyEventServer<any, any>, exchange: MessageExchange<MatterDevice>, fabricFiltered: boolean, message: Message, endpoint: EndpointInterface): Promise<EventStorageData<any>[]>;
|
|
45
45
|
handleWriteRequest(exchange: MessageExchange<MatterDevice>, writeRequest: WriteRequest, message: Message): Promise<WriteResponse>;
|
|
46
46
|
protected writeAttribute(path: AttributePath, attribute: AttributeServer<any>, value: any, exchange: MessageExchange<MatterDevice>, message: Message, endpoint: EndpointInterface, timed?: boolean, isListWrite?: boolean): Promise<void>;
|
|
47
47
|
protected invokeCommand(path: CommandPath, command: CommandServer<any, any>, exchange: MessageExchange<MatterDevice>, commandFields: any, message: Message, endpoint: EndpointInterface, timed?: boolean): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAEvG,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAEvG,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAIxE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAE9E,OAAO,EAEH,YAAY,EACZ,aAAa,EAChB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,OAAO,EACH,aAAa,EACb,WAAW,EACX,SAAS,EACT,iBAAiB,EACpB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAW9C;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA+B,SAAQ,iBAAiB;;gBASrD,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;IA6BjD,CAAC,MAAM,CAAC,YAAY,CAAC;IAM3B,gBAAgB;IAID,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC;IAiBpE,IAAI,SAAS,wBASZ;cAEwB,aAAa,CAClC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAClC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB;;;;cAgBN,SAAS,CAC9B,IAAI,EAAE,SAAS,EACf,YAAY,EAAE,cAAc,CAAC,OAAO,cAAc,CAAC,EAAE,GAAG,SAAS,EACjE,KAAK,EAAE,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAC/B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;IAsBpB,kBAAkB,CAC7B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,GACjB,OAAO,CAAC,aAAa,CAAC;cAWA,cAAc,CACnC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAC/B,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ,EACb,WAAW,CAAC,EAAE,OAAO;cA6BA,aAAa,CAClC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAChC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,GAAG,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ;;;;;;CAmCpB"}
|
|
@@ -56,7 +56,6 @@ import {
|
|
|
56
56
|
InteractionServer
|
|
57
57
|
} from "../../protocol/interaction/InteractionServer.js";
|
|
58
58
|
import { MaybePromise } from "../../util/Promises.js";
|
|
59
|
-
import { ServerStore } from "./storage/ServerStore.js";
|
|
60
59
|
const activityKey = Symbol("activity");
|
|
61
60
|
const AclClusterId = AccessControlCluster.id;
|
|
62
61
|
const AclAttributeId = AccessControlCluster.attributes.acl.id;
|
|
@@ -71,7 +70,6 @@ class TransactionalInteractionServer extends InteractionServer {
|
|
|
71
70
|
constructor(endpoint) {
|
|
72
71
|
const structure = new InteractionEndpointStructure();
|
|
73
72
|
super({
|
|
74
|
-
eventHandler: endpoint.env.get(ServerStore).eventHandler,
|
|
75
73
|
endpointStructure: structure,
|
|
76
74
|
subscriptionOptions: endpoint.state.network.subscriptionOptions
|
|
77
75
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/node/server/TransactionalInteractionServer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { AccessControl } from \"../../behavior/AccessControl.js\";\nimport { ActionContext } from \"../../behavior/context/ActionContext.js\";\nimport { ActionTracer } from \"../../behavior/context/ActionTracer.js\";\nimport { NodeActivity } from \"../../behavior/context/NodeActivity.js\";\nimport { OnlineContext } from \"../../behavior/context/server/OnlineContext.js\";\nimport { AccessControlServer } from \"../../behavior/definitions/access-control/AccessControlServer.js\";\nimport { AccessControlCluster } from \"../../cluster/definitions/AccessControlCluster.js\";\nimport { AnyAttributeServer, AttributeServer } from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { EventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { InternalError } from \"../../common/MatterError.js\";\nimport { Endpoint } from \"../../endpoint/Endpoint.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { EndpointServer } from \"../../endpoint/EndpointServer.js\";\nimport { EndpointLifecycle } from \"../../endpoint/properties/EndpointLifecycle.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { AccessDeniedError } from \"../../protocol/interaction/AccessControlManager.js\";\nimport { EventStorageData } from \"../../protocol/interaction/EventHandler.js\";\nimport { InteractionEndpointStructure } from \"../../protocol/interaction/InteractionEndpointStructure.js\";\nimport {\n InteractionServerMessenger,\n WriteRequest,\n WriteResponse,\n} from \"../../protocol/interaction/InteractionMessenger.js\";\nimport { TlvEventFilter } from \"../../protocol/interaction/InteractionProtocol.js\";\nimport {\n AttributePath,\n CommandPath,\n EventPath,\n InteractionServer,\n} from \"../../protocol/interaction/InteractionServer.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { ServerNode } from \"../ServerNode.js\";\nimport { ServerStore } from \"./storage/ServerStore.js\";\n\nconst activityKey = Symbol(\"activity\");\n\ninterface WithActivity {\n [activityKey]?: NodeActivity.Activity;\n}\n\nconst AclClusterId = AccessControlCluster.id;\nconst AclAttributeId = AccessControlCluster.attributes.acl.id;\n\n/**\n * Wire up an InteractionServer that initializes an InvocationContext earlier than the cluster API supports.\n *\n * This is necessary for attributes because the ClusterServer attribute APIs are synchronous while transaction\n * management is asynchronous.\n *\n * It's not necessary for command handling because that API is entirely async. We do it here, however, just for the\n * sake of consistency.\n *\n * This could be integrated directly into InteractionServer but this further refactoring is probably warranted there\n * regardless. This keeps the touch light for now.\n */\nexport class TransactionalInteractionServer extends InteractionServer {\n #endpointStructure: InteractionEndpointStructure;\n #changeListener: (type: EndpointLifecycle.Change) => void;\n #endpoint: Endpoint<ServerNode.RootEndpoint>;\n #activity: NodeActivity;\n #newActivityBlocked = false;\n #aclServer?: AccessControlServer;\n #aclUpdateIsDelayed = false;\n\n constructor(endpoint: Endpoint<ServerNode.RootEndpoint>) {\n const structure = new InteractionEndpointStructure();\n\n super({\n eventHandler: endpoint.env.get(ServerStore).eventHandler,\n endpointStructure: structure,\n subscriptionOptions: endpoint.state.network.subscriptionOptions,\n });\n\n this.#activity = endpoint.env.get(NodeActivity);\n\n this.#endpoint = endpoint;\n this.#endpointStructure = structure;\n\n // TODO - rewrite element lookup so we don't need to build the secondary endpoint structure cache\n this.#updateStructure();\n this.#changeListener = type => {\n switch (type) {\n case EndpointLifecycle.Change.TreeReady:\n case EndpointLifecycle.Change.ClientsChanged:\n case EndpointLifecycle.Change.ServersChanged:\n case EndpointLifecycle.Change.Destroyed:\n this.#updateStructure();\n break;\n }\n };\n\n endpoint.lifecycle.changed.on(this.#changeListener);\n }\n\n async [Symbol.asyncDispose]() {\n this.#endpoint.lifecycle.changed.off(this.#changeListener);\n await this.close();\n this.#endpointStructure.close();\n }\n\n blockNewActivity() {\n this.#newActivityBlocked = true;\n }\n\n override async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // When closing, ignore anything newly incoming\n if (this.#newActivityBlocked || this.isClosing) {\n return;\n }\n\n // Activity tracking. This provides diagnostic information and prevents the server from shutting down whilst\n // the exchange is active\n using activity = this.#activity.begin(`session#${exchange.session.id.toString(16)}`);\n (exchange as WithActivity)[activityKey] = activity;\n\n // Delegate to InteractionServerMessenger\n return new InteractionServerMessenger(exchange)\n .handleRequest(this)\n .finally(() => delete (exchange as WithActivity)[activityKey]);\n }\n\n get aclServer() {\n if (this.#aclServer !== undefined) {\n return this.#aclServer;\n }\n const aclServer = this.#endpoint.act(agent => agent.get(AccessControlServer));\n if (MaybePromise.is(aclServer)) {\n throw new InternalError(\"AccessControlServer should already be initialized.\");\n }\n return (this.#aclServer = aclServer);\n }\n\n protected override async readAttribute(\n path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ) {\n const readAttribute = () => super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint);\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readAttribute);\n }\n\n protected override async readEvent(\n path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: EventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ): Promise<EventStorageData<any>[]> {\n const readEvent = (context: ActionContext) => {\n if (!context.authorizedFor(event.readAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.readEvent(path, eventFilters, event, exchange, fabricFiltered, message, endpoint);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readEvent);\n }\n\n override async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n writeRequest: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n const result = await super.handleWriteRequest(exchange, writeRequest, message);\n\n // We delayed the ACL update during the write transaction, so we need to update it now that anything is written\n if (this.#aclUpdateIsDelayed) {\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n return result;\n }\n\n protected override async writeAttribute(\n path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n isListWrite?: boolean,\n ) {\n const writeAttribute = () =>\n super.writeAttribute(path, attribute, value, exchange, message, endpoint, timed, isListWrite);\n\n if (path.endpointId === 0 && path.clusterId === AclClusterId && path.attributeId === AclAttributeId) {\n // This is a hack to prevent the ACL from updating while we are in the middle of a write transaction\n // and is needed because Acl should not become effective during writing of the ACL itself.\n this.aclServer.aclUpdateDelayed = true;\n this.#aclUpdateIsDelayed = true;\n } else if (this.#aclUpdateIsDelayed) {\n // Ok it seems that acl was written, but we now write another path, so we can update Acl attribute now\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n timed,\n message,\n session: exchange.session,\n fabricFiltered: true,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Write,\n endpoint,\n root: this.#endpoint,\n }).act(writeAttribute);\n }\n\n protected override async invokeCommand(\n path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n ) {\n const invokeCommand = (context: ActionContext) => {\n if (!context.authorizedFor(command.invokeAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.invokeCommand(path, command, exchange, commandFields, message, endpoint, timed);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n command: true,\n timed,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Invoke,\n endpoint,\n root: this.#endpoint,\n }).act(invokeCommand);\n }\n\n get #tracer() {\n if (this.#endpoint.env.has(ActionTracer)) {\n return this.#endpoint.env.get(ActionTracer);\n }\n }\n\n #updateStructure() {\n if (this.#endpoint.lifecycle.isTreeReady) {\n this.#endpointStructure.initializeFromEndpoint(EndpointServer.forEndpoint(this.#endpoint));\n }\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AAKrC,SAAS,qBAAqB;AAG9B,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAE3B,SAAS,yBAAyB;AAElC,SAAS,oCAAoC;AAC7C;AAAA,EACI;AAAA,OAGG;AAEP;AAAA,EAII;AAAA,OACG;AAEP,SAAS,oBAAoB;
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { AccessControl } from \"../../behavior/AccessControl.js\";\nimport { ActionContext } from \"../../behavior/context/ActionContext.js\";\nimport { ActionTracer } from \"../../behavior/context/ActionTracer.js\";\nimport { NodeActivity } from \"../../behavior/context/NodeActivity.js\";\nimport { OnlineContext } from \"../../behavior/context/server/OnlineContext.js\";\nimport { AccessControlServer } from \"../../behavior/definitions/access-control/AccessControlServer.js\";\nimport { AccessControlCluster } from \"../../cluster/definitions/AccessControlCluster.js\";\nimport { AnyAttributeServer, AttributeServer } from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { AnyEventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { InternalError } from \"../../common/MatterError.js\";\nimport { Endpoint } from \"../../endpoint/Endpoint.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { EndpointServer } from \"../../endpoint/EndpointServer.js\";\nimport { EndpointLifecycle } from \"../../endpoint/properties/EndpointLifecycle.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { AccessDeniedError } from \"../../protocol/interaction/AccessControlManager.js\";\nimport { EventStorageData } from \"../../protocol/interaction/EventHandler.js\";\nimport { InteractionEndpointStructure } from \"../../protocol/interaction/InteractionEndpointStructure.js\";\nimport {\n InteractionServerMessenger,\n WriteRequest,\n WriteResponse,\n} from \"../../protocol/interaction/InteractionMessenger.js\";\nimport { TlvEventFilter } from \"../../protocol/interaction/InteractionProtocol.js\";\nimport {\n AttributePath,\n CommandPath,\n EventPath,\n InteractionServer,\n} from \"../../protocol/interaction/InteractionServer.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { ServerNode } from \"../ServerNode.js\";\n\nconst activityKey = Symbol(\"activity\");\n\ninterface WithActivity {\n [activityKey]?: NodeActivity.Activity;\n}\n\nconst AclClusterId = AccessControlCluster.id;\nconst AclAttributeId = AccessControlCluster.attributes.acl.id;\n\n/**\n * Wire up an InteractionServer that initializes an InvocationContext earlier than the cluster API supports.\n *\n * This is necessary for attributes because the ClusterServer attribute APIs are synchronous while transaction\n * management is asynchronous.\n *\n * It's not necessary for command handling because that API is entirely async. We do it here, however, just for the\n * sake of consistency.\n *\n * This could be integrated directly into InteractionServer but this further refactoring is probably warranted there\n * regardless. This keeps the touch light for now.\n */\nexport class TransactionalInteractionServer extends InteractionServer {\n #endpointStructure: InteractionEndpointStructure;\n #changeListener: (type: EndpointLifecycle.Change) => void;\n #endpoint: Endpoint<ServerNode.RootEndpoint>;\n #activity: NodeActivity;\n #newActivityBlocked = false;\n #aclServer?: AccessControlServer;\n #aclUpdateIsDelayed = false;\n\n constructor(endpoint: Endpoint<ServerNode.RootEndpoint>) {\n const structure = new InteractionEndpointStructure();\n\n super({\n endpointStructure: structure,\n subscriptionOptions: endpoint.state.network.subscriptionOptions,\n });\n\n this.#activity = endpoint.env.get(NodeActivity);\n\n this.#endpoint = endpoint;\n this.#endpointStructure = structure;\n\n // TODO - rewrite element lookup so we don't need to build the secondary endpoint structure cache\n this.#updateStructure();\n this.#changeListener = type => {\n switch (type) {\n case EndpointLifecycle.Change.TreeReady:\n case EndpointLifecycle.Change.ClientsChanged:\n case EndpointLifecycle.Change.ServersChanged:\n case EndpointLifecycle.Change.Destroyed:\n this.#updateStructure();\n break;\n }\n };\n\n endpoint.lifecycle.changed.on(this.#changeListener);\n }\n\n async [Symbol.asyncDispose]() {\n this.#endpoint.lifecycle.changed.off(this.#changeListener);\n await this.close();\n this.#endpointStructure.close();\n }\n\n blockNewActivity() {\n this.#newActivityBlocked = true;\n }\n\n override async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // When closing, ignore anything newly incoming\n if (this.#newActivityBlocked || this.isClosing) {\n return;\n }\n\n // Activity tracking. This provides diagnostic information and prevents the server from shutting down whilst\n // the exchange is active\n using activity = this.#activity.begin(`session#${exchange.session.id.toString(16)}`);\n (exchange as WithActivity)[activityKey] = activity;\n\n // Delegate to InteractionServerMessenger\n return new InteractionServerMessenger(exchange)\n .handleRequest(this)\n .finally(() => delete (exchange as WithActivity)[activityKey]);\n }\n\n get aclServer() {\n if (this.#aclServer !== undefined) {\n return this.#aclServer;\n }\n const aclServer = this.#endpoint.act(agent => agent.get(AccessControlServer));\n if (MaybePromise.is(aclServer)) {\n throw new InternalError(\"AccessControlServer should already be initialized.\");\n }\n return (this.#aclServer = aclServer);\n }\n\n protected override async readAttribute(\n path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ) {\n const readAttribute = () => super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint);\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readAttribute);\n }\n\n protected override async readEvent(\n path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: AnyEventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ): Promise<EventStorageData<any>[]> {\n const readEvent = (context: ActionContext) => {\n if (!context.authorizedFor(event.readAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.readEvent(path, eventFilters, event, exchange, fabricFiltered, message, endpoint);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readEvent);\n }\n\n override async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n writeRequest: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n const result = await super.handleWriteRequest(exchange, writeRequest, message);\n\n // We delayed the ACL update during the write transaction, so we need to update it now that anything is written\n if (this.#aclUpdateIsDelayed) {\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n return result;\n }\n\n protected override async writeAttribute(\n path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n isListWrite?: boolean,\n ) {\n const writeAttribute = () =>\n super.writeAttribute(path, attribute, value, exchange, message, endpoint, timed, isListWrite);\n\n if (path.endpointId === 0 && path.clusterId === AclClusterId && path.attributeId === AclAttributeId) {\n // This is a hack to prevent the ACL from updating while we are in the middle of a write transaction\n // and is needed because Acl should not become effective during writing of the ACL itself.\n this.aclServer.aclUpdateDelayed = true;\n this.#aclUpdateIsDelayed = true;\n } else if (this.#aclUpdateIsDelayed) {\n // Ok it seems that acl was written, but we now write another path, so we can update Acl attribute now\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n timed,\n message,\n session: exchange.session,\n fabricFiltered: true,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Write,\n endpoint,\n root: this.#endpoint,\n }).act(writeAttribute);\n }\n\n protected override async invokeCommand(\n path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n ) {\n const invokeCommand = (context: ActionContext) => {\n if (!context.authorizedFor(command.invokeAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.invokeCommand(path, command, exchange, commandFields, message, endpoint, timed);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n command: true,\n timed,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Invoke,\n endpoint,\n root: this.#endpoint,\n }).act(invokeCommand);\n }\n\n get #tracer() {\n if (this.#endpoint.env.has(ActionTracer)) {\n return this.#endpoint.env.get(ActionTracer);\n }\n }\n\n #updateStructure() {\n if (this.#endpoint.lifecycle.isTreeReady) {\n this.#endpointStructure.initializeFromEndpoint(EndpointServer.forEndpoint(this.#endpoint));\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,11 +2,12 @@ import { AttributeId } from "../../datatype/AttributeId.js";
|
|
|
2
2
|
import { ClusterId } from "../../datatype/ClusterId.js";
|
|
3
3
|
import { EndpointNumber } from "../../datatype/EndpointNumber.js";
|
|
4
4
|
import { NodeId } from "../../datatype/NodeId.js";
|
|
5
|
-
import { TlvSchema, TlvStream, TypeFromSchema } from "../../tlv/TlvSchema.js";
|
|
5
|
+
import { TlvEncodingOptions, TlvSchema, TlvStream, TypeFromSchema } from "../../tlv/TlvSchema.js";
|
|
6
6
|
import { TlvAttributeReport, TlvAttributeReportData, TlvDataReport, TlvEventData, TlvEventReport } from "./InteractionProtocol.js";
|
|
7
7
|
/** Type for TlvAttributeReport where the real data are represented with the schema and the JS value. */
|
|
8
8
|
export type AttributeReportPayload = Omit<TypeFromSchema<typeof TlvAttributeReport>, "attributeData"> & {
|
|
9
9
|
attributeData?: AttributeDataPayload;
|
|
10
|
+
hasFabricSensitiveData: boolean;
|
|
10
11
|
};
|
|
11
12
|
/** Type for TlvAttributeReportData where the real data are represented with the schema and the JS value. */
|
|
12
13
|
type AttributeDataPayload = Omit<TypeFromSchema<typeof TlvAttributeReportData>, "data"> & {
|
|
@@ -16,6 +17,7 @@ type AttributeDataPayload = Omit<TypeFromSchema<typeof TlvAttributeReportData>,
|
|
|
16
17
|
/** Type for TlvEventReport where the real data are represented with the schema and the JS value. */
|
|
17
18
|
export type EventReportPayload = Omit<TypeFromSchema<typeof TlvEventReport>, "eventData"> & {
|
|
18
19
|
eventData?: EventDataPayload;
|
|
20
|
+
hasFabricSensitiveData: boolean;
|
|
19
21
|
};
|
|
20
22
|
/** Type for TlvEventData where the real data are represented with the schema and the JS value. */
|
|
21
23
|
export type EventDataPayload = Omit<TypeFromSchema<typeof TlvEventData>, "data"> & {
|
|
@@ -28,9 +30,9 @@ export type DataReportPayload = Omit<TypeFromSchema<typeof TlvDataReport>, "attr
|
|
|
28
30
|
eventReportsPayload?: EventReportPayload[];
|
|
29
31
|
};
|
|
30
32
|
/** Encodes an AttributeReportPayload into a TlvStream (used for TlvAny type). */
|
|
31
|
-
export declare function encodeAttributePayload(attributePayload: AttributeReportPayload): TlvStream;
|
|
33
|
+
export declare function encodeAttributePayload(attributePayload: AttributeReportPayload, options?: TlvEncodingOptions): TlvStream;
|
|
32
34
|
/** Encodes an EventReportPayload into a TlvStream (used for TlvAny type). */
|
|
33
|
-
export declare function encodeEventPayload(eventPayload: EventReportPayload): TlvStream;
|
|
35
|
+
export declare function encodeEventPayload(eventPayload: EventReportPayload, options?: TlvEncodingOptions): TlvStream;
|
|
34
36
|
/** Return if an AttributeReportPayload can be chunked or not. */
|
|
35
37
|
export declare function canAttributePayloadBeChunked(attributePayload: AttributeReportPayload): boolean;
|
|
36
38
|
/** Chunk an AttributeReportPayload into multiple AttributeReportPayloads. */
|
|
@@ -42,6 +44,7 @@ export declare function chunkAttributePayload(attributePayload: AttributeReportP
|
|
|
42
44
|
export declare function sortAttributeDataByPath(data1: AttributeReportPayload, data2: AttributeReportPayload): 0 | 1 | -1;
|
|
43
45
|
/** Sort and use Tag compression to compress a list of AttributeReportPayloads. */
|
|
44
46
|
export declare function compressAttributeDataReportTags(data: AttributeReportPayload[]): {
|
|
47
|
+
hasFabricSensitiveData: boolean;
|
|
45
48
|
attributeData: AttributeDataPayload | undefined;
|
|
46
49
|
attributeStatus: import("../../tlv/TlvObject.js").TypeFromFields<{
|
|
47
50
|
path: import("../../tlv/TlvObject.js").FieldType<import("../../tlv/TlvObject.js").TypeFromFields<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttributeDataEncoder.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/AttributeDataEncoder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"AttributeDataEncoder.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/AttributeDataEncoder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,EAEH,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,cAAc,EACjB,MAAM,0BAA0B,CAAC;AAUlC,wGAAwG;AACxG,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,EAAE,eAAe,CAAC,GAAG;IACpG,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,sBAAsB,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF,4GAA4G;AAC5G,KAAK,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,EAAE,MAAM,CAAC,GAAG;IACtF,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,EAAE,GAAG,CAAC;CAChB,CAAC;AAEF,oGAAoG;AACpG,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG;IACxF,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF,kGAAkG;AAClG,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,YAAY,CAAC,EAAE,MAAM,CAAC,GAAG;IAC/E,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,EAAE,GAAG,CAAC;CAChB,CAAC;AAEF,mGAAmG;AACnG,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,EAAE,kBAAkB,GAAG,cAAc,CAAC,GAAG;IAC9G,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACnD,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC9C,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,sBAAsB,CAClC,gBAAgB,EAAE,sBAAsB,EACxC,OAAO,CAAC,EAAE,kBAAkB,GAC7B,SAAS,CAUX;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,SAAS,CA6B5G;AAED,iEAAiE;AACjE,wBAAgB,4BAA4B,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,OAAO,CAW9F;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,sBAAsB,EAAE,CAyCxG;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,sBAAsB,cAoBnG;AAED,kFAAkF;AAClF,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,sBAAsB,EAAE;;;;;;;;;;;;;;;;;IAuB7E"}
|
|
@@ -10,15 +10,17 @@ import {
|
|
|
10
10
|
TlvAttributeReport,
|
|
11
11
|
TlvEventReport
|
|
12
12
|
} from "./InteractionProtocol.js";
|
|
13
|
-
function encodeAttributePayload(attributePayload) {
|
|
13
|
+
function encodeAttributePayload(attributePayload, options) {
|
|
14
14
|
const { attributeData, attributeStatus } = attributePayload;
|
|
15
15
|
if (attributeData === void 0) {
|
|
16
16
|
return TlvAttributeReport.encodeTlv({ attributeStatus });
|
|
17
17
|
}
|
|
18
18
|
const { path, schema, payload, dataVersion } = attributeData;
|
|
19
|
-
return TlvAttributeReport.encodeTlv({
|
|
19
|
+
return TlvAttributeReport.encodeTlv({
|
|
20
|
+
attributeData: { path, data: schema.encodeTlv(payload, options), dataVersion }
|
|
21
|
+
});
|
|
20
22
|
}
|
|
21
|
-
function encodeEventPayload(eventPayload) {
|
|
23
|
+
function encodeEventPayload(eventPayload, options) {
|
|
22
24
|
const { eventData, eventStatus } = eventPayload;
|
|
23
25
|
if (eventData === void 0) {
|
|
24
26
|
return TlvEventReport.encodeTlv({ eventStatus });
|
|
@@ -37,7 +39,7 @@ function encodeEventPayload(eventPayload) {
|
|
|
37
39
|
return TlvEventReport.encodeTlv({
|
|
38
40
|
eventData: {
|
|
39
41
|
path,
|
|
40
|
-
data: schema.encodeTlv(payload),
|
|
42
|
+
data: schema.encodeTlv(payload, options),
|
|
41
43
|
priority,
|
|
42
44
|
systemTimestamp,
|
|
43
45
|
deltaSystemTimestamp,
|
|
@@ -60,7 +62,7 @@ function canAttributePayloadBeChunked(attributePayload) {
|
|
|
60
62
|
return schema instanceof ArraySchema && Array.isArray(payload) && payload.length > 0 && listIndex === void 0;
|
|
61
63
|
}
|
|
62
64
|
function chunkAttributePayload(attributePayload) {
|
|
63
|
-
const { attributeData } = attributePayload;
|
|
65
|
+
const { hasFabricSensitiveData, attributeData } = attributePayload;
|
|
64
66
|
if (attributeData === void 0) {
|
|
65
67
|
throw new MatterFlowError(
|
|
66
68
|
`Can not chunk an AttributePayload with just a attributeStatus: ${Logger.toJSON(attributePayload)}`
|
|
@@ -75,9 +77,13 @@ function chunkAttributePayload(attributePayload) {
|
|
|
75
77
|
);
|
|
76
78
|
}
|
|
77
79
|
const chunks = new Array();
|
|
78
|
-
chunks.push({
|
|
80
|
+
chunks.push({
|
|
81
|
+
hasFabricSensitiveData,
|
|
82
|
+
attributeData: { schema, path: { ...path, listIndex: void 0 }, payload: [], dataVersion }
|
|
83
|
+
});
|
|
79
84
|
payload.forEach((element) => {
|
|
80
85
|
chunks.push({
|
|
86
|
+
hasFabricSensitiveData,
|
|
81
87
|
attributeData: {
|
|
82
88
|
schema: schema.elementSchema,
|
|
83
89
|
path: { ...path, listIndex: null },
|
|
@@ -107,7 +113,7 @@ function sortAttributeDataByPath(data1, data2) {
|
|
|
107
113
|
}
|
|
108
114
|
function compressAttributeDataReportTags(data) {
|
|
109
115
|
let lastFullPath;
|
|
110
|
-
return data.sort(sortAttributeDataByPath).map(({ attributeData, attributeStatus }) => {
|
|
116
|
+
return data.sort(sortAttributeDataByPath).map(({ hasFabricSensitiveData, attributeData, attributeStatus }) => {
|
|
111
117
|
if (attributeData !== void 0) {
|
|
112
118
|
const { path, dataVersion } = attributeData;
|
|
113
119
|
const compressedPath = compressPath(path, dataVersion, lastFullPath);
|
|
@@ -125,7 +131,7 @@ function compressAttributeDataReportTags(data) {
|
|
|
125
131
|
attributeStatus = { ...attributeStatus, path: compressedPath.path };
|
|
126
132
|
lastFullPath = compressedPath.lastFullPath;
|
|
127
133
|
}
|
|
128
|
-
return { attributeData, attributeStatus };
|
|
134
|
+
return { hasFabricSensitiveData, attributeData, attributeStatus };
|
|
129
135
|
});
|
|
130
136
|
}
|
|
131
137
|
function compressPath(path, dataVersion, lastFullPath) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/protocol/interaction/AttributeDataEncoder.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { MatterFlowError } from \"../../common/MatterError.js\";\nimport { AttributeId } from \"../../datatype/AttributeId.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { EndpointNumber } from \"../../datatype/EndpointNumber.js\";\nimport { NodeId } from \"../../datatype/NodeId.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { ArraySchema } from \"../../tlv/TlvArray.js\";\nimport { TlvSchema, TlvStream, TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport {\n TlvAttributePath,\n TlvAttributeReport,\n TlvAttributeReportData,\n TlvDataReport,\n TlvEventData,\n TlvEventReport,\n} from \"./InteractionProtocol.js\";\n\ntype FullAttributePath = {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n attributeId: AttributeId;\n dataVersion?: number;\n};\n\n/** Type for TlvAttributeReport where the real data are represented with the schema and the JS value. */\nexport type AttributeReportPayload = Omit<TypeFromSchema<typeof TlvAttributeReport>, \"attributeData\"> & {\n attributeData?: AttributeDataPayload;\n};\n\n/** Type for TlvAttributeReportData where the real data are represented with the schema and the JS value. */\ntype AttributeDataPayload = Omit<TypeFromSchema<typeof TlvAttributeReportData>, \"data\"> & {\n schema: TlvSchema<any>;\n payload: any;\n};\n\n/** Type for TlvEventReport where the real data are represented with the schema and the JS value. */\nexport type EventReportPayload = Omit<TypeFromSchema<typeof TlvEventReport>, \"eventData\"> & {\n eventData?: EventDataPayload;\n};\n\n/** Type for TlvEventData where the real data are represented with the schema and the JS value. */\nexport type EventDataPayload = Omit<TypeFromSchema<typeof TlvEventData>, \"data\"> & {\n schema: TlvSchema<any>;\n payload: any;\n};\n\n/** Type for TlvDataReport where the real data are represented with the schema and the JS value. */\nexport type DataReportPayload = Omit<TypeFromSchema<typeof TlvDataReport>, \"attributeReports\" | \"eventReports\"> & {\n attributeReportsPayload?: AttributeReportPayload[];\n eventReportsPayload?: EventReportPayload[];\n};\n\n/** Encodes an AttributeReportPayload into a TlvStream (used for TlvAny type). */\nexport function encodeAttributePayload(attributePayload: AttributeReportPayload): TlvStream {\n const { attributeData, attributeStatus } = attributePayload;\n if (attributeData === undefined) {\n return TlvAttributeReport.encodeTlv({ attributeStatus });\n }\n\n const { path, schema, payload, dataVersion } = attributeData;\n return TlvAttributeReport.encodeTlv({ attributeData: { path, data: schema.encodeTlv(payload), dataVersion } });\n}\n\n/** Encodes an EventReportPayload into a TlvStream (used for TlvAny type). */\nexport function encodeEventPayload(eventPayload: EventReportPayload): TlvStream {\n const { eventData, eventStatus } = eventPayload;\n if (eventData === undefined) {\n return TlvEventReport.encodeTlv({ eventStatus });\n }\n\n const {\n path,\n schema,\n payload,\n eventNumber,\n deltaEpochTimestamp,\n epochTimestamp,\n deltaSystemTimestamp,\n systemTimestamp,\n priority,\n } = eventData;\n return TlvEventReport.encodeTlv({\n eventData: {\n path,\n data: schema.encodeTlv(payload),\n priority,\n systemTimestamp,\n deltaSystemTimestamp,\n deltaEpochTimestamp,\n epochTimestamp,\n eventNumber,\n },\n });\n}\n\n/** Return if an AttributeReportPayload can be chunked or not. */\nexport function canAttributePayloadBeChunked(attributePayload: AttributeReportPayload): boolean {\n const { attributeData } = attributePayload;\n if (attributeData === undefined) {\n return false;\n }\n const {\n schema,\n payload,\n path: { listIndex },\n } = attributeData;\n return schema instanceof ArraySchema && Array.isArray(payload) && payload.length > 0 && listIndex === undefined;\n}\n\n/** Chunk an AttributeReportPayload into multiple AttributeReportPayloads. */\nexport function chunkAttributePayload(attributePayload: AttributeReportPayload): AttributeReportPayload[] {\n const { attributeData } = attributePayload;\n if (attributeData === undefined) {\n throw new MatterFlowError(\n `Can not chunk an AttributePayload with just a attributeStatus: ${Logger.toJSON(attributePayload)}`,\n );\n }\n const { schema, path, dataVersion, payload } = attributeData;\n if (!(schema instanceof ArraySchema) || !Array.isArray(payload)) {\n throw new MatterFlowError(\n `Can not chunk an AttributePayload with attributeData that is not an array: ${Logger.toJSON(\n attributePayload,\n )}`,\n );\n }\n const chunks = new Array<AttributeReportPayload>();\n chunks.push({ attributeData: { schema, path: { ...path, listIndex: undefined }, payload: [], dataVersion } });\n payload.forEach(element => {\n chunks.push({\n attributeData: {\n schema: schema.elementSchema,\n path: { ...path, listIndex: null },\n payload: element,\n dataVersion,\n },\n });\n });\n\n // If the path of the initial AttributePayload was not compressed, we should compress the chunked data\n // TODO Enable once Tag Compression is supported https://github.com/project-chip/connectedhomeip/issues/29359\n /*\n if (path.enableTagCompression !== true) {\n return compressAttributeDataReportTags(chunks);\n }\n */\n\n return chunks;\n}\n\n/**\n * Sort function to sort AttributeReportPayloads by nodeId/EndpointId/clusterId/attributeId to generate an ideal\n * ground for tag compression.\n */\nexport function sortAttributeDataByPath(data1: AttributeReportPayload, data2: AttributeReportPayload) {\n const { path: path1 } = data1.attributeData ?? data1.attributeStatus ?? {};\n const { path: path2 } = data2.attributeData ?? data2.attributeStatus ?? {};\n if (path1?.nodeId !== undefined && path2?.nodeId !== undefined && path1.nodeId !== path2.nodeId) {\n return path1.nodeId < path2.nodeId ? -1 : 1;\n }\n if (path1?.endpointId !== undefined && path2?.endpointId !== undefined && path1.endpointId !== path2.endpointId) {\n return path1.endpointId < path2.endpointId ? -1 : 1;\n }\n if (path1?.clusterId !== undefined && path2?.clusterId !== undefined && path1.clusterId !== path2.clusterId) {\n return path1.clusterId < path2.clusterId ? -1 : 1;\n }\n if (\n path1?.attributeId !== undefined &&\n path2?.attributeId !== undefined &&\n path1.attributeId !== path2.attributeId\n ) {\n return path1.attributeId < path2.attributeId ? -1 : 1;\n }\n return 0;\n}\n\n/** Sort and use Tag compression to compress a list of AttributeReportPayloads. */\nexport function compressAttributeDataReportTags(data: AttributeReportPayload[]) {\n let lastFullPath: FullAttributePath | undefined;\n\n return data.sort(sortAttributeDataByPath).map(({ attributeData, attributeStatus }) => {\n if (attributeData !== undefined) {\n const { path, dataVersion } = attributeData;\n const compressedPath = compressPath(path, dataVersion, lastFullPath);\n const { enableTagCompression } = compressedPath.path;\n attributeData = {\n ...attributeData,\n path: compressedPath.path,\n dataVersion: enableTagCompression ? undefined : dataVersion,\n };\n lastFullPath = compressedPath.lastFullPath;\n }\n if (attributeStatus !== undefined) {\n const { path } = attributeStatus;\n const compressedPath = compressPath(path, undefined, lastFullPath);\n attributeStatus = { ...attributeStatus, path: compressedPath.path };\n lastFullPath = compressedPath.lastFullPath;\n }\n return { attributeData, attributeStatus };\n });\n}\n\n/** Helper method to compress one path and preserve the state for the next path. */\nfunction compressPath(\n path: TypeFromSchema<typeof TlvAttributePath>,\n dataVersion: number | undefined,\n lastFullPath: FullAttributePath | undefined,\n): { path: TypeFromSchema<typeof TlvAttributePath>; lastFullPath?: FullAttributePath } {\n const { nodeId, endpointId, clusterId, attributeId } = path;\n\n // Should never happen but typing likes it better that way\n if (endpointId === undefined || clusterId === undefined || attributeId === undefined) {\n return { path, lastFullPath };\n }\n\n const newFullPath = {\n path: { ...path, enableTagCompression: undefined },\n lastFullPath: { nodeId, endpointId, clusterId, attributeId, dataVersion },\n };\n // We have no stored Full path, so we take this as starting point\n if (lastFullPath === undefined) {\n return newFullPath;\n }\n\n // When dataVersion differs we can't compress\n if (dataVersion !== undefined && dataVersion !== lastFullPath.dataVersion) {\n return newFullPath;\n }\n\n // Based on Specs in DataReports AttributeId and CLusterId SHALL always be present in the path\n let compressedElements = 0;\n // Assume we can compress elements in the path\n const compressedPath = { ...path, enableTagCompression: true };\n if (endpointId === lastFullPath.endpointId) {\n delete compressedPath.endpointId;\n compressedElements++;\n }\n if (nodeId === lastFullPath.nodeId && nodeId !== undefined) {\n // No need to count if undefined\n delete compressedPath.nodeId;\n compressedElements++;\n }\n\n // Nothing was compressed, so we use this as new full path\n if (compressedElements === 0) {\n return newFullPath;\n }\n\n return { path: compressedPath, lastFullPath };\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,SAAS,uBAAuB;AAKhC,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAE5B;AAAA,EAEI;AAAA,EAIA;AAAA,OACG;
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { MatterFlowError } from \"../../common/MatterError.js\";\nimport { AttributeId } from \"../../datatype/AttributeId.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { EndpointNumber } from \"../../datatype/EndpointNumber.js\";\nimport { NodeId } from \"../../datatype/NodeId.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { ArraySchema } from \"../../tlv/TlvArray.js\";\nimport { TlvEncodingOptions, TlvSchema, TlvStream, TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport {\n TlvAttributePath,\n TlvAttributeReport,\n TlvAttributeReportData,\n TlvDataReport,\n TlvEventData,\n TlvEventReport,\n} from \"./InteractionProtocol.js\";\n\ntype FullAttributePath = {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n attributeId: AttributeId;\n dataVersion?: number;\n};\n\n/** Type for TlvAttributeReport where the real data are represented with the schema and the JS value. */\nexport type AttributeReportPayload = Omit<TypeFromSchema<typeof TlvAttributeReport>, \"attributeData\"> & {\n attributeData?: AttributeDataPayload;\n hasFabricSensitiveData: boolean;\n};\n\n/** Type for TlvAttributeReportData where the real data are represented with the schema and the JS value. */\ntype AttributeDataPayload = Omit<TypeFromSchema<typeof TlvAttributeReportData>, \"data\"> & {\n schema: TlvSchema<any>;\n payload: any;\n};\n\n/** Type for TlvEventReport where the real data are represented with the schema and the JS value. */\nexport type EventReportPayload = Omit<TypeFromSchema<typeof TlvEventReport>, \"eventData\"> & {\n eventData?: EventDataPayload;\n hasFabricSensitiveData: boolean;\n};\n\n/** Type for TlvEventData where the real data are represented with the schema and the JS value. */\nexport type EventDataPayload = Omit<TypeFromSchema<typeof TlvEventData>, \"data\"> & {\n schema: TlvSchema<any>;\n payload: any;\n};\n\n/** Type for TlvDataReport where the real data are represented with the schema and the JS value. */\nexport type DataReportPayload = Omit<TypeFromSchema<typeof TlvDataReport>, \"attributeReports\" | \"eventReports\"> & {\n attributeReportsPayload?: AttributeReportPayload[];\n eventReportsPayload?: EventReportPayload[];\n};\n\n/** Encodes an AttributeReportPayload into a TlvStream (used for TlvAny type). */\nexport function encodeAttributePayload(\n attributePayload: AttributeReportPayload,\n options?: TlvEncodingOptions,\n): TlvStream {\n const { attributeData, attributeStatus } = attributePayload;\n if (attributeData === undefined) {\n return TlvAttributeReport.encodeTlv({ attributeStatus });\n }\n\n const { path, schema, payload, dataVersion } = attributeData;\n return TlvAttributeReport.encodeTlv({\n attributeData: { path, data: schema.encodeTlv(payload, options), dataVersion },\n });\n}\n\n/** Encodes an EventReportPayload into a TlvStream (used for TlvAny type). */\nexport function encodeEventPayload(eventPayload: EventReportPayload, options?: TlvEncodingOptions): TlvStream {\n const { eventData, eventStatus } = eventPayload;\n if (eventData === undefined) {\n return TlvEventReport.encodeTlv({ eventStatus });\n }\n\n const {\n path,\n schema,\n payload,\n eventNumber,\n deltaEpochTimestamp,\n epochTimestamp,\n deltaSystemTimestamp,\n systemTimestamp,\n priority,\n } = eventData;\n return TlvEventReport.encodeTlv({\n eventData: {\n path,\n data: schema.encodeTlv(payload, options),\n priority,\n systemTimestamp,\n deltaSystemTimestamp,\n deltaEpochTimestamp,\n epochTimestamp,\n eventNumber,\n },\n });\n}\n\n/** Return if an AttributeReportPayload can be chunked or not. */\nexport function canAttributePayloadBeChunked(attributePayload: AttributeReportPayload): boolean {\n const { attributeData } = attributePayload;\n if (attributeData === undefined) {\n return false;\n }\n const {\n schema,\n payload,\n path: { listIndex },\n } = attributeData;\n return schema instanceof ArraySchema && Array.isArray(payload) && payload.length > 0 && listIndex === undefined;\n}\n\n/** Chunk an AttributeReportPayload into multiple AttributeReportPayloads. */\nexport function chunkAttributePayload(attributePayload: AttributeReportPayload): AttributeReportPayload[] {\n const { hasFabricSensitiveData, attributeData } = attributePayload;\n if (attributeData === undefined) {\n throw new MatterFlowError(\n `Can not chunk an AttributePayload with just a attributeStatus: ${Logger.toJSON(attributePayload)}`,\n );\n }\n const { schema, path, dataVersion, payload } = attributeData;\n if (!(schema instanceof ArraySchema) || !Array.isArray(payload)) {\n throw new MatterFlowError(\n `Can not chunk an AttributePayload with attributeData that is not an array: ${Logger.toJSON(\n attributePayload,\n )}`,\n );\n }\n const chunks = new Array<AttributeReportPayload>();\n chunks.push({\n hasFabricSensitiveData: hasFabricSensitiveData,\n attributeData: { schema, path: { ...path, listIndex: undefined }, payload: [], dataVersion },\n });\n payload.forEach(element => {\n chunks.push({\n hasFabricSensitiveData: hasFabricSensitiveData,\n attributeData: {\n schema: schema.elementSchema,\n path: { ...path, listIndex: null },\n payload: element,\n dataVersion,\n },\n });\n });\n\n // If the path of the initial AttributePayload was not compressed, we should compress the chunked data\n // TODO Enable once Tag Compression is supported https://github.com/project-chip/connectedhomeip/issues/29359\n /*\n if (path.enableTagCompression !== true) {\n return compressAttributeDataReportTags(chunks);\n }\n */\n\n return chunks;\n}\n\n/**\n * Sort function to sort AttributeReportPayloads by nodeId/EndpointId/clusterId/attributeId to generate an ideal\n * ground for tag compression.\n */\nexport function sortAttributeDataByPath(data1: AttributeReportPayload, data2: AttributeReportPayload) {\n const { path: path1 } = data1.attributeData ?? data1.attributeStatus ?? {};\n const { path: path2 } = data2.attributeData ?? data2.attributeStatus ?? {};\n if (path1?.nodeId !== undefined && path2?.nodeId !== undefined && path1.nodeId !== path2.nodeId) {\n return path1.nodeId < path2.nodeId ? -1 : 1;\n }\n if (path1?.endpointId !== undefined && path2?.endpointId !== undefined && path1.endpointId !== path2.endpointId) {\n return path1.endpointId < path2.endpointId ? -1 : 1;\n }\n if (path1?.clusterId !== undefined && path2?.clusterId !== undefined && path1.clusterId !== path2.clusterId) {\n return path1.clusterId < path2.clusterId ? -1 : 1;\n }\n if (\n path1?.attributeId !== undefined &&\n path2?.attributeId !== undefined &&\n path1.attributeId !== path2.attributeId\n ) {\n return path1.attributeId < path2.attributeId ? -1 : 1;\n }\n return 0;\n}\n\n/** Sort and use Tag compression to compress a list of AttributeReportPayloads. */\nexport function compressAttributeDataReportTags(data: AttributeReportPayload[]) {\n let lastFullPath: FullAttributePath | undefined;\n\n return data.sort(sortAttributeDataByPath).map(({ hasFabricSensitiveData, attributeData, attributeStatus }) => {\n if (attributeData !== undefined) {\n const { path, dataVersion } = attributeData;\n const compressedPath = compressPath(path, dataVersion, lastFullPath);\n const { enableTagCompression } = compressedPath.path;\n attributeData = {\n ...attributeData,\n path: compressedPath.path,\n dataVersion: enableTagCompression ? undefined : dataVersion,\n };\n lastFullPath = compressedPath.lastFullPath;\n }\n if (attributeStatus !== undefined) {\n const { path } = attributeStatus;\n const compressedPath = compressPath(path, undefined, lastFullPath);\n attributeStatus = { ...attributeStatus, path: compressedPath.path };\n lastFullPath = compressedPath.lastFullPath;\n }\n return { hasFabricSensitiveData, attributeData, attributeStatus };\n });\n}\n\n/** Helper method to compress one path and preserve the state for the next path. */\nfunction compressPath(\n path: TypeFromSchema<typeof TlvAttributePath>,\n dataVersion: number | undefined,\n lastFullPath: FullAttributePath | undefined,\n): { path: TypeFromSchema<typeof TlvAttributePath>; lastFullPath?: FullAttributePath } {\n const { nodeId, endpointId, clusterId, attributeId } = path;\n\n // Should never happen but typing likes it better that way\n if (endpointId === undefined || clusterId === undefined || attributeId === undefined) {\n return { path, lastFullPath };\n }\n\n const newFullPath = {\n path: { ...path, enableTagCompression: undefined },\n lastFullPath: { nodeId, endpointId, clusterId, attributeId, dataVersion },\n };\n // We have no stored Full path, so we take this as starting point\n if (lastFullPath === undefined) {\n return newFullPath;\n }\n\n // When dataVersion differs we can't compress\n if (dataVersion !== undefined && dataVersion !== lastFullPath.dataVersion) {\n return newFullPath;\n }\n\n // Based on Specs in DataReports AttributeId and CLusterId SHALL always be present in the path\n let compressedElements = 0;\n // Assume we can compress elements in the path\n const compressedPath = { ...path, enableTagCompression: true };\n if (endpointId === lastFullPath.endpointId) {\n delete compressedPath.endpointId;\n compressedElements++;\n }\n if (nodeId === lastFullPath.nodeId && nodeId !== undefined) {\n // No need to count if undefined\n delete compressedPath.nodeId;\n compressedElements++;\n }\n\n // Nothing was compressed, so we use this as new full path\n if (compressedElements === 0) {\n return newFullPath;\n }\n\n return { path: compressedPath, lastFullPath };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventHandler.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/EventHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAMxE;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IACxB,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,CAAC,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IACrD,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,OAAO,GAAG,GAAG;;IAoBjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAnBzC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAIrB;IAGF,IAAI,YAAY,yCAEf;WAEY,MAAM,CAAC,YAAY,EAAE,cAAc;gBAMnB,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;IAO5D,SAAS,CACL,SAAS,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,EAC9C,OAAO,CAAC,EAAE,cAAc,CAAC,OAAO,cAAc,CAAC,EAAE,EACjD,oBAAoB,CAAC,EAAE,WAAW;
|
|
1
|
+
{"version":3,"file":"EventHandler.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/EventHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAMxE;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IACxB,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,CAAC,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IACrD,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,OAAO,GAAG,GAAG;;IAoBjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAnBzC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAIrB;IAGF,IAAI,YAAY,yCAEf;WAEY,MAAM,CAAC,YAAY,EAAE,cAAc;gBAMnB,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;IAO5D,SAAS,CACL,SAAS,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,EAC9C,OAAO,CAAC,EAAE,cAAc,CAAC,OAAO,cAAc,CAAC,EAAE,EACjD,oBAAoB,CAAC,EAAE,WAAW;IAgCtC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC;IAmB/B,aAAa;CAYhB"}
|
|
@@ -55,9 +55,7 @@ class EventHandler {
|
|
|
55
55
|
`Got ${events.length} events for ${resolveEventName(eventPath)} with filters: ${Logger.toJSON(filters)}`
|
|
56
56
|
);
|
|
57
57
|
if (filterForFabricIndex !== void 0) {
|
|
58
|
-
return events.filter(
|
|
59
|
-
(event) => !("fabricIndex" in event.data) || event.data.fabricIndex === filterForFabricIndex
|
|
60
|
-
);
|
|
58
|
+
return events.filter(({ data }) => !("fabricIndex" in data) || data.fabricIndex === filterForFabricIndex);
|
|
61
59
|
}
|
|
62
60
|
return events;
|
|
63
61
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/protocol/interaction/EventHandler.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { EventPriority } from \"../../cluster/Cluster.js\";\nimport { resolveEventName } from \"../../cluster/ClusterHelper.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { EndpointNumber } from \"../../datatype/EndpointNumber.js\";\nimport { EventId } from \"../../datatype/EventId.js\";\nimport { EventNumber } from \"../../datatype/EventNumber.js\";\nimport { FabricIndex } from \"../../datatype/FabricIndex.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { Storage, StorageOperationResult } from \"../../storage/Storage.js\";\nimport { StorageContext } from \"../../storage/StorageContext.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { AsyncConstruction } from \"../../util/AsyncConstruction.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { TlvEventFilter, TlvEventPath } from \"./InteractionProtocol.js\";\n\nconst logger = Logger.get(\"EventHandler\");\n\nconst MAX_EVENTS = 10_000;\n\n/**\n * Data of one Event\n */\nexport interface EventData<T> {\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n eventId: EventId;\n epochTimestamp: number;\n priority: EventPriority;\n data: T;\n}\n\n/**\n * Data of an event which was triggered and stored internally\n */\nexport interface EventStorageData<T> extends EventData<T> {\n eventNumber: EventNumber;\n}\n\n/**\n * Class that collects all triggered events up to a certain limit of events and handle logic\n * to handle subscriptions (TBD)\n */\nexport class EventHandler<S extends Storage = any> {\n private eventNumber = EventNumber(0);\n private storedEventCount = 0;\n private readonly events = {\n [EventPriority.Critical]: new Array<EventStorageData<any>>(),\n [EventPriority.Info]: new Array<EventStorageData<any>>(),\n [EventPriority.Debug]: new Array<EventStorageData<any>>(),\n };\n #construction: AsyncConstruction<EventHandler>;\n\n get construction() {\n return this.#construction;\n }\n\n static async create(eventStorage: StorageContext) {\n const handler = new EventHandler(eventStorage);\n await handler.#construction;\n return handler;\n }\n\n constructor(private readonly eventStorage: StorageContext<S>) {\n this.#construction = AsyncConstruction(this, async () => {\n this.eventNumber = await this.eventStorage.get(\"lastEventNumber\", this.eventNumber);\n logger.debug(`Set/Restore last event number: ${this.eventNumber}`);\n });\n }\n\n getEvents(\n eventPath: TypeFromSchema<typeof TlvEventPath>,\n filters?: TypeFromSchema<typeof TlvEventFilter>[],\n filterForFabricIndex?: FabricIndex,\n ) {\n const eventFilter =\n filters !== undefined && filters.length > 0\n ? (event: EventStorageData<any>) =>\n filters.some(\n filter => filter.eventMin !== undefined && event.eventNumber >= EventNumber(filter.eventMin),\n )\n : () => true; // TODO also add Node Id check\n const events = new Array<EventStorageData<any>>();\n const { endpointId, clusterId, eventId } = eventPath;\n for (const priority of [EventPriority.Critical, EventPriority.Info, EventPriority.Debug]) {\n const eventsToCheck = this.events[priority];\n for (const event of eventsToCheck) {\n if (endpointId === event.endpointId && clusterId === event.clusterId && eventId === event.eventId) {\n if (eventFilter(event)) {\n events.push(event);\n }\n }\n }\n }\n logger.debug(\n `Got ${events.length} events for ${resolveEventName(eventPath)} with filters: ${Logger.toJSON(filters)}`,\n );\n\n if (filterForFabricIndex !== undefined) {\n return events.filter(
|
|
5
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AAIjC,SAAS,mBAAmB;AAE5B,SAAS,cAAc;AAIvB,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAG7B,MAAM,SAAS,OAAO,IAAI,cAAc;AAExC,MAAM,aAAa;AAyBZ,MAAM,aAAsC;AAAA,EAoB/C,YAA6B,cAAiC;AAAjC;AAnB7B,SAAQ,cAAc,YAAY,CAAC;AACnC,SAAQ,mBAAmB;AAC3B,SAAiB,SAAS;AAAA,MACtB,CAAC,cAAc,QAAQ,GAAG,IAAI,MAA6B;AAAA,MAC3D,CAAC,cAAc,IAAI,GAAG,IAAI,MAA6B;AAAA,MACvD,CAAC,cAAc,KAAK,GAAG,IAAI,MAA6B;AAAA,IAC5D;AAcI,SAAK,gBAAgB,kBAAkB,MAAM,YAAY;AACrD,WAAK,cAAc,MAAM,KAAK,aAAa,IAAI,mBAAmB,KAAK,WAAW;AAClF,aAAO,MAAM,kCAAkC,KAAK,WAAW,EAAE;AAAA,IACrE,CAAC;AAAA,EACL;AAAA,EAjBA;AAAA,EAEA,IAAI,eAAe;AACf,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,aAAa,OAAO,cAA8B;AAC9C,UAAM,UAAU,IAAI,aAAa,YAAY;AAC7C,UAAM,QAAQ;AACd,WAAO;AAAA,EACX;AAAA,EASA,UACI,WACA,SACA,sBACF;AACE,UAAM,cACF,YAAY,UAAa,QAAQ,SAAS,IACpC,CAAC,UACG,QAAQ;AAAA,MACJ,YAAU,OAAO,aAAa,UAAa,MAAM,eAAe,YAAY,OAAO,QAAQ;AAAA,IAC/F,IACJ,MAAM;AAChB,UAAM,SAAS,IAAI,MAA6B;AAChD,UAAM,EAAE,YAAY,WAAW,QAAQ,IAAI;AAC3C,eAAW,YAAY,CAAC,cAAc,UAAU,cAAc,MAAM,cAAc,KAAK,GAAG;AACtF,YAAM,gBAAgB,KAAK,OAAO,QAAQ;AAC1C,iBAAW,SAAS,eAAe;AAC/B,YAAI,eAAe,MAAM,cAAc,cAAc,MAAM,aAAa,YAAY,MAAM,SAAS;AAC/F,cAAI,YAAY,KAAK,GAAG;AACpB,mBAAO,KAAK,KAAK;AAAA,UACrB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AACA,WAAO;AAAA,MACH,OAAO,OAAO,MAAM,eAAe,iBAAiB,SAAS,CAAC,kBAAkB,OAAO,OAAO,OAAO,CAAC;AAAA,IAC1G;AAEA,QAAI,yBAAyB,QAAW;AACpC,aAAO,OAAO
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { EventPriority } from \"../../cluster/Cluster.js\";\nimport { resolveEventName } from \"../../cluster/ClusterHelper.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { EndpointNumber } from \"../../datatype/EndpointNumber.js\";\nimport { EventId } from \"../../datatype/EventId.js\";\nimport { EventNumber } from \"../../datatype/EventNumber.js\";\nimport { FabricIndex } from \"../../datatype/FabricIndex.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { Storage, StorageOperationResult } from \"../../storage/Storage.js\";\nimport { StorageContext } from \"../../storage/StorageContext.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { AsyncConstruction } from \"../../util/AsyncConstruction.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { TlvEventFilter, TlvEventPath } from \"./InteractionProtocol.js\";\n\nconst logger = Logger.get(\"EventHandler\");\n\nconst MAX_EVENTS = 10_000;\n\n/**\n * Data of one Event\n */\nexport interface EventData<T> {\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n eventId: EventId;\n epochTimestamp: number;\n priority: EventPriority;\n data: T;\n}\n\n/**\n * Data of an event which was triggered and stored internally\n */\nexport interface EventStorageData<T> extends EventData<T> {\n eventNumber: EventNumber;\n}\n\n/**\n * Class that collects all triggered events up to a certain limit of events and handle logic\n * to handle subscriptions (TBD)\n */\nexport class EventHandler<S extends Storage = any> {\n private eventNumber = EventNumber(0);\n private storedEventCount = 0;\n private readonly events = {\n [EventPriority.Critical]: new Array<EventStorageData<any>>(),\n [EventPriority.Info]: new Array<EventStorageData<any>>(),\n [EventPriority.Debug]: new Array<EventStorageData<any>>(),\n };\n #construction: AsyncConstruction<EventHandler>;\n\n get construction() {\n return this.#construction;\n }\n\n static async create(eventStorage: StorageContext) {\n const handler = new EventHandler(eventStorage);\n await handler.#construction;\n return handler;\n }\n\n constructor(private readonly eventStorage: StorageContext<S>) {\n this.#construction = AsyncConstruction(this, async () => {\n this.eventNumber = await this.eventStorage.get(\"lastEventNumber\", this.eventNumber);\n logger.debug(`Set/Restore last event number: ${this.eventNumber}`);\n });\n }\n\n getEvents(\n eventPath: TypeFromSchema<typeof TlvEventPath>,\n filters?: TypeFromSchema<typeof TlvEventFilter>[],\n filterForFabricIndex?: FabricIndex,\n ) {\n const eventFilter =\n filters !== undefined && filters.length > 0\n ? (event: EventStorageData<any>) =>\n filters.some(\n filter => filter.eventMin !== undefined && event.eventNumber >= EventNumber(filter.eventMin),\n )\n : () => true; // TODO also add Node Id check\n const events = new Array<EventStorageData<any>>();\n const { endpointId, clusterId, eventId } = eventPath;\n for (const priority of [EventPriority.Critical, EventPriority.Info, EventPriority.Debug]) {\n const eventsToCheck = this.events[priority];\n for (const event of eventsToCheck) {\n if (endpointId === event.endpointId && clusterId === event.clusterId && eventId === event.eventId) {\n if (eventFilter(event)) {\n events.push(event);\n }\n }\n }\n }\n logger.debug(\n `Got ${events.length} events for ${resolveEventName(eventPath)} with filters: ${Logger.toJSON(filters)}`,\n );\n\n if (filterForFabricIndex !== undefined) {\n return events.filter(({ data }) => !(\"fabricIndex\" in data) || data.fabricIndex === filterForFabricIndex);\n }\n\n return events;\n }\n\n pushEvent(event: EventData<any>) {\n const eventData = {\n eventNumber: EventNumber(++this.eventNumber),\n ...event,\n };\n logger.debug(`Received event: ${Logger.toJSON(eventData)}`);\n this.events[event.priority].push(eventData);\n this.storedEventCount++;\n const setPromise = this.eventStorage.set(\"lastEventNumber\", this.eventNumber);\n if (MaybePromise.is(setPromise)) {\n return setPromise.then(() => {\n this.cleanUpEvents();\n return eventData;\n }) as StorageOperationResult<S, EventStorageData<any>>;\n }\n this.cleanUpEvents();\n return eventData as StorageOperationResult<S, EventStorageData<any>>;\n }\n\n cleanUpEvents() {\n if (this.storedEventCount < MAX_EVENTS) return;\n const eventsToDelete = this.storedEventCount - MAX_EVENTS; // should be always 1, but let's be sure\n for (const priority of [EventPriority.Debug, EventPriority.Info, EventPriority.Critical]) {\n const events = this.events[priority];\n if (events.length > 0) {\n const removedEvents = events.splice(0, events.length - eventsToDelete);\n logger.debug(`Removed ${removedEvents.length} events from priority ${priority}`);\n return;\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -284,7 +284,7 @@ class InteractionClient {
|
|
|
284
284
|
const writeRequests = attributes.map(
|
|
285
285
|
({ endpointId, clusterId, attribute: { id, schema }, value, dataVersion }) => ({
|
|
286
286
|
path: { endpointId, clusterId, attributeId: id },
|
|
287
|
-
data: schema.encodeTlv(value, true),
|
|
287
|
+
data: schema.encodeTlv(value, { forWriteInteraction: true }),
|
|
288
288
|
dataVersion
|
|
289
289
|
})
|
|
290
290
|
);
|