react-native-ble-mesh 1.0.1

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 (465) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/LICENSE +21 -0
  3. package/README.md +706 -0
  4. package/docs/API.md +462 -0
  5. package/docs/ARCHITECTURE.md +384 -0
  6. package/docs/CONTRIBUTING.md +244 -0
  7. package/docs/NODE_QUICKSTART.md +259 -0
  8. package/docs/PROTOCOL.md +195 -0
  9. package/docs/REACT_NATIVE.md +315 -0
  10. package/docs/SECURITY.md +152 -0
  11. package/docs/api/constants_audio.js.html +184 -0
  12. package/docs/api/constants_ble.js.html +165 -0
  13. package/docs/api/constants_crypto.js.html +107 -0
  14. package/docs/api/constants_errors.js.html +256 -0
  15. package/docs/api/constants_events.js.html +148 -0
  16. package/docs/api/constants_index.js.html +76 -0
  17. package/docs/api/constants_protocol.js.html +205 -0
  18. package/docs/api/crypto_aead.js.html +243 -0
  19. package/docs/api/crypto_chacha20.js.html +235 -0
  20. package/docs/api/crypto_hkdf.js.html +241 -0
  21. package/docs/api/crypto_hmac.js.html +197 -0
  22. package/docs/api/crypto_index.js.html +126 -0
  23. package/docs/api/crypto_keys_KeyManager.js.html +325 -0
  24. package/docs/api/crypto_keys_KeyPair.js.html +270 -0
  25. package/docs/api/crypto_keys_SecureStorage.js.html +273 -0
  26. package/docs/api/crypto_keys_index.js.html +86 -0
  27. package/docs/api/crypto_noise_handshake.js.html +464 -0
  28. package/docs/api/crypto_noise_index.js.html +81 -0
  29. package/docs/api/crypto_noise_session.js.html +307 -0
  30. package/docs/api/crypto_noise_state.js.html +322 -0
  31. package/docs/api/crypto_poly1305.js.html +167 -0
  32. package/docs/api/crypto_sha256.js.html +294 -0
  33. package/docs/api/crypto_x25519.js.html +208 -0
  34. package/docs/api/errors_AudioError.js.html +218 -0
  35. package/docs/api/errors_ConnectionError.js.html +163 -0
  36. package/docs/api/errors_CryptoError.js.html +157 -0
  37. package/docs/api/errors_HandshakeError.js.html +176 -0
  38. package/docs/api/errors_MeshError.js.html +154 -0
  39. package/docs/api/errors_MessageError.js.html +183 -0
  40. package/docs/api/errors_ValidationError.js.html +204 -0
  41. package/docs/api/errors_index.js.html +78 -0
  42. package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
  43. package/docs/api/fonts/OpenSans-Bold-webfont.svg +1830 -0
  44. package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
  45. package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  46. package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
  47. package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  48. package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
  49. package/docs/api/fonts/OpenSans-Italic-webfont.svg +1830 -0
  50. package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
  51. package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
  52. package/docs/api/fonts/OpenSans-Light-webfont.svg +1831 -0
  53. package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
  54. package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  55. package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
  56. package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  57. package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
  58. package/docs/api/fonts/OpenSans-Regular-webfont.svg +1831 -0
  59. package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
  60. package/docs/api/hooks_AppStateManager.js.html +233 -0
  61. package/docs/api/hooks_index.js.html +87 -0
  62. package/docs/api/hooks_useMesh.js.html +213 -0
  63. package/docs/api/hooks_useMessages.js.html +263 -0
  64. package/docs/api/hooks_usePeers.js.html +165 -0
  65. package/docs/api/index.html +868 -0
  66. package/docs/api/index.js.html +236 -0
  67. package/docs/api/mesh_dedup_BloomFilter.js.html +261 -0
  68. package/docs/api/mesh_dedup_DedupManager.js.html +266 -0
  69. package/docs/api/mesh_dedup_MessageCache.js.html +273 -0
  70. package/docs/api/mesh_dedup_index.js.html +70 -0
  71. package/docs/api/mesh_fragment_Assembler.js.html +335 -0
  72. package/docs/api/mesh_fragment_Fragmenter.js.html +230 -0
  73. package/docs/api/mesh_fragment_index.js.html +75 -0
  74. package/docs/api/mesh_index.js.html +72 -0
  75. package/docs/api/mesh_peer_Peer.js.html +296 -0
  76. package/docs/api/mesh_peer_PeerDiscovery.js.html +334 -0
  77. package/docs/api/mesh_peer_PeerManager.js.html +320 -0
  78. package/docs/api/mesh_peer_index.js.html +70 -0
  79. package/docs/api/mesh_router_MessageRouter.js.html +411 -0
  80. package/docs/api/mesh_router_PathFinder.js.html +386 -0
  81. package/docs/api/mesh_router_RouteTable.js.html +346 -0
  82. package/docs/api/mesh_router_index.js.html +70 -0
  83. package/docs/api/module-audio_buffer.html +168 -0
  84. package/docs/api/module-audio_buffer_FrameBuffer-FrameBuffer.html +2971 -0
  85. package/docs/api/module-audio_buffer_FrameBuffer.html +178 -0
  86. package/docs/api/module-audio_buffer_JitterBuffer-JitterBuffer.html +2761 -0
  87. package/docs/api/module-audio_buffer_JitterBuffer.html +178 -0
  88. package/docs/api/module-audio_codec.html +168 -0
  89. package/docs/api/module-audio_codec_LC3Codec-LC3Codec.html +2876 -0
  90. package/docs/api/module-audio_codec_LC3Codec.html +178 -0
  91. package/docs/api/module-audio_codec_LC3Decoder-LC3Decoder.html +1788 -0
  92. package/docs/api/module-audio_codec_LC3Decoder.html +178 -0
  93. package/docs/api/module-audio_codec_LC3Encoder-LC3Encoder.html +1512 -0
  94. package/docs/api/module-audio_codec_LC3Encoder.html +178 -0
  95. package/docs/api/module-audio_session.html +168 -0
  96. package/docs/api/module-audio_session_AudioSession-AudioSession.html +3922 -0
  97. package/docs/api/module-audio_session_AudioSession.html +178 -0
  98. package/docs/api/module-audio_session_VoiceMessage-VoiceMessage.html +3690 -0
  99. package/docs/api/module-audio_session_VoiceMessage-VoiceMessageRecorder.html +1780 -0
  100. package/docs/api/module-audio_session_VoiceMessage.html +332 -0
  101. package/docs/api/module-audio_transport.html +168 -0
  102. package/docs/api/module-audio_transport_AudioFragmenter-AudioAssembler.html +1545 -0
  103. package/docs/api/module-audio_transport_AudioFragmenter-AudioFragmenter.html +658 -0
  104. package/docs/api/module-audio_transport_AudioFragmenter.html +181 -0
  105. package/docs/api/module-audio_transport_AudioFramer.html +1414 -0
  106. package/docs/api/module-constants.html +168 -0
  107. package/docs/api/module-constants_audio.html +1782 -0
  108. package/docs/api/module-constants_ble.html +940 -0
  109. package/docs/api/module-constants_crypto.html +823 -0
  110. package/docs/api/module-constants_errors.html +316 -0
  111. package/docs/api/module-constants_events.html +244 -0
  112. package/docs/api/module-constants_protocol.html +1534 -0
  113. package/docs/api/module-crypto.html +169 -0
  114. package/docs/api/module-crypto_aead.html +1625 -0
  115. package/docs/api/module-crypto_chacha20.html +1440 -0
  116. package/docs/api/module-crypto_hkdf.html +1421 -0
  117. package/docs/api/module-crypto_hmac.html +828 -0
  118. package/docs/api/module-crypto_keys.html +169 -0
  119. package/docs/api/module-crypto_keys_KeyManager-KeyManager.html +2364 -0
  120. package/docs/api/module-crypto_keys_KeyManager.html +252 -0
  121. package/docs/api/module-crypto_keys_KeyPair.html +245 -0
  122. package/docs/api/module-crypto_keys_SecureStorage-MemorySecureStorage.html +923 -0
  123. package/docs/api/module-crypto_keys_SecureStorage-SecureStorage.html +942 -0
  124. package/docs/api/module-crypto_keys_SecureStorage.html +516 -0
  125. package/docs/api/module-crypto_noise.html +169 -0
  126. package/docs/api/module-crypto_noise_handshake-NoiseHandshake.html +2240 -0
  127. package/docs/api/module-crypto_noise_handshake.html +782 -0
  128. package/docs/api/module-crypto_noise_session-NoiseSession.html +1804 -0
  129. package/docs/api/module-crypto_noise_session.html +325 -0
  130. package/docs/api/module-crypto_noise_state-SymmetricState.html +1387 -0
  131. package/docs/api/module-crypto_noise_state.html +324 -0
  132. package/docs/api/module-crypto_poly1305.html +884 -0
  133. package/docs/api/module-crypto_sha256-HashContext.html +447 -0
  134. package/docs/api/module-crypto_sha256.html +942 -0
  135. package/docs/api/module-crypto_x25519.html +1503 -0
  136. package/docs/api/module-errors.html +168 -0
  137. package/docs/api/module-errors_AudioError-AudioError.html +4711 -0
  138. package/docs/api/module-errors_AudioError.html +178 -0
  139. package/docs/api/module-errors_ConnectionError-ConnectionError.html +3649 -0
  140. package/docs/api/module-errors_ConnectionError.html +178 -0
  141. package/docs/api/module-errors_CryptoError-CryptoError.html +3453 -0
  142. package/docs/api/module-errors_CryptoError.html +178 -0
  143. package/docs/api/module-errors_HandshakeError-HandshakeError.html +4261 -0
  144. package/docs/api/module-errors_HandshakeError.html +178 -0
  145. package/docs/api/module-errors_MeshError-MeshError.html +2155 -0
  146. package/docs/api/module-errors_MeshError.html +178 -0
  147. package/docs/api/module-errors_MessageError-MessageError.html +4545 -0
  148. package/docs/api/module-errors_MessageError.html +178 -0
  149. package/docs/api/module-errors_ValidationError-ValidationError.html +3432 -0
  150. package/docs/api/module-errors_ValidationError.html +178 -0
  151. package/docs/api/module-hooks.html +182 -0
  152. package/docs/api/module-hooks_AppStateManager-AppStateManager.html +1620 -0
  153. package/docs/api/module-hooks_AppStateManager.html +178 -0
  154. package/docs/api/module-hooks_useMesh.html +457 -0
  155. package/docs/api/module-hooks_useMessages.html +466 -0
  156. package/docs/api/module-hooks_usePeers.html +348 -0
  157. package/docs/api/module-mesh.html +168 -0
  158. package/docs/api/module-mesh_dedup.html +168 -0
  159. package/docs/api/module-mesh_dedup_BloomFilter-BloomFilter.html +2158 -0
  160. package/docs/api/module-mesh_dedup_BloomFilter.html +178 -0
  161. package/docs/api/module-mesh_dedup_DedupManager-DedupManager.html +2880 -0
  162. package/docs/api/module-mesh_dedup_DedupManager.html +178 -0
  163. package/docs/api/module-mesh_dedup_MessageCache-CacheNode.html +246 -0
  164. package/docs/api/module-mesh_dedup_MessageCache-MessageCache.html +2314 -0
  165. package/docs/api/module-mesh_dedup_MessageCache.html +181 -0
  166. package/docs/api/module-mesh_fragment.html +168 -0
  167. package/docs/api/module-mesh_fragment_Assembler-Assembler.html +2869 -0
  168. package/docs/api/module-mesh_fragment_Assembler-PendingFragmentSet.html +895 -0
  169. package/docs/api/module-mesh_fragment_Assembler.html +181 -0
  170. package/docs/api/module-mesh_fragment_Fragmenter.html +1084 -0
  171. package/docs/api/module-mesh_peer.html +168 -0
  172. package/docs/api/module-mesh_peer_Peer-Peer.html +4986 -0
  173. package/docs/api/module-mesh_peer_Peer.html +178 -0
  174. package/docs/api/module-mesh_peer_PeerDiscovery-PeerDiscovery.html +3423 -0
  175. package/docs/api/module-mesh_peer_PeerDiscovery.html +438 -0
  176. package/docs/api/module-mesh_peer_PeerManager-PeerManager.html +5258 -0
  177. package/docs/api/module-mesh_peer_PeerManager.html +178 -0
  178. package/docs/api/module-mesh_router.html +168 -0
  179. package/docs/api/module-mesh_router_MessageRouter-MessageRouter.html +3285 -0
  180. package/docs/api/module-mesh_router_MessageRouter.html +178 -0
  181. package/docs/api/module-mesh_router_PathFinder-PathFinder.html +3323 -0
  182. package/docs/api/module-mesh_router_PathFinder.html +421 -0
  183. package/docs/api/module-mesh_router_RouteTable-RouteTable.html +4115 -0
  184. package/docs/api/module-mesh_router_RouteTable.html +421 -0
  185. package/docs/api/module-protocol.html +169 -0
  186. package/docs/api/module-protocol_crc32.html +815 -0
  187. package/docs/api/module-protocol_deserializer.html +1393 -0
  188. package/docs/api/module-protocol_header-MessageHeader.html +2879 -0
  189. package/docs/api/module-protocol_header.html +892 -0
  190. package/docs/api/module-protocol_message-Message.html +4682 -0
  191. package/docs/api/module-protocol_message.html +178 -0
  192. package/docs/api/module-protocol_serializer.html +911 -0
  193. package/docs/api/module-protocol_validator.html +1396 -0
  194. package/docs/api/module-rn-ble-mesh.html +866 -0
  195. package/docs/api/module-service.html +168 -0
  196. package/docs/api/module-service_HandshakeManager-HandshakeManager.html +185 -0
  197. package/docs/api/module-service_HandshakeManager.html +175 -0
  198. package/docs/api/module-service_MeshService-MeshService.html +185 -0
  199. package/docs/api/module-service_MeshService.html +175 -0
  200. package/docs/api/module-service_SessionManager-SessionManager.html +174 -0
  201. package/docs/api/module-service_SessionManager.html +175 -0
  202. package/docs/api/module-service_audio.html +168 -0
  203. package/docs/api/module-service_audio_AudioManager-AudioManager.html +4653 -0
  204. package/docs/api/module-service_audio_AudioManager.html +254 -0
  205. package/docs/api/module-service_text.html +168 -0
  206. package/docs/api/module-service_text_TextManager-TextManager.html +6104 -0
  207. package/docs/api/module-service_text_TextManager.html +254 -0
  208. package/docs/api/module-service_text_broadcast.html +168 -0
  209. package/docs/api/module-service_text_broadcast_BroadcastManager-BroadcastManager.html +2434 -0
  210. package/docs/api/module-service_text_broadcast_BroadcastManager.html +254 -0
  211. package/docs/api/module-service_text_channel.html +168 -0
  212. package/docs/api/module-service_text_channel_Channel-Channel.html +4337 -0
  213. package/docs/api/module-service_text_channel_Channel.html +178 -0
  214. package/docs/api/module-service_text_channel_ChannelManager-ChannelManager.html +1927 -0
  215. package/docs/api/module-service_text_channel_ChannelManager.html +175 -0
  216. package/docs/api/module-service_text_message.html +168 -0
  217. package/docs/api/module-service_text_message_TextMessage-TextMessage.html +4162 -0
  218. package/docs/api/module-service_text_message_TextMessage.html +178 -0
  219. package/docs/api/module-service_text_message_TextSerializer.html +1725 -0
  220. package/docs/api/module-storage.html +168 -0
  221. package/docs/api/module-storage_AsyncStorageAdapter-AsyncStorageAdapter.html +4159 -0
  222. package/docs/api/module-storage_AsyncStorageAdapter.html +178 -0
  223. package/docs/api/module-storage_MemoryStorage-MemoryStorage.html +3154 -0
  224. package/docs/api/module-storage_MemoryStorage.html +178 -0
  225. package/docs/api/module-storage_MessageStore-MessageStore.html +5299 -0
  226. package/docs/api/module-storage_MessageStore.html +178 -0
  227. package/docs/api/module-storage_Storage-Storage.html +4169 -0
  228. package/docs/api/module-storage_Storage.html +178 -0
  229. package/docs/api/module-transport.html +168 -0
  230. package/docs/api/module-transport_BLEAdapter-BLEAdapter.html +4724 -0
  231. package/docs/api/module-transport_BLEAdapter.html +178 -0
  232. package/docs/api/module-transport_BLETransport-BLETransport.html +3263 -0
  233. package/docs/api/module-transport_BLETransport.html +178 -0
  234. package/docs/api/module-transport_MockTransport-MockTransport.html +3947 -0
  235. package/docs/api/module-transport_MockTransport.html +178 -0
  236. package/docs/api/module-transport_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
  237. package/docs/api/module-transport_NodeBLEAdapter.html +178 -0
  238. package/docs/api/module-transport_RNBLEAdapter-RNBLEAdapter.html +3216 -0
  239. package/docs/api/module-transport_RNBLEAdapter.html +178 -0
  240. package/docs/api/module-transport_Transport-Transport.html +4071 -0
  241. package/docs/api/module-transport_Transport.html +254 -0
  242. package/docs/api/module-transport_adapters.html +168 -0
  243. package/docs/api/module-transport_adapters_BLEAdapter-BLEAdapter.html +4724 -0
  244. package/docs/api/module-transport_adapters_BLEAdapter.html +178 -0
  245. package/docs/api/module-transport_adapters_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
  246. package/docs/api/module-transport_adapters_NodeBLEAdapter.html +178 -0
  247. package/docs/api/module-transport_adapters_RNBLEAdapter-RNBLEAdapter.html +3216 -0
  248. package/docs/api/module-transport_adapters_RNBLEAdapter.html +178 -0
  249. package/docs/api/module-utils.html +168 -0
  250. package/docs/api/module-utils_BoundedMap-BoundedMap.html +3301 -0
  251. package/docs/api/module-utils_BoundedMap.html +178 -0
  252. package/docs/api/module-utils_EventEmitter-EventEmitter.html +3358 -0
  253. package/docs/api/module-utils_EventEmitter.html +178 -0
  254. package/docs/api/module-utils_LRUCache-LRUCache.html +4134 -0
  255. package/docs/api/module-utils_LRUCache.html +178 -0
  256. package/docs/api/module-utils_RateLimiter-RateLimiter.html +2176 -0
  257. package/docs/api/module-utils_RateLimiter.html +500 -0
  258. package/docs/api/module-utils_TimeoutManager-TimeoutManager.html +1781 -0
  259. package/docs/api/module-utils_TimeoutManager.html +175 -0
  260. package/docs/api/module-utils_bytes.html +1789 -0
  261. package/docs/api/module-utils_debug.html +837 -0
  262. package/docs/api/module-utils_encoding.html +1184 -0
  263. package/docs/api/module-utils_retry.html +1457 -0
  264. package/docs/api/module-utils_time.html +1665 -0
  265. package/docs/api/module-utils_uuid.html +1269 -0
  266. package/docs/api/module-utils_validation.html +2176 -0
  267. package/docs/api/protocol_crc32.js.html +147 -0
  268. package/docs/api/protocol_deserializer.js.html +295 -0
  269. package/docs/api/protocol_header.js.html +276 -0
  270. package/docs/api/protocol_index.js.html +120 -0
  271. package/docs/api/protocol_message.js.html +287 -0
  272. package/docs/api/protocol_serializer.js.html +240 -0
  273. package/docs/api/protocol_validator.js.html +330 -0
  274. package/docs/api/scripts/linenumber.js +25 -0
  275. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
  276. package/docs/api/scripts/prettify/lang-css.js +2 -0
  277. package/docs/api/scripts/prettify/prettify.js +28 -0
  278. package/docs/api/service_HandshakeManager.js.html +232 -0
  279. package/docs/api/service_MeshService.js.html +371 -0
  280. package/docs/api/service_SessionManager.js.html +153 -0
  281. package/docs/api/service_audio_AudioManager.js.html +541 -0
  282. package/docs/api/service_audio_buffer_FrameBuffer.js.html +223 -0
  283. package/docs/api/service_audio_buffer_JitterBuffer.js.html +244 -0
  284. package/docs/api/service_audio_buffer_index.js.html +68 -0
  285. package/docs/api/service_audio_codec_LC3Codec.js.html +345 -0
  286. package/docs/api/service_audio_codec_LC3Decoder.js.html +185 -0
  287. package/docs/api/service_audio_codec_LC3Encoder.js.html +194 -0
  288. package/docs/api/service_audio_codec_index.js.html +70 -0
  289. package/docs/api/service_audio_index.js.html +96 -0
  290. package/docs/api/service_audio_session_AudioSession.js.html +348 -0
  291. package/docs/api/service_audio_session_VoiceMessage.js.html +432 -0
  292. package/docs/api/service_audio_session_index.js.html +70 -0
  293. package/docs/api/service_audio_transport_AudioFragmenter.js.html +314 -0
  294. package/docs/api/service_audio_transport_AudioFramer.js.html +236 -0
  295. package/docs/api/service_audio_transport_index.js.html +69 -0
  296. package/docs/api/service_index.js.html +93 -0
  297. package/docs/api/service_text_TextManager.js.html +578 -0
  298. package/docs/api/service_text_broadcast_BroadcastManager.js.html +276 -0
  299. package/docs/api/service_text_broadcast_index.js.html +66 -0
  300. package/docs/api/service_text_channel_Channel.js.html +280 -0
  301. package/docs/api/service_text_channel_ChannelManager.js.html +225 -0
  302. package/docs/api/service_text_channel_index.js.html +68 -0
  303. package/docs/api/service_text_index.js.html +85 -0
  304. package/docs/api/service_text_message_TextMessage.js.html +350 -0
  305. package/docs/api/service_text_message_TextSerializer.js.html +218 -0
  306. package/docs/api/service_text_message_index.js.html +68 -0
  307. package/docs/api/storage_AsyncStorageAdapter.js.html +357 -0
  308. package/docs/api/storage_MemoryStorage.js.html +279 -0
  309. package/docs/api/storage_MessageStore.js.html +369 -0
  310. package/docs/api/storage_Storage.js.html +214 -0
  311. package/docs/api/storage_index.js.html +72 -0
  312. package/docs/api/styles/jsdoc-default.css +358 -0
  313. package/docs/api/styles/prettify-jsdoc.css +111 -0
  314. package/docs/api/styles/prettify-tomorrow.css +132 -0
  315. package/docs/api/transport_BLEAdapter.js.html +231 -0
  316. package/docs/api/transport_BLETransport.js.html +411 -0
  317. package/docs/api/transport_MockTransport.js.html +339 -0
  318. package/docs/api/transport_NodeBLEAdapter.js.html +479 -0
  319. package/docs/api/transport_RNBLEAdapter.js.html +382 -0
  320. package/docs/api/transport_Transport.js.html +242 -0
  321. package/docs/api/transport_adapters_BLEAdapter.js.html +231 -0
  322. package/docs/api/transport_adapters_NodeBLEAdapter.js.html +479 -0
  323. package/docs/api/transport_adapters_RNBLEAdapter.js.html +382 -0
  324. package/docs/api/transport_adapters_index.js.html +70 -0
  325. package/docs/api/transport_index.js.html +87 -0
  326. package/docs/api/utils_BoundedMap.js.html +205 -0
  327. package/docs/api/utils_EventEmitter.js.html +259 -0
  328. package/docs/api/utils_LRUCache.js.html +256 -0
  329. package/docs/api/utils_RateLimiter.js.html +256 -0
  330. package/docs/api/utils_TimeoutManager.js.html +218 -0
  331. package/docs/api/utils_base64%0A%0AThis%20implementation%20avoids%20string%20concatenation%20in%20loops%20which%20is%20O(n%C2%B2).%0AUses%20array%20building%20which%20is%20O(n)%20-%20critical%20for%20React%20Native%20performance.module_.html +717 -0
  332. package/docs/api/utils_base64.js.html +205 -0
  333. package/docs/api/utils_bytes.js.html +241 -0
  334. package/docs/api/utils_debug.js.html +205 -0
  335. package/docs/api/utils_encoding.js.html +302 -0
  336. package/docs/api/utils_index.js.html +160 -0
  337. package/docs/api/utils_retry.js.html +200 -0
  338. package/docs/api/utils_time.js.html +220 -0
  339. package/docs/api/utils_uuid.js.html +199 -0
  340. package/docs/api/utils_validation.js.html +259 -0
  341. package/examples/node-chat/chat.js +220 -0
  342. package/examples/node-quickstart/index.js +94 -0
  343. package/examples/testing/test-helper.js +182 -0
  344. package/package.json +111 -0
  345. package/src/constants/audio.js +130 -0
  346. package/src/constants/ble.js +111 -0
  347. package/src/constants/crypto.js +53 -0
  348. package/src/constants/errors.js +202 -0
  349. package/src/constants/events.js +94 -0
  350. package/src/constants/index.js +22 -0
  351. package/src/constants/protocol.js +151 -0
  352. package/src/crypto/aead.js +189 -0
  353. package/src/crypto/chacha20.js +181 -0
  354. package/src/crypto/hkdf.js +187 -0
  355. package/src/crypto/hmac.js +143 -0
  356. package/src/crypto/index.js +72 -0
  357. package/src/crypto/keys/KeyManager.js +271 -0
  358. package/src/crypto/keys/KeyPair.js +216 -0
  359. package/src/crypto/keys/SecureStorage.js +219 -0
  360. package/src/crypto/keys/index.js +32 -0
  361. package/src/crypto/noise/handshake.js +410 -0
  362. package/src/crypto/noise/index.js +27 -0
  363. package/src/crypto/noise/session.js +253 -0
  364. package/src/crypto/noise/state.js +268 -0
  365. package/src/crypto/poly1305.js +113 -0
  366. package/src/crypto/sha256.js +240 -0
  367. package/src/crypto/x25519.js +154 -0
  368. package/src/errors/AudioError.js +164 -0
  369. package/src/errors/ConnectionError.js +109 -0
  370. package/src/errors/CryptoError.js +103 -0
  371. package/src/errors/HandshakeError.js +122 -0
  372. package/src/errors/MeshError.js +100 -0
  373. package/src/errors/MessageError.js +129 -0
  374. package/src/errors/ValidationError.js +150 -0
  375. package/src/errors/index.js +24 -0
  376. package/src/hooks/AppStateManager.js +179 -0
  377. package/src/hooks/index.js +33 -0
  378. package/src/hooks/useMesh.js +159 -0
  379. package/src/hooks/useMessages.js +209 -0
  380. package/src/hooks/usePeers.js +111 -0
  381. package/src/index.d.ts +494 -0
  382. package/src/index.js +182 -0
  383. package/src/index.mjs +62 -0
  384. package/src/mesh/dedup/BloomFilter.js +207 -0
  385. package/src/mesh/dedup/DedupManager.js +212 -0
  386. package/src/mesh/dedup/MessageCache.js +219 -0
  387. package/src/mesh/dedup/index.js +16 -0
  388. package/src/mesh/fragment/Assembler.js +281 -0
  389. package/src/mesh/fragment/Fragmenter.js +176 -0
  390. package/src/mesh/fragment/index.js +21 -0
  391. package/src/mesh/index.js +18 -0
  392. package/src/mesh/peer/Peer.js +242 -0
  393. package/src/mesh/peer/PeerDiscovery.js +280 -0
  394. package/src/mesh/peer/PeerManager.js +266 -0
  395. package/src/mesh/peer/index.js +16 -0
  396. package/src/mesh/router/MessageRouter.js +357 -0
  397. package/src/mesh/router/PathFinder.js +332 -0
  398. package/src/mesh/router/RouteTable.js +292 -0
  399. package/src/mesh/router/index.js +16 -0
  400. package/src/protocol/crc32.js +93 -0
  401. package/src/protocol/deserializer.js +241 -0
  402. package/src/protocol/header.js +222 -0
  403. package/src/protocol/index.js +66 -0
  404. package/src/protocol/message.js +233 -0
  405. package/src/protocol/serializer.js +186 -0
  406. package/src/protocol/validator.js +276 -0
  407. package/src/service/HandshakeManager.js +178 -0
  408. package/src/service/MeshService.js +317 -0
  409. package/src/service/SessionManager.js +99 -0
  410. package/src/service/audio/AudioManager.js +487 -0
  411. package/src/service/audio/buffer/FrameBuffer.js +169 -0
  412. package/src/service/audio/buffer/JitterBuffer.js +190 -0
  413. package/src/service/audio/buffer/index.js +14 -0
  414. package/src/service/audio/codec/LC3Codec.js +291 -0
  415. package/src/service/audio/codec/LC3Decoder.js +131 -0
  416. package/src/service/audio/codec/LC3Encoder.js +140 -0
  417. package/src/service/audio/codec/index.js +16 -0
  418. package/src/service/audio/index.js +42 -0
  419. package/src/service/audio/session/AudioSession.js +294 -0
  420. package/src/service/audio/session/VoiceMessage.js +378 -0
  421. package/src/service/audio/session/index.js +16 -0
  422. package/src/service/audio/transport/AudioFragmenter.js +260 -0
  423. package/src/service/audio/transport/AudioFramer.js +182 -0
  424. package/src/service/audio/transport/index.js +15 -0
  425. package/src/service/index.js +39 -0
  426. package/src/service/text/TextManager.js +524 -0
  427. package/src/service/text/broadcast/BroadcastManager.js +222 -0
  428. package/src/service/text/broadcast/index.js +12 -0
  429. package/src/service/text/channel/Channel.js +226 -0
  430. package/src/service/text/channel/ChannelManager.js +171 -0
  431. package/src/service/text/channel/index.js +14 -0
  432. package/src/service/text/index.js +31 -0
  433. package/src/service/text/message/TextMessage.js +296 -0
  434. package/src/service/text/message/TextSerializer.js +164 -0
  435. package/src/service/text/message/index.js +14 -0
  436. package/src/storage/AsyncStorageAdapter.js +303 -0
  437. package/src/storage/MemoryStorage.js +225 -0
  438. package/src/storage/MessageStore.js +315 -0
  439. package/src/storage/Storage.js +160 -0
  440. package/src/storage/index.js +18 -0
  441. package/src/transport/BLEAdapter.js +177 -0
  442. package/src/transport/BLETransport.js +357 -0
  443. package/src/transport/MockTransport.js +285 -0
  444. package/src/transport/NodeBLEAdapter.js +425 -0
  445. package/src/transport/RNBLEAdapter.js +328 -0
  446. package/src/transport/Transport.js +188 -0
  447. package/src/transport/adapters/BLEAdapter.js +177 -0
  448. package/src/transport/adapters/NodeBLEAdapter.js +425 -0
  449. package/src/transport/adapters/RNBLEAdapter.js +328 -0
  450. package/src/transport/adapters/index.js +16 -0
  451. package/src/transport/index.js +33 -0
  452. package/src/utils/BoundedMap.js +151 -0
  453. package/src/utils/EventEmitter.js +205 -0
  454. package/src/utils/LRUCache.js +202 -0
  455. package/src/utils/RateLimiter.js +202 -0
  456. package/src/utils/TimeoutManager.js +164 -0
  457. package/src/utils/base64.js +151 -0
  458. package/src/utils/bytes.js +187 -0
  459. package/src/utils/debug.js +151 -0
  460. package/src/utils/encoding.js +248 -0
  461. package/src/utils/index.js +106 -0
  462. package/src/utils/retry.js +146 -0
  463. package/src/utils/time.js +166 -0
  464. package/src/utils/uuid.js +145 -0
  465. package/src/utils/validation.js +205 -0
@@ -0,0 +1,233 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Message container class combining header and payload.
5
+ * @module protocol/message
6
+ */
7
+
8
+ const { MessageHeader, HEADER_SIZE, generateUuid } = require('./header');
9
+ const { MESSAGE_FLAGS, MESH_CONFIG } = require('../constants');
10
+ const { MessageError } = require('../errors');
11
+
12
+ /**
13
+ * Message class representing a complete mesh network message.
14
+ * @class Message
15
+ */
16
+ class Message {
17
+ /**
18
+ * Creates a new Message instance.
19
+ * @param {MessageHeader} header - Message header
20
+ * @param {Uint8Array} payload - Message payload
21
+ */
22
+ constructor(header, payload) {
23
+ /** @type {MessageHeader} */
24
+ this.header = header;
25
+ /** @type {Uint8Array} */
26
+ this.payload = payload;
27
+ }
28
+
29
+ /**
30
+ * Creates a new message with the given options.
31
+ * @param {Object} options - Message options
32
+ * @param {number} options.type - Message type from MESSAGE_TYPE
33
+ * @param {Uint8Array|string} options.payload - Message payload
34
+ * @param {number} [options.flags=0] - Message flags
35
+ * @param {number} [options.maxHops=7] - Maximum hops
36
+ * @param {number} [options.ttlMs] - Time-to-live in ms
37
+ * @param {number} [options.fragmentIndex=0] - Fragment index
38
+ * @param {number} [options.fragmentTotal=1] - Total fragments
39
+ * @param {Uint8Array} [options.messageId] - Optional message ID
40
+ * @returns {Message} New message instance
41
+ */
42
+ static create(options) {
43
+ let payload = options.payload;
44
+
45
+ // Convert string payload to bytes
46
+ if (typeof payload === 'string') {
47
+ payload = new TextEncoder().encode(payload);
48
+ }
49
+
50
+ if (!(payload instanceof Uint8Array)) {
51
+ payload = new Uint8Array(0);
52
+ }
53
+
54
+ const now = Date.now();
55
+ const ttl = options.ttlMs ?? MESH_CONFIG.MESSAGE_TTL_MS;
56
+
57
+ const header = new MessageHeader({
58
+ type: options.type,
59
+ flags: options.flags ?? MESSAGE_FLAGS.NONE,
60
+ maxHops: options.maxHops ?? MESH_CONFIG.MAX_HOPS,
61
+ messageId: options.messageId ?? generateUuid(),
62
+ timestamp: now,
63
+ expiresAt: now + ttl,
64
+ payloadLength: payload.length,
65
+ fragmentIndex: options.fragmentIndex ?? 0,
66
+ fragmentTotal: options.fragmentTotal ?? 1
67
+ });
68
+
69
+ return new Message(header, payload);
70
+ }
71
+
72
+ /**
73
+ * Deserializes a message from bytes.
74
+ * @param {Uint8Array} data - Raw message bytes
75
+ * @returns {Message} Parsed message
76
+ * @throws {MessageError} If data is invalid
77
+ */
78
+ static fromBytes(data) {
79
+ if (!(data instanceof Uint8Array)) {
80
+ throw MessageError.invalidFormat(null, { reason: 'Data must be Uint8Array' });
81
+ }
82
+
83
+ if (data.length < HEADER_SIZE) {
84
+ throw MessageError.invalidFormat(null, {
85
+ reason: 'Message too small',
86
+ size: data.length,
87
+ minSize: HEADER_SIZE
88
+ });
89
+ }
90
+
91
+ const header = MessageHeader.fromBytes(data);
92
+ const expectedLength = HEADER_SIZE + header.payloadLength;
93
+
94
+ if (data.length < expectedLength) {
95
+ throw MessageError.invalidFormat(header.getMessageIdHex(), {
96
+ reason: 'Incomplete payload',
97
+ expected: expectedLength,
98
+ actual: data.length
99
+ });
100
+ }
101
+
102
+ const payload = data.slice(HEADER_SIZE, HEADER_SIZE + header.payloadLength);
103
+
104
+ return new Message(header, payload);
105
+ }
106
+
107
+ /**
108
+ * Serializes the message to bytes.
109
+ * @returns {Uint8Array} Complete message bytes
110
+ */
111
+ toBytes() {
112
+ const headerBytes = this.header.toBytes();
113
+ const result = new Uint8Array(headerBytes.length + this.payload.length);
114
+ result.set(headerBytes, 0);
115
+ result.set(this.payload, headerBytes.length);
116
+ return result;
117
+ }
118
+
119
+ /**
120
+ * Checks if the message has expired.
121
+ * @returns {boolean} True if expired
122
+ */
123
+ isExpired() {
124
+ return Date.now() > this.header.expiresAt;
125
+ }
126
+
127
+ /**
128
+ * Checks if the message is a fragment.
129
+ * @returns {boolean} True if this is a fragment
130
+ */
131
+ isFragment() {
132
+ return this.header.fragmentTotal > 1 ||
133
+ (this.header.flags & MESSAGE_FLAGS.IS_FRAGMENT) !== 0;
134
+ }
135
+
136
+ /**
137
+ * Checks if the message payload is encrypted.
138
+ * @returns {boolean} True if encrypted
139
+ */
140
+ isEncrypted() {
141
+ return (this.header.flags & MESSAGE_FLAGS.ENCRYPTED) !== 0;
142
+ }
143
+
144
+ /**
145
+ * Checks if the message requires acknowledgment.
146
+ * @returns {boolean} True if ACK required
147
+ */
148
+ requiresAck() {
149
+ return (this.header.flags & MESSAGE_FLAGS.REQUIRES_ACK) !== 0;
150
+ }
151
+
152
+ /**
153
+ * Checks if the message is a broadcast.
154
+ * @returns {boolean} True if broadcast
155
+ */
156
+ isBroadcast() {
157
+ return (this.header.flags & MESSAGE_FLAGS.IS_BROADCAST) !== 0;
158
+ }
159
+
160
+ /**
161
+ * Checks if the message is high priority.
162
+ * @returns {boolean} True if high priority
163
+ */
164
+ isHighPriority() {
165
+ return (this.header.flags & MESSAGE_FLAGS.HIGH_PRIORITY) !== 0;
166
+ }
167
+
168
+ /**
169
+ * Gets the payload content as a UTF-8 string.
170
+ * Only meaningful for text message types.
171
+ * @returns {string} Decoded payload content
172
+ */
173
+ getContent() {
174
+ return new TextDecoder().decode(this.payload);
175
+ }
176
+
177
+ /**
178
+ * Gets the message ID as a hex string.
179
+ * @returns {string} Message ID hex string
180
+ */
181
+ getMessageId() {
182
+ return this.header.getMessageIdHex();
183
+ }
184
+
185
+ /**
186
+ * Gets the total size of the message in bytes.
187
+ * @returns {number} Total message size
188
+ */
189
+ getSize() {
190
+ return HEADER_SIZE + this.payload.length;
191
+ }
192
+
193
+ /**
194
+ * Increments the hop count. Used when relaying messages.
195
+ * @throws {MessageError} If max hops exceeded
196
+ */
197
+ incrementHopCount() {
198
+ if (this.header.hopCount >= this.header.maxHops) {
199
+ throw MessageError.maxHopsExceeded(this.getMessageId(), {
200
+ hopCount: this.header.hopCount,
201
+ maxHops: this.header.maxHops
202
+ });
203
+ }
204
+ this.header.hopCount++;
205
+ }
206
+
207
+ /**
208
+ * Creates a clone of this message.
209
+ * @returns {Message} Cloned message
210
+ */
211
+ clone() {
212
+ const headerClone = new MessageHeader({
213
+ version: this.header.version,
214
+ type: this.header.type,
215
+ flags: this.header.flags,
216
+ hopCount: this.header.hopCount,
217
+ maxHops: this.header.maxHops,
218
+ messageId: new Uint8Array(this.header.messageId),
219
+ timestamp: this.header.timestamp,
220
+ expiresAt: this.header.expiresAt,
221
+ payloadLength: this.header.payloadLength,
222
+ fragmentIndex: this.header.fragmentIndex,
223
+ fragmentTotal: this.header.fragmentTotal,
224
+ checksum: this.header.checksum
225
+ });
226
+
227
+ return new Message(headerClone, new Uint8Array(this.payload));
228
+ }
229
+ }
230
+
231
+ module.exports = {
232
+ Message
233
+ };
@@ -0,0 +1,186 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Binary serialization for mesh protocol messages.
5
+ * @module protocol/serializer
6
+ */
7
+
8
+ const { HEADER_SIZE } = require('./header');
9
+ const { Message } = require('./message');
10
+ const { crc32 } = require('./crc32');
11
+ const { PROTOCOL_VERSION, MESSAGE_FLAGS, MESH_CONFIG } = require('../constants');
12
+ const { MessageError } = require('../errors');
13
+
14
+ /**
15
+ * Serializes a message header to bytes.
16
+ * Calculates CRC32 checksum and includes it in the output.
17
+ *
18
+ * @param {MessageHeader|Object} header - Header to serialize
19
+ * @returns {Uint8Array} 48-byte serialized header
20
+ * @throws {MessageError} If header is invalid
21
+ *
22
+ * @example
23
+ * const header = MessageHeader.create({ type: MESSAGE_TYPE.TEXT, payloadLength: 5 });
24
+ * const bytes = serializeHeader(header);
25
+ */
26
+ function serializeHeader(header) {
27
+ if (!header || typeof header !== 'object') {
28
+ throw MessageError.invalidFormat(null, { reason: 'Header must be an object' });
29
+ }
30
+
31
+ const buffer = new Uint8Array(HEADER_SIZE);
32
+ const view = new DataView(buffer.buffer);
33
+
34
+ // Validate required fields
35
+ if (header.messageId === null || header.messageId === undefined || header.messageId.length !== 16) {
36
+ throw new Error('Invalid messageId');
37
+ }
38
+
39
+ // Byte 0: version
40
+ buffer[0] = header.version ?? PROTOCOL_VERSION;
41
+
42
+ // Byte 1: type
43
+ buffer[1] = header.type;
44
+
45
+ // Byte 2: flags
46
+ buffer[2] = header.flags ?? MESSAGE_FLAGS.NONE;
47
+
48
+ // Byte 3: hopCount
49
+ buffer[3] = header.hopCount ?? 0;
50
+
51
+ // Byte 4: maxHops
52
+ buffer[4] = header.maxHops ?? MESH_CONFIG.MAX_HOPS;
53
+
54
+ // Bytes 5-7: reserved (already zeros)
55
+
56
+ // Bytes 8-23: messageId (16 bytes)
57
+ buffer.set(header.messageId, 8);
58
+
59
+ // Bytes 24-31: timestamp (big-endian uint64)
60
+ writeUint64BE(view, 24, header.timestamp);
61
+
62
+ // Bytes 32-39: expiresAt (big-endian uint64)
63
+ writeUint64BE(view, 32, header.expiresAt);
64
+
65
+ // Bytes 40-41: payloadLength (big-endian uint16)
66
+ view.setUint16(40, header.payloadLength, false);
67
+
68
+ // Byte 42: fragmentIndex
69
+ buffer[42] = header.fragmentIndex ?? 0;
70
+
71
+ // Byte 43: fragmentTotal
72
+ buffer[43] = header.fragmentTotal ?? 1;
73
+
74
+ // Bytes 44-47: checksum (calculated over bytes 0-43)
75
+ const checksumData = buffer.slice(0, 44);
76
+ const checksum = crc32(checksumData);
77
+ view.setUint32(44, checksum, false);
78
+
79
+ return buffer;
80
+ }
81
+
82
+ /**
83
+ * Serializes a complete message (header + payload) to bytes.
84
+ *
85
+ * @param {Message|Object} message - Message to serialize
86
+ * @returns {Uint8Array} Serialized message bytes
87
+ * @throws {MessageError} If message is invalid
88
+ *
89
+ * @example
90
+ * const message = Message.create({ type: MESSAGE_TYPE.TEXT, payload: 'Hello' });
91
+ * const bytes = serialize(message);
92
+ */
93
+ function serialize(message) {
94
+ if (!message || typeof message !== 'object') {
95
+ throw MessageError.invalidFormat(null, { reason: 'Message must be an object' });
96
+ }
97
+
98
+ // Handle Message instances
99
+ if (message instanceof Message) {
100
+ return message.toBytes();
101
+ }
102
+
103
+ // Handle plain objects with header and payload
104
+ const header = message.header;
105
+ let payload = message.payload;
106
+
107
+ if (!header) {
108
+ throw MessageError.invalidFormat(null, { reason: 'Message must have a header' });
109
+ }
110
+
111
+ // Convert string payload to bytes
112
+ if (typeof payload === 'string') {
113
+ payload = new TextEncoder().encode(payload);
114
+ }
115
+
116
+ // Default to empty payload
117
+ if (!payload) {
118
+ payload = new Uint8Array(0);
119
+ }
120
+
121
+ if (!(payload instanceof Uint8Array)) {
122
+ throw MessageError.invalidFormat(null, { reason: 'Payload must be Uint8Array or string' });
123
+ }
124
+
125
+ // Update payloadLength in header
126
+ const headerWithLength = {
127
+ ...header,
128
+ payloadLength: payload.length
129
+ };
130
+
131
+ const headerBytes = serializeHeader(headerWithLength);
132
+ const result = new Uint8Array(headerBytes.length + payload.length);
133
+
134
+ result.set(headerBytes, 0);
135
+ result.set(payload, headerBytes.length);
136
+
137
+ return result;
138
+ }
139
+
140
+ /**
141
+ * Writes a 64-bit unsigned integer in big-endian format.
142
+ * JavaScript numbers can safely represent integers up to 2^53.
143
+ *
144
+ * @param {DataView} view - DataView to write to
145
+ * @param {number} offset - Byte offset
146
+ * @param {number} value - Value to write
147
+ */
148
+ function writeUint64BE(view, offset, value) {
149
+ // Split into high and low 32-bit parts
150
+ const high = Math.floor(value / 0x100000000);
151
+ const low = value >>> 0;
152
+
153
+ view.setUint32(offset, high, false);
154
+ view.setUint32(offset + 4, low, false);
155
+ }
156
+
157
+ /**
158
+ * Serializes multiple messages into a single buffer.
159
+ * Useful for batch transmission.
160
+ *
161
+ * @param {Array<Message>} messages - Array of messages
162
+ * @returns {Uint8Array} Concatenated message bytes
163
+ */
164
+ function serializeBatch(messages) {
165
+ if (!Array.isArray(messages)) {
166
+ throw MessageError.invalidFormat(null, { reason: 'Messages must be an array' });
167
+ }
168
+
169
+ const serialized = messages.map(msg => serialize(msg));
170
+ const totalLength = serialized.reduce((sum, arr) => sum + arr.length, 0);
171
+ const result = new Uint8Array(totalLength);
172
+
173
+ let offset = 0;
174
+ for (const bytes of serialized) {
175
+ result.set(bytes, offset);
176
+ offset += bytes.length;
177
+ }
178
+
179
+ return result;
180
+ }
181
+
182
+ module.exports = {
183
+ serialize,
184
+ serializeHeader,
185
+ serializeBatch
186
+ };
@@ -0,0 +1,276 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Message and header validation for mesh protocol.
5
+ * @module protocol/validator
6
+ */
7
+
8
+ const { HEADER_SIZE } = require('./header');
9
+ const { crc32 } = require('./crc32');
10
+ const { PROTOCOL_VERSION, MESSAGE_TYPE, MESH_CONFIG } = require('../constants');
11
+
12
+ /**
13
+ * Set of valid message type values for fast lookup.
14
+ * @type {Set<number>}
15
+ */
16
+ const VALID_MESSAGE_TYPES = new Set(Object.values(MESSAGE_TYPE));
17
+
18
+ /**
19
+ * Validates a message header.
20
+ *
21
+ * @param {MessageHeader|Object} header - Header to validate
22
+ * @returns {{ valid: boolean, errors: string[] }} Validation result
23
+ *
24
+ * @example
25
+ * const result = validateHeader(header);
26
+ * if (!result.valid) {
27
+ * console.error('Header errors:', result.errors);
28
+ * }
29
+ */
30
+ function validateHeader(header) {
31
+ const errors = [];
32
+
33
+ if (!header || typeof header !== 'object') {
34
+ return { valid: false, errors: ['Header must be an object'] };
35
+ }
36
+
37
+ // Validate protocol version
38
+ if (header.version !== PROTOCOL_VERSION) {
39
+ errors.push(`Unsupported protocol version: ${header.version}, expected: ${PROTOCOL_VERSION}`);
40
+ }
41
+
42
+ // Validate message type
43
+ if (!VALID_MESSAGE_TYPES.has(header.type)) {
44
+ errors.push(`Invalid message type: 0x${header.type?.toString(16) ?? 'undefined'}`);
45
+ }
46
+
47
+ // Validate hop count
48
+ if (typeof header.hopCount !== 'number' || header.hopCount < 0) {
49
+ errors.push(`Invalid hop count: ${header.hopCount}`);
50
+ }
51
+
52
+ // Validate max hops
53
+ if (typeof header.maxHops !== 'number' || header.maxHops < 1) {
54
+ errors.push(`Invalid max hops: ${header.maxHops}`);
55
+ }
56
+
57
+ // Validate hop count vs max hops
58
+ if (header.hopCount > header.maxHops) {
59
+ errors.push(`Hop count (${header.hopCount}) exceeds max hops (${header.maxHops})`);
60
+ }
61
+
62
+ // Validate message ID
63
+ if (!header.messageId || !(header.messageId instanceof Uint8Array)) {
64
+ errors.push('Message ID must be a Uint8Array');
65
+ } else if (header.messageId.length !== 16) {
66
+ errors.push(`Message ID must be 16 bytes, got ${header.messageId.length}`);
67
+ }
68
+
69
+ // Validate timestamps
70
+ if (typeof header.timestamp !== 'number' || header.timestamp <= 0) {
71
+ errors.push(`Invalid timestamp: ${header.timestamp}`);
72
+ }
73
+
74
+ if (typeof header.expiresAt !== 'number' || header.expiresAt <= 0) {
75
+ errors.push(`Invalid expiresAt: ${header.expiresAt}`);
76
+ }
77
+
78
+ // Check if expired
79
+ if (header.expiresAt <= Date.now()) {
80
+ errors.push('Message has expired');
81
+ }
82
+
83
+ // Validate payload length
84
+ if (typeof header.payloadLength !== 'number' || header.payloadLength < 0) {
85
+ errors.push(`Invalid payload length: ${header.payloadLength}`);
86
+ }
87
+
88
+ if (header.payloadLength > MESH_CONFIG.MAX_MESSAGE_SIZE) {
89
+ errors.push(`Payload too large: ${header.payloadLength} > ${MESH_CONFIG.MAX_MESSAGE_SIZE}`);
90
+ }
91
+
92
+ // Validate fragment fields
93
+ if (typeof header.fragmentIndex !== 'number' || header.fragmentIndex < 0) {
94
+ errors.push(`Invalid fragment index: ${header.fragmentIndex}`);
95
+ }
96
+
97
+ if (typeof header.fragmentTotal !== 'number' || header.fragmentTotal < 1) {
98
+ errors.push(`Invalid fragment total: ${header.fragmentTotal}`);
99
+ }
100
+
101
+ if (header.fragmentIndex >= header.fragmentTotal) {
102
+ errors.push(`Fragment index (${header.fragmentIndex}) >= total (${header.fragmentTotal})`);
103
+ }
104
+
105
+ return {
106
+ valid: errors.length === 0,
107
+ errors
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Validates a complete message (header + payload).
113
+ *
114
+ * @param {Message|Object} message - Message to validate
115
+ * @returns {{ valid: boolean, errors: string[] }} Validation result
116
+ *
117
+ * @example
118
+ * const result = validateMessage(message);
119
+ * if (!result.valid) {
120
+ * console.error('Message errors:', result.errors);
121
+ * }
122
+ */
123
+ function validateMessage(message) {
124
+ const errors = [];
125
+
126
+ if (!message || typeof message !== 'object') {
127
+ return { valid: false, errors: ['Message must be an object'] };
128
+ }
129
+
130
+ // Validate header exists
131
+ if (!message.header) {
132
+ errors.push('Message must have a header');
133
+ return { valid: false, errors };
134
+ }
135
+
136
+ // Validate header
137
+ const headerResult = validateHeader(message.header);
138
+ errors.push(...headerResult.errors);
139
+
140
+ // Validate payload exists
141
+ if (!message.payload) {
142
+ errors.push('Message must have a payload');
143
+ } else if (!(message.payload instanceof Uint8Array)) {
144
+ errors.push('Payload must be a Uint8Array');
145
+ } else {
146
+ // Validate payload length matches header
147
+ if (message.payload.length !== message.header.payloadLength) {
148
+ errors.push(
149
+ `Payload length mismatch: header says ${message.header.payloadLength}, ` +
150
+ `actual is ${message.payload.length}`
151
+ );
152
+ }
153
+ }
154
+
155
+ return {
156
+ valid: errors.length === 0,
157
+ errors
158
+ };
159
+ }
160
+
161
+ /**
162
+ * Validates message checksum against the header data.
163
+ *
164
+ * @param {Uint8Array} headerBytes - Raw 48-byte header
165
+ * @returns {{ valid: boolean, expected: number, actual: number }} Checksum result
166
+ */
167
+ function validateChecksum(headerBytes) {
168
+ if (!(headerBytes instanceof Uint8Array) || headerBytes.length < HEADER_SIZE) {
169
+ return { valid: false, expected: 0, actual: 0 };
170
+ }
171
+
172
+ const view = new DataView(headerBytes.buffer, headerBytes.byteOffset, HEADER_SIZE);
173
+ const storedChecksum = view.getUint32(44, false);
174
+ const checksumData = headerBytes.slice(0, 44);
175
+ const calculatedChecksum = crc32(checksumData);
176
+
177
+ return {
178
+ valid: storedChecksum === calculatedChecksum,
179
+ expected: storedChecksum,
180
+ actual: calculatedChecksum
181
+ };
182
+ }
183
+
184
+ /**
185
+ * Checks if a message type is valid.
186
+ *
187
+ * @param {number} type - Message type to check
188
+ * @returns {boolean} True if valid
189
+ */
190
+ function isValidMessageType(type) {
191
+ return VALID_MESSAGE_TYPES.has(type);
192
+ }
193
+
194
+ /**
195
+ * Checks if a message is expired.
196
+ *
197
+ * @param {Message|MessageHeader|Object} messageOrHeader - Message or header
198
+ * @returns {boolean} True if expired
199
+ */
200
+ function isExpired(messageOrHeader) {
201
+ const header = messageOrHeader.header || messageOrHeader;
202
+ return header.expiresAt <= Date.now();
203
+ }
204
+
205
+ /**
206
+ * Checks if hop count has exceeded maximum.
207
+ *
208
+ * @param {Message|MessageHeader|Object} messageOrHeader - Message or header
209
+ * @returns {boolean} True if exceeded
210
+ */
211
+ function hasExceededMaxHops(messageOrHeader) {
212
+ const header = messageOrHeader.header || messageOrHeader;
213
+ return header.hopCount > header.maxHops;
214
+ }
215
+
216
+ /**
217
+ * Validates raw bytes can be parsed as a valid message.
218
+ * Does not fully parse, just validates structure.
219
+ *
220
+ * @param {Uint8Array} data - Raw message bytes
221
+ * @returns {{ valid: boolean, errors: string[] }} Validation result
222
+ */
223
+ function validateRawMessage(data) {
224
+ const errors = [];
225
+
226
+ if (!(data instanceof Uint8Array)) {
227
+ return { valid: false, errors: ['Data must be a Uint8Array'] };
228
+ }
229
+
230
+ if (data.length < HEADER_SIZE) {
231
+ return { valid: false, errors: [`Data too short: ${data.length} < ${HEADER_SIZE}`] };
232
+ }
233
+
234
+ // Check version
235
+ if (data[0] !== PROTOCOL_VERSION) {
236
+ errors.push(`Unsupported version: ${data[0]}`);
237
+ }
238
+
239
+ // Check message type
240
+ if (!VALID_MESSAGE_TYPES.has(data[1])) {
241
+ errors.push(`Invalid message type: 0x${data[1].toString(16)}`);
242
+ }
243
+
244
+ // Validate checksum
245
+ const checksumResult = validateChecksum(data.slice(0, HEADER_SIZE));
246
+ if (!checksumResult.valid) {
247
+ errors.push(
248
+ `Checksum mismatch: expected 0x${checksumResult.expected.toString(16)}, ` +
249
+ `got 0x${checksumResult.actual.toString(16)}`
250
+ );
251
+ }
252
+
253
+ // Check payload length
254
+ const view = new DataView(data.buffer, data.byteOffset, HEADER_SIZE);
255
+ const payloadLength = view.getUint16(40, false);
256
+ const expectedTotal = HEADER_SIZE + payloadLength;
257
+
258
+ if (data.length < expectedTotal) {
259
+ errors.push(`Incomplete message: expected ${expectedTotal} bytes, got ${data.length}`);
260
+ }
261
+
262
+ return {
263
+ valid: errors.length === 0,
264
+ errors
265
+ };
266
+ }
267
+
268
+ module.exports = {
269
+ validateMessage,
270
+ validateHeader,
271
+ validateChecksum,
272
+ validateRawMessage,
273
+ isValidMessageType,
274
+ isExpired,
275
+ hasExceededMaxHops
276
+ };