react-native-ble-mesh 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/package.json +1 -1
  2. package/src/MeshNetwork.js +48 -46
  3. package/src/constants/audio.js +4 -4
  4. package/src/constants/ble.js +1 -1
  5. package/src/constants/crypto.js +1 -1
  6. package/src/constants/errors.js +2 -2
  7. package/src/constants/events.js +1 -1
  8. package/src/constants/protocol.js +2 -2
  9. package/src/crypto/AutoCrypto.js +2 -0
  10. package/src/crypto/CryptoProvider.js +17 -17
  11. package/src/crypto/providers/ExpoCryptoProvider.js +12 -7
  12. package/src/crypto/providers/QuickCryptoProvider.js +12 -7
  13. package/src/crypto/providers/TweetNaClProvider.js +9 -7
  14. package/src/errors/AudioError.js +2 -1
  15. package/src/errors/ConnectionError.js +2 -2
  16. package/src/errors/CryptoError.js +1 -1
  17. package/src/errors/HandshakeError.js +2 -2
  18. package/src/errors/MeshError.js +4 -4
  19. package/src/errors/MessageError.js +2 -2
  20. package/src/errors/ValidationError.js +3 -3
  21. package/src/expo/withBLEMesh.js +10 -10
  22. package/src/hooks/AppStateManager.js +2 -1
  23. package/src/hooks/useMesh.js +7 -7
  24. package/src/hooks/useMessages.js +13 -12
  25. package/src/hooks/usePeers.js +10 -9
  26. package/src/index.js +2 -2
  27. package/src/mesh/dedup/BloomFilter.js +1 -0
  28. package/src/mesh/dedup/DedupManager.js +4 -7
  29. package/src/mesh/dedup/MessageCache.js +3 -0
  30. package/src/mesh/fragment/Assembler.js +5 -4
  31. package/src/mesh/fragment/Fragmenter.js +2 -2
  32. package/src/mesh/monitor/ConnectionQuality.js +17 -8
  33. package/src/mesh/monitor/NetworkMonitor.js +22 -15
  34. package/src/mesh/peer/Peer.js +4 -9
  35. package/src/mesh/peer/PeerDiscovery.js +18 -19
  36. package/src/mesh/peer/PeerManager.js +14 -14
  37. package/src/mesh/router/MessageRouter.js +15 -15
  38. package/src/mesh/router/PathFinder.js +10 -13
  39. package/src/mesh/router/RouteTable.js +8 -7
  40. package/src/mesh/store/StoreAndForwardManager.js +20 -23
  41. package/src/protocol/message.js +5 -13
  42. package/src/protocol/serializer.js +4 -4
  43. package/src/protocol/validator.js +7 -6
  44. package/src/service/BatteryOptimizer.js +18 -17
  45. package/src/service/EmergencyManager.js +18 -25
  46. package/src/service/HandshakeManager.js +100 -2
  47. package/src/service/MeshService.js +106 -22
  48. package/src/service/SessionManager.js +38 -3
  49. package/src/service/audio/AudioManager.js +80 -38
  50. package/src/service/audio/buffer/FrameBuffer.js +7 -8
  51. package/src/service/audio/buffer/JitterBuffer.js +1 -1
  52. package/src/service/audio/codec/LC3Codec.js +18 -19
  53. package/src/service/audio/codec/LC3Decoder.js +10 -10
  54. package/src/service/audio/codec/LC3Encoder.js +11 -9
  55. package/src/service/audio/session/AudioSession.js +14 -17
  56. package/src/service/audio/session/VoiceMessage.js +15 -22
  57. package/src/service/audio/transport/AudioFragmenter.js +17 -9
  58. package/src/service/audio/transport/AudioFramer.js +8 -12
  59. package/src/service/file/FileAssembler.js +4 -2
  60. package/src/service/file/FileChunker.js +1 -1
  61. package/src/service/file/FileManager.js +26 -20
  62. package/src/service/file/FileMessage.js +7 -12
  63. package/src/service/text/TextManager.js +55 -28
  64. package/src/service/text/broadcast/BroadcastManager.js +14 -17
  65. package/src/service/text/channel/Channel.js +10 -14
  66. package/src/service/text/channel/ChannelManager.js +10 -10
  67. package/src/service/text/message/TextMessage.js +12 -19
  68. package/src/service/text/message/TextSerializer.js +2 -2
  69. package/src/storage/AsyncStorageAdapter.js +17 -14
  70. package/src/storage/MemoryStorage.js +11 -8
  71. package/src/storage/MessageStore.js +22 -30
  72. package/src/storage/Storage.js +9 -9
  73. package/src/transport/BLETransport.js +16 -14
  74. package/src/transport/MockTransport.js +7 -2
  75. package/src/transport/MultiTransport.js +13 -6
  76. package/src/transport/Transport.js +9 -9
  77. package/src/transport/WiFiDirectTransport.js +22 -17
  78. package/src/transport/adapters/BLEAdapter.js +19 -19
  79. package/src/transport/adapters/NodeBLEAdapter.js +24 -23
  80. package/src/transport/adapters/RNBLEAdapter.js +14 -11
  81. package/src/utils/EventEmitter.js +9 -7
  82. package/src/utils/LRUCache.js +10 -4
  83. package/src/utils/RateLimiter.js +1 -1
  84. package/src/utils/compression.js +5 -5
  85. package/src/utils/encoding.js +8 -2
  86. package/src/utils/retry.js +11 -13
  87. package/src/utils/time.js +9 -4
  88. package/src/utils/validation.js +1 -1
@@ -13,7 +13,7 @@ const { ConnectionError } = require('../errors');
13
13
 
14
14
  /**
15
15
  * Wi-Fi Direct transport states
16
- * @constant {Object}
16
+ * @constant {any}
17
17
  */
18
18
  const WIFI_DIRECT_STATE = Object.freeze({
19
19
  AVAILABLE: 'available',
@@ -46,6 +46,7 @@ class WiFiDirectTransport extends Transport {
46
46
  this._isDiscovering = false;
47
47
  this._isGroupOwner = false;
48
48
  this._groupInfo = null;
49
+ /** @type {any} */
49
50
  this._subscriptions = [];
50
51
  }
51
52
 
@@ -75,16 +76,16 @@ class WiFiDirectTransport extends Transport {
75
76
 
76
77
  try {
77
78
  const p2p = this._getWifiP2p();
78
- await p2p.initialize();
79
+ await p2p?.initialize();
79
80
 
80
81
  // Check if Wi-Fi Direct is supported
81
- const isAvailable = await p2p.isSuccessfulInitialize();
82
+ const isAvailable = await p2p?.isSuccessfulInitialize();
82
83
  if (!isAvailable) {
83
84
  throw new ConnectionError('Wi-Fi Direct is not available on this device', 'E100');
84
85
  }
85
86
 
86
87
  this._setState(Transport.STATE.RUNNING);
87
- } catch (error) {
88
+ } catch (/** @type {any} */ error) {
88
89
  this._setState(Transport.STATE.ERROR);
89
90
  throw error;
90
91
  }
@@ -107,13 +108,13 @@ class WiFiDirectTransport extends Transport {
107
108
 
108
109
  // Disconnect from group
109
110
  try {
110
- await p2p.removeGroup();
111
+ await p2p?.removeGroup();
111
112
  } catch (e) {
112
113
  // Ignore — may not be in a group
113
114
  }
114
115
 
115
116
  // Cleanup subscriptions
116
- this._subscriptions.forEach(sub => {
117
+ this._subscriptions.forEach((/** @type {any} */ sub) => {
117
118
  if (sub && typeof sub.remove === 'function') { sub.remove(); }
118
119
  });
119
120
  this._subscriptions = [];
@@ -132,7 +133,7 @@ class WiFiDirectTransport extends Transport {
132
133
  if (!this.isRunning || this._isDiscovering) { return; }
133
134
 
134
135
  const p2p = this._getWifiP2p();
135
- await p2p.discoverPeers();
136
+ await p2p?.discoverPeers();
136
137
  this._isDiscovering = true;
137
138
  this.emit('discoveryStarted');
138
139
  }
@@ -146,7 +147,7 @@ class WiFiDirectTransport extends Transport {
146
147
 
147
148
  const p2p = this._getWifiP2p();
148
149
  try {
149
- await p2p.stopDiscoveringPeers();
150
+ await p2p?.stopDiscoveringPeers();
150
151
  } catch (e) {
151
152
  // Ignore
152
153
  }
@@ -173,9 +174,9 @@ class WiFiDirectTransport extends Transport {
173
174
  const p2p = this._getWifiP2p();
174
175
 
175
176
  try {
176
- await p2p.connect(peerId);
177
+ await p2p?.connect(peerId);
177
178
 
178
- const connectionInfo = await p2p.getConnectionInfo();
179
+ const connectionInfo = await p2p?.getConnectionInfo();
179
180
  this._isGroupOwner = connectionInfo.isGroupOwner || false;
180
181
  this._groupInfo = connectionInfo;
181
182
 
@@ -187,7 +188,7 @@ class WiFiDirectTransport extends Transport {
187
188
  });
188
189
 
189
190
  this.emit('peerConnected', { peerId, transport: 'wifi-direct' });
190
- } catch (error) {
191
+ } catch (/** @type {any} */ error) {
191
192
  throw ConnectionError.connectionFailed(peerId, { cause: error.message });
192
193
  }
193
194
  }
@@ -202,7 +203,7 @@ class WiFiDirectTransport extends Transport {
202
203
 
203
204
  const p2p = this._getWifiP2p();
204
205
  try {
205
- await p2p.removeGroup();
206
+ await p2p?.removeGroup();
206
207
  } catch (e) {
207
208
  // Ignore
208
209
  }
@@ -231,10 +232,10 @@ class WiFiDirectTransport extends Transport {
231
232
 
232
233
  if (this._isGroupOwner) {
233
234
  // Group owner sends via server socket
234
- await p2p.sendMessage(base64);
235
+ await p2p?.sendMessage(base64);
235
236
  } else {
236
237
  // Client sends to group owner address
237
- await p2p.sendMessageTo(peerInfo.groupOwnerAddress, this._port, base64);
238
+ await p2p?.sendMessageTo(peerInfo.groupOwnerAddress, this._port, base64);
238
239
  }
239
240
  }
240
241
 
@@ -261,16 +262,20 @@ class WiFiDirectTransport extends Transport {
261
262
  if (!this.isRunning) { return []; }
262
263
  const p2p = this._getWifiP2p();
263
264
  try {
264
- return await p2p.getAvailablePeers();
265
+ return await p2p?.getAvailablePeers();
265
266
  } catch (e) {
266
267
  return [];
267
268
  }
268
269
  }
269
270
 
270
- /** @private */
271
+ /**
272
+ * @private
273
+ * @returns {any}
274
+ */
271
275
  _getWifiP2p() {
272
276
  if (!this._wifiP2p) {
273
277
  try {
278
+ // @ts-ignore
274
279
  this._wifiP2p = require('react-native-wifi-p2p');
275
280
  } catch (e) {
276
281
  throw new Error(
@@ -283,7 +288,7 @@ class WiFiDirectTransport extends Transport {
283
288
  }
284
289
 
285
290
  /** @private */
286
- _uint8ArrayToBase64(bytes) {
291
+ _uint8ArrayToBase64(/** @type {any} */ bytes) {
287
292
  const chunks = [];
288
293
  for (let i = 0; i < bytes.length; i += 8192) {
289
294
  chunks.push(String.fromCharCode.apply(null, bytes.subarray(i, Math.min(i + 8192, bytes.length))));
@@ -17,12 +17,12 @@ const { BLUETOOTH_STATE } = require('../../constants');
17
17
  class BLEAdapter {
18
18
  /**
19
19
  * Creates a new BLEAdapter instance
20
- * @param {Object} [options={}] - Adapter options
20
+ * @param {any} [options={}] - Adapter options
21
21
  */
22
22
  constructor(options = {}) {
23
23
  /**
24
24
  * Adapter options
25
- * @type {Object}
25
+ * @type {any}
26
26
  * @protected
27
27
  */
28
28
  this._options = options;
@@ -73,12 +73,12 @@ class BLEAdapter {
73
73
  /**
74
74
  * Starts scanning for BLE devices
75
75
  * @abstract
76
- * @param {string[]} serviceUUIDs - Service UUIDs to filter by
77
- * @param {Function} callback - Callback for discovered devices
76
+ * @param {string[]} _serviceUUIDs - Service UUIDs to filter by
77
+ * @param {Function} _callback - Callback for discovered devices
78
78
  * @returns {Promise<void>}
79
79
  * @throws {Error} If not implemented by subclass
80
80
  */
81
- async startScan(_serviceUUIDs, _callback) {
81
+ async startScan(/** @type {any} */ _serviceUUIDs, _callback) {
82
82
  throw new Error('BLEAdapter.startScan() must be implemented by subclass');
83
83
  }
84
84
 
@@ -94,50 +94,50 @@ class BLEAdapter {
94
94
  /**
95
95
  * Connects to a BLE device
96
96
  * @abstract
97
- * @param {string} deviceId - Device ID to connect to
97
+ * @param {string} _deviceId - Device ID to connect to
98
98
  * @returns {Promise<Object>} Connected device info
99
99
  * @throws {Error} If not implemented by subclass
100
100
  */
101
- async connect(_deviceId) {
101
+ async connect(/** @type {any} */ _deviceId) {
102
102
  throw new Error('BLEAdapter.connect() must be implemented by subclass');
103
103
  }
104
104
 
105
105
  /**
106
106
  * Disconnects from a BLE device
107
107
  * @abstract
108
- * @param {string} deviceId - Device ID to disconnect from
108
+ * @param {string} _deviceId - Device ID to disconnect from
109
109
  * @returns {Promise<void>}
110
110
  * @throws {Error} If not implemented by subclass
111
111
  */
112
- async disconnect(_deviceId) {
112
+ async disconnect(/** @type {any} */ _deviceId) {
113
113
  throw new Error('BLEAdapter.disconnect() must be implemented by subclass');
114
114
  }
115
115
 
116
116
  /**
117
117
  * Writes data to a characteristic
118
118
  * @abstract
119
- * @param {string} deviceId - Target device ID
120
- * @param {string} serviceUUID - Service UUID
121
- * @param {string} charUUID - Characteristic UUID
122
- * @param {Uint8Array} data - Data to write
119
+ * @param {string} _deviceId - Target device ID
120
+ * @param {string} _serviceUUID - Service UUID
121
+ * @param {string} _charUUID - Characteristic UUID
122
+ * @param {Uint8Array} _data - Data to write
123
123
  * @returns {Promise<void>}
124
124
  * @throws {Error} If not implemented by subclass
125
125
  */
126
- async write(_deviceId, _serviceUUID, _charUUID, _data) {
126
+ async write(/** @type {any} */ _deviceId, _serviceUUID, _charUUID, _data) {
127
127
  throw new Error('BLEAdapter.write() must be implemented by subclass');
128
128
  }
129
129
 
130
130
  /**
131
131
  * Subscribes to characteristic notifications
132
132
  * @abstract
133
- * @param {string} deviceId - Target device ID
134
- * @param {string} serviceUUID - Service UUID
135
- * @param {string} charUUID - Characteristic UUID
136
- * @param {Function} callback - Notification callback
133
+ * @param {string} _deviceId - Target device ID
134
+ * @param {string} _serviceUUID - Service UUID
135
+ * @param {string} _charUUID - Characteristic UUID
136
+ * @param {Function} _callback - Notification callback
137
137
  * @returns {Promise<void>}
138
138
  * @throws {Error} If not implemented by subclass
139
139
  */
140
- async subscribe(_deviceId, _serviceUUID, _charUUID, _callback) {
140
+ async subscribe(/** @type {any} */ _deviceId, _serviceUUID, _charUUID, _callback) {
141
141
  throw new Error('BLEAdapter.subscribe() must be implemented by subclass');
142
142
  }
143
143
 
@@ -21,35 +21,35 @@ class NodeBLEAdapter extends BLEAdapter {
21
21
  /**
22
22
  * Creates a new NodeBLEAdapter instance
23
23
  * @param {Object} [options={}] - Adapter options
24
- * @param {Object} [options.noble] - Noble instance
24
+ * @param {any} [options.noble] - Noble instance
25
25
  */
26
26
  constructor(options = {}) {
27
27
  super(options);
28
28
 
29
29
  /**
30
30
  * Noble instance
31
- * @type {Object|null}
31
+ * @type {any}
32
32
  * @private
33
33
  */
34
34
  this._noble = options.noble || null;
35
35
 
36
36
  /**
37
37
  * Connected peripherals map
38
- * @type {Map<string, Object>}
38
+ * @type {Map<string, any>}
39
39
  * @private
40
40
  */
41
41
  this._peripherals = new Map();
42
42
 
43
43
  /**
44
44
  * Discovered peripherals cache
45
- * @type {Map<string, Object>}
45
+ * @type {Map<string, any>}
46
46
  * @private
47
47
  */
48
48
  this._discoveredPeripherals = new Map();
49
49
 
50
50
  /**
51
51
  * Subscription handlers map
52
- * @type {Map<string, Object>}
52
+ * @type {Map<string, any>}
53
53
  * @private
54
54
  */
55
55
  this._subscriptions = new Map();
@@ -82,6 +82,7 @@ class NodeBLEAdapter extends BLEAdapter {
82
82
  // Try to load noble if not provided
83
83
  if (!this._noble) {
84
84
  try {
85
+ // @ts-ignore
85
86
  this._noble = require('@abandonware/noble');
86
87
  } catch (error) {
87
88
  throw new Error(
@@ -91,7 +92,7 @@ class NodeBLEAdapter extends BLEAdapter {
91
92
  }
92
93
 
93
94
  // Set up state change listener
94
- this._noble.on('stateChange', (state) => {
95
+ this._noble.on('stateChange', (/** @type {any} */ state) => {
95
96
  this._notifyStateChange(this._mapState(state));
96
97
  });
97
98
 
@@ -141,7 +142,7 @@ class NodeBLEAdapter extends BLEAdapter {
141
142
  uuid.toLowerCase().replace(/-/g, '')
142
143
  );
143
144
 
144
- this._noble.on('discover', (peripheral) => {
145
+ this._noble.on('discover', (/** @type {any} */ peripheral) => {
145
146
  this._discoveredPeripherals.set(peripheral.id, peripheral);
146
147
 
147
148
  if (this._scanCallback) {
@@ -284,7 +285,7 @@ class NodeBLEAdapter extends BLEAdapter {
284
285
  throw new Error(`Characteristic ${charUUID} not found`);
285
286
  }
286
287
 
287
- characteristic.on('data', (data) => {
288
+ characteristic.on('data', (/** @type {any} */ data) => {
288
289
  callback(new Uint8Array(data));
289
290
  });
290
291
 
@@ -318,7 +319,7 @@ class NodeBLEAdapter extends BLEAdapter {
318
319
  poweredOff: BLEAdapter.STATE.POWERED_OFF,
319
320
  poweredOn: BLEAdapter.STATE.POWERED_ON
320
321
  };
321
- return stateMap[state] || BLEAdapter.STATE.UNKNOWN;
322
+ return /** @type {any} */ (stateMap)[state] || BLEAdapter.STATE.UNKNOWN;
322
323
  }
323
324
 
324
325
  /**
@@ -336,7 +337,7 @@ class NodeBLEAdapter extends BLEAdapter {
336
337
  reject(new Error('Bluetooth initialization timeout'));
337
338
  }, 10000);
338
339
 
339
- this._noble.once('stateChange', (state) => {
340
+ this._noble.once('stateChange', (/** @type {any} */ state) => {
340
341
  clearTimeout(timeout);
341
342
  if (state === 'poweredOn') {
342
343
  resolve();
@@ -349,13 +350,13 @@ class NodeBLEAdapter extends BLEAdapter {
349
350
 
350
351
  /**
351
352
  * Connects to a peripheral
352
- * @param {Object} peripheral - Noble peripheral
353
+ * @param {any} peripheral - Noble peripheral
353
354
  * @returns {Promise<void>}
354
355
  * @private
355
356
  */
356
357
  _connectPeripheral(peripheral) {
357
358
  return new Promise((resolve, reject) => {
358
- peripheral.connect((error) => {
359
+ peripheral.connect((/** @type {any} */ error) => {
359
360
  if (error) { reject(error); } else { resolve(); }
360
361
  });
361
362
  });
@@ -363,7 +364,7 @@ class NodeBLEAdapter extends BLEAdapter {
363
364
 
364
365
  /**
365
366
  * Disconnects from a peripheral
366
- * @param {Object} peripheral - Noble peripheral
367
+ * @param {any} peripheral - Noble peripheral
367
368
  * @returns {Promise<void>}
368
369
  * @private
369
370
  */
@@ -375,13 +376,13 @@ class NodeBLEAdapter extends BLEAdapter {
375
376
 
376
377
  /**
377
378
  * Discovers services and characteristics
378
- * @param {Object} peripheral - Noble peripheral
379
+ * @param {any} peripheral - Noble peripheral
379
380
  * @returns {Promise<void>}
380
381
  * @private
381
382
  */
382
383
  _discoverServices(peripheral) {
383
384
  return new Promise((resolve, reject) => {
384
- peripheral.discoverAllServicesAndCharacteristics((error) => {
385
+ peripheral.discoverAllServicesAndCharacteristics((/** @type {any} */ error) => {
385
386
  if (error) { reject(error); } else { resolve(); }
386
387
  });
387
388
  });
@@ -389,10 +390,10 @@ class NodeBLEAdapter extends BLEAdapter {
389
390
 
390
391
  /**
391
392
  * Finds a characteristic on a peripheral
392
- * @param {Object} peripheral - Noble peripheral
393
+ * @param {any} peripheral - Noble peripheral
393
394
  * @param {string} serviceUUID - Service UUID
394
395
  * @param {string} charUUID - Characteristic UUID
395
- * @returns {Object|null} Characteristic or null
396
+ * @returns {any} Characteristic or null
396
397
  * @private
397
398
  */
398
399
  _findCharacteristic(peripheral, serviceUUID, charUUID) {
@@ -400,23 +401,23 @@ class NodeBLEAdapter extends BLEAdapter {
400
401
  const formattedCharUUID = charUUID.toLowerCase().replace(/-/g, '');
401
402
 
402
403
  const service = peripheral.services?.find(
403
- s => s.uuid === formattedServiceUUID
404
+ (/** @type {any} */ s) => s.uuid === formattedServiceUUID
404
405
  );
405
406
  return service?.characteristics?.find(
406
- c => c.uuid === formattedCharUUID
407
+ (/** @type {any} */ c) => c.uuid === formattedCharUUID
407
408
  ) || null;
408
409
  }
409
410
 
410
411
  /**
411
412
  * Writes to a characteristic
412
- * @param {Object} characteristic - Noble characteristic
413
+ * @param {any} characteristic - Noble characteristic
413
414
  * @param {Buffer} data - Data to write
414
415
  * @returns {Promise<void>}
415
416
  * @private
416
417
  */
417
418
  _writeCharacteristic(characteristic, data) {
418
419
  return new Promise((resolve, reject) => {
419
- characteristic.write(data, false, (error) => {
420
+ characteristic.write(data, false, (/** @type {any} */ error) => {
420
421
  if (error) { reject(error); } else { resolve(); }
421
422
  });
422
423
  });
@@ -424,13 +425,13 @@ class NodeBLEAdapter extends BLEAdapter {
424
425
 
425
426
  /**
426
427
  * Subscribes to a characteristic
427
- * @param {Object} characteristic - Noble characteristic
428
+ * @param {any} characteristic - Noble characteristic
428
429
  * @returns {Promise<void>}
429
430
  * @private
430
431
  */
431
432
  _subscribeCharacteristic(characteristic) {
432
433
  return new Promise((resolve, reject) => {
433
- characteristic.subscribe((error) => {
434
+ characteristic.subscribe((/** @type {any} */ error) => {
434
435
  if (error) { reject(error); } else { resolve(); }
435
436
  });
436
437
  });
@@ -21,14 +21,14 @@ class RNBLEAdapter extends BLEAdapter {
21
21
  /**
22
22
  * Creates a new RNBLEAdapter instance
23
23
  * @param {Object} [options={}] - Adapter options
24
- * @param {Object} [options.BleManager] - BleManager class from react-native-ble-plx
24
+ * @param {any} [options.BleManager] - BleManager class from react-native-ble-plx
25
25
  */
26
26
  constructor(options = {}) {
27
27
  super(options);
28
28
 
29
29
  /**
30
30
  * BleManager instance
31
- * @type {Object|null}
31
+ * @type {any}
32
32
  * @private
33
33
  */
34
34
  this._manager = null;
@@ -45,32 +45,33 @@ class RNBLEAdapter extends BLEAdapter {
45
45
  * @type {string|null}
46
46
  * @private
47
47
  */
48
+ // @ts-ignore
48
49
  this._restoreIdentifier = options.restoreIdentifier || null;
49
50
 
50
51
  /**
51
52
  * Connected devices map
52
- * @type {Map<string, Object>}
53
+ * @type {Map<string, any>}
53
54
  * @private
54
55
  */
55
56
  this._devices = new Map();
56
57
 
57
58
  /**
58
59
  * Subscription handlers map
59
- * @type {Map<string, Object>}
60
+ * @type {Map<string, any>}
60
61
  * @private
61
62
  */
62
63
  this._subscriptions = new Map();
63
64
 
64
65
  /**
65
66
  * Scan subscription reference
66
- * @type {Object|null}
67
+ * @type {any}
67
68
  * @private
68
69
  */
69
70
  this._scanSubscription = null;
70
71
 
71
72
  /**
72
73
  * State subscription reference
73
- * @type {Object|null}
74
+ * @type {any}
74
75
  * @private
75
76
  */
76
77
  this._stateSubscription = null;
@@ -96,6 +97,7 @@ class RNBLEAdapter extends BLEAdapter {
96
97
  // Try to load BleManager if not provided
97
98
  if (!this._BleManager) {
98
99
  try {
100
+ // @ts-ignore
99
101
  const blePlx = require('react-native-ble-plx');
100
102
  this._BleManager = blePlx.BleManager;
101
103
  } catch (error) {
@@ -108,7 +110,7 @@ class RNBLEAdapter extends BLEAdapter {
108
110
  const managerOptions = {};
109
111
  if (this._restoreIdentifier) {
110
112
  managerOptions.restoreStateIdentifier = this._restoreIdentifier;
111
- managerOptions.restoreStateFunction = (restoredState) => {
113
+ managerOptions.restoreStateFunction = (/** @type {any} */ restoredState) => {
112
114
  // Re-populate devices from restored state
113
115
  if (restoredState && restoredState.connectedPeripherals) {
114
116
  for (const peripheral of restoredState.connectedPeripherals) {
@@ -117,10 +119,11 @@ class RNBLEAdapter extends BLEAdapter {
117
119
  }
118
120
  };
119
121
  }
122
+ // @ts-ignore
120
123
  this._manager = new this._BleManager(managerOptions);
121
124
 
122
125
  // Subscribe to state changes
123
- this._stateSubscription = this._manager.onStateChange((state) => {
126
+ this._stateSubscription = this._manager.onStateChange((/** @type {any} */ state) => {
124
127
  this._notifyStateChange(this._mapState(state));
125
128
  }, true);
126
129
 
@@ -174,7 +177,7 @@ class RNBLEAdapter extends BLEAdapter {
174
177
  async startScan(serviceUUIDs, callback) {
175
178
  this._ensureInitialized();
176
179
 
177
- this._manager.startDeviceScan(serviceUUIDs, null, (error, device) => {
180
+ this._manager.startDeviceScan(serviceUUIDs, null, (/** @type {any} */ error, /** @type {any} */ device) => {
178
181
  if (error) {
179
182
  return;
180
183
  }
@@ -292,7 +295,7 @@ class RNBLEAdapter extends BLEAdapter {
292
295
  deviceId,
293
296
  serviceUUID,
294
297
  charUUID,
295
- (error, characteristic) => {
298
+ (/** @type {any} */ error, /** @type {any} */ characteristic) => {
296
299
  if (!error && characteristic) {
297
300
  const data = this._base64ToUint8Array(characteristic.value);
298
301
  callback(data);
@@ -328,7 +331,7 @@ class RNBLEAdapter extends BLEAdapter {
328
331
  PoweredOff: BLEAdapter.STATE.POWERED_OFF,
329
332
  PoweredOn: BLEAdapter.STATE.POWERED_ON
330
333
  };
331
- return stateMap[state] || BLEAdapter.STATE.UNKNOWN;
334
+ return /** @type {any} */ (stateMap)[state] || BLEAdapter.STATE.UNKNOWN;
332
335
  }
333
336
 
334
337
  /**
@@ -12,8 +12,8 @@
12
12
  class EventEmitter {
13
13
  /**
14
14
  * Creates a new EventEmitter
15
- * @param {Object} [options] - Configuration options
16
- * @param {number} [options.maxListeners=10] - Maximum listeners per event
15
+ * @param {any} [options] - Configuration options
16
+ *
17
17
  */
18
18
  constructor(options = {}) {
19
19
  /**
@@ -47,6 +47,7 @@ class EventEmitter {
47
47
  }
48
48
 
49
49
  const listeners = this._events.get(event);
50
+ if (!listeners) { return this; }
50
51
 
51
52
  // Warn if max listeners exceeded
52
53
  if (listeners.length >= this._maxListeners) {
@@ -76,7 +77,7 @@ class EventEmitter {
76
77
  this._events.set(event, []);
77
78
  }
78
79
 
79
- this._events.get(event).push({ listener, once: true });
80
+ this._events.get(event)?.push({ listener, once: true });
80
81
  return this;
81
82
  }
82
83
 
@@ -92,13 +93,13 @@ class EventEmitter {
92
93
  }
93
94
 
94
95
  const listeners = this._events.get(event);
95
- const index = listeners.findIndex(entry => entry.listener === listener);
96
+ const index = listeners?.findIndex(entry => entry.listener === listener) ?? -1;
96
97
 
97
98
  if (index !== -1) {
98
- listeners.splice(index, 1);
99
+ listeners?.splice(index, 1);
99
100
  }
100
101
 
101
- if (listeners.length === 0) {
102
+ if (listeners?.length === 0) {
102
103
  this._events.delete(event);
103
104
  }
104
105
 
@@ -117,6 +118,7 @@ class EventEmitter {
117
118
  }
118
119
 
119
120
  const listeners = this._events.get(event);
121
+ if (!listeners) { return false; }
120
122
  const hasOnce = listeners.some(e => e.once);
121
123
  const iterList = hasOnce ? listeners.slice() : listeners;
122
124
 
@@ -169,7 +171,7 @@ class EventEmitter {
169
171
  if (!this._events.has(event)) {
170
172
  return 0;
171
173
  }
172
- return this._events.get(event).length;
174
+ return this._events.get(event)?.length ?? 0;
173
175
  }
174
176
 
175
177
  /**
@@ -47,7 +47,7 @@ class LRUCache {
47
47
  }
48
48
 
49
49
  // Move to end (most recently used)
50
- const value = this._cache.get(key);
50
+ const value = /** @type {V} */ (this._cache.get(key));
51
51
  this._cache.delete(key);
52
52
  this._cache.set(key, value);
53
53
 
@@ -67,7 +67,9 @@ class LRUCache {
67
67
  } else if (this._cache.size >= this._maxSize) {
68
68
  // Remove least recently used (first item)
69
69
  const firstKey = this._cache.keys().next().value;
70
- this._cache.delete(firstKey);
70
+ if (firstKey !== undefined) {
71
+ this._cache.delete(firstKey);
72
+ }
71
73
  }
72
74
 
73
75
  this._cache.set(key, value);
@@ -134,7 +136,7 @@ class LRUCache {
134
136
 
135
137
  /**
136
138
  * Returns all entries in the cache (most recent last)
137
- * @returns {Array} Array of [key, value] pairs
139
+ * @returns {any[]} Array of [key, value] pairs
138
140
  */
139
141
  entries() {
140
142
  return Array.from(this._cache.entries());
@@ -194,7 +196,11 @@ class LRUCache {
194
196
  // Evict oldest items if over new limit
195
197
  while (this._cache.size > this._maxSize) {
196
198
  const firstKey = this._cache.keys().next().value;
197
- this._cache.delete(firstKey);
199
+ if (firstKey !== undefined) {
200
+ this._cache.delete(firstKey);
201
+ } else {
202
+ break;
203
+ }
198
204
  }
199
205
  }
200
206
  }
@@ -162,7 +162,7 @@ class RateLimiter {
162
162
 
163
163
  /**
164
164
  * Gets rate limiter configuration
165
- * @returns {Object} Configuration object
165
+ * @returns {any} Configuration object
166
166
  */
167
167
  getConfig() {
168
168
  return {
@@ -15,7 +15,7 @@ const { ValidationError, MeshError } = require('../errors');
15
15
 
16
16
  /**
17
17
  * Default compression configuration
18
- * @constant {Object}
18
+ * @constant {any}
19
19
  */
20
20
  const DEFAULT_CONFIG = Object.freeze({
21
21
  /** Minimum payload size to compress (bytes) */
@@ -45,8 +45,8 @@ const DEFAULT_CONFIG = Object.freeze({
45
45
  class MessageCompressor {
46
46
  /**
47
47
  * Creates a new MessageCompressor instance.
48
- * @param {Object} [options={}] - Compression options
49
- * @param {number} [options.threshold=100] - Min size to compress
48
+ * @param {any} [options={}] - Compression options
49
+ *
50
50
  */
51
51
  constructor(options = {}) {
52
52
  this._config = { ...DEFAULT_CONFIG, ...options };
@@ -89,7 +89,7 @@ class MessageCompressor {
89
89
  this._stats.bytesOut += compressed.length;
90
90
  return { data: compressed, compressed: true };
91
91
  }
92
- } catch (error) {
92
+ } catch (/** @type {any} */ error) {
93
93
  // Log compression error at debug level for troubleshooting
94
94
  if (typeof console !== 'undefined' && console.debug) {
95
95
  console.debug('Compression failed, using uncompressed:', error.message);
@@ -132,7 +132,7 @@ class MessageCompressor {
132
132
 
133
133
  /**
134
134
  * Gets compression statistics.
135
- * @returns {Object} Statistics
135
+ * @returns {any} Statistics
136
136
  */
137
137
  getStats() {
138
138
  const ratio = this._stats.bytesIn > 0