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.
- package/CHANGELOG.md +151 -0
- package/LICENSE +21 -0
- package/README.md +706 -0
- package/docs/API.md +462 -0
- package/docs/ARCHITECTURE.md +384 -0
- package/docs/CONTRIBUTING.md +244 -0
- package/docs/NODE_QUICKSTART.md +259 -0
- package/docs/PROTOCOL.md +195 -0
- package/docs/REACT_NATIVE.md +315 -0
- package/docs/SECURITY.md +152 -0
- package/docs/api/constants_audio.js.html +184 -0
- package/docs/api/constants_ble.js.html +165 -0
- package/docs/api/constants_crypto.js.html +107 -0
- package/docs/api/constants_errors.js.html +256 -0
- package/docs/api/constants_events.js.html +148 -0
- package/docs/api/constants_index.js.html +76 -0
- package/docs/api/constants_protocol.js.html +205 -0
- package/docs/api/crypto_aead.js.html +243 -0
- package/docs/api/crypto_chacha20.js.html +235 -0
- package/docs/api/crypto_hkdf.js.html +241 -0
- package/docs/api/crypto_hmac.js.html +197 -0
- package/docs/api/crypto_index.js.html +126 -0
- package/docs/api/crypto_keys_KeyManager.js.html +325 -0
- package/docs/api/crypto_keys_KeyPair.js.html +270 -0
- package/docs/api/crypto_keys_SecureStorage.js.html +273 -0
- package/docs/api/crypto_keys_index.js.html +86 -0
- package/docs/api/crypto_noise_handshake.js.html +464 -0
- package/docs/api/crypto_noise_index.js.html +81 -0
- package/docs/api/crypto_noise_session.js.html +307 -0
- package/docs/api/crypto_noise_state.js.html +322 -0
- package/docs/api/crypto_poly1305.js.html +167 -0
- package/docs/api/crypto_sha256.js.html +294 -0
- package/docs/api/crypto_x25519.js.html +208 -0
- package/docs/api/errors_AudioError.js.html +218 -0
- package/docs/api/errors_ConnectionError.js.html +163 -0
- package/docs/api/errors_CryptoError.js.html +157 -0
- package/docs/api/errors_HandshakeError.js.html +176 -0
- package/docs/api/errors_MeshError.js.html +154 -0
- package/docs/api/errors_MessageError.js.html +183 -0
- package/docs/api/errors_ValidationError.js.html +204 -0
- package/docs/api/errors_index.js.html +78 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/api/hooks_AppStateManager.js.html +233 -0
- package/docs/api/hooks_index.js.html +87 -0
- package/docs/api/hooks_useMesh.js.html +213 -0
- package/docs/api/hooks_useMessages.js.html +263 -0
- package/docs/api/hooks_usePeers.js.html +165 -0
- package/docs/api/index.html +868 -0
- package/docs/api/index.js.html +236 -0
- package/docs/api/mesh_dedup_BloomFilter.js.html +261 -0
- package/docs/api/mesh_dedup_DedupManager.js.html +266 -0
- package/docs/api/mesh_dedup_MessageCache.js.html +273 -0
- package/docs/api/mesh_dedup_index.js.html +70 -0
- package/docs/api/mesh_fragment_Assembler.js.html +335 -0
- package/docs/api/mesh_fragment_Fragmenter.js.html +230 -0
- package/docs/api/mesh_fragment_index.js.html +75 -0
- package/docs/api/mesh_index.js.html +72 -0
- package/docs/api/mesh_peer_Peer.js.html +296 -0
- package/docs/api/mesh_peer_PeerDiscovery.js.html +334 -0
- package/docs/api/mesh_peer_PeerManager.js.html +320 -0
- package/docs/api/mesh_peer_index.js.html +70 -0
- package/docs/api/mesh_router_MessageRouter.js.html +411 -0
- package/docs/api/mesh_router_PathFinder.js.html +386 -0
- package/docs/api/mesh_router_RouteTable.js.html +346 -0
- package/docs/api/mesh_router_index.js.html +70 -0
- package/docs/api/module-audio_buffer.html +168 -0
- package/docs/api/module-audio_buffer_FrameBuffer-FrameBuffer.html +2971 -0
- package/docs/api/module-audio_buffer_FrameBuffer.html +178 -0
- package/docs/api/module-audio_buffer_JitterBuffer-JitterBuffer.html +2761 -0
- package/docs/api/module-audio_buffer_JitterBuffer.html +178 -0
- package/docs/api/module-audio_codec.html +168 -0
- package/docs/api/module-audio_codec_LC3Codec-LC3Codec.html +2876 -0
- package/docs/api/module-audio_codec_LC3Codec.html +178 -0
- package/docs/api/module-audio_codec_LC3Decoder-LC3Decoder.html +1788 -0
- package/docs/api/module-audio_codec_LC3Decoder.html +178 -0
- package/docs/api/module-audio_codec_LC3Encoder-LC3Encoder.html +1512 -0
- package/docs/api/module-audio_codec_LC3Encoder.html +178 -0
- package/docs/api/module-audio_session.html +168 -0
- package/docs/api/module-audio_session_AudioSession-AudioSession.html +3922 -0
- package/docs/api/module-audio_session_AudioSession.html +178 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessage.html +3690 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessageRecorder.html +1780 -0
- package/docs/api/module-audio_session_VoiceMessage.html +332 -0
- package/docs/api/module-audio_transport.html +168 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioAssembler.html +1545 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioFragmenter.html +658 -0
- package/docs/api/module-audio_transport_AudioFragmenter.html +181 -0
- package/docs/api/module-audio_transport_AudioFramer.html +1414 -0
- package/docs/api/module-constants.html +168 -0
- package/docs/api/module-constants_audio.html +1782 -0
- package/docs/api/module-constants_ble.html +940 -0
- package/docs/api/module-constants_crypto.html +823 -0
- package/docs/api/module-constants_errors.html +316 -0
- package/docs/api/module-constants_events.html +244 -0
- package/docs/api/module-constants_protocol.html +1534 -0
- package/docs/api/module-crypto.html +169 -0
- package/docs/api/module-crypto_aead.html +1625 -0
- package/docs/api/module-crypto_chacha20.html +1440 -0
- package/docs/api/module-crypto_hkdf.html +1421 -0
- package/docs/api/module-crypto_hmac.html +828 -0
- package/docs/api/module-crypto_keys.html +169 -0
- package/docs/api/module-crypto_keys_KeyManager-KeyManager.html +2364 -0
- package/docs/api/module-crypto_keys_KeyManager.html +252 -0
- package/docs/api/module-crypto_keys_KeyPair.html +245 -0
- package/docs/api/module-crypto_keys_SecureStorage-MemorySecureStorage.html +923 -0
- package/docs/api/module-crypto_keys_SecureStorage-SecureStorage.html +942 -0
- package/docs/api/module-crypto_keys_SecureStorage.html +516 -0
- package/docs/api/module-crypto_noise.html +169 -0
- package/docs/api/module-crypto_noise_handshake-NoiseHandshake.html +2240 -0
- package/docs/api/module-crypto_noise_handshake.html +782 -0
- package/docs/api/module-crypto_noise_session-NoiseSession.html +1804 -0
- package/docs/api/module-crypto_noise_session.html +325 -0
- package/docs/api/module-crypto_noise_state-SymmetricState.html +1387 -0
- package/docs/api/module-crypto_noise_state.html +324 -0
- package/docs/api/module-crypto_poly1305.html +884 -0
- package/docs/api/module-crypto_sha256-HashContext.html +447 -0
- package/docs/api/module-crypto_sha256.html +942 -0
- package/docs/api/module-crypto_x25519.html +1503 -0
- package/docs/api/module-errors.html +168 -0
- package/docs/api/module-errors_AudioError-AudioError.html +4711 -0
- package/docs/api/module-errors_AudioError.html +178 -0
- package/docs/api/module-errors_ConnectionError-ConnectionError.html +3649 -0
- package/docs/api/module-errors_ConnectionError.html +178 -0
- package/docs/api/module-errors_CryptoError-CryptoError.html +3453 -0
- package/docs/api/module-errors_CryptoError.html +178 -0
- package/docs/api/module-errors_HandshakeError-HandshakeError.html +4261 -0
- package/docs/api/module-errors_HandshakeError.html +178 -0
- package/docs/api/module-errors_MeshError-MeshError.html +2155 -0
- package/docs/api/module-errors_MeshError.html +178 -0
- package/docs/api/module-errors_MessageError-MessageError.html +4545 -0
- package/docs/api/module-errors_MessageError.html +178 -0
- package/docs/api/module-errors_ValidationError-ValidationError.html +3432 -0
- package/docs/api/module-errors_ValidationError.html +178 -0
- package/docs/api/module-hooks.html +182 -0
- package/docs/api/module-hooks_AppStateManager-AppStateManager.html +1620 -0
- package/docs/api/module-hooks_AppStateManager.html +178 -0
- package/docs/api/module-hooks_useMesh.html +457 -0
- package/docs/api/module-hooks_useMessages.html +466 -0
- package/docs/api/module-hooks_usePeers.html +348 -0
- package/docs/api/module-mesh.html +168 -0
- package/docs/api/module-mesh_dedup.html +168 -0
- package/docs/api/module-mesh_dedup_BloomFilter-BloomFilter.html +2158 -0
- package/docs/api/module-mesh_dedup_BloomFilter.html +178 -0
- package/docs/api/module-mesh_dedup_DedupManager-DedupManager.html +2880 -0
- package/docs/api/module-mesh_dedup_DedupManager.html +178 -0
- package/docs/api/module-mesh_dedup_MessageCache-CacheNode.html +246 -0
- package/docs/api/module-mesh_dedup_MessageCache-MessageCache.html +2314 -0
- package/docs/api/module-mesh_dedup_MessageCache.html +181 -0
- package/docs/api/module-mesh_fragment.html +168 -0
- package/docs/api/module-mesh_fragment_Assembler-Assembler.html +2869 -0
- package/docs/api/module-mesh_fragment_Assembler-PendingFragmentSet.html +895 -0
- package/docs/api/module-mesh_fragment_Assembler.html +181 -0
- package/docs/api/module-mesh_fragment_Fragmenter.html +1084 -0
- package/docs/api/module-mesh_peer.html +168 -0
- package/docs/api/module-mesh_peer_Peer-Peer.html +4986 -0
- package/docs/api/module-mesh_peer_Peer.html +178 -0
- package/docs/api/module-mesh_peer_PeerDiscovery-PeerDiscovery.html +3423 -0
- package/docs/api/module-mesh_peer_PeerDiscovery.html +438 -0
- package/docs/api/module-mesh_peer_PeerManager-PeerManager.html +5258 -0
- package/docs/api/module-mesh_peer_PeerManager.html +178 -0
- package/docs/api/module-mesh_router.html +168 -0
- package/docs/api/module-mesh_router_MessageRouter-MessageRouter.html +3285 -0
- package/docs/api/module-mesh_router_MessageRouter.html +178 -0
- package/docs/api/module-mesh_router_PathFinder-PathFinder.html +3323 -0
- package/docs/api/module-mesh_router_PathFinder.html +421 -0
- package/docs/api/module-mesh_router_RouteTable-RouteTable.html +4115 -0
- package/docs/api/module-mesh_router_RouteTable.html +421 -0
- package/docs/api/module-protocol.html +169 -0
- package/docs/api/module-protocol_crc32.html +815 -0
- package/docs/api/module-protocol_deserializer.html +1393 -0
- package/docs/api/module-protocol_header-MessageHeader.html +2879 -0
- package/docs/api/module-protocol_header.html +892 -0
- package/docs/api/module-protocol_message-Message.html +4682 -0
- package/docs/api/module-protocol_message.html +178 -0
- package/docs/api/module-protocol_serializer.html +911 -0
- package/docs/api/module-protocol_validator.html +1396 -0
- package/docs/api/module-rn-ble-mesh.html +866 -0
- package/docs/api/module-service.html +168 -0
- package/docs/api/module-service_HandshakeManager-HandshakeManager.html +185 -0
- package/docs/api/module-service_HandshakeManager.html +175 -0
- package/docs/api/module-service_MeshService-MeshService.html +185 -0
- package/docs/api/module-service_MeshService.html +175 -0
- package/docs/api/module-service_SessionManager-SessionManager.html +174 -0
- package/docs/api/module-service_SessionManager.html +175 -0
- package/docs/api/module-service_audio.html +168 -0
- package/docs/api/module-service_audio_AudioManager-AudioManager.html +4653 -0
- package/docs/api/module-service_audio_AudioManager.html +254 -0
- package/docs/api/module-service_text.html +168 -0
- package/docs/api/module-service_text_TextManager-TextManager.html +6104 -0
- package/docs/api/module-service_text_TextManager.html +254 -0
- package/docs/api/module-service_text_broadcast.html +168 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager-BroadcastManager.html +2434 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager.html +254 -0
- package/docs/api/module-service_text_channel.html +168 -0
- package/docs/api/module-service_text_channel_Channel-Channel.html +4337 -0
- package/docs/api/module-service_text_channel_Channel.html +178 -0
- package/docs/api/module-service_text_channel_ChannelManager-ChannelManager.html +1927 -0
- package/docs/api/module-service_text_channel_ChannelManager.html +175 -0
- package/docs/api/module-service_text_message.html +168 -0
- package/docs/api/module-service_text_message_TextMessage-TextMessage.html +4162 -0
- package/docs/api/module-service_text_message_TextMessage.html +178 -0
- package/docs/api/module-service_text_message_TextSerializer.html +1725 -0
- package/docs/api/module-storage.html +168 -0
- package/docs/api/module-storage_AsyncStorageAdapter-AsyncStorageAdapter.html +4159 -0
- package/docs/api/module-storage_AsyncStorageAdapter.html +178 -0
- package/docs/api/module-storage_MemoryStorage-MemoryStorage.html +3154 -0
- package/docs/api/module-storage_MemoryStorage.html +178 -0
- package/docs/api/module-storage_MessageStore-MessageStore.html +5299 -0
- package/docs/api/module-storage_MessageStore.html +178 -0
- package/docs/api/module-storage_Storage-Storage.html +4169 -0
- package/docs/api/module-storage_Storage.html +178 -0
- package/docs/api/module-transport.html +168 -0
- package/docs/api/module-transport_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_BLEAdapter.html +178 -0
- package/docs/api/module-transport_BLETransport-BLETransport.html +3263 -0
- package/docs/api/module-transport_BLETransport.html +178 -0
- package/docs/api/module-transport_MockTransport-MockTransport.html +3947 -0
- package/docs/api/module-transport_MockTransport.html +178 -0
- package/docs/api/module-transport_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_RNBLEAdapter.html +178 -0
- package/docs/api/module-transport_Transport-Transport.html +4071 -0
- package/docs/api/module-transport_Transport.html +254 -0
- package/docs/api/module-transport_adapters.html +168 -0
- package/docs/api/module-transport_adapters_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_adapters_BLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter.html +178 -0
- package/docs/api/module-utils.html +168 -0
- package/docs/api/module-utils_BoundedMap-BoundedMap.html +3301 -0
- package/docs/api/module-utils_BoundedMap.html +178 -0
- package/docs/api/module-utils_EventEmitter-EventEmitter.html +3358 -0
- package/docs/api/module-utils_EventEmitter.html +178 -0
- package/docs/api/module-utils_LRUCache-LRUCache.html +4134 -0
- package/docs/api/module-utils_LRUCache.html +178 -0
- package/docs/api/module-utils_RateLimiter-RateLimiter.html +2176 -0
- package/docs/api/module-utils_RateLimiter.html +500 -0
- package/docs/api/module-utils_TimeoutManager-TimeoutManager.html +1781 -0
- package/docs/api/module-utils_TimeoutManager.html +175 -0
- package/docs/api/module-utils_bytes.html +1789 -0
- package/docs/api/module-utils_debug.html +837 -0
- package/docs/api/module-utils_encoding.html +1184 -0
- package/docs/api/module-utils_retry.html +1457 -0
- package/docs/api/module-utils_time.html +1665 -0
- package/docs/api/module-utils_uuid.html +1269 -0
- package/docs/api/module-utils_validation.html +2176 -0
- package/docs/api/protocol_crc32.js.html +147 -0
- package/docs/api/protocol_deserializer.js.html +295 -0
- package/docs/api/protocol_header.js.html +276 -0
- package/docs/api/protocol_index.js.html +120 -0
- package/docs/api/protocol_message.js.html +287 -0
- package/docs/api/protocol_serializer.js.html +240 -0
- package/docs/api/protocol_validator.js.html +330 -0
- package/docs/api/scripts/linenumber.js +25 -0
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/prettify/lang-css.js +2 -0
- package/docs/api/scripts/prettify/prettify.js +28 -0
- package/docs/api/service_HandshakeManager.js.html +232 -0
- package/docs/api/service_MeshService.js.html +371 -0
- package/docs/api/service_SessionManager.js.html +153 -0
- package/docs/api/service_audio_AudioManager.js.html +541 -0
- package/docs/api/service_audio_buffer_FrameBuffer.js.html +223 -0
- package/docs/api/service_audio_buffer_JitterBuffer.js.html +244 -0
- package/docs/api/service_audio_buffer_index.js.html +68 -0
- package/docs/api/service_audio_codec_LC3Codec.js.html +345 -0
- package/docs/api/service_audio_codec_LC3Decoder.js.html +185 -0
- package/docs/api/service_audio_codec_LC3Encoder.js.html +194 -0
- package/docs/api/service_audio_codec_index.js.html +70 -0
- package/docs/api/service_audio_index.js.html +96 -0
- package/docs/api/service_audio_session_AudioSession.js.html +348 -0
- package/docs/api/service_audio_session_VoiceMessage.js.html +432 -0
- package/docs/api/service_audio_session_index.js.html +70 -0
- package/docs/api/service_audio_transport_AudioFragmenter.js.html +314 -0
- package/docs/api/service_audio_transport_AudioFramer.js.html +236 -0
- package/docs/api/service_audio_transport_index.js.html +69 -0
- package/docs/api/service_index.js.html +93 -0
- package/docs/api/service_text_TextManager.js.html +578 -0
- package/docs/api/service_text_broadcast_BroadcastManager.js.html +276 -0
- package/docs/api/service_text_broadcast_index.js.html +66 -0
- package/docs/api/service_text_channel_Channel.js.html +280 -0
- package/docs/api/service_text_channel_ChannelManager.js.html +225 -0
- package/docs/api/service_text_channel_index.js.html +68 -0
- package/docs/api/service_text_index.js.html +85 -0
- package/docs/api/service_text_message_TextMessage.js.html +350 -0
- package/docs/api/service_text_message_TextSerializer.js.html +218 -0
- package/docs/api/service_text_message_index.js.html +68 -0
- package/docs/api/storage_AsyncStorageAdapter.js.html +357 -0
- package/docs/api/storage_MemoryStorage.js.html +279 -0
- package/docs/api/storage_MessageStore.js.html +369 -0
- package/docs/api/storage_Storage.js.html +214 -0
- package/docs/api/storage_index.js.html +72 -0
- package/docs/api/styles/jsdoc-default.css +358 -0
- package/docs/api/styles/prettify-jsdoc.css +111 -0
- package/docs/api/styles/prettify-tomorrow.css +132 -0
- package/docs/api/transport_BLEAdapter.js.html +231 -0
- package/docs/api/transport_BLETransport.js.html +411 -0
- package/docs/api/transport_MockTransport.js.html +339 -0
- package/docs/api/transport_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_Transport.js.html +242 -0
- package/docs/api/transport_adapters_BLEAdapter.js.html +231 -0
- package/docs/api/transport_adapters_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_adapters_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_adapters_index.js.html +70 -0
- package/docs/api/transport_index.js.html +87 -0
- package/docs/api/utils_BoundedMap.js.html +205 -0
- package/docs/api/utils_EventEmitter.js.html +259 -0
- package/docs/api/utils_LRUCache.js.html +256 -0
- package/docs/api/utils_RateLimiter.js.html +256 -0
- package/docs/api/utils_TimeoutManager.js.html +218 -0
- 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
- package/docs/api/utils_base64.js.html +205 -0
- package/docs/api/utils_bytes.js.html +241 -0
- package/docs/api/utils_debug.js.html +205 -0
- package/docs/api/utils_encoding.js.html +302 -0
- package/docs/api/utils_index.js.html +160 -0
- package/docs/api/utils_retry.js.html +200 -0
- package/docs/api/utils_time.js.html +220 -0
- package/docs/api/utils_uuid.js.html +199 -0
- package/docs/api/utils_validation.js.html +259 -0
- package/examples/node-chat/chat.js +220 -0
- package/examples/node-quickstart/index.js +94 -0
- package/examples/testing/test-helper.js +182 -0
- package/package.json +111 -0
- package/src/constants/audio.js +130 -0
- package/src/constants/ble.js +111 -0
- package/src/constants/crypto.js +53 -0
- package/src/constants/errors.js +202 -0
- package/src/constants/events.js +94 -0
- package/src/constants/index.js +22 -0
- package/src/constants/protocol.js +151 -0
- package/src/crypto/aead.js +189 -0
- package/src/crypto/chacha20.js +181 -0
- package/src/crypto/hkdf.js +187 -0
- package/src/crypto/hmac.js +143 -0
- package/src/crypto/index.js +72 -0
- package/src/crypto/keys/KeyManager.js +271 -0
- package/src/crypto/keys/KeyPair.js +216 -0
- package/src/crypto/keys/SecureStorage.js +219 -0
- package/src/crypto/keys/index.js +32 -0
- package/src/crypto/noise/handshake.js +410 -0
- package/src/crypto/noise/index.js +27 -0
- package/src/crypto/noise/session.js +253 -0
- package/src/crypto/noise/state.js +268 -0
- package/src/crypto/poly1305.js +113 -0
- package/src/crypto/sha256.js +240 -0
- package/src/crypto/x25519.js +154 -0
- package/src/errors/AudioError.js +164 -0
- package/src/errors/ConnectionError.js +109 -0
- package/src/errors/CryptoError.js +103 -0
- package/src/errors/HandshakeError.js +122 -0
- package/src/errors/MeshError.js +100 -0
- package/src/errors/MessageError.js +129 -0
- package/src/errors/ValidationError.js +150 -0
- package/src/errors/index.js +24 -0
- package/src/hooks/AppStateManager.js +179 -0
- package/src/hooks/index.js +33 -0
- package/src/hooks/useMesh.js +159 -0
- package/src/hooks/useMessages.js +209 -0
- package/src/hooks/usePeers.js +111 -0
- package/src/index.d.ts +494 -0
- package/src/index.js +182 -0
- package/src/index.mjs +62 -0
- package/src/mesh/dedup/BloomFilter.js +207 -0
- package/src/mesh/dedup/DedupManager.js +212 -0
- package/src/mesh/dedup/MessageCache.js +219 -0
- package/src/mesh/dedup/index.js +16 -0
- package/src/mesh/fragment/Assembler.js +281 -0
- package/src/mesh/fragment/Fragmenter.js +176 -0
- package/src/mesh/fragment/index.js +21 -0
- package/src/mesh/index.js +18 -0
- package/src/mesh/peer/Peer.js +242 -0
- package/src/mesh/peer/PeerDiscovery.js +280 -0
- package/src/mesh/peer/PeerManager.js +266 -0
- package/src/mesh/peer/index.js +16 -0
- package/src/mesh/router/MessageRouter.js +357 -0
- package/src/mesh/router/PathFinder.js +332 -0
- package/src/mesh/router/RouteTable.js +292 -0
- package/src/mesh/router/index.js +16 -0
- package/src/protocol/crc32.js +93 -0
- package/src/protocol/deserializer.js +241 -0
- package/src/protocol/header.js +222 -0
- package/src/protocol/index.js +66 -0
- package/src/protocol/message.js +233 -0
- package/src/protocol/serializer.js +186 -0
- package/src/protocol/validator.js +276 -0
- package/src/service/HandshakeManager.js +178 -0
- package/src/service/MeshService.js +317 -0
- package/src/service/SessionManager.js +99 -0
- package/src/service/audio/AudioManager.js +487 -0
- package/src/service/audio/buffer/FrameBuffer.js +169 -0
- package/src/service/audio/buffer/JitterBuffer.js +190 -0
- package/src/service/audio/buffer/index.js +14 -0
- package/src/service/audio/codec/LC3Codec.js +291 -0
- package/src/service/audio/codec/LC3Decoder.js +131 -0
- package/src/service/audio/codec/LC3Encoder.js +140 -0
- package/src/service/audio/codec/index.js +16 -0
- package/src/service/audio/index.js +42 -0
- package/src/service/audio/session/AudioSession.js +294 -0
- package/src/service/audio/session/VoiceMessage.js +378 -0
- package/src/service/audio/session/index.js +16 -0
- package/src/service/audio/transport/AudioFragmenter.js +260 -0
- package/src/service/audio/transport/AudioFramer.js +182 -0
- package/src/service/audio/transport/index.js +15 -0
- package/src/service/index.js +39 -0
- package/src/service/text/TextManager.js +524 -0
- package/src/service/text/broadcast/BroadcastManager.js +222 -0
- package/src/service/text/broadcast/index.js +12 -0
- package/src/service/text/channel/Channel.js +226 -0
- package/src/service/text/channel/ChannelManager.js +171 -0
- package/src/service/text/channel/index.js +14 -0
- package/src/service/text/index.js +31 -0
- package/src/service/text/message/TextMessage.js +296 -0
- package/src/service/text/message/TextSerializer.js +164 -0
- package/src/service/text/message/index.js +14 -0
- package/src/storage/AsyncStorageAdapter.js +303 -0
- package/src/storage/MemoryStorage.js +225 -0
- package/src/storage/MessageStore.js +315 -0
- package/src/storage/Storage.js +160 -0
- package/src/storage/index.js +18 -0
- package/src/transport/BLEAdapter.js +177 -0
- package/src/transport/BLETransport.js +357 -0
- package/src/transport/MockTransport.js +285 -0
- package/src/transport/NodeBLEAdapter.js +425 -0
- package/src/transport/RNBLEAdapter.js +328 -0
- package/src/transport/Transport.js +188 -0
- package/src/transport/adapters/BLEAdapter.js +177 -0
- package/src/transport/adapters/NodeBLEAdapter.js +425 -0
- package/src/transport/adapters/RNBLEAdapter.js +328 -0
- package/src/transport/adapters/index.js +16 -0
- package/src/transport/index.js +33 -0
- package/src/utils/BoundedMap.js +151 -0
- package/src/utils/EventEmitter.js +205 -0
- package/src/utils/LRUCache.js +202 -0
- package/src/utils/RateLimiter.js +202 -0
- package/src/utils/TimeoutManager.js +164 -0
- package/src/utils/base64.js +151 -0
- package/src/utils/bytes.js +187 -0
- package/src/utils/debug.js +151 -0
- package/src/utils/encoding.js +248 -0
- package/src/utils/index.js +106 -0
- package/src/utils/retry.js +146 -0
- package/src/utils/time.js +166 -0
- package/src/utils/uuid.js +145 -0
- package/src/utils/validation.js +205 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Fragment assembler for reconstructing fragmented messages
|
|
5
|
+
* @module mesh/fragment/Assembler
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { MESH_CONFIG } = require('../../constants');
|
|
9
|
+
const { MessageError, ValidationError } = require('../../errors');
|
|
10
|
+
const { getFragmentInfo, isValidFragment } = require('./Fragmenter');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Default assembly timeout
|
|
14
|
+
* @constant
|
|
15
|
+
* @private
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_TIMEOUT = MESH_CONFIG.FRAGMENT_TIMEOUT_MS;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Pending fragment set
|
|
21
|
+
* @class PendingFragmentSet
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
class PendingFragmentSet {
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new PendingFragmentSet
|
|
27
|
+
* @param {string} messageId - Message ID
|
|
28
|
+
* @param {number} total - Total expected fragments
|
|
29
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
30
|
+
*/
|
|
31
|
+
constructor(messageId, total, timeout) {
|
|
32
|
+
this.messageId = messageId;
|
|
33
|
+
this.total = total;
|
|
34
|
+
this.received = new Map();
|
|
35
|
+
this.createdAt = Date.now();
|
|
36
|
+
this.expiresAt = this.createdAt + timeout;
|
|
37
|
+
this.totalPayloadLength = 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Checks if the fragment set is complete
|
|
42
|
+
* @returns {boolean} True if all fragments received
|
|
43
|
+
*/
|
|
44
|
+
isComplete() {
|
|
45
|
+
return this.received.size === this.total;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Checks if the fragment set has expired
|
|
50
|
+
* @returns {boolean} True if expired
|
|
51
|
+
*/
|
|
52
|
+
isExpired() {
|
|
53
|
+
return Date.now() > this.expiresAt;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Adds a fragment to the set
|
|
58
|
+
* @param {number} index - Fragment index
|
|
59
|
+
* @param {Uint8Array} payload - Fragment payload
|
|
60
|
+
* @returns {boolean} True if fragment was new
|
|
61
|
+
*/
|
|
62
|
+
addFragment(index, payload) {
|
|
63
|
+
if (this.received.has(index)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
this.received.set(index, payload);
|
|
67
|
+
this.totalPayloadLength += payload.length;
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Assembles all fragments into complete payload
|
|
73
|
+
* @returns {Uint8Array} Complete assembled payload
|
|
74
|
+
*/
|
|
75
|
+
assemble() {
|
|
76
|
+
const result = new Uint8Array(this.totalPayloadLength);
|
|
77
|
+
let offset = 0;
|
|
78
|
+
|
|
79
|
+
for (let i = 0; i < this.total; i++) {
|
|
80
|
+
const payload = this.received.get(i);
|
|
81
|
+
if (!payload) {
|
|
82
|
+
throw MessageError.fromCode('E508', this.messageId, {
|
|
83
|
+
reason: `Missing fragment ${i}`
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
result.set(payload, offset);
|
|
87
|
+
offset += payload.length;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Gets progress information
|
|
95
|
+
* @returns {Object} Progress { received, total, percent }
|
|
96
|
+
*/
|
|
97
|
+
getProgress() {
|
|
98
|
+
return {
|
|
99
|
+
received: this.received.size,
|
|
100
|
+
total: this.total,
|
|
101
|
+
percent: Math.round((this.received.size / this.total) * 100)
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Fragment assembler for reconstructing fragmented messages
|
|
108
|
+
* @class Assembler
|
|
109
|
+
*/
|
|
110
|
+
class Assembler {
|
|
111
|
+
/**
|
|
112
|
+
* Creates a new Assembler
|
|
113
|
+
* @param {number} [timeout] - Timeout for incomplete fragment sets
|
|
114
|
+
*/
|
|
115
|
+
constructor(timeout = DEFAULT_TIMEOUT) {
|
|
116
|
+
if (!Number.isInteger(timeout) || timeout <= 0) {
|
|
117
|
+
throw ValidationError.outOfRange('timeout', timeout, { min: 1 });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Timeout for incomplete fragment sets
|
|
122
|
+
* @type {number}
|
|
123
|
+
*/
|
|
124
|
+
this.timeout = timeout;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Pending fragment sets by message ID
|
|
128
|
+
* @type {Map<string, PendingFragmentSet>}
|
|
129
|
+
* @private
|
|
130
|
+
*/
|
|
131
|
+
this._pending = new Map();
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Statistics
|
|
135
|
+
* @type {Object}
|
|
136
|
+
* @private
|
|
137
|
+
*/
|
|
138
|
+
this._stats = {
|
|
139
|
+
fragmentsReceived: 0,
|
|
140
|
+
messagesAssembled: 0,
|
|
141
|
+
duplicateFragments: 0,
|
|
142
|
+
expiredSets: 0
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Adds a fragment and returns assembled payload if complete
|
|
148
|
+
* @param {string} messageId - Message ID
|
|
149
|
+
* @param {Uint8Array} fragmentData - Fragment data with header
|
|
150
|
+
* @returns {Uint8Array|null} Assembled payload or null if incomplete
|
|
151
|
+
*/
|
|
152
|
+
addFragment(messageId, fragmentData) {
|
|
153
|
+
if (typeof messageId !== 'string' || messageId.length === 0) {
|
|
154
|
+
throw ValidationError.invalidArgument('messageId', messageId);
|
|
155
|
+
}
|
|
156
|
+
if (!isValidFragment(fragmentData)) {
|
|
157
|
+
throw MessageError.invalidFormat(messageId, {
|
|
158
|
+
reason: 'Invalid fragment data'
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const info = getFragmentInfo(fragmentData);
|
|
163
|
+
this._stats.fragmentsReceived++;
|
|
164
|
+
|
|
165
|
+
// Get or create pending set
|
|
166
|
+
let pendingSet = this._pending.get(messageId);
|
|
167
|
+
if (!pendingSet) {
|
|
168
|
+
pendingSet = new PendingFragmentSet(messageId, info.total, this.timeout);
|
|
169
|
+
this._pending.set(messageId, pendingSet);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Validate fragment belongs to this set
|
|
173
|
+
if (info.total !== pendingSet.total) {
|
|
174
|
+
throw MessageError.invalidFormat(messageId, {
|
|
175
|
+
reason: 'Fragment total mismatch'
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Add fragment
|
|
180
|
+
const isNew = pendingSet.addFragment(info.index, info.payload);
|
|
181
|
+
if (!isNew) {
|
|
182
|
+
this._stats.duplicateFragments++;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Check if complete
|
|
186
|
+
if (pendingSet.isComplete()) {
|
|
187
|
+
const payload = pendingSet.assemble();
|
|
188
|
+
this._pending.delete(messageId);
|
|
189
|
+
this._stats.messagesAssembled++;
|
|
190
|
+
return payload;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Cleans up expired pending fragment sets
|
|
198
|
+
* @returns {string[]} Array of expired message IDs
|
|
199
|
+
*/
|
|
200
|
+
cleanup() {
|
|
201
|
+
const expired = [];
|
|
202
|
+
|
|
203
|
+
for (const [messageId, pendingSet] of this._pending) {
|
|
204
|
+
if (pendingSet.isExpired()) {
|
|
205
|
+
expired.push(messageId);
|
|
206
|
+
this._pending.delete(messageId);
|
|
207
|
+
this._stats.expiredSets++;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return expired;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Gets the number of pending fragment sets
|
|
216
|
+
* @returns {number} Count of pending sets
|
|
217
|
+
*/
|
|
218
|
+
getPendingCount() {
|
|
219
|
+
return this._pending.size;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Checks if there are pending fragments for a message
|
|
224
|
+
* @param {string} messageId - Message ID to check
|
|
225
|
+
* @returns {boolean} True if there are pending fragments
|
|
226
|
+
*/
|
|
227
|
+
hasPending(messageId) {
|
|
228
|
+
return this._pending.has(messageId);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Gets progress for a pending message
|
|
233
|
+
* @param {string} messageId - Message ID
|
|
234
|
+
* @returns {Object|null} Progress or null if not found
|
|
235
|
+
*/
|
|
236
|
+
getProgress(messageId) {
|
|
237
|
+
const pendingSet = this._pending.get(messageId);
|
|
238
|
+
return pendingSet ? pendingSet.getProgress() : null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Removes a pending fragment set
|
|
243
|
+
* @param {string} messageId - Message ID to remove
|
|
244
|
+
* @returns {boolean} True if removed
|
|
245
|
+
*/
|
|
246
|
+
removePending(messageId) {
|
|
247
|
+
return this._pending.delete(messageId);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Gets assembler statistics
|
|
252
|
+
* @returns {Object} Statistics
|
|
253
|
+
*/
|
|
254
|
+
getStats() {
|
|
255
|
+
return {
|
|
256
|
+
...this._stats,
|
|
257
|
+
pendingCount: this._pending.size
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Resets statistics
|
|
263
|
+
*/
|
|
264
|
+
resetStats() {
|
|
265
|
+
this._stats = {
|
|
266
|
+
fragmentsReceived: 0,
|
|
267
|
+
messagesAssembled: 0,
|
|
268
|
+
duplicateFragments: 0,
|
|
269
|
+
expiredSets: 0
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Clears all pending fragment sets
|
|
275
|
+
*/
|
|
276
|
+
clear() {
|
|
277
|
+
this._pending.clear();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
module.exports = Assembler;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Message fragmenter for splitting large payloads
|
|
5
|
+
* @module mesh/fragment/Fragmenter
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { MESH_CONFIG } = require('../../constants');
|
|
9
|
+
const { ValidationError } = require('../../errors');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default fragment size
|
|
13
|
+
* @constant
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
const DEFAULT_FRAGMENT_SIZE = MESH_CONFIG.FRAGMENT_SIZE;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Fragment header overhead (4 bytes: index, total, length high, length low)
|
|
20
|
+
* @constant
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
const FRAGMENT_HEADER_SIZE = 4;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Checks if a payload needs fragmentation
|
|
27
|
+
* @param {Uint8Array} payload - Payload to check
|
|
28
|
+
* @param {number} [maxSize] - Maximum fragment payload size
|
|
29
|
+
* @returns {boolean} True if fragmentation is needed
|
|
30
|
+
*/
|
|
31
|
+
function needsFragmentation(payload, maxSize = DEFAULT_FRAGMENT_SIZE) {
|
|
32
|
+
if (!(payload instanceof Uint8Array)) {
|
|
33
|
+
throw ValidationError.invalidType('payload', payload, 'Uint8Array');
|
|
34
|
+
}
|
|
35
|
+
return payload.length > maxSize;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Calculates the number of fragments needed
|
|
40
|
+
* @param {number} payloadLength - Total payload length
|
|
41
|
+
* @param {number} maxSize - Maximum fragment payload size
|
|
42
|
+
* @returns {number} Number of fragments required
|
|
43
|
+
* @private
|
|
44
|
+
*/
|
|
45
|
+
function calculateFragmentCount(payloadLength, maxSize) {
|
|
46
|
+
return Math.ceil(payloadLength / maxSize);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Creates a fragment header
|
|
51
|
+
* @param {number} index - Fragment index (0-based)
|
|
52
|
+
* @param {number} total - Total number of fragments
|
|
53
|
+
* @param {number} payloadLength - Length of this fragment's payload
|
|
54
|
+
* @returns {Uint8Array} 4-byte fragment header
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
function createFragmentHeader(index, total, payloadLength) {
|
|
58
|
+
const header = new Uint8Array(FRAGMENT_HEADER_SIZE);
|
|
59
|
+
header[0] = index;
|
|
60
|
+
header[1] = total;
|
|
61
|
+
header[2] = (payloadLength >> 8) & 0xff;
|
|
62
|
+
header[3] = payloadLength & 0xff;
|
|
63
|
+
return header;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Parses a fragment header
|
|
68
|
+
* @param {Uint8Array} data - Fragment data
|
|
69
|
+
* @returns {Object} Parsed header { index, total, payloadLength }
|
|
70
|
+
*/
|
|
71
|
+
function parseFragmentHeader(data) {
|
|
72
|
+
if (data.length < FRAGMENT_HEADER_SIZE) {
|
|
73
|
+
throw ValidationError.invalidArgument('data', null, {
|
|
74
|
+
reason: 'Fragment data too short for header'
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
index: data[0],
|
|
79
|
+
total: data[1],
|
|
80
|
+
payloadLength: (data[2] << 8) | data[3]
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Fragments a payload into multiple chunks
|
|
86
|
+
* @param {Uint8Array} payload - Payload to fragment
|
|
87
|
+
* @param {string} messageId - Message ID for the fragments
|
|
88
|
+
* @param {number} [maxSize] - Maximum fragment payload size
|
|
89
|
+
* @returns {Uint8Array[]} Array of fragment data chunks
|
|
90
|
+
*/
|
|
91
|
+
function fragment(payload, messageId, maxSize = DEFAULT_FRAGMENT_SIZE) {
|
|
92
|
+
if (!(payload instanceof Uint8Array)) {
|
|
93
|
+
throw ValidationError.invalidType('payload', payload, 'Uint8Array');
|
|
94
|
+
}
|
|
95
|
+
if (typeof messageId !== 'string' || messageId.length === 0) {
|
|
96
|
+
throw ValidationError.invalidArgument('messageId', messageId, {
|
|
97
|
+
reason: 'Message ID must be a non-empty string'
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (!Number.isInteger(maxSize) || maxSize <= FRAGMENT_HEADER_SIZE) {
|
|
101
|
+
throw ValidationError.outOfRange('maxSize', maxSize, {
|
|
102
|
+
min: FRAGMENT_HEADER_SIZE + 1
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Calculate actual payload capacity per fragment
|
|
107
|
+
const payloadCapacity = maxSize - FRAGMENT_HEADER_SIZE;
|
|
108
|
+
const fragmentCount = calculateFragmentCount(payload.length, payloadCapacity);
|
|
109
|
+
|
|
110
|
+
// Validate fragment count limit (single byte index)
|
|
111
|
+
if (fragmentCount > 255) {
|
|
112
|
+
throw ValidationError.outOfRange('payload.length', payload.length, {
|
|
113
|
+
max: payloadCapacity * 255,
|
|
114
|
+
reason: 'Payload too large, would exceed maximum fragment count'
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const fragments = [];
|
|
119
|
+
let offset = 0;
|
|
120
|
+
|
|
121
|
+
for (let i = 0; i < fragmentCount; i++) {
|
|
122
|
+
const remainingLength = payload.length - offset;
|
|
123
|
+
const chunkLength = Math.min(payloadCapacity, remainingLength);
|
|
124
|
+
const chunk = payload.slice(offset, offset + chunkLength);
|
|
125
|
+
|
|
126
|
+
// Create fragment with header
|
|
127
|
+
const header = createFragmentHeader(i, fragmentCount, chunkLength);
|
|
128
|
+
const fragmentData = new Uint8Array(FRAGMENT_HEADER_SIZE + chunkLength);
|
|
129
|
+
fragmentData.set(header, 0);
|
|
130
|
+
fragmentData.set(chunk, FRAGMENT_HEADER_SIZE);
|
|
131
|
+
|
|
132
|
+
fragments.push(fragmentData);
|
|
133
|
+
offset += chunkLength;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return fragments;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Gets fragment information without parsing full data
|
|
141
|
+
* @param {Uint8Array} fragmentData - Fragment data
|
|
142
|
+
* @returns {Object} Fragment info { index, total, payloadLength, payload }
|
|
143
|
+
*/
|
|
144
|
+
function getFragmentInfo(fragmentData) {
|
|
145
|
+
const header = parseFragmentHeader(fragmentData);
|
|
146
|
+
return {
|
|
147
|
+
...header,
|
|
148
|
+
payload: fragmentData.slice(FRAGMENT_HEADER_SIZE, FRAGMENT_HEADER_SIZE + header.payloadLength)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Validates fragment data structure
|
|
154
|
+
* @param {Uint8Array} fragmentData - Fragment data to validate
|
|
155
|
+
* @returns {boolean} True if valid
|
|
156
|
+
*/
|
|
157
|
+
function isValidFragment(fragmentData) {
|
|
158
|
+
if (!(fragmentData instanceof Uint8Array)) { return false; }
|
|
159
|
+
if (fragmentData.length < FRAGMENT_HEADER_SIZE) { return false; }
|
|
160
|
+
|
|
161
|
+
const header = parseFragmentHeader(fragmentData);
|
|
162
|
+
if (header.index >= header.total) { return false; }
|
|
163
|
+
if (header.total === 0) { return false; }
|
|
164
|
+
if (fragmentData.length < FRAGMENT_HEADER_SIZE + header.payloadLength) { return false; }
|
|
165
|
+
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = {
|
|
170
|
+
fragment,
|
|
171
|
+
needsFragmentation,
|
|
172
|
+
parseFragmentHeader,
|
|
173
|
+
getFragmentInfo,
|
|
174
|
+
isValidFragment,
|
|
175
|
+
FRAGMENT_HEADER_SIZE
|
|
176
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Fragment module exports
|
|
5
|
+
* @module mesh/fragment
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const Fragmenter = require('./Fragmenter');
|
|
9
|
+
const Assembler = require('./Assembler');
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
// Fragmenter exports
|
|
13
|
+
fragment: Fragmenter.fragment,
|
|
14
|
+
needsFragmentation: Fragmenter.needsFragmentation,
|
|
15
|
+
parseFragmentHeader: Fragmenter.parseFragmentHeader,
|
|
16
|
+
getFragmentInfo: Fragmenter.getFragmentInfo,
|
|
17
|
+
isValidFragment: Fragmenter.isValidFragment,
|
|
18
|
+
FRAGMENT_HEADER_SIZE: Fragmenter.FRAGMENT_HEADER_SIZE,
|
|
19
|
+
// Assembler class
|
|
20
|
+
Assembler
|
|
21
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Mesh module exports
|
|
3
|
+
* @module mesh
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const dedup = require('./dedup');
|
|
9
|
+
const fragment = require('./fragment');
|
|
10
|
+
const peer = require('./peer');
|
|
11
|
+
const router = require('./router');
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
...dedup,
|
|
15
|
+
...fragment,
|
|
16
|
+
...peer,
|
|
17
|
+
...router
|
|
18
|
+
};
|