homebridge 2.0.0-beta.35 → 2.0.0-beta.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/dist/api.d.ts +74 -32
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/api.js +48 -46
  4. package/dist/api.js.map +1 -1
  5. package/dist/api.spec.d.ts +2 -0
  6. package/dist/api.spec.d.ts.map +1 -0
  7. package/dist/api.spec.js +413 -0
  8. package/dist/api.spec.js.map +1 -0
  9. package/dist/childBridgeFork.d.ts +1 -18
  10. package/dist/childBridgeFork.d.ts.map +1 -1
  11. package/dist/childBridgeFork.js +21 -258
  12. package/dist/childBridgeFork.js.map +1 -1
  13. package/dist/index.d.ts +10 -10
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -3
  16. package/dist/index.js.map +1 -1
  17. package/dist/logger.spec.d.ts +2 -0
  18. package/dist/logger.spec.d.ts.map +1 -0
  19. package/dist/logger.spec.js +95 -0
  20. package/dist/logger.spec.js.map +1 -0
  21. package/dist/matter/ChildBridgeMatterManager.d.ts +96 -0
  22. package/dist/matter/ChildBridgeMatterManager.d.ts.map +1 -0
  23. package/dist/matter/ChildBridgeMatterManager.js +397 -0
  24. package/dist/matter/ChildBridgeMatterManager.js.map +1 -0
  25. package/dist/matter/ExternalMatterAccessoryPublisher.d.ts +48 -0
  26. package/dist/matter/ExternalMatterAccessoryPublisher.d.ts.map +1 -0
  27. package/dist/matter/ExternalMatterAccessoryPublisher.js +73 -0
  28. package/dist/matter/ExternalMatterAccessoryPublisher.js.map +1 -0
  29. package/dist/matter/ExternalMatterAccessoryPublisher.spec.d.ts +2 -0
  30. package/dist/matter/ExternalMatterAccessoryPublisher.spec.d.ts.map +1 -0
  31. package/dist/matter/ExternalMatterAccessoryPublisher.spec.js +293 -0
  32. package/dist/matter/ExternalMatterAccessoryPublisher.spec.js.map +1 -0
  33. package/dist/matter/{matterServer.d.ts → MatterAPIImpl.d.ts} +203 -367
  34. package/dist/matter/MatterAPIImpl.d.ts.map +1 -0
  35. package/dist/matter/MatterAPIImpl.js +305 -0
  36. package/dist/matter/MatterAPIImpl.js.map +1 -0
  37. package/dist/matter/MatterBridgeManager.d.ts +91 -0
  38. package/dist/matter/MatterBridgeManager.d.ts.map +1 -0
  39. package/dist/matter/MatterBridgeManager.js +426 -0
  40. package/dist/matter/MatterBridgeManager.js.map +1 -0
  41. package/dist/matter/MatterConfigCollector.d.ts +26 -0
  42. package/dist/matter/MatterConfigCollector.d.ts.map +1 -0
  43. package/dist/matter/MatterConfigCollector.js +78 -0
  44. package/dist/matter/MatterConfigCollector.js.map +1 -0
  45. package/dist/matter/{matterAccessoryCache.d.ts → accessoryCache.d.ts} +12 -3
  46. package/dist/matter/accessoryCache.d.ts.map +1 -0
  47. package/dist/matter/{matterAccessoryCache.js → accessoryCache.js} +32 -10
  48. package/dist/matter/accessoryCache.js.map +1 -0
  49. package/dist/matter/accessoryCache.spec.d.ts +2 -0
  50. package/dist/matter/accessoryCache.spec.d.ts.map +1 -0
  51. package/dist/matter/accessoryCache.spec.js +452 -0
  52. package/dist/matter/accessoryCache.spec.js.map +1 -0
  53. package/dist/matter/behaviors/BehaviorRegistry.d.ts +65 -0
  54. package/dist/matter/behaviors/BehaviorRegistry.d.ts.map +1 -0
  55. package/dist/matter/behaviors/BehaviorRegistry.js +139 -0
  56. package/dist/matter/behaviors/BehaviorRegistry.js.map +1 -0
  57. package/dist/matter/behaviors/BehaviorRegistry.spec.d.ts +2 -0
  58. package/dist/matter/behaviors/BehaviorRegistry.spec.d.ts.map +1 -0
  59. package/dist/matter/behaviors/BehaviorRegistry.spec.js +307 -0
  60. package/dist/matter/behaviors/BehaviorRegistry.spec.js.map +1 -0
  61. package/dist/matter/behaviors/ColorControlBehavior.d.ts +64 -0
  62. package/dist/matter/behaviors/ColorControlBehavior.d.ts.map +1 -0
  63. package/dist/matter/behaviors/ColorControlBehavior.js +160 -0
  64. package/dist/matter/behaviors/ColorControlBehavior.js.map +1 -0
  65. package/dist/matter/behaviors/ColorControlBehavior.spec.d.ts +2 -0
  66. package/dist/matter/behaviors/ColorControlBehavior.spec.d.ts.map +1 -0
  67. package/dist/matter/behaviors/ColorControlBehavior.spec.js +29 -0
  68. package/dist/matter/behaviors/ColorControlBehavior.spec.js.map +1 -0
  69. package/dist/matter/behaviors/DoorLockBehavior.d.ts +21 -0
  70. package/dist/matter/behaviors/DoorLockBehavior.d.ts.map +1 -0
  71. package/dist/matter/behaviors/DoorLockBehavior.js +49 -0
  72. package/dist/matter/behaviors/DoorLockBehavior.js.map +1 -0
  73. package/dist/matter/behaviors/DoorLockBehavior.spec.d.ts +2 -0
  74. package/dist/matter/behaviors/DoorLockBehavior.spec.d.ts.map +1 -0
  75. package/dist/matter/behaviors/DoorLockBehavior.spec.js +108 -0
  76. package/dist/matter/behaviors/DoorLockBehavior.spec.js.map +1 -0
  77. package/dist/matter/behaviors/FanControlBehavior.d.ts +20 -0
  78. package/dist/matter/behaviors/FanControlBehavior.d.ts.map +1 -0
  79. package/dist/matter/behaviors/FanControlBehavior.js +45 -0
  80. package/dist/matter/behaviors/FanControlBehavior.js.map +1 -0
  81. package/dist/matter/behaviors/FanControlBehavior.spec.d.ts +2 -0
  82. package/dist/matter/behaviors/FanControlBehavior.spec.d.ts.map +1 -0
  83. package/dist/matter/behaviors/FanControlBehavior.spec.js +23 -0
  84. package/dist/matter/behaviors/FanControlBehavior.spec.js.map +1 -0
  85. package/dist/matter/behaviors/IdentifyBehavior.d.ts +21 -0
  86. package/dist/matter/behaviors/IdentifyBehavior.d.ts.map +1 -0
  87. package/dist/matter/behaviors/IdentifyBehavior.js +27 -0
  88. package/dist/matter/behaviors/IdentifyBehavior.js.map +1 -0
  89. package/dist/matter/behaviors/IdentifyBehavior.spec.d.ts +2 -0
  90. package/dist/matter/behaviors/IdentifyBehavior.spec.d.ts.map +1 -0
  91. package/dist/matter/behaviors/IdentifyBehavior.spec.js +64 -0
  92. package/dist/matter/behaviors/IdentifyBehavior.spec.js.map +1 -0
  93. package/dist/matter/behaviors/LevelControlBehavior.d.ts +34 -0
  94. package/dist/matter/behaviors/LevelControlBehavior.d.ts.map +1 -0
  95. package/dist/matter/behaviors/LevelControlBehavior.js +75 -0
  96. package/dist/matter/behaviors/LevelControlBehavior.js.map +1 -0
  97. package/dist/matter/behaviors/LevelControlBehavior.spec.d.ts +2 -0
  98. package/dist/matter/behaviors/LevelControlBehavior.spec.d.ts.map +1 -0
  99. package/dist/matter/behaviors/LevelControlBehavior.spec.js +140 -0
  100. package/dist/matter/behaviors/LevelControlBehavior.spec.js.map +1 -0
  101. package/dist/matter/behaviors/OnOffBehavior.d.ts +28 -0
  102. package/dist/matter/behaviors/OnOffBehavior.d.ts.map +1 -0
  103. package/dist/matter/behaviors/OnOffBehavior.js +63 -0
  104. package/dist/matter/behaviors/OnOffBehavior.js.map +1 -0
  105. package/dist/matter/behaviors/OnOffBehavior.spec.d.ts +2 -0
  106. package/dist/matter/behaviors/OnOffBehavior.spec.d.ts.map +1 -0
  107. package/dist/matter/behaviors/OnOffBehavior.spec.js +116 -0
  108. package/dist/matter/behaviors/OnOffBehavior.spec.js.map +1 -0
  109. package/dist/matter/behaviors/RvcCleanModeBehavior.d.ts +19 -0
  110. package/dist/matter/behaviors/RvcCleanModeBehavior.d.ts.map +1 -0
  111. package/dist/matter/behaviors/RvcCleanModeBehavior.js +27 -0
  112. package/dist/matter/behaviors/RvcCleanModeBehavior.js.map +1 -0
  113. package/dist/matter/behaviors/RvcCleanModeBehavior.spec.d.ts +2 -0
  114. package/dist/matter/behaviors/RvcCleanModeBehavior.spec.d.ts.map +1 -0
  115. package/dist/matter/behaviors/RvcCleanModeBehavior.spec.js +56 -0
  116. package/dist/matter/behaviors/RvcCleanModeBehavior.spec.js.map +1 -0
  117. package/dist/matter/behaviors/RvcOperationalStateBehavior.d.ts +23 -0
  118. package/dist/matter/behaviors/RvcOperationalStateBehavior.d.ts.map +1 -0
  119. package/dist/matter/behaviors/RvcOperationalStateBehavior.js +49 -0
  120. package/dist/matter/behaviors/RvcOperationalStateBehavior.js.map +1 -0
  121. package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.d.ts +2 -0
  122. package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.d.ts.map +1 -0
  123. package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.js +55 -0
  124. package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.js.map +1 -0
  125. package/dist/matter/behaviors/RvcRunModeBehavior.d.ts +19 -0
  126. package/dist/matter/behaviors/RvcRunModeBehavior.d.ts.map +1 -0
  127. package/dist/matter/behaviors/RvcRunModeBehavior.js +27 -0
  128. package/dist/matter/behaviors/RvcRunModeBehavior.js.map +1 -0
  129. package/dist/matter/behaviors/RvcRunModeBehavior.spec.d.ts +2 -0
  130. package/dist/matter/behaviors/RvcRunModeBehavior.spec.d.ts.map +1 -0
  131. package/dist/matter/behaviors/RvcRunModeBehavior.spec.js +56 -0
  132. package/dist/matter/behaviors/RvcRunModeBehavior.spec.js.map +1 -0
  133. package/dist/matter/behaviors/ServiceAreaBehavior.d.ts +22 -0
  134. package/dist/matter/behaviors/ServiceAreaBehavior.d.ts.map +1 -0
  135. package/dist/matter/behaviors/ServiceAreaBehavior.js +35 -0
  136. package/dist/matter/behaviors/ServiceAreaBehavior.js.map +1 -0
  137. package/dist/matter/behaviors/ServiceAreaBehavior.spec.d.ts +2 -0
  138. package/dist/matter/behaviors/ServiceAreaBehavior.spec.d.ts.map +1 -0
  139. package/dist/matter/behaviors/ServiceAreaBehavior.spec.js +52 -0
  140. package/dist/matter/behaviors/ServiceAreaBehavior.spec.js.map +1 -0
  141. package/dist/matter/behaviors/ThermostatBehavior.d.ts +23 -0
  142. package/dist/matter/behaviors/ThermostatBehavior.d.ts.map +1 -0
  143. package/dist/matter/behaviors/ThermostatBehavior.js +79 -0
  144. package/dist/matter/behaviors/ThermostatBehavior.js.map +1 -0
  145. package/dist/matter/behaviors/ThermostatBehavior.spec.d.ts +2 -0
  146. package/dist/matter/behaviors/ThermostatBehavior.spec.d.ts.map +1 -0
  147. package/dist/matter/behaviors/ThermostatBehavior.spec.js +23 -0
  148. package/dist/matter/behaviors/ThermostatBehavior.spec.js.map +1 -0
  149. package/dist/matter/behaviors/WindowCoveringBehavior.d.ts +32 -0
  150. package/dist/matter/behaviors/WindowCoveringBehavior.d.ts.map +1 -0
  151. package/dist/matter/behaviors/WindowCoveringBehavior.js +106 -0
  152. package/dist/matter/behaviors/WindowCoveringBehavior.js.map +1 -0
  153. package/dist/matter/behaviors/WindowCoveringBehavior.spec.d.ts +2 -0
  154. package/dist/matter/behaviors/WindowCoveringBehavior.spec.d.ts.map +1 -0
  155. package/dist/matter/behaviors/WindowCoveringBehavior.spec.js +27 -0
  156. package/dist/matter/behaviors/WindowCoveringBehavior.spec.js.map +1 -0
  157. package/dist/matter/behaviors/index.d.ts +20 -0
  158. package/dist/matter/behaviors/index.d.ts.map +1 -0
  159. package/dist/matter/behaviors/index.js +21 -0
  160. package/dist/matter/behaviors/index.js.map +1 -0
  161. package/dist/matter/{matterConfigValidator.d.ts → configValidator.d.ts} +1 -1
  162. package/dist/matter/configValidator.d.ts.map +1 -0
  163. package/dist/matter/{matterConfigValidator.js → configValidator.js} +1 -1
  164. package/dist/matter/configValidator.js.map +1 -0
  165. package/dist/matter/configValidator.spec.d.ts +2 -0
  166. package/dist/matter/configValidator.spec.d.ts.map +1 -0
  167. package/dist/matter/configValidator.spec.js +390 -0
  168. package/dist/matter/configValidator.spec.js.map +1 -0
  169. package/dist/matter/errorHandler.d.ts +33 -0
  170. package/dist/matter/errorHandler.d.ts.map +1 -0
  171. package/dist/matter/errorHandler.js +113 -0
  172. package/dist/matter/errorHandler.js.map +1 -0
  173. package/dist/matter/errorHandler.spec.d.ts +2 -0
  174. package/dist/matter/errorHandler.spec.d.ts.map +1 -0
  175. package/dist/matter/errorHandler.spec.js +159 -0
  176. package/dist/matter/errorHandler.spec.js.map +1 -0
  177. package/dist/matter/index.d.ts +7 -4
  178. package/dist/matter/index.d.ts.map +1 -1
  179. package/dist/matter/index.js +7 -4
  180. package/dist/matter/index.js.map +1 -1
  181. package/dist/matter/{matterLogFormatter.d.ts → logFormatter.d.ts} +1 -1
  182. package/dist/matter/logFormatter.d.ts.map +1 -0
  183. package/dist/matter/{matterLogFormatter.js → logFormatter.js} +33 -6
  184. package/dist/matter/logFormatter.js.map +1 -0
  185. package/dist/matter/logFormatter.spec.d.ts +2 -0
  186. package/dist/matter/logFormatter.spec.d.ts.map +1 -0
  187. package/dist/matter/logFormatter.spec.js +284 -0
  188. package/dist/matter/logFormatter.spec.js.map +1 -0
  189. package/dist/matter/server.d.ts +350 -0
  190. package/dist/matter/server.d.ts.map +1 -0
  191. package/dist/matter/{matterServer.js → server.js} +533 -352
  192. package/dist/matter/server.js.map +1 -0
  193. package/dist/matter/{matterServerHelpers.d.ts → serverHelpers.d.ts} +2 -2
  194. package/dist/matter/serverHelpers.d.ts.map +1 -0
  195. package/dist/matter/{matterServerHelpers.js → serverHelpers.js} +11 -8
  196. package/dist/matter/serverHelpers.js.map +1 -0
  197. package/dist/matter/serverHelpers.spec.d.ts +2 -0
  198. package/dist/matter/serverHelpers.spec.d.ts.map +1 -0
  199. package/dist/matter/serverHelpers.spec.js +521 -0
  200. package/dist/matter/serverHelpers.spec.js.map +1 -0
  201. package/dist/matter/{matterSharedTypes.d.ts → sharedTypes.d.ts} +4 -10
  202. package/dist/matter/sharedTypes.d.ts.map +1 -0
  203. package/dist/matter/{matterSharedTypes.js → sharedTypes.js} +4 -10
  204. package/dist/matter/sharedTypes.js.map +1 -0
  205. package/dist/matter/{matterStorage.d.ts → storage.d.ts} +9 -2
  206. package/dist/matter/storage.d.ts.map +1 -0
  207. package/dist/matter/{matterStorage.js → storage.js} +14 -5
  208. package/dist/matter/{matterStorage.js.map → storage.js.map} +1 -1
  209. package/dist/matter/storage.spec.d.ts +2 -0
  210. package/dist/matter/storage.spec.d.ts.map +1 -0
  211. package/dist/matter/storage.spec.js +570 -0
  212. package/dist/matter/storage.spec.js.map +1 -0
  213. package/dist/matter/typeHelpers.d.ts +45 -0
  214. package/dist/matter/typeHelpers.d.ts.map +1 -0
  215. package/dist/matter/typeHelpers.js +57 -0
  216. package/dist/matter/typeHelpers.js.map +1 -0
  217. package/dist/matter/typeHelpers.spec.d.ts +2 -0
  218. package/dist/matter/typeHelpers.spec.d.ts.map +1 -0
  219. package/dist/matter/typeHelpers.spec.js +127 -0
  220. package/dist/matter/typeHelpers.spec.js.map +1 -0
  221. package/dist/matter/{matterTypes.d.ts → types.d.ts} +2 -2
  222. package/dist/matter/types.d.ts.map +1 -0
  223. package/dist/matter/{matterTypes.js → types.js} +1 -2
  224. package/dist/matter/types.js.map +1 -0
  225. package/dist/platformAccessory.spec.d.ts +2 -0
  226. package/dist/platformAccessory.spec.d.ts.map +1 -0
  227. package/dist/platformAccessory.spec.js +126 -0
  228. package/dist/platformAccessory.spec.js.map +1 -0
  229. package/dist/pluginManager.spec.d.ts +2 -0
  230. package/dist/pluginManager.spec.d.ts.map +1 -0
  231. package/dist/pluginManager.spec.js +43 -0
  232. package/dist/pluginManager.spec.js.map +1 -0
  233. package/dist/server.d.ts +4 -13
  234. package/dist/server.d.ts.map +1 -1
  235. package/dist/server.js +43 -346
  236. package/dist/server.js.map +1 -1
  237. package/dist/server.spec.d.ts +2 -0
  238. package/dist/server.spec.d.ts.map +1 -0
  239. package/dist/server.spec.js +57 -0
  240. package/dist/server.spec.js.map +1 -0
  241. package/dist/user.spec.d.ts +2 -0
  242. package/dist/user.spec.d.ts.map +1 -0
  243. package/dist/user.spec.js +31 -0
  244. package/dist/user.spec.js.map +1 -0
  245. package/dist/util/mac.spec.d.ts +2 -0
  246. package/dist/util/mac.spec.d.ts.map +1 -0
  247. package/dist/util/mac.spec.js +36 -0
  248. package/dist/util/mac.spec.js.map +1 -0
  249. package/dist/version.spec.d.ts +2 -0
  250. package/dist/version.spec.d.ts.map +1 -0
  251. package/dist/version.spec.js +20 -0
  252. package/dist/version.spec.js.map +1 -0
  253. package/package.json +4 -4
  254. package/dist/matter/matterAccessoryCache.d.ts.map +0 -1
  255. package/dist/matter/matterAccessoryCache.js.map +0 -1
  256. package/dist/matter/matterBehaviors.d.ts +0 -194
  257. package/dist/matter/matterBehaviors.d.ts.map +0 -1
  258. package/dist/matter/matterBehaviors.js +0 -665
  259. package/dist/matter/matterBehaviors.js.map +0 -1
  260. package/dist/matter/matterConfigValidator.d.ts.map +0 -1
  261. package/dist/matter/matterConfigValidator.js.map +0 -1
  262. package/dist/matter/matterErrorHandler.d.ts +0 -106
  263. package/dist/matter/matterErrorHandler.d.ts.map +0 -1
  264. package/dist/matter/matterErrorHandler.js +0 -495
  265. package/dist/matter/matterErrorHandler.js.map +0 -1
  266. package/dist/matter/matterLogFormatter.d.ts.map +0 -1
  267. package/dist/matter/matterLogFormatter.js.map +0 -1
  268. package/dist/matter/matterNetworkMonitor.d.ts +0 -68
  269. package/dist/matter/matterNetworkMonitor.d.ts.map +0 -1
  270. package/dist/matter/matterNetworkMonitor.js +0 -249
  271. package/dist/matter/matterNetworkMonitor.js.map +0 -1
  272. package/dist/matter/matterServer.d.ts.map +0 -1
  273. package/dist/matter/matterServer.js.map +0 -1
  274. package/dist/matter/matterServerHelpers.d.ts.map +0 -1
  275. package/dist/matter/matterServerHelpers.js.map +0 -1
  276. package/dist/matter/matterSharedTypes.d.ts.map +0 -1
  277. package/dist/matter/matterSharedTypes.js.map +0 -1
  278. package/dist/matter/matterStorage.d.ts.map +0 -1
  279. package/dist/matter/matterTypes.d.ts.map +0 -1
  280. package/dist/matter/matterTypes.js.map +0 -1
@@ -1,9 +1,4 @@
1
- /**
2
- * Matter Accessory Cache
3
- *
4
- * Handles persistence of Matter accessories across Homebridge restarts.
5
- * Similar to HAP's cached accessories, but designed for Matter's simpler API.
6
- */
1
+ /* global NodeJS */
7
2
  import { dirname, join } from 'node:path';
8
3
  import fs from 'fs-extra';
9
4
  import { Logger } from '../logger.js';
@@ -17,6 +12,8 @@ export class MatterAccessoryCache {
17
12
  cacheLoaded = false;
18
13
  saveQueue = Promise.resolve();
19
14
  directoryEnsured = false;
15
+ saveDebounceTimer = null;
16
+ SAVE_DEBOUNCE_MS = 2000; // Debounce cache saves by 2 seconds
20
17
  constructor(storagePath, bridgeId) {
21
18
  this.cacheFilePath = join(storagePath, bridgeId, 'accessories.json');
22
19
  }
@@ -54,7 +51,8 @@ export class MatterAccessoryCache {
54
51
  }
55
52
  catch (error) {
56
53
  // If JSON parsing failed (corrupted file), delete it and start fresh
57
- log.error(`Failed to load Matter accessory cache from ${this.cacheFilePath}: ${error.message}`);
54
+ const errorMessage = error instanceof Error ? error.message : String(error);
55
+ log.error(`Failed to load Matter accessory cache from ${this.cacheFilePath}: ${errorMessage}`);
58
56
  log.warn('Deleting corrupted cache file and starting fresh');
59
57
  try {
60
58
  await fs.remove(this.cacheFilePath);
@@ -68,10 +66,33 @@ export class MatterAccessoryCache {
68
66
  }
69
67
  }
70
68
  /**
71
- * Save accessories to cache (serialized to prevent concurrent write conflicts)
69
+ * Request a debounced save to cache
70
+ * Multiple rapid calls within the debounce window will only result in one disk write
71
+ * Use this for normal operations to reduce disk I/O
72
+ */
73
+ requestSave(accessories) {
74
+ // Clear any existing debounce timer
75
+ if (this.saveDebounceTimer) {
76
+ clearTimeout(this.saveDebounceTimer);
77
+ }
78
+ // Schedule a new save after the debounce period
79
+ this.saveDebounceTimer = setTimeout(() => {
80
+ this.save(accessories).catch((error) => {
81
+ log.error('Debounced cache save failed:', error);
82
+ });
83
+ }, this.SAVE_DEBOUNCE_MS);
84
+ }
85
+ /**
86
+ * Save accessories to cache immediately (serialized to prevent concurrent write conflicts)
72
87
  * Uses a queue pattern to ensure saves are truly serialized even when called concurrently
88
+ * Use this for shutdown/critical operations that need immediate persistence
73
89
  */
74
90
  async save(accessories) {
91
+ // Clear any pending debounced save since we're saving now
92
+ if (this.saveDebounceTimer) {
93
+ clearTimeout(this.saveDebounceTimer);
94
+ this.saveDebounceTimer = null;
95
+ }
75
96
  // Chain this save to the end of the queue
76
97
  // This ensures all saves run sequentially without race conditions
77
98
  this.saveQueue = this.saveQueue.then(() => this.performSave(accessories));
@@ -108,7 +129,8 @@ export class MatterAccessoryCache {
108
129
  log.debug(`Saved ${serialized.length} Matter accessor${serialized.length === 1 ? 'y' : 'ies'} to cache`);
109
130
  }
110
131
  catch (error) {
111
- log.error(`Failed to save Matter accessory cache: ${error.message}`);
132
+ const errorMessage = error instanceof Error ? error.message : String(error);
133
+ log.error(`Failed to save Matter accessory cache: ${errorMessage}`);
112
134
  // Clean up temp file if it exists
113
135
  try {
114
136
  if (await fs.pathExists(tempFilePath)) {
@@ -189,4 +211,4 @@ export class MatterAccessoryCache {
189
211
  };
190
212
  }
191
213
  }
192
- //# sourceMappingURL=matterAccessoryCache.js.map
214
+ //# sourceMappingURL=accessoryCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessoryCache.js","sourceRoot":"","sources":["../../src/matter/accessoryCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=accessoryCache.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessoryCache.spec.d.ts","sourceRoot":"","sources":["../../src/matter/accessoryCache.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,452 @@
1
+ import fs from 'fs-extra';
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
3
+ import { Logger } from '../logger.js';
4
+ import { MatterAccessoryCache } from './accessoryCache.js';
5
+ // Mock dependencies
6
+ vi.mock('fs-extra');
7
+ vi.mock('../logger.js', () => {
8
+ const mockLogger = {
9
+ error: vi.fn(),
10
+ info: vi.fn(),
11
+ warn: vi.fn(),
12
+ debug: vi.fn(),
13
+ log: vi.fn(),
14
+ };
15
+ return {
16
+ Logger: {
17
+ withPrefix: vi.fn(() => mockLogger),
18
+ },
19
+ };
20
+ });
21
+ describe('matterAccessoryCache', () => {
22
+ let cache;
23
+ let logInfoSpy;
24
+ let logErrorSpy;
25
+ let logWarnSpy;
26
+ let logDebugSpy;
27
+ beforeEach(() => {
28
+ vi.clearAllMocks();
29
+ // Get logger spies
30
+ const logger = vi.mocked(Logger).withPrefix('test');
31
+ logInfoSpy = logger.info;
32
+ logErrorSpy = logger.error;
33
+ logWarnSpy = logger.warn;
34
+ logDebugSpy = logger.debug;
35
+ // Create cache instance
36
+ cache = new MatterAccessoryCache('/mock/storage', 'test-bridge');
37
+ });
38
+ describe('constructor', () => {
39
+ it('should create cache with correct file path', () => {
40
+ expect(cache).toBeDefined();
41
+ // Path should be /mock/storage/test-bridge/accessories.json
42
+ });
43
+ });
44
+ describe('load', () => {
45
+ it('should return empty map on first run (file does not exist)', async () => {
46
+ ;
47
+ vi.mocked(fs.pathExists).mockResolvedValue(false);
48
+ const result = await cache.load();
49
+ expect(result.size).toBe(0);
50
+ expect(logInfoSpy).toHaveBeenCalledWith('No cached Matter accessories found (first run)');
51
+ });
52
+ it('should load cached accessories from file', async () => {
53
+ const mockData = [
54
+ {
55
+ plugin: 'homebridge-test',
56
+ platform: 'TestPlatform',
57
+ uuid: 'uuid-1',
58
+ displayName: 'Test Device 1',
59
+ deviceType: { name: 'OnOffLight', code: 256 },
60
+ serialNumber: 'SN-001',
61
+ manufacturer: 'Test Mfg',
62
+ model: 'Test Model',
63
+ clusters: { onOff: { onOff: false } },
64
+ },
65
+ {
66
+ plugin: 'homebridge-test',
67
+ platform: 'TestPlatform',
68
+ uuid: 'uuid-2',
69
+ displayName: 'Test Device 2',
70
+ deviceType: { name: 'OnOffLight', code: 256 },
71
+ serialNumber: 'SN-002',
72
+ manufacturer: 'Test Mfg',
73
+ model: 'Test Model',
74
+ clusters: { onOff: { onOff: true } },
75
+ },
76
+ ];
77
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
78
+ vi.mocked(fs.readJson).mockResolvedValue(mockData);
79
+ const result = await cache.load();
80
+ expect(result.size).toBe(2);
81
+ expect(result.get('uuid-1')).toEqual(mockData[0]);
82
+ expect(result.get('uuid-2')).toEqual(mockData[1]);
83
+ expect(logInfoSpy).toHaveBeenCalledWith('Loaded 2 cached Matter accessories');
84
+ });
85
+ it('should skip accessories without UUID', async () => {
86
+ const mockData = [
87
+ {
88
+ plugin: 'homebridge-test',
89
+ platform: 'TestPlatform',
90
+ uuid: 'uuid-1',
91
+ displayName: 'Valid',
92
+ deviceType: {},
93
+ serialNumber: 'SN-001',
94
+ manufacturer: 'Test',
95
+ model: 'Test',
96
+ },
97
+ {
98
+ // Missing UUID
99
+ plugin: 'homebridge-test',
100
+ platform: 'TestPlatform',
101
+ displayName: 'Invalid',
102
+ deviceType: {},
103
+ serialNumber: 'SN-002',
104
+ manufacturer: 'Test',
105
+ model: 'Test',
106
+ },
107
+ ];
108
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
109
+ vi.mocked(fs.readJson).mockResolvedValue(mockData);
110
+ const result = await cache.load();
111
+ expect(result.size).toBe(1);
112
+ expect(result.has('uuid-1')).toBe(true);
113
+ });
114
+ it('should handle non-array cache data', async () => {
115
+ ;
116
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
117
+ vi.mocked(fs.readJson).mockResolvedValue({ notAnArray: true });
118
+ const result = await cache.load();
119
+ expect(result.size).toBe(0);
120
+ expect(logErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to load'));
121
+ expect(logWarnSpy).toHaveBeenCalledWith('Deleting corrupted cache file and starting fresh');
122
+ expect(fs.remove).toHaveBeenCalled();
123
+ });
124
+ it('should handle corrupted JSON file', async () => {
125
+ ;
126
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
127
+ vi.mocked(fs.readJson).mockRejectedValue(new Error('Invalid JSON'));
128
+ const result = await cache.load();
129
+ expect(result.size).toBe(0);
130
+ expect(logErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to load'));
131
+ expect(logWarnSpy).toHaveBeenCalledWith('Deleting corrupted cache file and starting fresh');
132
+ expect(fs.remove).toHaveBeenCalled();
133
+ });
134
+ it('should handle error when deleting corrupted file', async () => {
135
+ ;
136
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
137
+ vi.mocked(fs.readJson).mockRejectedValue(new Error('Invalid JSON'));
138
+ vi.mocked(fs.remove).mockRejectedValue(new Error('Cannot delete'));
139
+ const result = await cache.load();
140
+ expect(result.size).toBe(0);
141
+ expect(logDebugSpy).toHaveBeenCalledWith('Could not delete corrupted cache file:', expect.anything());
142
+ });
143
+ it('should not load twice (cacheLoaded flag)', async () => {
144
+ ;
145
+ vi.mocked(fs.pathExists).mockResolvedValue(false);
146
+ await cache.load();
147
+ await cache.load(); // second load
148
+ // pathExists should only be called once
149
+ expect(fs.pathExists).toHaveBeenCalledTimes(1);
150
+ });
151
+ });
152
+ describe('requestSave', () => {
153
+ it('should debounce multiple rapid save requests', async () => {
154
+ vi.useFakeTimers();
155
+ const accessories = new Map();
156
+ const mockAccessory = {
157
+ uuid: 'test-uuid',
158
+ displayName: 'Test',
159
+ deviceType: { name: 'OnOffLight', code: 256 },
160
+ serialNumber: 'SN-001',
161
+ manufacturer: 'Test',
162
+ model: 'Test',
163
+ clusters: {},
164
+ };
165
+ accessories.set('test-uuid', mockAccessory);
166
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
167
+ vi.mocked(fs.writeJson).mockResolvedValue(undefined);
168
+ vi.mocked(fs.move).mockResolvedValue(undefined);
169
+ // Request multiple saves rapidly
170
+ cache.requestSave(accessories);
171
+ cache.requestSave(accessories);
172
+ cache.requestSave(accessories);
173
+ // Fast-forward timers
174
+ await vi.runAllTimersAsync();
175
+ // Only one actual save should occur
176
+ expect(fs.writeJson).toHaveBeenCalledTimes(1);
177
+ vi.useRealTimers();
178
+ });
179
+ });
180
+ describe('save', () => {
181
+ it('should save accessories to cache', async () => {
182
+ ;
183
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
184
+ vi.mocked(fs.ensureDir).mockResolvedValue(undefined);
185
+ vi.mocked(fs.writeJson).mockResolvedValue(undefined);
186
+ vi.mocked(fs.move).mockResolvedValue(undefined);
187
+ const accessories = new Map();
188
+ const mockAccessory = {
189
+ _associatedPlugin: 'homebridge-test',
190
+ _associatedPlatform: 'TestPlatform',
191
+ uuid: 'test-uuid',
192
+ displayName: 'Test Device',
193
+ deviceType: { name: 'OnOffLight', code: 256 },
194
+ serialNumber: 'SN-001',
195
+ manufacturer: 'Test Mfg',
196
+ model: 'Test Model',
197
+ firmwareRevision: '1.0.0',
198
+ clusters: { onOff: { onOff: false } },
199
+ };
200
+ accessories.set('test-uuid', mockAccessory);
201
+ await cache.save(accessories);
202
+ expect(fs.writeJson).toHaveBeenCalledWith(expect.stringContaining('.tmp'), expect.arrayContaining([
203
+ expect.objectContaining({
204
+ uuid: 'test-uuid',
205
+ displayName: 'Test Device',
206
+ }),
207
+ ]), { spaces: 2 });
208
+ expect(fs.move).toHaveBeenCalled();
209
+ expect(logDebugSpy).toHaveBeenCalledWith('Saved 1 Matter accessory to cache');
210
+ });
211
+ it('should serialize accessories with parts', async () => {
212
+ ;
213
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
214
+ vi.mocked(fs.writeJson).mockResolvedValue(undefined);
215
+ vi.mocked(fs.move).mockResolvedValue(undefined);
216
+ const accessories = new Map();
217
+ const mockAccessory = {
218
+ _associatedPlugin: 'homebridge-test',
219
+ _associatedPlatform: 'TestPlatform',
220
+ uuid: 'test-uuid',
221
+ displayName: 'Test Device',
222
+ deviceType: { name: 'Aggregator', code: 14 },
223
+ serialNumber: 'SN-001',
224
+ manufacturer: 'Test',
225
+ model: 'Test',
226
+ clusters: {},
227
+ parts: [
228
+ {
229
+ id: 'part-1',
230
+ displayName: 'Part 1',
231
+ deviceType: { name: 'OnOffLight', code: 256 },
232
+ clusters: { onOff: { onOff: true } },
233
+ },
234
+ ],
235
+ };
236
+ accessories.set('test-uuid', mockAccessory);
237
+ await cache.save(accessories);
238
+ const savedData = vi.mocked(fs.writeJson).mock.calls[0][1];
239
+ expect(savedData[0].parts).toBeDefined();
240
+ expect(savedData[0].parts[0].id).toBe('part-1');
241
+ });
242
+ it('should ensure directory exists on first save', async () => {
243
+ ;
244
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
245
+ vi.mocked(fs.ensureDir).mockResolvedValue(undefined);
246
+ vi.mocked(fs.writeJson).mockResolvedValue(undefined);
247
+ vi.mocked(fs.move).mockResolvedValue(undefined);
248
+ const accessories = new Map();
249
+ await cache.save(accessories);
250
+ expect(fs.ensureDir).toHaveBeenCalledWith(expect.stringContaining('/mock/storage/test-bridge'));
251
+ expect(logDebugSpy).toHaveBeenCalledWith(expect.stringContaining('Cache directory ensured'));
252
+ });
253
+ it('should throw error if directory creation fails', async () => {
254
+ ;
255
+ vi.mocked(fs.pathExists).mockResolvedValue(false) // directory doesn't exist after creation
256
+ ;
257
+ vi.mocked(fs.ensureDir).mockResolvedValue(undefined);
258
+ const accessories = new Map();
259
+ await cache.save(accessories);
260
+ expect(logErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to save'));
261
+ });
262
+ it('should use atomic write pattern (temp file then move)', async () => {
263
+ ;
264
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
265
+ vi.mocked(fs.writeJson).mockResolvedValue(undefined);
266
+ vi.mocked(fs.move).mockResolvedValue(undefined);
267
+ const accessories = new Map();
268
+ await cache.save(accessories);
269
+ // Should write to temp file first
270
+ expect(fs.writeJson).toHaveBeenCalledWith(expect.stringContaining('.tmp'), expect.anything(), expect.anything());
271
+ // Then move temp file to final location
272
+ expect(fs.move).toHaveBeenCalledWith(expect.stringContaining('.tmp'), expect.stringContaining('accessories.json'), { overwrite: true });
273
+ });
274
+ it('should clean up temp file on write error', async () => {
275
+ ;
276
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
277
+ vi.mocked(fs.writeJson).mockRejectedValue(new Error('Write failed'));
278
+ const accessories = new Map();
279
+ await cache.save(accessories);
280
+ expect(logErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to save'));
281
+ expect(fs.pathExists).toHaveBeenCalled();
282
+ });
283
+ it('should handle cleanup error gracefully', async () => {
284
+ ;
285
+ vi.mocked(fs.pathExists)
286
+ .mockResolvedValueOnce(true) // directory exists
287
+ .mockResolvedValueOnce(true) // temp file exists for cleanup
288
+ ;
289
+ vi.mocked(fs.writeJson).mockRejectedValue(new Error('Write failed'));
290
+ vi.mocked(fs.remove).mockRejectedValue(new Error('Remove failed'));
291
+ const accessories = new Map();
292
+ await cache.save(accessories);
293
+ expect(logDebugSpy).toHaveBeenCalledWith('Could not clean up temporary cache file:', expect.anything());
294
+ });
295
+ it('should serialize multiple accessories', async () => {
296
+ ;
297
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
298
+ vi.mocked(fs.writeJson).mockResolvedValue(undefined);
299
+ vi.mocked(fs.move).mockResolvedValue(undefined);
300
+ const accessories = new Map();
301
+ for (let i = 1; i <= 3; i++) {
302
+ accessories.set(`uuid-${i}`, {
303
+ uuid: `uuid-${i}`,
304
+ displayName: `Device ${i}`,
305
+ deviceType: { name: 'OnOffLight', code: 256 },
306
+ serialNumber: `SN-00${i}`,
307
+ manufacturer: 'Test',
308
+ model: 'Test',
309
+ clusters: {},
310
+ });
311
+ }
312
+ await cache.save(accessories);
313
+ const savedData = vi.mocked(fs.writeJson).mock.calls[0][1];
314
+ expect(savedData).toHaveLength(3);
315
+ expect(logDebugSpy).toHaveBeenCalledWith('Saved 3 Matter accessories to cache');
316
+ });
317
+ it('should queue concurrent saves to prevent race conditions', async () => {
318
+ ;
319
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
320
+ vi.mocked(fs.writeJson).mockResolvedValue(undefined);
321
+ vi.mocked(fs.move).mockResolvedValue(undefined);
322
+ const accessories = new Map();
323
+ // Start multiple saves concurrently
324
+ await Promise.all([
325
+ cache.save(accessories),
326
+ cache.save(accessories),
327
+ cache.save(accessories),
328
+ ]);
329
+ // All saves should complete (queued sequentially)
330
+ expect(fs.writeJson).toHaveBeenCalled();
331
+ });
332
+ });
333
+ describe('getCached', () => {
334
+ it('should return cached accessory by UUID', async () => {
335
+ const mockData = [
336
+ {
337
+ plugin: 'homebridge-test',
338
+ platform: 'TestPlatform',
339
+ uuid: 'uuid-1',
340
+ displayName: 'Test Device',
341
+ deviceType: { name: 'OnOffLight', code: 256 },
342
+ serialNumber: 'SN-001',
343
+ manufacturer: 'Test',
344
+ model: 'Test',
345
+ },
346
+ ];
347
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
348
+ vi.mocked(fs.readJson).mockResolvedValue(mockData);
349
+ await cache.load();
350
+ const result = cache.getCached('uuid-1');
351
+ expect(result).toEqual(mockData[0]);
352
+ });
353
+ it('should return undefined for non-existent UUID', async () => {
354
+ ;
355
+ vi.mocked(fs.pathExists).mockResolvedValue(false);
356
+ await cache.load();
357
+ const result = cache.getCached('non-existent');
358
+ expect(result).toBeUndefined();
359
+ });
360
+ });
361
+ describe('hasCached', () => {
362
+ it('should return true for cached accessory', async () => {
363
+ const mockData = [
364
+ {
365
+ plugin: 'homebridge-test',
366
+ platform: 'TestPlatform',
367
+ uuid: 'uuid-1',
368
+ displayName: 'Test',
369
+ deviceType: {},
370
+ serialNumber: 'SN-001',
371
+ manufacturer: 'Test',
372
+ model: 'Test',
373
+ },
374
+ ];
375
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
376
+ vi.mocked(fs.readJson).mockResolvedValue(mockData);
377
+ await cache.load();
378
+ expect(cache.hasCached('uuid-1')).toBe(true);
379
+ });
380
+ it('should return false for non-existent accessory', async () => {
381
+ ;
382
+ vi.mocked(fs.pathExists).mockResolvedValue(false);
383
+ await cache.load();
384
+ expect(cache.hasCached('non-existent')).toBe(false);
385
+ });
386
+ });
387
+ describe('removeCached', () => {
388
+ it('should remove accessory from cache', async () => {
389
+ const mockData = [
390
+ {
391
+ plugin: 'homebridge-test',
392
+ platform: 'TestPlatform',
393
+ uuid: 'uuid-1',
394
+ displayName: 'Test',
395
+ deviceType: {},
396
+ serialNumber: 'SN-001',
397
+ manufacturer: 'Test',
398
+ model: 'Test',
399
+ },
400
+ ];
401
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
402
+ vi.mocked(fs.readJson).mockResolvedValue(mockData);
403
+ await cache.load();
404
+ expect(cache.hasCached('uuid-1')).toBe(true);
405
+ cache.removeCached('uuid-1');
406
+ expect(cache.hasCached('uuid-1')).toBe(false);
407
+ });
408
+ });
409
+ describe('getAllCached', () => {
410
+ it('should return all cached accessories', async () => {
411
+ const mockData = [
412
+ {
413
+ plugin: 'homebridge-test',
414
+ platform: 'TestPlatform',
415
+ uuid: 'uuid-1',
416
+ displayName: 'Device 1',
417
+ deviceType: {},
418
+ serialNumber: 'SN-001',
419
+ manufacturer: 'Test',
420
+ model: 'Test',
421
+ },
422
+ {
423
+ plugin: 'homebridge-test',
424
+ platform: 'TestPlatform',
425
+ uuid: 'uuid-2',
426
+ displayName: 'Device 2',
427
+ deviceType: {},
428
+ serialNumber: 'SN-002',
429
+ manufacturer: 'Test',
430
+ model: 'Test',
431
+ },
432
+ ];
433
+ vi.mocked(fs.pathExists).mockResolvedValue(true);
434
+ vi.mocked(fs.readJson).mockResolvedValue(mockData);
435
+ await cache.load();
436
+ const all = cache.getAllCached();
437
+ expect(all.size).toBe(2);
438
+ expect(all.get('uuid-1')).toEqual(mockData[0]);
439
+ expect(all.get('uuid-2')).toEqual(mockData[1]);
440
+ });
441
+ it('should return a copy of the cache (not reference)', async () => {
442
+ ;
443
+ vi.mocked(fs.pathExists).mockResolvedValue(false);
444
+ await cache.load();
445
+ const all = cache.getAllCached();
446
+ all.set('test-uuid', {});
447
+ // Original cache should not be modified
448
+ expect(cache.hasCached('test-uuid')).toBe(false);
449
+ });
450
+ });
451
+ });
452
+ //# sourceMappingURL=accessoryCache.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessoryCache.spec.js","sourceRoot":"","sources":["../../src/matter/accessoryCache.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Behavior Registry
3
+ *
4
+ * Manages handler registration and accessory state without global mutable state.
5
+ * This replaces the global Maps in matterBehaviors.ts.
6
+ */
7
+ import type { InternalMatterAccessory } from '../types.js';
8
+ /**
9
+ * Handler function signature
10
+ */
11
+ export type MatterCommandHandler = (...args: any[]) => void | Promise<void>;
12
+ /**
13
+ * Accessory map type
14
+ */
15
+ export type MatterAccessoryMap = Map<string, InternalMatterAccessory>;
16
+ /**
17
+ * Registry for behavior handlers and accessory state
18
+ * Replaces global state with a proper class instance
19
+ */
20
+ export declare class BehaviorRegistry {
21
+ private handlers;
22
+ private partEndpoints;
23
+ private accessoriesMap;
24
+ constructor(accessoriesMap: MatterAccessoryMap);
25
+ /**
26
+ * Register a command handler for an endpoint
27
+ */
28
+ registerHandler(endpointId: string, clusterName: string, commandName: string, handler: MatterCommandHandler): void;
29
+ /**
30
+ * Get a registered handler
31
+ */
32
+ getHandler(endpointId: string, clusterName: string, commandName: string): MatterCommandHandler | undefined;
33
+ /**
34
+ * Execute a handler if it exists
35
+ */
36
+ executeHandler(endpointId: string, clusterName: string, commandName: string, ...args: any[]): Promise<boolean>;
37
+ /**
38
+ * Register a part endpoint mapping
39
+ */
40
+ registerPartEndpoint(endpointId: string, parentUuid: string, partId: string): void;
41
+ /**
42
+ * Get part endpoint info
43
+ */
44
+ getPartEndpointInfo(endpointId: string): {
45
+ parentUuid: string;
46
+ partId: string;
47
+ } | undefined;
48
+ /**
49
+ * Sync cluster state to cache
50
+ * Updates the accessory's cached cluster state when values change
51
+ */
52
+ syncStateToCache(endpointId: string, clusterName: string, attributes: Record<string, unknown>): void;
53
+ /**
54
+ * Clear all handlers (for cleanup)
55
+ */
56
+ clear(): void;
57
+ /**
58
+ * Get statistics
59
+ */
60
+ getStats(): {
61
+ handlerCount: number;
62
+ partCount: number;
63
+ };
64
+ }
65
+ //# sourceMappingURL=BehaviorRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BehaviorRegistry.d.ts","sourceRoot":"","sources":["../../../src/matter/behaviors/BehaviorRegistry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAM1D;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAE3E;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;AAErE;;;GAGG;AACH,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,QAAQ,CAAoE;IAGpF,OAAO,CAAC,aAAa,CAA4D;IAGjF,OAAO,CAAC,cAAc,CAAoB;gBAE9B,cAAc,EAAE,kBAAkB;IAI9C;;OAEG;IACH,eAAe,CACb,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,oBAAoB,GAC5B,IAAI;IAgBP;;OAEG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,oBAAoB,GAAG,SAAS;IAInC;;OAEG;IACG,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,OAAO,CAAC,OAAO,CAAC;IAenB;;OAEG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKlF;;OAEG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAI3F;;;OAGG;IACH,gBAAgB,CACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,IAAI;IA8CP;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,QAAQ,IAAI;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;CAaxD"}