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,248 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Encoding conversion utilities
|
|
5
|
+
* @module utils/encoding
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Lookup tables for hex encoding
|
|
10
|
+
* @private
|
|
11
|
+
*/
|
|
12
|
+
const HEX_CHARS = '0123456789abcdef';
|
|
13
|
+
const HEX_LOOKUP = new Uint8Array(256);
|
|
14
|
+
|
|
15
|
+
// Initialize hex lookup table
|
|
16
|
+
for (let i = 0; i < 16; i++) {
|
|
17
|
+
HEX_LOOKUP[HEX_CHARS.charCodeAt(i)] = i;
|
|
18
|
+
HEX_LOOKUP[HEX_CHARS.toUpperCase().charCodeAt(i)] = i;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Converts a byte array to a hexadecimal string
|
|
23
|
+
* @param {Uint8Array} bytes - Bytes to convert
|
|
24
|
+
* @returns {string} Hexadecimal string
|
|
25
|
+
*/
|
|
26
|
+
function bytesToHex(bytes) {
|
|
27
|
+
let result = '';
|
|
28
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
29
|
+
result += HEX_CHARS[bytes[i] >> 4];
|
|
30
|
+
result += HEX_CHARS[bytes[i] & 0x0f];
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Converts a hexadecimal string to a byte array
|
|
37
|
+
* @param {string} hex - Hexadecimal string
|
|
38
|
+
* @returns {Uint8Array} Byte array
|
|
39
|
+
* @throws {Error} If hex string has invalid length or characters
|
|
40
|
+
*/
|
|
41
|
+
function hexToBytes(hex) {
|
|
42
|
+
if (typeof hex !== 'string') {
|
|
43
|
+
throw new Error('Input must be a string');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Remove optional 0x prefix
|
|
47
|
+
if (hex.startsWith('0x') || hex.startsWith('0X')) {
|
|
48
|
+
hex = hex.slice(2);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (hex.length % 2 !== 0) {
|
|
52
|
+
throw new Error('Hex string must have even length');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
56
|
+
|
|
57
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
58
|
+
const hi = HEX_LOOKUP[hex.charCodeAt(i * 2)];
|
|
59
|
+
const lo = HEX_LOOKUP[hex.charCodeAt(i * 2 + 1)];
|
|
60
|
+
|
|
61
|
+
if (hi === undefined || lo === undefined) {
|
|
62
|
+
throw new Error(`Invalid hex character at position ${i * 2}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
bytes[i] = (hi << 4) | lo;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return bytes;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Base64 character set
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
76
|
+
const BASE64_LOOKUP = new Uint8Array(256);
|
|
77
|
+
|
|
78
|
+
// Initialize base64 lookup table
|
|
79
|
+
for (let i = 0; i < BASE64_CHARS.length; i++) {
|
|
80
|
+
BASE64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Converts a byte array to a Base64 string
|
|
85
|
+
* @param {Uint8Array} bytes - Bytes to convert
|
|
86
|
+
* @returns {string} Base64 string
|
|
87
|
+
*/
|
|
88
|
+
function bytesToBase64(bytes) {
|
|
89
|
+
let result = '';
|
|
90
|
+
const len = bytes.length;
|
|
91
|
+
const remainder = len % 3;
|
|
92
|
+
|
|
93
|
+
// Process 3 bytes at a time
|
|
94
|
+
for (let i = 0; i < len - remainder; i += 3) {
|
|
95
|
+
const n = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
|
|
96
|
+
result += BASE64_CHARS[(n >> 18) & 0x3f];
|
|
97
|
+
result += BASE64_CHARS[(n >> 12) & 0x3f];
|
|
98
|
+
result += BASE64_CHARS[(n >> 6) & 0x3f];
|
|
99
|
+
result += BASE64_CHARS[n & 0x3f];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Handle remainder
|
|
103
|
+
if (remainder === 1) {
|
|
104
|
+
const n = bytes[len - 1];
|
|
105
|
+
result += BASE64_CHARS[(n >> 2) & 0x3f];
|
|
106
|
+
result += BASE64_CHARS[(n << 4) & 0x3f];
|
|
107
|
+
result += '==';
|
|
108
|
+
} else if (remainder === 2) {
|
|
109
|
+
const n = (bytes[len - 2] << 8) | bytes[len - 1];
|
|
110
|
+
result += BASE64_CHARS[(n >> 10) & 0x3f];
|
|
111
|
+
result += BASE64_CHARS[(n >> 4) & 0x3f];
|
|
112
|
+
result += BASE64_CHARS[(n << 2) & 0x3f];
|
|
113
|
+
result += '=';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Converts a Base64 string to a byte array
|
|
121
|
+
* @param {string} base64 - Base64 string
|
|
122
|
+
* @returns {Uint8Array} Byte array
|
|
123
|
+
* @throws {Error} If base64 string is invalid
|
|
124
|
+
*/
|
|
125
|
+
function base64ToBytes(base64) {
|
|
126
|
+
if (typeof base64 !== 'string') {
|
|
127
|
+
throw new Error('Input must be a string');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Remove padding and calculate length
|
|
131
|
+
let paddingLength = 0;
|
|
132
|
+
if (base64.endsWith('==')) {
|
|
133
|
+
paddingLength = 2;
|
|
134
|
+
} else if (base64.endsWith('=')) {
|
|
135
|
+
paddingLength = 1;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const len = base64.length;
|
|
139
|
+
const outputLength = (len * 3) / 4 - paddingLength;
|
|
140
|
+
const bytes = new Uint8Array(outputLength);
|
|
141
|
+
|
|
142
|
+
let j = 0;
|
|
143
|
+
for (let i = 0; i < len; i += 4) {
|
|
144
|
+
const a = BASE64_LOOKUP[base64.charCodeAt(i)];
|
|
145
|
+
const b = BASE64_LOOKUP[base64.charCodeAt(i + 1)];
|
|
146
|
+
const c = BASE64_LOOKUP[base64.charCodeAt(i + 2)];
|
|
147
|
+
const d = BASE64_LOOKUP[base64.charCodeAt(i + 3)];
|
|
148
|
+
|
|
149
|
+
bytes[j++] = (a << 2) | (b >> 4);
|
|
150
|
+
if (j < outputLength) { bytes[j++] = ((b & 0x0f) << 4) | (c >> 2); }
|
|
151
|
+
if (j < outputLength) { bytes[j++] = ((c & 0x03) << 6) | d; }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return bytes;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Converts a UTF-8 string to a byte array
|
|
159
|
+
* @param {string} str - String to convert
|
|
160
|
+
* @returns {Uint8Array} UTF-8 encoded bytes
|
|
161
|
+
*/
|
|
162
|
+
function stringToBytes(str) {
|
|
163
|
+
if (typeof TextEncoder !== 'undefined') {
|
|
164
|
+
return new TextEncoder().encode(str);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Fallback for environments without TextEncoder
|
|
168
|
+
const bytes = [];
|
|
169
|
+
for (let i = 0; i < str.length; i++) {
|
|
170
|
+
let code = str.charCodeAt(i);
|
|
171
|
+
|
|
172
|
+
if (code < 0x80) {
|
|
173
|
+
bytes.push(code);
|
|
174
|
+
} else if (code < 0x800) {
|
|
175
|
+
bytes.push(0xc0 | (code >> 6));
|
|
176
|
+
bytes.push(0x80 | (code & 0x3f));
|
|
177
|
+
} else if (code < 0xd800 || code >= 0xe000) {
|
|
178
|
+
bytes.push(0xe0 | (code >> 12));
|
|
179
|
+
bytes.push(0x80 | ((code >> 6) & 0x3f));
|
|
180
|
+
bytes.push(0x80 | (code & 0x3f));
|
|
181
|
+
} else {
|
|
182
|
+
// Surrogate pair
|
|
183
|
+
i++;
|
|
184
|
+
code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
|
|
185
|
+
bytes.push(0xf0 | (code >> 18));
|
|
186
|
+
bytes.push(0x80 | ((code >> 12) & 0x3f));
|
|
187
|
+
bytes.push(0x80 | ((code >> 6) & 0x3f));
|
|
188
|
+
bytes.push(0x80 | (code & 0x3f));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return new Uint8Array(bytes);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Converts a UTF-8 byte array to a string
|
|
197
|
+
* @param {Uint8Array} bytes - UTF-8 encoded bytes
|
|
198
|
+
* @returns {string} Decoded string
|
|
199
|
+
*/
|
|
200
|
+
function bytesToString(bytes) {
|
|
201
|
+
if (typeof TextDecoder !== 'undefined') {
|
|
202
|
+
return new TextDecoder().decode(bytes);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Fallback for environments without TextDecoder
|
|
206
|
+
let result = '';
|
|
207
|
+
let i = 0;
|
|
208
|
+
|
|
209
|
+
while (i < bytes.length) {
|
|
210
|
+
const byte1 = bytes[i++];
|
|
211
|
+
|
|
212
|
+
if (byte1 < 0x80) {
|
|
213
|
+
result += String.fromCharCode(byte1);
|
|
214
|
+
} else if (byte1 < 0xe0) {
|
|
215
|
+
const byte2 = bytes[i++];
|
|
216
|
+
result += String.fromCharCode(((byte1 & 0x1f) << 6) | (byte2 & 0x3f));
|
|
217
|
+
} else if (byte1 < 0xf0) {
|
|
218
|
+
const byte2 = bytes[i++];
|
|
219
|
+
const byte3 = bytes[i++];
|
|
220
|
+
result += String.fromCharCode(
|
|
221
|
+
((byte1 & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f)
|
|
222
|
+
);
|
|
223
|
+
} else {
|
|
224
|
+
const byte2 = bytes[i++];
|
|
225
|
+
const byte3 = bytes[i++];
|
|
226
|
+
const byte4 = bytes[i++];
|
|
227
|
+
const codePoint =
|
|
228
|
+
((byte1 & 0x07) << 18) |
|
|
229
|
+
((byte2 & 0x3f) << 12) |
|
|
230
|
+
((byte3 & 0x3f) << 6) |
|
|
231
|
+
(byte4 & 0x3f);
|
|
232
|
+
// Convert to surrogate pair
|
|
233
|
+
const adjusted = codePoint - 0x10000;
|
|
234
|
+
result += String.fromCharCode(0xd800 + (adjusted >> 10), 0xdc00 + (adjusted & 0x3ff));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
module.exports = {
|
|
242
|
+
bytesToHex,
|
|
243
|
+
hexToBytes,
|
|
244
|
+
bytesToBase64,
|
|
245
|
+
base64ToBytes,
|
|
246
|
+
stringToBytes,
|
|
247
|
+
bytesToString
|
|
248
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Utility module exports
|
|
5
|
+
* @module utils
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const bytes = require('./bytes');
|
|
9
|
+
const encoding = require('./encoding');
|
|
10
|
+
const uuid = require('./uuid');
|
|
11
|
+
const time = require('./time');
|
|
12
|
+
const validation = require('./validation');
|
|
13
|
+
const EventEmitter = require('./EventEmitter');
|
|
14
|
+
const LRUCache = require('./LRUCache');
|
|
15
|
+
const RateLimiter = require('./RateLimiter');
|
|
16
|
+
const retry = require('./retry');
|
|
17
|
+
const debug = require('./debug');
|
|
18
|
+
const BoundedMap = require('./BoundedMap');
|
|
19
|
+
const TimeoutManager = require('./TimeoutManager');
|
|
20
|
+
const base64 = require('./base64');
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
// Byte manipulation
|
|
24
|
+
concat: bytes.concat,
|
|
25
|
+
constantTimeEqual: bytes.constantTimeEqual,
|
|
26
|
+
randomBytes: bytes.randomBytes,
|
|
27
|
+
xor: bytes.xor,
|
|
28
|
+
fill: bytes.fill,
|
|
29
|
+
copy: bytes.copy,
|
|
30
|
+
secureWipe: bytes.secureWipe,
|
|
31
|
+
equals: bytes.equals,
|
|
32
|
+
slice: bytes.slice,
|
|
33
|
+
|
|
34
|
+
// Encoding
|
|
35
|
+
bytesToHex: encoding.bytesToHex,
|
|
36
|
+
hexToBytes: encoding.hexToBytes,
|
|
37
|
+
bytesToBase64: encoding.bytesToBase64,
|
|
38
|
+
base64ToBytes: encoding.base64ToBytes,
|
|
39
|
+
stringToBytes: encoding.stringToBytes,
|
|
40
|
+
bytesToString: encoding.bytesToString,
|
|
41
|
+
|
|
42
|
+
// UUID
|
|
43
|
+
generateUUID: uuid.generateUUID,
|
|
44
|
+
uuidToBytes: uuid.uuidToBytes,
|
|
45
|
+
bytesToUuid: uuid.bytesToUuid,
|
|
46
|
+
isValidUUID: uuid.isValidUUID,
|
|
47
|
+
generateShortId: uuid.generateShortId,
|
|
48
|
+
shortenUUID: uuid.shortenUUID,
|
|
49
|
+
compareUUID: uuid.compareUUID,
|
|
50
|
+
|
|
51
|
+
// Time
|
|
52
|
+
delay: time.delay,
|
|
53
|
+
withTimeout: time.withTimeout,
|
|
54
|
+
now: time.now,
|
|
55
|
+
hrTime: time.hrTime,
|
|
56
|
+
elapsed: time.elapsed,
|
|
57
|
+
isExpired: time.isExpired,
|
|
58
|
+
formatDuration: time.formatDuration,
|
|
59
|
+
debounce: time.debounce,
|
|
60
|
+
throttle: time.throttle,
|
|
61
|
+
|
|
62
|
+
// Validation
|
|
63
|
+
validateString: validation.validateString,
|
|
64
|
+
validateBytes: validation.validateBytes,
|
|
65
|
+
validatePositiveInt: validation.validatePositiveInt,
|
|
66
|
+
validateEnum: validation.validateEnum,
|
|
67
|
+
validateNonNegativeInt: validation.validateNonNegativeInt,
|
|
68
|
+
validateRange: validation.validateRange,
|
|
69
|
+
validateBoolean: validation.validateBoolean,
|
|
70
|
+
validateFunction: validation.validateFunction,
|
|
71
|
+
validateObject: validation.validateObject,
|
|
72
|
+
validateOptional: validation.validateOptional,
|
|
73
|
+
|
|
74
|
+
// Classes
|
|
75
|
+
EventEmitter,
|
|
76
|
+
LRUCache,
|
|
77
|
+
RateLimiter,
|
|
78
|
+
BoundedMap,
|
|
79
|
+
TimeoutManager,
|
|
80
|
+
|
|
81
|
+
// Optimized Base64 (for React Native)
|
|
82
|
+
base64Encode: base64.encode,
|
|
83
|
+
base64Decode: base64.decode,
|
|
84
|
+
isValidBase64: base64.isValid,
|
|
85
|
+
|
|
86
|
+
// Retry
|
|
87
|
+
retry: retry.retry,
|
|
88
|
+
retryable: retry.retryable,
|
|
89
|
+
retryOn: retry.retryOn,
|
|
90
|
+
retryExcept: retry.retryExcept,
|
|
91
|
+
retryOnCodes: retry.retryOnCodes,
|
|
92
|
+
|
|
93
|
+
// Debug
|
|
94
|
+
debug,
|
|
95
|
+
createDebugger: debug.createDebugger,
|
|
96
|
+
enableDebug: debug.enable,
|
|
97
|
+
disableDebug: debug.disable,
|
|
98
|
+
|
|
99
|
+
// Sub-modules (for specific imports)
|
|
100
|
+
bytes,
|
|
101
|
+
encoding,
|
|
102
|
+
uuid,
|
|
103
|
+
time,
|
|
104
|
+
validation,
|
|
105
|
+
base64
|
|
106
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Retry utilities with exponential backoff
|
|
5
|
+
* @module utils/retry
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default retry options
|
|
10
|
+
* @constant {Object}
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_OPTIONS = {
|
|
13
|
+
maxRetries: 3,
|
|
14
|
+
initialDelay: 100,
|
|
15
|
+
maxDelay: 10000,
|
|
16
|
+
factor: 2,
|
|
17
|
+
jitter: true,
|
|
18
|
+
shouldRetry: () => true
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Calculates delay with optional jitter
|
|
23
|
+
* @param {number} attempt - Current attempt number (0-based)
|
|
24
|
+
* @param {Object} options - Retry options
|
|
25
|
+
* @returns {number} Delay in milliseconds
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
function calculateDelay(attempt, options) {
|
|
29
|
+
const { initialDelay, maxDelay, factor, jitter } = options;
|
|
30
|
+
|
|
31
|
+
// Exponential backoff
|
|
32
|
+
let delay = initialDelay * Math.pow(factor, attempt);
|
|
33
|
+
|
|
34
|
+
// Cap at max delay
|
|
35
|
+
delay = Math.min(delay, maxDelay);
|
|
36
|
+
|
|
37
|
+
// Add jitter (0 to 100% of delay)
|
|
38
|
+
if (jitter) {
|
|
39
|
+
delay = delay * (0.5 + Math.random());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return Math.floor(delay);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Retries an async function with exponential backoff
|
|
47
|
+
* @template T
|
|
48
|
+
* @param {function(): Promise<T>} fn - Async function to retry
|
|
49
|
+
* @param {Object} [options] - Retry options
|
|
50
|
+
* @param {number} [options.maxRetries=3] - Maximum number of retries
|
|
51
|
+
* @param {number} [options.initialDelay=100] - Initial delay in milliseconds
|
|
52
|
+
* @param {number} [options.maxDelay=10000] - Maximum delay in milliseconds
|
|
53
|
+
* @param {number} [options.factor=2] - Exponential factor
|
|
54
|
+
* @param {boolean} [options.jitter=true] - Add randomness to delays
|
|
55
|
+
* @param {function(Error, number): boolean} [options.shouldRetry] - Predicate to determine if should retry
|
|
56
|
+
* @param {function(Error, number): void} [options.onRetry] - Callback on each retry
|
|
57
|
+
* @returns {Promise<T>} Result of the function
|
|
58
|
+
* @throws {Error} Last error if all retries fail
|
|
59
|
+
*/
|
|
60
|
+
async function retry(fn, options = {}) {
|
|
61
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
62
|
+
const { maxRetries, shouldRetry, onRetry } = opts;
|
|
63
|
+
|
|
64
|
+
let lastError;
|
|
65
|
+
|
|
66
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
67
|
+
try {
|
|
68
|
+
return await fn();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
lastError = error;
|
|
71
|
+
|
|
72
|
+
// Check if we should retry
|
|
73
|
+
if (attempt >= maxRetries || !shouldRetry(error, attempt)) {
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Calculate delay
|
|
78
|
+
const delay = calculateDelay(attempt, opts);
|
|
79
|
+
|
|
80
|
+
// Call onRetry callback if provided
|
|
81
|
+
if (onRetry) {
|
|
82
|
+
onRetry(error, attempt);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Wait before retrying
|
|
86
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
throw lastError;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Creates a retryable version of an async function
|
|
95
|
+
* @template T
|
|
96
|
+
* @param {function(...*): Promise<T>} fn - Async function to wrap
|
|
97
|
+
* @param {Object} [options] - Retry options
|
|
98
|
+
* @returns {function(...*): Promise<T>} Wrapped function with retry logic
|
|
99
|
+
*/
|
|
100
|
+
function retryable(fn, options = {}) {
|
|
101
|
+
return function retryableFn(...args) {
|
|
102
|
+
return retry(() => fn.apply(this, args), options);
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Retry predicate that retries on specific error types
|
|
108
|
+
* @param {Array<Function>} errorTypes - Error constructors to retry on
|
|
109
|
+
* @returns {function(Error): boolean} Predicate function
|
|
110
|
+
*/
|
|
111
|
+
function retryOn(errorTypes) {
|
|
112
|
+
return (error) => {
|
|
113
|
+
return errorTypes.some(ErrorType => error instanceof ErrorType);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Retry predicate that does not retry on specific error types
|
|
119
|
+
* @param {Array<Function>} errorTypes - Error constructors to not retry on
|
|
120
|
+
* @returns {function(Error): boolean} Predicate function
|
|
121
|
+
*/
|
|
122
|
+
function retryExcept(errorTypes) {
|
|
123
|
+
return (error) => {
|
|
124
|
+
return !errorTypes.some(ErrorType => error instanceof ErrorType);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Retry predicate that retries on specific error codes
|
|
130
|
+
* @param {Array<string>} codes - Error codes to retry on
|
|
131
|
+
* @returns {function(Error): boolean} Predicate function
|
|
132
|
+
*/
|
|
133
|
+
function retryOnCodes(codes) {
|
|
134
|
+
return (error) => {
|
|
135
|
+
return error.code && codes.includes(error.code);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = {
|
|
140
|
+
retry,
|
|
141
|
+
retryable,
|
|
142
|
+
retryOn,
|
|
143
|
+
retryExcept,
|
|
144
|
+
retryOnCodes,
|
|
145
|
+
DEFAULT_OPTIONS
|
|
146
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Time-related utilities
|
|
5
|
+
* @module utils/time
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns a promise that resolves after the specified delay
|
|
10
|
+
* @param {number} ms - Delay in milliseconds
|
|
11
|
+
* @returns {Promise<void>} Promise that resolves after delay
|
|
12
|
+
*/
|
|
13
|
+
function delay(ms) {
|
|
14
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Wraps a promise with a timeout
|
|
19
|
+
* @template T
|
|
20
|
+
* @param {Promise<T>} promise - Promise to wrap
|
|
21
|
+
* @param {number} ms - Timeout in milliseconds
|
|
22
|
+
* @param {string} [message='Operation timed out'] - Error message on timeout
|
|
23
|
+
* @returns {Promise<T>} Promise that rejects on timeout
|
|
24
|
+
*/
|
|
25
|
+
function withTimeout(promise, ms, message = 'Operation timed out') {
|
|
26
|
+
let timeoutId;
|
|
27
|
+
|
|
28
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
29
|
+
timeoutId = setTimeout(() => {
|
|
30
|
+
reject(new Error(message));
|
|
31
|
+
}, ms);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return Promise.race([
|
|
35
|
+
promise.then(result => {
|
|
36
|
+
clearTimeout(timeoutId);
|
|
37
|
+
return result;
|
|
38
|
+
}).catch(error => {
|
|
39
|
+
clearTimeout(timeoutId);
|
|
40
|
+
throw error;
|
|
41
|
+
}),
|
|
42
|
+
timeoutPromise
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns the current timestamp in milliseconds
|
|
48
|
+
* @returns {number} Current timestamp in milliseconds since epoch
|
|
49
|
+
*/
|
|
50
|
+
function now() {
|
|
51
|
+
return Date.now();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Returns a high-resolution timestamp for performance measurements
|
|
56
|
+
* Falls back to Date.now() if performance API is not available
|
|
57
|
+
* @returns {number} High-resolution timestamp
|
|
58
|
+
*/
|
|
59
|
+
function hrTime() {
|
|
60
|
+
if (typeof performance !== 'undefined' && performance.now) {
|
|
61
|
+
return performance.now();
|
|
62
|
+
}
|
|
63
|
+
return Date.now();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Calculates time elapsed since a given timestamp
|
|
68
|
+
* @param {number} startTime - Start timestamp
|
|
69
|
+
* @returns {number} Elapsed time in milliseconds
|
|
70
|
+
*/
|
|
71
|
+
function elapsed(startTime) {
|
|
72
|
+
return now() - startTime;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Checks if a timestamp has expired based on a TTL
|
|
77
|
+
* @param {number} timestamp - Timestamp to check
|
|
78
|
+
* @param {number} ttlMs - Time-to-live in milliseconds
|
|
79
|
+
* @returns {boolean} True if timestamp has expired
|
|
80
|
+
*/
|
|
81
|
+
function isExpired(timestamp, ttlMs) {
|
|
82
|
+
return now() > timestamp + ttlMs;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Formats a duration in milliseconds to a human-readable string
|
|
87
|
+
* @param {number} ms - Duration in milliseconds
|
|
88
|
+
* @returns {string} Formatted duration (e.g., "5m 30s")
|
|
89
|
+
*/
|
|
90
|
+
function formatDuration(ms) {
|
|
91
|
+
if (ms < 1000) {
|
|
92
|
+
return `${ms}ms`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const seconds = Math.floor(ms / 1000) % 60;
|
|
96
|
+
const minutes = Math.floor(ms / 60000) % 60;
|
|
97
|
+
const hours = Math.floor(ms / 3600000);
|
|
98
|
+
|
|
99
|
+
const parts = [];
|
|
100
|
+
|
|
101
|
+
if (hours > 0) {
|
|
102
|
+
parts.push(`${hours}h`);
|
|
103
|
+
}
|
|
104
|
+
if (minutes > 0) {
|
|
105
|
+
parts.push(`${minutes}m`);
|
|
106
|
+
}
|
|
107
|
+
if (seconds > 0) {
|
|
108
|
+
parts.push(`${seconds}s`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return parts.join(' ') || '0s';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Creates a debounced function that delays invocation
|
|
116
|
+
* @template T
|
|
117
|
+
* @param {function(...*): T} fn - Function to debounce
|
|
118
|
+
* @param {number} waitMs - Delay in milliseconds
|
|
119
|
+
* @returns {function(...*): void} Debounced function
|
|
120
|
+
*/
|
|
121
|
+
function debounce(fn, waitMs) {
|
|
122
|
+
let timeoutId = null;
|
|
123
|
+
|
|
124
|
+
return function debounced(...args) {
|
|
125
|
+
if (timeoutId !== null) {
|
|
126
|
+
clearTimeout(timeoutId);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
timeoutId = setTimeout(() => {
|
|
130
|
+
timeoutId = null;
|
|
131
|
+
fn.apply(this, args);
|
|
132
|
+
}, waitMs);
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Creates a throttled function that only invokes at most once per interval
|
|
138
|
+
* @template T
|
|
139
|
+
* @param {function(...*): T} fn - Function to throttle
|
|
140
|
+
* @param {number} intervalMs - Minimum interval in milliseconds
|
|
141
|
+
* @returns {function(...*): T|undefined} Throttled function
|
|
142
|
+
*/
|
|
143
|
+
function throttle(fn, intervalMs) {
|
|
144
|
+
let lastCall = 0;
|
|
145
|
+
|
|
146
|
+
return function throttled(...args) {
|
|
147
|
+
const currentTime = now();
|
|
148
|
+
|
|
149
|
+
if (currentTime - lastCall >= intervalMs) {
|
|
150
|
+
lastCall = currentTime;
|
|
151
|
+
return fn.apply(this, args);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = {
|
|
157
|
+
delay,
|
|
158
|
+
withTimeout,
|
|
159
|
+
now,
|
|
160
|
+
hrTime,
|
|
161
|
+
elapsed,
|
|
162
|
+
isExpired,
|
|
163
|
+
formatDuration,
|
|
164
|
+
debounce,
|
|
165
|
+
throttle
|
|
166
|
+
};
|