matterbridge 3.5.0 → 3.5.1-dev-20260121-22e98b4

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 (328) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/mb_coap.js +1 -1
  3. package/bin/mb_mdns.js +1 -1
  4. package/dist/broadcastServer.d.ts +0 -115
  5. package/dist/broadcastServer.js +1 -119
  6. package/dist/broadcastServerTypes.d.ts +0 -43
  7. package/dist/broadcastServerTypes.js +0 -24
  8. package/dist/cli.d.ts +1 -26
  9. package/dist/cli.js +2 -102
  10. package/dist/cliEmitter.d.ts +0 -36
  11. package/dist/cliEmitter.js +0 -37
  12. package/dist/cliHistory.d.ts +0 -42
  13. package/dist/cliHistory.js +1 -39
  14. package/dist/clusters/export.d.ts +0 -1
  15. package/dist/clusters/export.js +0 -2
  16. package/dist/deviceManager.d.ts +0 -108
  17. package/dist/deviceManager.js +2 -114
  18. package/dist/devices/airConditioner.d.ts +0 -75
  19. package/dist/devices/airConditioner.js +0 -57
  20. package/dist/devices/batteryStorage.d.ts +0 -43
  21. package/dist/devices/batteryStorage.js +1 -48
  22. package/dist/devices/cooktop.d.ts +0 -55
  23. package/dist/devices/cooktop.js +0 -56
  24. package/dist/devices/dishwasher.d.ts +0 -55
  25. package/dist/devices/dishwasher.js +0 -57
  26. package/dist/devices/evse.d.ts +0 -57
  27. package/dist/devices/evse.js +10 -74
  28. package/dist/devices/export.d.ts +0 -1
  29. package/dist/devices/export.js +0 -5
  30. package/dist/devices/extractorHood.d.ts +0 -41
  31. package/dist/devices/extractorHood.js +0 -43
  32. package/dist/devices/heatPump.d.ts +0 -43
  33. package/dist/devices/heatPump.js +2 -50
  34. package/dist/devices/laundryDryer.d.ts +0 -58
  35. package/dist/devices/laundryDryer.js +3 -62
  36. package/dist/devices/laundryWasher.d.ts +0 -64
  37. package/dist/devices/laundryWasher.js +4 -70
  38. package/dist/devices/microwaveOven.d.ts +1 -77
  39. package/dist/devices/microwaveOven.js +5 -88
  40. package/dist/devices/oven.d.ts +0 -82
  41. package/dist/devices/oven.js +0 -85
  42. package/dist/devices/refrigerator.d.ts +0 -100
  43. package/dist/devices/refrigerator.js +0 -102
  44. package/dist/devices/roboticVacuumCleaner.d.ts +0 -83
  45. package/dist/devices/roboticVacuumCleaner.js +9 -100
  46. package/dist/devices/solarPower.d.ts +0 -36
  47. package/dist/devices/solarPower.js +0 -38
  48. package/dist/devices/speaker.d.ts +0 -79
  49. package/dist/devices/speaker.js +0 -84
  50. package/dist/devices/temperatureControl.d.ts +0 -21
  51. package/dist/devices/temperatureControl.js +3 -24
  52. package/dist/devices/waterHeater.d.ts +0 -74
  53. package/dist/devices/waterHeater.js +2 -82
  54. package/dist/frontend.d.ts +0 -187
  55. package/dist/frontend.js +39 -505
  56. package/dist/frontendTypes.d.ts +0 -57
  57. package/dist/frontendTypes.js +0 -45
  58. package/dist/helpers.d.ts +0 -43
  59. package/dist/helpers.js +1 -54
  60. package/dist/index.d.ts +0 -23
  61. package/dist/index.js +0 -25
  62. package/dist/jestutils/export.d.ts +0 -1
  63. package/dist/jestutils/export.js +0 -1
  64. package/dist/jestutils/jestHelpers.d.ts +0 -255
  65. package/dist/jestutils/jestHelpers.js +14 -372
  66. package/dist/logger/export.d.ts +0 -1
  67. package/dist/logger/export.js +0 -1
  68. package/dist/matter/behaviors.d.ts +0 -1
  69. package/dist/matter/behaviors.js +0 -2
  70. package/dist/matter/clusters.d.ts +0 -1
  71. package/dist/matter/clusters.js +0 -2
  72. package/dist/matter/devices.d.ts +0 -1
  73. package/dist/matter/devices.js +0 -2
  74. package/dist/matter/endpoints.d.ts +0 -1
  75. package/dist/matter/endpoints.js +0 -2
  76. package/dist/matter/export.d.ts +0 -1
  77. package/dist/matter/export.js +0 -2
  78. package/dist/matter/types.d.ts +0 -1
  79. package/dist/matter/types.js +0 -2
  80. package/dist/matterNode.d.ts +0 -258
  81. package/dist/matterNode.js +9 -364
  82. package/dist/matterbridge.d.ts +0 -362
  83. package/dist/matterbridge.js +60 -860
  84. package/dist/matterbridgeAccessoryPlatform.d.ts +0 -36
  85. package/dist/matterbridgeAccessoryPlatform.js +0 -38
  86. package/dist/matterbridgeBehaviors.d.ts +0 -24
  87. package/dist/matterbridgeBehaviors.js +5 -68
  88. package/dist/matterbridgeDeviceTypes.d.ts +0 -649
  89. package/dist/matterbridgeDeviceTypes.js +6 -673
  90. package/dist/matterbridgeDynamicPlatform.d.ts +0 -36
  91. package/dist/matterbridgeDynamicPlatform.js +0 -38
  92. package/dist/matterbridgeEndpoint.d.ts +2 -1332
  93. package/dist/matterbridgeEndpoint.js +94 -1459
  94. package/dist/matterbridgeEndpointHelpers.d.ts +0 -425
  95. package/dist/matterbridgeEndpointHelpers.js +21 -486
  96. package/dist/matterbridgeEndpointTypes.d.ts +0 -70
  97. package/dist/matterbridgeEndpointTypes.js +0 -25
  98. package/dist/matterbridgePlatform.d.ts +0 -425
  99. package/dist/matterbridgePlatform.js +2 -453
  100. package/dist/matterbridgeTypes.d.ts +0 -46
  101. package/dist/matterbridgeTypes.js +0 -26
  102. package/dist/mb_coap.d.ts +1 -0
  103. package/dist/{dgram/mb_coap.js → mb_coap.js} +3 -41
  104. package/dist/mb_mdns.d.ts +1 -0
  105. package/dist/{dgram/mb_mdns.js → mb_mdns.js} +37 -81
  106. package/dist/pluginManager.d.ts +0 -305
  107. package/dist/pluginManager.js +8 -345
  108. package/dist/shelly.d.ts +0 -157
  109. package/dist/shelly.js +7 -178
  110. package/dist/spawn.d.ts +1 -0
  111. package/dist/{utils/spawn.js → spawn.js} +3 -73
  112. package/dist/storage/export.d.ts +0 -1
  113. package/dist/storage/export.js +0 -1
  114. package/dist/update.d.ts +0 -75
  115. package/dist/update.js +7 -100
  116. package/dist/utils/export.d.ts +1 -13
  117. package/dist/utils/export.js +1 -13
  118. package/dist/workerGlobalPrefix.d.ts +0 -24
  119. package/dist/workerGlobalPrefix.js +6 -40
  120. package/dist/workerTypes.d.ts +0 -25
  121. package/dist/workerTypes.js +0 -24
  122. package/dist/workers.d.ts +0 -61
  123. package/dist/workers.js +4 -68
  124. package/npm-shrinkwrap.json +35 -5
  125. package/package.json +5 -5
  126. package/dist/broadcastServer.d.ts.map +0 -1
  127. package/dist/broadcastServer.js.map +0 -1
  128. package/dist/broadcastServerTypes.d.ts.map +0 -1
  129. package/dist/broadcastServerTypes.js.map +0 -1
  130. package/dist/cli.d.ts.map +0 -1
  131. package/dist/cli.js.map +0 -1
  132. package/dist/cliEmitter.d.ts.map +0 -1
  133. package/dist/cliEmitter.js.map +0 -1
  134. package/dist/cliHistory.d.ts.map +0 -1
  135. package/dist/cliHistory.js.map +0 -1
  136. package/dist/clusters/export.d.ts.map +0 -1
  137. package/dist/clusters/export.js.map +0 -1
  138. package/dist/deviceManager.d.ts.map +0 -1
  139. package/dist/deviceManager.js.map +0 -1
  140. package/dist/devices/airConditioner.d.ts.map +0 -1
  141. package/dist/devices/airConditioner.js.map +0 -1
  142. package/dist/devices/batteryStorage.d.ts.map +0 -1
  143. package/dist/devices/batteryStorage.js.map +0 -1
  144. package/dist/devices/cooktop.d.ts.map +0 -1
  145. package/dist/devices/cooktop.js.map +0 -1
  146. package/dist/devices/dishwasher.d.ts.map +0 -1
  147. package/dist/devices/dishwasher.js.map +0 -1
  148. package/dist/devices/evse.d.ts.map +0 -1
  149. package/dist/devices/evse.js.map +0 -1
  150. package/dist/devices/export.d.ts.map +0 -1
  151. package/dist/devices/export.js.map +0 -1
  152. package/dist/devices/extractorHood.d.ts.map +0 -1
  153. package/dist/devices/extractorHood.js.map +0 -1
  154. package/dist/devices/heatPump.d.ts.map +0 -1
  155. package/dist/devices/heatPump.js.map +0 -1
  156. package/dist/devices/laundryDryer.d.ts.map +0 -1
  157. package/dist/devices/laundryDryer.js.map +0 -1
  158. package/dist/devices/laundryWasher.d.ts.map +0 -1
  159. package/dist/devices/laundryWasher.js.map +0 -1
  160. package/dist/devices/microwaveOven.d.ts.map +0 -1
  161. package/dist/devices/microwaveOven.js.map +0 -1
  162. package/dist/devices/oven.d.ts.map +0 -1
  163. package/dist/devices/oven.js.map +0 -1
  164. package/dist/devices/refrigerator.d.ts.map +0 -1
  165. package/dist/devices/refrigerator.js.map +0 -1
  166. package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
  167. package/dist/devices/roboticVacuumCleaner.js.map +0 -1
  168. package/dist/devices/solarPower.d.ts.map +0 -1
  169. package/dist/devices/solarPower.js.map +0 -1
  170. package/dist/devices/speaker.d.ts.map +0 -1
  171. package/dist/devices/speaker.js.map +0 -1
  172. package/dist/devices/temperatureControl.d.ts.map +0 -1
  173. package/dist/devices/temperatureControl.js.map +0 -1
  174. package/dist/devices/waterHeater.d.ts.map +0 -1
  175. package/dist/devices/waterHeater.js.map +0 -1
  176. package/dist/dgram/coap.d.ts +0 -205
  177. package/dist/dgram/coap.d.ts.map +0 -1
  178. package/dist/dgram/coap.js +0 -365
  179. package/dist/dgram/coap.js.map +0 -1
  180. package/dist/dgram/dgram.d.ts +0 -144
  181. package/dist/dgram/dgram.d.ts.map +0 -1
  182. package/dist/dgram/dgram.js +0 -363
  183. package/dist/dgram/dgram.js.map +0 -1
  184. package/dist/dgram/mb_coap.d.ts +0 -24
  185. package/dist/dgram/mb_coap.d.ts.map +0 -1
  186. package/dist/dgram/mb_coap.js.map +0 -1
  187. package/dist/dgram/mb_mdns.d.ts +0 -24
  188. package/dist/dgram/mb_mdns.d.ts.map +0 -1
  189. package/dist/dgram/mb_mdns.js.map +0 -1
  190. package/dist/dgram/mdns.d.ts +0 -371
  191. package/dist/dgram/mdns.d.ts.map +0 -1
  192. package/dist/dgram/mdns.js +0 -934
  193. package/dist/dgram/mdns.js.map +0 -1
  194. package/dist/dgram/multicast.d.ts +0 -67
  195. package/dist/dgram/multicast.d.ts.map +0 -1
  196. package/dist/dgram/multicast.js +0 -179
  197. package/dist/dgram/multicast.js.map +0 -1
  198. package/dist/dgram/unicast.d.ts +0 -64
  199. package/dist/dgram/unicast.d.ts.map +0 -1
  200. package/dist/dgram/unicast.js +0 -100
  201. package/dist/dgram/unicast.js.map +0 -1
  202. package/dist/frontend.d.ts.map +0 -1
  203. package/dist/frontend.js.map +0 -1
  204. package/dist/frontendTypes.d.ts.map +0 -1
  205. package/dist/frontendTypes.js.map +0 -1
  206. package/dist/helpers.d.ts.map +0 -1
  207. package/dist/helpers.js.map +0 -1
  208. package/dist/index.d.ts.map +0 -1
  209. package/dist/index.js.map +0 -1
  210. package/dist/jestutils/export.d.ts.map +0 -1
  211. package/dist/jestutils/export.js.map +0 -1
  212. package/dist/jestutils/jestHelpers.d.ts.map +0 -1
  213. package/dist/jestutils/jestHelpers.js.map +0 -1
  214. package/dist/logger/export.d.ts.map +0 -1
  215. package/dist/logger/export.js.map +0 -1
  216. package/dist/matter/behaviors.d.ts.map +0 -1
  217. package/dist/matter/behaviors.js.map +0 -1
  218. package/dist/matter/clusters.d.ts.map +0 -1
  219. package/dist/matter/clusters.js.map +0 -1
  220. package/dist/matter/devices.d.ts.map +0 -1
  221. package/dist/matter/devices.js.map +0 -1
  222. package/dist/matter/endpoints.d.ts.map +0 -1
  223. package/dist/matter/endpoints.js.map +0 -1
  224. package/dist/matter/export.d.ts.map +0 -1
  225. package/dist/matter/export.js.map +0 -1
  226. package/dist/matter/types.d.ts.map +0 -1
  227. package/dist/matter/types.js.map +0 -1
  228. package/dist/matterNode.d.ts.map +0 -1
  229. package/dist/matterNode.js.map +0 -1
  230. package/dist/matterbridge.d.ts.map +0 -1
  231. package/dist/matterbridge.js.map +0 -1
  232. package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
  233. package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
  234. package/dist/matterbridgeBehaviors.d.ts.map +0 -1
  235. package/dist/matterbridgeBehaviors.js.map +0 -1
  236. package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
  237. package/dist/matterbridgeDeviceTypes.js.map +0 -1
  238. package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
  239. package/dist/matterbridgeDynamicPlatform.js.map +0 -1
  240. package/dist/matterbridgeEndpoint.d.ts.map +0 -1
  241. package/dist/matterbridgeEndpoint.js.map +0 -1
  242. package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
  243. package/dist/matterbridgeEndpointHelpers.js.map +0 -1
  244. package/dist/matterbridgeEndpointTypes.d.ts.map +0 -1
  245. package/dist/matterbridgeEndpointTypes.js.map +0 -1
  246. package/dist/matterbridgePlatform.d.ts.map +0 -1
  247. package/dist/matterbridgePlatform.js.map +0 -1
  248. package/dist/matterbridgeTypes.d.ts.map +0 -1
  249. package/dist/matterbridgeTypes.js.map +0 -1
  250. package/dist/pluginManager.d.ts.map +0 -1
  251. package/dist/pluginManager.js.map +0 -1
  252. package/dist/shelly.d.ts.map +0 -1
  253. package/dist/shelly.js.map +0 -1
  254. package/dist/storage/export.d.ts.map +0 -1
  255. package/dist/storage/export.js.map +0 -1
  256. package/dist/update.d.ts.map +0 -1
  257. package/dist/update.js.map +0 -1
  258. package/dist/utils/colorUtils.d.ts +0 -101
  259. package/dist/utils/colorUtils.d.ts.map +0 -1
  260. package/dist/utils/colorUtils.js +0 -282
  261. package/dist/utils/colorUtils.js.map +0 -1
  262. package/dist/utils/commandLine.d.ts +0 -66
  263. package/dist/utils/commandLine.d.ts.map +0 -1
  264. package/dist/utils/commandLine.js +0 -123
  265. package/dist/utils/commandLine.js.map +0 -1
  266. package/dist/utils/copyDirectory.d.ts +0 -35
  267. package/dist/utils/copyDirectory.d.ts.map +0 -1
  268. package/dist/utils/copyDirectory.js +0 -76
  269. package/dist/utils/copyDirectory.js.map +0 -1
  270. package/dist/utils/createDirectory.d.ts +0 -34
  271. package/dist/utils/createDirectory.d.ts.map +0 -1
  272. package/dist/utils/createDirectory.js +0 -54
  273. package/dist/utils/createDirectory.js.map +0 -1
  274. package/dist/utils/createZip.d.ts +0 -39
  275. package/dist/utils/createZip.d.ts.map +0 -1
  276. package/dist/utils/createZip.js +0 -114
  277. package/dist/utils/createZip.js.map +0 -1
  278. package/dist/utils/deepCopy.d.ts +0 -32
  279. package/dist/utils/deepCopy.d.ts.map +0 -1
  280. package/dist/utils/deepCopy.js +0 -79
  281. package/dist/utils/deepCopy.js.map +0 -1
  282. package/dist/utils/deepEqual.d.ts +0 -54
  283. package/dist/utils/deepEqual.d.ts.map +0 -1
  284. package/dist/utils/deepEqual.js +0 -129
  285. package/dist/utils/deepEqual.js.map +0 -1
  286. package/dist/utils/error.d.ts +0 -45
  287. package/dist/utils/error.d.ts.map +0 -1
  288. package/dist/utils/error.js +0 -54
  289. package/dist/utils/error.js.map +0 -1
  290. package/dist/utils/export.d.ts.map +0 -1
  291. package/dist/utils/export.js.map +0 -1
  292. package/dist/utils/format.d.ts +0 -53
  293. package/dist/utils/format.d.ts.map +0 -1
  294. package/dist/utils/format.js +0 -78
  295. package/dist/utils/format.js.map +0 -1
  296. package/dist/utils/hex.d.ts +0 -89
  297. package/dist/utils/hex.d.ts.map +0 -1
  298. package/dist/utils/hex.js +0 -242
  299. package/dist/utils/hex.js.map +0 -1
  300. package/dist/utils/inspector.d.ts +0 -87
  301. package/dist/utils/inspector.d.ts.map +0 -1
  302. package/dist/utils/inspector.js +0 -268
  303. package/dist/utils/inspector.js.map +0 -1
  304. package/dist/utils/isValid.d.ts +0 -103
  305. package/dist/utils/isValid.d.ts.map +0 -1
  306. package/dist/utils/isValid.js +0 -162
  307. package/dist/utils/isValid.js.map +0 -1
  308. package/dist/utils/network.d.ts +0 -141
  309. package/dist/utils/network.d.ts.map +0 -1
  310. package/dist/utils/network.js +0 -314
  311. package/dist/utils/network.js.map +0 -1
  312. package/dist/utils/spawn.d.ts +0 -33
  313. package/dist/utils/spawn.d.ts.map +0 -1
  314. package/dist/utils/spawn.js.map +0 -1
  315. package/dist/utils/tracker.d.ts +0 -108
  316. package/dist/utils/tracker.d.ts.map +0 -1
  317. package/dist/utils/tracker.js +0 -264
  318. package/dist/utils/tracker.js.map +0 -1
  319. package/dist/utils/wait.d.ts +0 -54
  320. package/dist/utils/wait.d.ts.map +0 -1
  321. package/dist/utils/wait.js +0 -125
  322. package/dist/utils/wait.js.map +0 -1
  323. package/dist/workerGlobalPrefix.d.ts.map +0 -1
  324. package/dist/workerGlobalPrefix.js.map +0 -1
  325. package/dist/workerTypes.d.ts.map +0 -1
  326. package/dist/workerTypes.js.map +0 -1
  327. package/dist/workers.d.ts.map +0 -1
  328. package/dist/workers.js.map +0 -1
@@ -1,35 +1,8 @@
1
- /**
2
- * This file contains the class MatterNode.
3
- *
4
- * @file matterNode.ts
5
- * @author Luca Liguori
6
- * @created 2025-10-01
7
- * @version 1.0.0
8
- * @license Apache-2.0
9
- *
10
- * Copyright 2025, 2026, 2027 Luca Liguori.
11
- *
12
- * Licensed under the Apache License, Version 2.0 (the "License");
13
- * you may not use this file except in compliance with the License.
14
- * You may obtain a copy of the License at
15
- *
16
- * http://www.apache.org/licenses/LICENSE-2.0
17
- *
18
- * Unless required by applicable law or agreed to in writing, software
19
- * distributed under the License is distributed on an "AS IS" BASIS,
20
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
- * See the License for the specific language governing permissions and
22
- * limitations under the License.
23
- */
24
- // Node modules
25
1
  import path from 'node:path';
26
2
  import fs from 'node:fs';
27
3
  import EventEmitter from 'node:events';
28
- // AnsiLogger module
29
4
  import { AnsiLogger, BLUE, CYAN, db, debugStringify, er, nf, or, zb } from 'node-ansi-logger';
30
- // Node persist manager module
31
5
  import { NodeStorageManager } from 'node-persist-manager';
32
- // @matter
33
6
  import '@matter/nodejs';
34
7
  import { Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, StorageService, UINT32_MAX, UINT16_MAX, Environment } from '@matter/general';
35
8
  import { MdnsService } from '@matter/protocol';
@@ -38,59 +11,34 @@ import { ServerNode, Endpoint } from '@matter/node';
38
11
  import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
39
12
  import { BasicInformationServer } from '@matter/node/behaviors/basic-information';
40
13
  import { BridgedDeviceBasicInformationServer } from '@matter/node/behaviors/bridged-device-basic-information';
14
+ import { copyDirectory, getIntParameter, getParameter, hasParameter, inspectError, isValidNumber, isValidString, parseVersionString, wait, withTimeout } from '@matterbridge/utils';
41
15
  import { dev, MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, plg, NODE_STORAGE_DIR, MATTERBRIDGE_LOGGER_FILE } from './matterbridgeTypes.js';
42
16
  import { bridge } from './matterbridgeDeviceTypes.js';
43
- import { getIntParameter, getParameter, hasParameter } from './utils/commandLine.js';
44
- import { copyDirectory } from './utils/copyDirectory.js';
45
- import { isValidNumber, isValidString, parseVersionString } from './utils/isValid.js';
46
- import { wait, withTimeout } from './utils/wait.js';
47
- import { inspectError } from './utils/error.js';
48
17
  import { BroadcastServer } from './broadcastServer.js';
49
18
  import { toBaseDevice } from './deviceManager.js';
50
19
  import { PluginManager } from './pluginManager.js';
51
20
  import { addVirtualDevice } from './helpers.js';
52
- /**
53
- * Represents the Matter class.
54
- */
55
21
  export class MatterNode extends EventEmitter {
56
22
  matterbridge;
57
23
  pluginName;
58
24
  device;
59
- /** Matterbridge logger */
60
- log = new AnsiLogger({ logName: 'MatterNode', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: "debug" /* LogLevel.DEBUG */ });
61
- /** Matter logger */
62
- matterLog = new AnsiLogger({ logName: 'MatterNode', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: "debug" /* LogLevel.DEBUG */ });
63
- /** Matter environment default */
25
+ log = new AnsiLogger({ logName: 'MatterNode', logTimestampFormat: 4, logLevel: "debug" });
26
+ matterLog = new AnsiLogger({ logName: 'MatterNode', logTimestampFormat: 4, logLevel: "debug" });
64
27
  environment = Environment.default;
65
- /** Matter storage id */
66
28
  storeId;
67
- /** Matter mdns service from environment default */
68
29
  matterMdnsService;
69
- /** Matter storage service from environment default */
70
30
  matterStorageService;
71
- /** Matter storage manager created with name 'Matterbridge' */
72
31
  matterStorageManager;
73
- /** Matter storage context created in the storage manager with name 'persist' */
74
32
  matterStorageContext;
75
- /** Matter mdns interface name e.g. 'eth0' or 'wlan0' or 'Wi-Fi' */
76
33
  mdnsInterface;
77
- /** Matter listeningAddressIpv4 address */
78
34
  ipv4Address;
79
- /** Matter listeningAddressIpv6 address */
80
35
  ipv6Address;
81
- /** Matter commissioning port It is incremented in childbridge mode. */
82
36
  port;
83
- /** Matter commissioning passcode. It is incremented in childbridge mode. */
84
37
  passcode;
85
- /** Matter commissioning discriminator. It is incremented in childbridge mode. */
86
38
  discriminator;
87
- /** Matter device certification */
88
39
  certification;
89
- /** Matter server node */
90
40
  serverNode;
91
- /** Matter aggregator node */
92
41
  aggregatorNode;
93
- // Default values for the aggregator node
94
42
  aggregatorVendorId = VendorId(getIntParameter('vendorId') ?? 0xfff1);
95
43
  aggregatorVendorName = getParameter('vendorName') ?? 'Matterbridge';
96
44
  aggregatorProductId = getIntParameter('productId') ?? 0x8000;
@@ -98,23 +46,12 @@ export class MatterNode extends EventEmitter {
98
46
  aggregatorDeviceType = DeviceTypeId(getIntParameter('deviceType') ?? bridge.code);
99
47
  aggregatorSerialNumber = getParameter('serialNumber');
100
48
  aggregatorUniqueId = getParameter('uniqueId');
101
- /** Advertising nodes map: time advertising started keyed by storeId */
102
49
  advertisingNodes = new Map();
103
- /** Plugins */
104
50
  pluginManager;
105
- /** Dependant MatterNodes keyed by device id */
106
51
  dependantMatterNodes = new Map();
107
- /** Broadcast server */
108
52
  server;
109
53
  debug = hasParameter('debug') || hasParameter('verbose');
110
54
  verbose = hasParameter('verbose');
111
- /**
112
- * Creates an instance of the Matter class.
113
- *
114
- * @param {SharedMatterbridge} matterbridge - The shared matterbridge instance.
115
- * @param {PluginName} [pluginName] - The plugin name (optional). If not provided, it is assumed to be the main matter node instance and all plugins are included.
116
- * @param {MatterbridgeEndpoint} [device] - The matterbridge endpoint device (optional). It is used to create a server mode device.
117
- */
118
55
  constructor(matterbridge, pluginName, device) {
119
56
  super();
120
57
  this.matterbridge = matterbridge;
@@ -123,25 +60,19 @@ export class MatterNode extends EventEmitter {
123
60
  this.log.logNameColor = '\x1b[38;5;65m';
124
61
  if (this.debug)
125
62
  this.log.debug(`MatterNode ${this.pluginName ? 'for plugin ' + this.pluginName : 'bridge'} loading...`);
126
- // Setup Matter parameters
127
63
  this.port = matterbridge.port;
128
64
  this.passcode = matterbridge.passcode;
129
65
  this.discriminator = matterbridge.discriminator;
130
- // Setup the broadcast server
131
66
  this.server = new BroadcastServer('matter', this.log);
132
67
  this.server.on('broadcast_message', this.msgHandler.bind(this));
133
68
  if (this.verbose)
134
69
  this.log.debug(`BroadcastServer is ready`);
135
- // Ensure the matterbridge directory exists
136
70
  fs.mkdirSync(matterbridge.matterbridgeDirectory, { recursive: true });
137
- // Setup the plugin manager with thread server closed
138
71
  this.pluginManager = new PluginManager(this.matterbridge);
139
- this.pluginManager.logLevel = this.debug ? "debug" /* LogLevel.DEBUG */ : "info" /* LogLevel.INFO */;
140
- // @ts-expect-error access private property
72
+ this.pluginManager.logLevel = this.debug ? "debug" : "info";
141
73
  this.pluginManager.server.close();
142
74
  if (this.verbose)
143
75
  this.log.debug(`PluginManager is ready`);
144
- // Setup the matter environment
145
76
  this.environment.vars.set('log.level', MatterLogLevel.DEBUG);
146
77
  this.environment.vars.set('log.format', MatterLogFormat.ANSI);
147
78
  this.environment.vars.set('path.root', path.join(matterbridge.matterbridgeDirectory, MATTER_STORAGE_NAME));
@@ -149,18 +80,15 @@ export class MatterNode extends EventEmitter {
149
80
  this.environment.vars.set('runtime.exitcode', false);
150
81
  if (this.verbose)
151
82
  this.log.debug(`Matter Environment is ready`);
152
- // Ensure MdnsService is registered in the default environment
153
83
  this.matterMdnsService = new MdnsService(this.environment);
154
84
  setImmediate(async () => {
155
85
  await this.matterMdnsService?.construction.ready;
156
86
  if (this.verbose)
157
87
  this.log.debug(`Matter MdnsService is ready`);
158
88
  });
159
- // Setup the matterbridge logger
160
89
  if (this.matterbridge.fileLogger) {
161
90
  AnsiLogger.setGlobalLogfile(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_LOGGER_FILE), this.matterbridge.logLevel);
162
91
  }
163
- // Setup the matter logger
164
92
  Logger.destinations.default.write = this.createDestinationMatterLogger();
165
93
  const levels = ['debug', 'info', 'notice', 'warn', 'error', 'fatal'];
166
94
  if (this.verbose)
@@ -168,11 +96,6 @@ export class MatterNode extends EventEmitter {
168
96
  if (this.debug)
169
97
  this.log.debug(`MatterNode ${this.pluginName ? 'for plugin ' + this.pluginName : 'bridge'} loaded`);
170
98
  }
171
- /**
172
- * Handles incoming messages from the broadcast server.
173
- *
174
- * @param {WorkerMessage} msg - The incoming message.
175
- */
176
99
  async msgHandler(msg) {
177
100
  if (this.server.isWorkerRequest(msg) && (msg.dst === 'all' || msg.dst === 'matter')) {
178
101
  if (this.verbose)
@@ -203,17 +126,9 @@ export class MatterNode extends EventEmitter {
203
126
  }
204
127
  }
205
128
  }
206
- /**
207
- * Destroys the Matter instance.
208
- * It closes the mDNS service and the broadcast server.
209
- *
210
- * @param {boolean} closeMdns - Whether to close the mDNS service. Default is true.
211
- * @returns {Promise<void>} A promise that resolves when the instance is destroyed.
212
- */
213
129
  async destroy(closeMdns = true) {
214
130
  if (this.verbose)
215
131
  this.log.debug(`Destroying MatterNode instance for ${this.storeId}...`);
216
- // Close mDNS service
217
132
  if (closeMdns) {
218
133
  if (this.verbose)
219
134
  this.log.debug(`Closing Matter MdnsService for ${this.storeId}...`);
@@ -221,26 +136,18 @@ export class MatterNode extends EventEmitter {
221
136
  if (this.verbose)
222
137
  this.log.debug(`Closed Matter MdnsService for ${this.storeId}`);
223
138
  }
224
- // Close the plugin manager
225
139
  this.pluginManager.destroy();
226
- // Close the broadcast server
227
140
  this.server.close();
228
- // Yield to the Node.js event loop to allow all resources to be released
229
141
  await this.yieldToNode();
230
142
  if (this.verbose)
231
143
  this.log.debug(`Destroyed MatterNode instance for ${this.storeId}`);
232
144
  }
233
145
  async create() {
234
146
  this.log.info('Creating Matter node...');
235
- // Start matter storage
236
147
  await this.startMatterStorage();
237
- // Load plugins from storage
238
- // @ts-expect-error access private property
239
148
  this.pluginManager.matterbridge.nodeStorage = new NodeStorageManager({ dir: path.join(this.matterbridge.matterbridgeDirectory, NODE_STORAGE_DIR), writeQueue: false, expiredInterval: undefined, logging: false });
240
- // @ts-expect-error access private property
241
149
  this.pluginManager.matterbridge.nodeContext = await this.pluginManager.matterbridge.nodeStorage.createStorage('matterbridge');
242
150
  await this.pluginManager.loadFromStorage();
243
- // Create Matter node for a server mode device
244
151
  if (this.pluginName && this.device && this.device.deviceName) {
245
152
  this.log.debug(`Creating MatterNode instance for server node device ${CYAN}${this.device.deviceName}${db}...`);
246
153
  await this.createDeviceServerNode(this.pluginName, this.device);
@@ -251,7 +158,6 @@ export class MatterNode extends EventEmitter {
251
158
  if (!this.pluginName) {
252
159
  this.log.debug('Creating MatterNode instance for all plugins...');
253
160
  await this.createMatterbridgeServerNode();
254
- // Load all enabled plugins
255
161
  this.log.debug('Loading all plugins...');
256
162
  const loadPromises = [];
257
163
  for (const plugin of this.pluginManager.array().filter((p) => p.enabled)) {
@@ -264,7 +170,6 @@ export class MatterNode extends EventEmitter {
264
170
  }
265
171
  else {
266
172
  this.log.debug(`Creating MatterNode instance for plugin ${CYAN}${this.pluginName}${db}...`);
267
- // Load only the specified plugin
268
173
  this.log.debug(`Loading plugin ${CYAN}${this.pluginName}${db}...`);
269
174
  await this.pluginManager.load(this.pluginName);
270
175
  this.log.debug(`Loaded plugin ${CYAN}${this.pluginName}${db}`);
@@ -278,16 +183,13 @@ export class MatterNode extends EventEmitter {
278
183
  if (!this.serverNode && !this.pluginName)
279
184
  throw new Error('Matter server node not created yet. Call create() first.');
280
185
  this.log.info('Starting MatterNode...');
281
- // Start Matter node for a server mode device
282
186
  if (this.pluginName && this.device && this.device.deviceName) {
283
- // Start the server node
284
187
  this.log.debug(`Starting MatterNode for server device ${this.pluginName}:${this.device.deviceName}...`);
285
188
  await this.startServerNode();
286
189
  this.log.debug(`Started MatterNode for server device ${this.pluginName}:${this.device.deviceName}`);
287
190
  return;
288
191
  }
289
192
  if (!this.pluginName) {
290
- // Start all loaded plugins
291
193
  this.log.debug('Starting all plugins...');
292
194
  const startPromises = [];
293
195
  for (const plugin of this.pluginManager.array().filter((p) => p.enabled && p.loaded)) {
@@ -295,11 +197,9 @@ export class MatterNode extends EventEmitter {
295
197
  }
296
198
  await Promise.all(startPromises);
297
199
  this.log.debug('Started all plugins');
298
- // Start the server node
299
200
  this.log.debug('Starting MatterNode for all plugins...');
300
201
  await this.startServerNode();
301
202
  this.log.debug('Started MatterNode for all plugins');
302
- // Configure all loaded plugins
303
203
  this.log.debug('Configuring all plugins...');
304
204
  const configurePromises = [];
305
205
  for (const plugin of this.pluginManager.array().filter((p) => p.enabled && p.started)) {
@@ -309,16 +209,12 @@ export class MatterNode extends EventEmitter {
309
209
  this.log.debug('Configured all plugins');
310
210
  }
311
211
  else {
312
- // Start the loaded plugin
313
212
  await this.pluginManager.start(this.pluginName, 'Starting MatterNode');
314
- // Start the server node
315
213
  this.log.debug(`Starting MatterNode for plugin ${this.pluginName}...`);
316
214
  await this.startServerNode();
317
215
  this.log.debug(`Started MatterNode for plugin ${this.pluginName}`);
318
- // Configure the plugin
319
216
  await this.pluginManager.configure(this.pluginName);
320
217
  }
321
- // Start the dependant MatterNodes
322
218
  this.log.debug(`Starting dependant MatterNodes...`);
323
219
  for (const dependantMatterNode of this.dependantMatterNodes.values()) {
324
220
  await dependantMatterNode.start();
@@ -331,15 +227,13 @@ export class MatterNode extends EventEmitter {
331
227
  if (!this.serverNode)
332
228
  throw new Error('Matter server node not created yet. Call create() first.');
333
229
  this.log.info('Stopping MatterNode...');
334
- // Stop Matter node for a server mode device
335
230
  if (this.pluginName && this.device && this.device.deviceName) {
336
- // Stop the server node
337
231
  this.log.debug(`Stopping MatterNode for server device ${this.pluginName}:${this.device.deviceName}...`);
338
232
  await this.stopServerNode();
339
233
  this.serverNode = undefined;
340
234
  this.aggregatorNode = undefined;
341
235
  await this.stopMatterStorage();
342
- await this.destroy(false); // Do not close mDNS since it is shared
236
+ await this.destroy(false);
343
237
  this.log.debug(`Stopped MatterNode for server device ${this.pluginName}:${this.device.deviceName}`);
344
238
  this.log.info('Stopped MatterNode');
345
239
  await this.yieldToNode();
@@ -359,7 +253,6 @@ export class MatterNode extends EventEmitter {
359
253
  await this.pluginManager.shutdown(this.pluginName, 'Stopping MatterNode');
360
254
  this.log.debug(`Stopped plugin ${this.pluginName}`);
361
255
  }
362
- // Stop the dependant MatterNodes
363
256
  this.log.debug(`Stopping dependant MatterNodes...`);
364
257
  for (const dependantMatterNode of this.dependantMatterNodes.values()) {
365
258
  await dependantMatterNode.stop();
@@ -372,46 +265,24 @@ export class MatterNode extends EventEmitter {
372
265
  this.log.info('Stopped MatterNode');
373
266
  await this.yieldToNode();
374
267
  }
375
- /**
376
- * Creates a MatterLogger function to show the matter.js log messages in AnsiLogger (console and frontend).
377
- * It also logs to file (matter.log) if fileLogger is true.
378
- *
379
- * @returns {Function} The MatterLogger function. \x1b[35m for violet \x1b[34m is blue
380
- */
381
268
  createDestinationMatterLogger() {
382
- this.matterLog.logNameColor = '\x1b[34m'; // Blue matter.js Logger
269
+ this.matterLog.logNameColor = '\x1b[34m';
383
270
  if (this.matterbridge.matterFileLogger) {
384
271
  this.matterLog.logFilePath = path.join(this.matterbridge.matterbridgeDirectory, MATTER_LOGGER_FILE);
385
272
  }
386
273
  return (text, message) => {
387
- // 2024-08-21 08:55:19.488 DEBUG InteractionMessenger Sending DataReport chunk with 28 attributes and 0 events: 1004 bytes
388
274
  const logger = text.slice(44, 44 + 20).trim();
389
275
  const msg = text.slice(65);
390
276
  this.matterLog.logName = logger;
391
277
  this.matterLog.log(MatterLogLevel.names[message.level], msg);
392
278
  };
393
279
  }
394
- /**
395
- * Starts the matter storage with name Matterbridge and performs a backup.
396
- *
397
- * @returns {Promise<void>} - A promise that resolves when the storage is started.
398
- */
399
280
  async startMatterStorage() {
400
- // Setup Matter storage
401
281
  this.log.info(`Starting matter node storage...`);
402
282
  this.matterStorageService = this.environment.get(StorageService);
403
283
  this.log.info(`Started matter node storage in ${CYAN}${this.matterStorageService.location}${nf}`);
404
- // Backup matter storage since it is created/opened correctly
405
284
  await this.backupMatterStorage(path.join(this.matterbridge.matterbridgeDirectory, MATTER_STORAGE_NAME), path.join(this.matterbridge.matterbridgeDirectory, MATTER_STORAGE_NAME + '.backup'));
406
285
  }
407
- /**
408
- * Makes a backup copy of the specified matter storage directory.
409
- *
410
- * @param {string} storageName - The name of the storage directory to be backed up.
411
- * @param {string} backupName - The name of the backup directory to be created.
412
- * @private
413
- * @returns {Promise<void>} A promise that resolves when the has been done.
414
- */
415
286
  async backupMatterStorage(storageName, backupName) {
416
287
  this.log.info(`Creating matter node storage backup from ${CYAN}${storageName}${nf} to ${CYAN}${backupName}${nf}...`);
417
288
  try {
@@ -419,7 +290,6 @@ export class MatterNode extends EventEmitter {
419
290
  this.log.info('Created matter node storage backup');
420
291
  }
421
292
  catch (error) {
422
- // istanbul ignore next if
423
293
  if (error instanceof Error && error?.code === 'ENOENT') {
424
294
  this.log.info(`No matter node storage found to backup from ${CYAN}${storageName}${nf} to ${CYAN}${backupName}${nf}`);
425
295
  }
@@ -428,11 +298,6 @@ export class MatterNode extends EventEmitter {
428
298
  }
429
299
  }
430
300
  }
431
- /**
432
- * Stops the matter storage.
433
- *
434
- * @returns {Promise<void>} A promise that resolves when the storage is stopped.
435
- */
436
301
  async stopMatterStorage() {
437
302
  this.log.info('Closing matter node storage...');
438
303
  await this.matterStorageManager?.close();
@@ -442,21 +307,6 @@ export class MatterNode extends EventEmitter {
442
307
  this.log.info('Closed matter node storage');
443
308
  this.emit('closed');
444
309
  }
445
- /**
446
- * Creates a server node storage context.
447
- *
448
- * @param {string} storeId - The storeId.
449
- * @param {string} deviceName - The name of the device.
450
- * @param {DeviceTypeId} deviceType - The device type of the device.
451
- * @param {VendorId} vendorId - The vendor ID.
452
- * @param {string} vendorName - The vendor name.
453
- * @param {number} productId - The product ID.
454
- * @param {string} productName - The product name.
455
- * @param {string} [serialNumber] - The serial number of the device (optional).
456
- * @param {string} [uniqueId] - The unique ID of the device (optional).
457
- * @returns {Promise<StorageContext>} The storage context for the commissioning server.
458
- * @throws {Error} If the storage service is not initialized.
459
- */
460
310
  async createServerNodeContext(storeId, deviceName, deviceType, vendorId, vendorName, productId, productName, serialNumber, uniqueId) {
461
311
  if (!this.matterStorageService) {
462
312
  throw new Error('No storage service initialized');
@@ -499,52 +349,33 @@ export class MatterNode extends EventEmitter {
499
349
  this.log.debug(`- hardwareVersionString: ${await storageContext.get('hardwareVersionString')}`);
500
350
  return storageContext;
501
351
  }
502
- /**
503
- * Creates a server node.
504
- *
505
- * @param {number} [port] - The port number for the server node. Defaults to 5540.
506
- * @param {number} [passcode] - The passcode for the server node. Defaults to 20242025.
507
- * @param {number} [discriminator] - The discriminator for the server node. Defaults to 3850.
508
- * @returns {Promise<ServerNode<ServerNode.RootEndpoint>>} A promise that resolves to the created server node.
509
- * @throws {Error} If the matter storage context is not created yet.
510
- */
511
352
  async createServerNode(port = 5540, passcode = 20252026, discriminator = 3850) {
512
353
  if (!this.matterStorageContext) {
513
354
  throw new Error('Matter server node context not created yet. Call createServerNodeContext() first.');
514
355
  }
515
356
  const storeId = await this.matterStorageContext.get('storeId');
516
357
  this.log.notice(`Creating server node for ${storeId} on port ${port} with passcode ${passcode} and discriminator ${discriminator}...`);
517
- /**
518
- * Create a Matter ServerNode, which contains the Root Endpoint and all relevant data and configuration
519
- */
520
358
  const serverNode = await ServerNode.create({
521
- // Required: Give the Node a unique ID which is used to store the state of this node
522
359
  id: storeId,
523
- // Provide the environment to run this node in
524
360
  environment: this.environment,
525
- // Provide Network relevant configuration like the port
526
361
  network: {
527
362
  listeningAddressIpv4: this.ipv4Address,
528
363
  listeningAddressIpv6: this.ipv6Address,
529
364
  port,
530
365
  },
531
- // Provide the certificate for the device
532
366
  operationalCredentials: {
533
367
  certification: this.certification,
534
368
  },
535
- // Provide Commissioning relevant settings
536
369
  commissioning: {
537
370
  passcode,
538
371
  discriminator,
539
372
  },
540
- // Provide Node announcement settings
541
373
  productDescription: {
542
374
  name: await this.matterStorageContext.get('deviceName'),
543
375
  deviceType: DeviceTypeId(await this.matterStorageContext.get('deviceType')),
544
376
  vendorId: VendorId(await this.matterStorageContext.get('vendorId')),
545
377
  productId: await this.matterStorageContext.get('productId'),
546
378
  },
547
- // Provide defaults for the BasicInformation cluster on the Root endpoint
548
379
  basicInformation: {
549
380
  vendorId: VendorId(await this.matterStorageContext.get('vendorId')),
550
381
  vendorName: await this.matterStorageContext.get('vendorName'),
@@ -561,23 +392,17 @@ export class MatterNode extends EventEmitter {
561
392
  reachable: true,
562
393
  },
563
394
  });
564
- /**
565
- * This event is triggered when the device is initially commissioned successfully.
566
- * This means: It is added to the first fabric.
567
- */
568
395
  serverNode.lifecycle.commissioned.on(() => {
569
396
  this.log.notice(`Server node for ${storeId} was initially commissioned successfully!`);
570
397
  this.advertisingNodes.delete(storeId);
571
398
  this.server.request({ type: 'frontend_refreshrequired', src: 'matter', dst: 'frontend', params: { changed: 'matter', matter: { ...this.getServerNodeData(serverNode) } } });
572
399
  });
573
- /** This event is triggered when all fabrics are removed from the device, usually it also does a factory reset then. */
574
400
  serverNode.lifecycle.decommissioned.on(() => {
575
401
  this.log.notice(`Server node for ${storeId} was fully decommissioned successfully!`);
576
402
  this.advertisingNodes.delete(storeId);
577
403
  this.server.request({ type: 'frontend_refreshrequired', src: 'matter', dst: 'frontend', params: { changed: 'matter', matter: { ...this.getServerNodeData(serverNode) } } });
578
404
  this.server.request({ type: 'frontend_snackbarmessage', src: 'matter', dst: 'frontend', params: { message: `${storeId} is offline`, timeout: 5, severity: 'warning' } });
579
405
  });
580
- /** This event is triggered when the device went online. This means that it is discoverable in the network. */
581
406
  serverNode.lifecycle.online.on(async () => {
582
407
  this.log.notice(`Server node for ${storeId} is online`);
583
408
  if (!serverNode.lifecycle.isCommissioned) {
@@ -595,7 +420,6 @@ export class MatterNode extends EventEmitter {
595
420
  this.server.request({ type: 'frontend_snackbarmessage', src: 'matter', dst: 'frontend', params: { message: `${storeId} is online`, timeout: 5, severity: 'success' } });
596
421
  this.emit('online', storeId);
597
422
  });
598
- /** This event is triggered when the device went offline. it is not longer discoverable or connectable in the network. */
599
423
  serverNode.lifecycle.offline.on(() => {
600
424
  this.log.notice(`Server node for ${storeId} is offline`);
601
425
  this.advertisingNodes.delete(storeId);
@@ -603,15 +427,11 @@ export class MatterNode extends EventEmitter {
603
427
  this.server.request({ type: 'frontend_snackbarmessage', src: 'matter', dst: 'frontend', params: { message: `${storeId} is offline`, timeout: 5, severity: 'warning' } });
604
428
  this.emit('offline', storeId);
605
429
  });
606
- /**
607
- * This event is triggered when a fabric is added, removed or updated on the device. Use this if more granular
608
- * information is needed.
609
- */
610
430
  serverNode.events.commissioning.fabricsChanged.on((fabricIndex, fabricAction) => {
611
431
  let action = '';
612
432
  switch (fabricAction) {
613
433
  case 'added':
614
- this.advertisingNodes.delete(storeId); // The advertising stops when a fabric is added
434
+ this.advertisingNodes.delete(storeId);
615
435
  action = 'added';
616
436
  break;
617
437
  case 'deleted':
@@ -624,22 +444,14 @@ export class MatterNode extends EventEmitter {
624
444
  this.log.notice(`Commissioned fabric index ${fabricIndex} ${action} on server node for ${storeId}: ${debugStringify(serverNode.state.commissioning.fabrics[fabricIndex])}`);
625
445
  this.server.request({ type: 'frontend_refreshrequired', src: 'matter', dst: 'frontend', params: { changed: 'matter', matter: { ...this.getServerNodeData(serverNode) } } });
626
446
  });
627
- /**
628
- * This event is triggered when an operative new session was opened by a Controller.
629
- * It is not triggered for the initial commissioning process, just afterwards for real connections.
630
- */
631
447
  serverNode.events.sessions.opened.on((session) => {
632
448
  this.log.notice(`Session opened on server node for ${storeId}: ${debugStringify(session)}`);
633
449
  this.server.request({ type: 'frontend_refreshrequired', src: 'matter', dst: 'frontend', params: { changed: 'matter', matter: { ...this.getServerNodeData(serverNode) } } });
634
450
  });
635
- /**
636
- * This event is triggered when an operative session is closed by a Controller or because the Device goes offline.
637
- */
638
451
  serverNode.events.sessions.closed.on((session) => {
639
452
  this.log.notice(`Session closed on server node for ${storeId}: ${debugStringify(session)}`);
640
453
  this.server.request({ type: 'frontend_refreshrequired', src: 'matter', dst: 'frontend', params: { changed: 'matter', matter: { ...this.getServerNodeData(serverNode) } } });
641
454
  });
642
- /** This event is triggered when a subscription gets added or removed on an operative session. */
643
455
  serverNode.events.sessions.subscriptionsChanged.on((session) => {
644
456
  this.log.notice(`Session subscriptions changed on server node for ${storeId}: ${debugStringify(session)}`);
645
457
  this.server.request({ type: 'frontend_refreshrequired', src: 'matter', dst: 'frontend', params: { changed: 'matter', matter: { ...this.getServerNodeData(serverNode) } } });
@@ -648,12 +460,6 @@ export class MatterNode extends EventEmitter {
648
460
  this.log.info(`Created server node for ${this.storeId}`);
649
461
  return serverNode;
650
462
  }
651
- /**
652
- * Gets the matter serializable data of the specified server node.
653
- *
654
- * @param {ServerNode} [serverNode] - The server node to start.
655
- * @returns {ApiMatter} The serializable data of the server node.
656
- */
657
463
  getServerNodeData(serverNode) {
658
464
  const advertiseTime = this.advertisingNodes.get(serverNode.id) || 0;
659
465
  return {
@@ -670,13 +476,6 @@ export class MatterNode extends EventEmitter {
670
476
  serialNumber: serverNode.state.basicInformation.serialNumber,
671
477
  };
672
478
  }
673
- /**
674
- * Starts the specified server node.
675
- *
676
- * @param {number} [timeout] - The timeout in milliseconds for starting the server node. Defaults to 30 seconds.
677
- * @returns {Promise<void>} A promise that resolves when the server node has started.
678
- * @throws {Error} If the server node is not created yet.
679
- */
680
479
  async startServerNode(timeout = 30000) {
681
480
  if (!this.serverNode) {
682
481
  throw new Error('Matter server node not created yet. Call create() first.');
@@ -687,17 +486,9 @@ export class MatterNode extends EventEmitter {
687
486
  this.log.notice(`Started ${this.serverNode.id} server node`);
688
487
  }
689
488
  catch (error) {
690
- // istanbul ignore next
691
489
  this.log.error(`Failed to start ${this.serverNode.id} server node: ${error instanceof Error ? error.message : error}`);
692
490
  }
693
491
  }
694
- /**
695
- * Stops the specified server node.
696
- *
697
- * @param {number} [timeout] - The timeout in milliseconds for stopping the server node. Defaults to 30 seconds.
698
- * @returns {Promise<void>} A promise that resolves when the server node has stopped.
699
- * @throws {Error} If the server node is not created yet.
700
- */
701
492
  async stopServerNode(timeout = 30000) {
702
493
  if (!this.serverNode) {
703
494
  throw new Error('Matter server node not created yet. Call create() first.');
@@ -708,16 +499,9 @@ export class MatterNode extends EventEmitter {
708
499
  this.log.info(`Closed ${this.serverNode.id} server node`);
709
500
  }
710
501
  catch (error) {
711
- // istanbul ignore next
712
502
  this.log.error(`Failed to close ${this.serverNode.id} server node: ${error instanceof Error ? error.message : error}`);
713
503
  }
714
504
  }
715
- /**
716
- * Creates an aggregator node with the specified storage context.
717
- *
718
- * @returns {Promise<Endpoint<AggregatorEndpoint>>} A promise that resolves to the created aggregator node.
719
- * @throws {Error} If the matter storage context is not created yet.
720
- */
721
505
  async createAggregatorNode() {
722
506
  if (!this.matterStorageContext) {
723
507
  throw new Error('Matter server node context not created yet. Call createServerNodeContext() first.');
@@ -727,16 +511,9 @@ export class MatterNode extends EventEmitter {
727
511
  this.log.info(`Created ${await this.matterStorageContext.get('storeId')} aggregator`);
728
512
  return aggregatorNode;
729
513
  }
730
- /**
731
- * Creates the matterbridge server node.
732
- *
733
- * @returns {Promise<ServerNode<ServerNode.RootEndpoint>>} A promise that resolves to the created matterbridge server node.
734
- */
735
514
  async createMatterbridgeServerNode() {
736
515
  this.log.debug(`Creating ${plg}Matterbridge${db} server node...`);
737
- this.matterStorageContext = await this.createServerNodeContext('Matterbridge', // storeId
738
- 'Matterbridge', // deviceName
739
- this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, this.aggregatorSerialNumber, this.aggregatorUniqueId);
516
+ this.matterStorageContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, this.aggregatorSerialNumber, this.aggregatorUniqueId);
740
517
  this.serverNode = await this.createServerNode(this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
741
518
  this.aggregatorNode = await this.createAggregatorNode();
742
519
  this.log.debug(`Adding ${plg}Matterbridge${db} aggregator node...`);
@@ -747,13 +524,6 @@ export class MatterNode extends EventEmitter {
747
524
  this.log.debug(`Created ${plg}Matterbridge${db} server node`);
748
525
  return this.serverNode;
749
526
  }
750
- /**
751
- * Creates and configures the server node for an accessory plugin for a given device.
752
- *
753
- * @param {Plugin | PluginName} plugin - The plugin to configure.
754
- * @param {MatterbridgeEndpoint} device - The device to associate with the plugin.
755
- * @returns {Promise<ServerNode<ServerNode.RootEndpoint> | undefined>} A promise that resolves to the server node for the accessory plugin.
756
- */
757
527
  async createAccessoryPlugin(plugin, device) {
758
528
  if (typeof plugin === 'string') {
759
529
  const _plugin = this.pluginManager.get(plugin);
@@ -775,12 +545,6 @@ export class MatterNode extends EventEmitter {
775
545
  }
776
546
  return this.serverNode;
777
547
  }
778
- /**
779
- * Creates and configures the server node and the aggregator node for a dynamic plugin.
780
- *
781
- * @param {Plugin | PluginName} plugin - The plugin to configure.
782
- * @returns {Promise<ServerNode<ServerNode.RootEndpoint> | undefined>} A promise that resolves to the server node for the dynamic plugin.
783
- */
784
548
  async createDynamicPlugin(plugin) {
785
549
  if (typeof plugin === 'string') {
786
550
  const _plugin = this.pluginManager.get(plugin);
@@ -804,13 +568,6 @@ export class MatterNode extends EventEmitter {
804
568
  }
805
569
  return this.serverNode;
806
570
  }
807
- /**
808
- * Creates and configures the server node for a single not bridged device.
809
- *
810
- * @param {Plugin | PluginName} plugin - The plugin to configure.
811
- * @param {MatterbridgeEndpoint} device - The device to associate with the plugin.
812
- * @returns {Promise<ServerNode<ServerNode.RootEndpoint> | undefined>} A promise that resolves to the server node for the device with mode server.
813
- */
814
571
  async createDeviceServerNode(plugin, device) {
815
572
  if (typeof plugin === 'string') {
816
573
  const _plugin = this.pluginManager.get(plugin);
@@ -831,22 +588,13 @@ export class MatterNode extends EventEmitter {
831
588
  }
832
589
  return this.serverNode;
833
590
  }
834
- /**
835
- * Adds a MatterbridgeEndpoint to the specified plugin.
836
- *
837
- * @param {string} pluginName - The name of the plugin.
838
- * @param {MatterbridgeEndpoint} device - The device to add as a bridged endpoint.
839
- * @returns {Promise<MatterbridgeEndpoint | undefined>} A promise that resolves to the added bridged endpoint, or undefined if there was an error.
840
- */
841
591
  async addBridgedEndpoint(pluginName, device) {
842
- // Check if the plugin is registered
843
592
  const plugin = this.pluginManager.get(pluginName);
844
593
  if (!plugin)
845
594
  throw new Error(`Error adding bridged endpoint ${plg}${pluginName}${er}:${dev}${device.deviceName}${er} (${zb}${device.name}${er}): plugin not found`);
846
595
  if (device.mode === 'server') {
847
596
  try {
848
597
  this.log.debug(`Creating MatterNode for device ${plg}${pluginName}${db}:${dev}${device.deviceName}${db} (${zb}${device.name}${db})...`);
849
- // Create the MatterNode to manage the device
850
598
  const matterNode = new MatterNode(this.matterbridge, pluginName, device);
851
599
  matterNode.port = this.port ? this.port++ : undefined;
852
600
  matterNode.passcode = this.passcode ? this.passcode++ : undefined;
@@ -862,7 +610,6 @@ export class MatterNode extends EventEmitter {
862
610
  }
863
611
  else if (this.matterbridge.bridgeMode === 'bridge') {
864
612
  if (device.mode === 'matter') {
865
- // Register and add the device to the Matter server node
866
613
  this.log.debug(`Adding matter endpoint ${plg}${pluginName}${db}:${dev}${device.deviceName}${db} (${zb}${device.name}${db})...`);
867
614
  if (!this.serverNode)
868
615
  throw new Error(`Server node not found for matter endpoint ${plg}${pluginName}${er}:${dev}${device.deviceName}${er} (${zb}${device.name}${er})`);
@@ -875,7 +622,6 @@ export class MatterNode extends EventEmitter {
875
622
  }
876
623
  }
877
624
  else {
878
- // Register and add the device to the Matter aggregator node
879
625
  this.log.debug(`Adding bridged endpoint ${plg}${pluginName}${db}:${dev}${device.deviceName}${db} (${zb}${device.name}${db})...`);
880
626
  if (!this.aggregatorNode)
881
627
  throw new Error(`Aggregator node not found for endpoint ${plg}${pluginName}${er}:${dev}${device.deviceName}${er} (${zb}${device.name}${er})`);
@@ -889,7 +635,6 @@ export class MatterNode extends EventEmitter {
889
635
  }
890
636
  }
891
637
  else if (this.matterbridge.bridgeMode === 'childbridge') {
892
- // Register and add the device to the plugin server node
893
638
  if (plugin.type === 'AccessoryPlatform') {
894
639
  try {
895
640
  this.log.debug(`Adding accessory endpoint ${plg}${pluginName}${db}:${dev}${device.deviceName}${db} (${zb}${device.name}${db})...`);
@@ -905,12 +650,10 @@ export class MatterNode extends EventEmitter {
905
650
  return;
906
651
  }
907
652
  }
908
- // Register and add the device to the plugin aggregator node
909
653
  if (plugin.type === 'DynamicPlatform') {
910
654
  try {
911
655
  this.log.debug(`Adding bridged endpoint ${plg}${pluginName}${db}:${dev}${device.deviceName}${db} (${zb}${device.name}${db})...`);
912
656
  if (!this.serverNode) {
913
- // Fast plugins can add another device before the server node is ready, so we wait for the server node to be ready
914
657
  await this.createDynamicPlugin(plugin);
915
658
  }
916
659
  if (device.mode === 'matter')
@@ -926,31 +669,19 @@ export class MatterNode extends EventEmitter {
926
669
  }
927
670
  if (plugin.registeredDevices !== undefined)
928
671
  plugin.registeredDevices++;
929
- // Add the device to the DeviceManager
930
672
  await this.server.fetch({ type: 'devices_set', src: this.server.name, dst: 'devices', params: { device: toBaseDevice(device) } });
931
- // Add the device to the DeviceManager
932
673
  await device.construction.ready;
933
- // Subscribe to the attributes changed event
934
674
  await this.subscribeAttributeChanged(plugin, device);
935
675
  this.log.info(`Added endpoint #${plugin.registeredDevices} ${plg}${pluginName}${nf}:${dev}${device.deviceName}${nf} (${zb}${device.name}${nf})`);
936
676
  await this.yieldToNode(10);
937
677
  return device;
938
678
  }
939
- /**
940
- * Removes a MatterbridgeEndpoint from the specified plugin.
941
- *
942
- * @param {string} pluginName - The name of the plugin.
943
- * @param {MatterbridgeEndpoint} device - The device to remove as a bridged endpoint.
944
- * @returns {Promise<MatterbridgeEndpoint | undefined>} A promise that resolves to the removed bridged endpoint, or undefined if there was an error.
945
- */
946
679
  async removeBridgedEndpoint(pluginName, device) {
947
680
  this.log.debug(`Removing bridged endpoint ${plg}${pluginName}${db}:${dev}${device.deviceName}${db} (${zb}${device.name}${db})...`);
948
- // Check if the plugin is registered
949
681
  const plugin = this.pluginManager.get(pluginName);
950
682
  if (!plugin)
951
683
  throw new Error(`Error removing bridged endpoint ${plg}${pluginName}${er}:${dev}${device.deviceName}${er} (${zb}${device.name}${er}): plugin not found`);
952
684
  if (device.serverNode) {
953
- // TODO: Close and remove the MatterNode managing the device
954
685
  }
955
686
  else if (this.matterbridge.bridgeMode === 'bridge') {
956
687
  if (!this.aggregatorNode)
@@ -972,25 +703,11 @@ export class MatterNode extends EventEmitter {
972
703
  this.log.info(`Removed bridged endpoint #${plugin.registeredDevices} ${plg}${pluginName}${nf}:${dev}${device.deviceName}${nf} (${zb}${device.name}${nf})`);
973
704
  if (plugin.registeredDevices !== undefined)
974
705
  plugin.registeredDevices--;
975
- // Remove the device from the DeviceManager
976
706
  await this.server.fetch({ type: 'devices_remove', src: this.server.name, dst: 'devices', params: { device: toBaseDevice(device) } });
977
707
  await this.yieldToNode(10);
978
708
  return device;
979
709
  }
980
- /**
981
- * Removes all bridged endpoints from the specified plugin.
982
- *
983
- * @param {string} pluginName - The name of the plugin.
984
- * @param {number} [delay] - The delay in milliseconds between removing each bridged endpoint (default: 0).
985
- * @returns {Promise<void>} A promise that resolves when all bridged endpoints have been removed.
986
- *
987
- * @remarks
988
- * This method iterates through all devices in the DeviceManager and removes each bridged endpoint associated with the specified plugin.
989
- * It also applies a delay between each removal if specified.
990
- * The delay is useful to allow the controllers to receive a single subscription for each device removed.
991
- */
992
710
  async removeAllBridgedEndpoints(pluginName, delay = 0) {
993
- // Check if the plugin is registered
994
711
  const plugin = this.pluginManager.get(pluginName);
995
712
  if (!plugin)
996
713
  throw new Error(`Error removing all bridged endpoints for plugin ${plg}${pluginName}${er}: plugin not found`);
@@ -1005,7 +722,6 @@ export class MatterNode extends EventEmitter {
1005
722
  this.log.info(`Removed bridged endpoint #${plugin.registeredDevices} ${plg}${pluginName}${nf}:${dev}${device.deviceName}${nf} (${zb}${endpoint?.name}${nf})`);
1006
723
  if (plugin.registeredDevices !== undefined)
1007
724
  plugin.registeredDevices--;
1008
- // Remove the device from the DeviceManager
1009
725
  await this.server.fetch({ type: 'devices_remove', src: this.server.name, dst: 'devices', params: { device: toBaseDevice(device) } });
1010
726
  await this.yieldToNode(10);
1011
727
  if (delay > 0)
@@ -1014,25 +730,6 @@ export class MatterNode extends EventEmitter {
1014
730
  if (delay > 0)
1015
731
  await wait(Number(process.env['MATTERBRIDGE_REMOVE_ALL_ENDPOINT_TIMEOUT_MS']) || 2000);
1016
732
  }
1017
- /**
1018
- * Registers a virtual device with the Matterbridge platform.
1019
- * Virtual devices are only supported in bridge mode and childbridge mode with a DynamicPlatform.
1020
- *
1021
- * The virtual device is created as an instance of `Endpoint` with the provided device type.
1022
- * When the virtual device is turned on, the provided callback function is executed.
1023
- * The onOff state of the virtual device always reverts to false when the device is turned on.
1024
- *
1025
- * @param {string} pluginName - The name of the plugin.
1026
- * @param { string } name - The name of the virtual device.
1027
- * @param { 'light' | 'outlet' | 'switch' | 'mounted_switch' } type - The type of the virtual device.
1028
- * @param { () => Promise<void> } callback - The callback to call when the virtual device is turned on.
1029
- *
1030
- * @returns {Promise<boolean>} A promise that resolves to true if the virtual device was successfully registered, false otherwise.
1031
- *
1032
- * @remarks
1033
- * The virtual devices don't show up in the device list of the frontend.
1034
- * Type 'switch' is not supported by Alexa and 'mounted_switch' is not supported by Apple Home.
1035
- */
1036
733
  async addVirtualEndpoint(pluginName, name, type, callback) {
1037
734
  this.log.debug(`Creating virtual device ${plg}${pluginName}${db}:${dev}${name}${db}...`);
1038
735
  const plugin = this.pluginManager.get(pluginName);
@@ -1057,20 +754,10 @@ export class MatterNode extends EventEmitter {
1057
754
  await this.yieldToNode(10);
1058
755
  return true;
1059
756
  }
1060
- /**
1061
- * Subscribes to the attribute change event for the given device and plugin.
1062
- * Specifically, it listens for changes in the 'reachable' attribute of the
1063
- * BridgedDeviceBasicInformationServer cluster server of the bridged device or BasicInformationServer cluster server of server node.
1064
- *
1065
- * @param {Plugin} plugin - The plugin associated with the device.
1066
- * @param {MatterbridgeEndpoint} device - The device to subscribe to attribute changes for.
1067
- * @returns {Promise<void>} A promise that resolves when the subscription is set up.
1068
- */
1069
757
  async subscribeAttributeChanged(plugin, device) {
1070
758
  if (!plugin || !device || !device.plugin || !device.serialNumber || !device.uniqueId || !device.maybeNumber)
1071
759
  return;
1072
760
  this.log.debug(`Subscribing attributes for endpoint ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db}:${or}${device.id}${db}:${or}${device.number}${db} (${zb}${device.name}${db})`);
1073
- // Subscribe to the reachable$Changed event of the BasicInformationServer cluster server of the server node in childbridge mode
1074
761
  if (this.matterbridge.bridgeMode === 'childbridge' && plugin.type === 'AccessoryPlatform' && this.serverNode) {
1075
762
  this.serverNode.eventsOf(BasicInformationServer).reachable$Changed?.on((reachable) => {
1076
763
  this.log.debug(`Accessory endpoint ${plg}${plugin.name}${nf}:${dev}${device.deviceName}${nf}:${or}${device.id}${nf}:${or}${device.number}${nf} is ${reachable ? 'reachable' : 'unreachable'}`);
@@ -1078,7 +765,6 @@ export class MatterNode extends EventEmitter {
1078
765
  type: 'frontend_attributechanged',
1079
766
  src: 'matter',
1080
767
  dst: 'frontend',
1081
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1082
768
  params: { plugin: device.plugin, serialNumber: device.serialNumber, uniqueId: device.uniqueId, number: device.number, id: device.id, cluster: 'BasicInformation', attribute: 'reachable', value: reachable },
1083
769
  });
1084
770
  });
@@ -1131,7 +817,6 @@ export class MatterNode extends EventEmitter {
1131
817
  type: 'frontend_attributechanged',
1132
818
  src: 'matter',
1133
819
  dst: 'frontend',
1134
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1135
820
  params: { plugin: device.plugin, serialNumber: device.serialNumber, uniqueId: device.uniqueId, number: device.number, id: device.id, cluster: sub.cluster, attribute: sub.attribute, value: value },
1136
821
  });
1137
822
  });
@@ -1145,7 +830,6 @@ export class MatterNode extends EventEmitter {
1145
830
  type: 'frontend_attributechanged',
1146
831
  src: 'matter',
1147
832
  dst: 'frontend',
1148
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1149
833
  params: { plugin: device.plugin, serialNumber: device.serialNumber, uniqueId: device.uniqueId, number: child.number, id: child.id, cluster: sub.cluster, attribute: sub.attribute, value: value },
1150
834
  });
1151
835
  });
@@ -1153,12 +837,6 @@ export class MatterNode extends EventEmitter {
1153
837
  }
1154
838
  }
1155
839
  }
1156
- /**
1157
- * Sanitizes the fabric information by converting bigint properties to strings because `res.json` doesn't support bigint.
1158
- *
1159
- * @param {ExposedFabricInformation[]} fabricInfo - The array of exposed fabric information objects.
1160
- * @returns {SanitizedExposedFabricInformation[]} An array of sanitized exposed fabric information objects.
1161
- */
1162
840
  sanitizeFabricInformations(fabricInfo) {
1163
841
  return fabricInfo.map((info) => {
1164
842
  return {
@@ -1172,12 +850,6 @@ export class MatterNode extends EventEmitter {
1172
850
  };
1173
851
  });
1174
852
  }
1175
- /**
1176
- * Sanitizes the session information by converting bigint properties to strings because `res.json` doesn't support bigint.
1177
- *
1178
- * @param {SessionsBehavior.Session[]} sessions - The array of session information objects.
1179
- * @returns {SanitizedSession[]} An array of sanitized session information objects.
1180
- */
1181
853
  sanitizeSessionInformation(sessions) {
1182
854
  return sessions
1183
855
  .filter((session) => session.isPeerActive)
@@ -1204,21 +876,10 @@ export class MatterNode extends EventEmitter {
1204
876
  };
1205
877
  });
1206
878
  }
1207
- /**
1208
- * Sets the reachability of the specified server node and trigger the corresponding event.
1209
- *
1210
- * @param {boolean} reachable - A boolean indicating the reachability status to set.
1211
- */
1212
879
  async setServerReachability(reachable) {
1213
880
  await this.serverNode?.setStateOf(BasicInformationServer, { reachable });
1214
881
  this.serverNode?.act((agent) => this.serverNode?.eventsOf(BasicInformationServer).reachableChanged?.emit({ reachableNewValue: reachable }, agent.context));
1215
882
  }
1216
- /**
1217
- * Sets the reachability of the specified aggregator node bridged devices and trigger.
1218
- *
1219
- * @param {Endpoint<AggregatorEndpoint>} aggregatorNode - The aggregator node to set the reachability for.
1220
- * @param {boolean} reachable - A boolean indicating the reachability status to set.
1221
- */
1222
883
  async setAggregatorReachability(aggregatorNode, reachable) {
1223
884
  for (const child of aggregatorNode.parts) {
1224
885
  this.log.debug(`Setting reachability of ${child?.deviceName} to ${reachable}`);
@@ -1264,35 +925,19 @@ export class MatterNode extends EventEmitter {
1264
925
  case 0x1488:
1265
926
  vendorName = '(ShortcutLabsFlic)';
1266
927
  break;
1267
- case 65521: // 0xFFF1
928
+ case 65521:
1268
929
  vendorName = '(MatterTest)';
1269
930
  break;
1270
931
  }
1271
932
  return vendorName;
1272
933
  };
1273
- /**
1274
- * Yield to the Node.js event loop:
1275
- * 1. Flushes the current microtask queue (Promise/async continuations queued so far).
1276
- * 2. Yields one macrotask turn (setImmediate) and then its microtasks.
1277
- * 3. Waits a bit (setTimeout) to allow other macrotasks to run.
1278
- *
1279
- * This does **not** guarantee that every promise in the process is settled,
1280
- * but it gives all already-scheduled work a very good chance to run before continuing.
1281
- *
1282
- * @param {number} [timeout] - Optional timeout in milliseconds to wait after yielding. Default is 100 ms (minimum 10 ms).
1283
- * @returns {Promise<void>}
1284
- */
1285
934
  async yieldToNode(timeout = 100) {
1286
- // 1. Let all currently queued microtasks run
1287
935
  await Promise.resolve();
1288
- // 2. Yield to the next event-loop turn (macrotask + its microtasks)
1289
936
  await new Promise((resolve) => {
1290
937
  setImmediate(resolve);
1291
938
  });
1292
- // 3. Pause a bit to allow other macrotasks to run
1293
939
  await new Promise((resolve) => {
1294
940
  setTimeout(resolve, Math.min(timeout, 10));
1295
941
  });
1296
942
  }
1297
943
  }
1298
- //# sourceMappingURL=matterNode.js.map