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.
- package/package.json +1 -1
- package/src/MeshNetwork.js +48 -46
- package/src/constants/audio.js +4 -4
- package/src/constants/ble.js +1 -1
- package/src/constants/crypto.js +1 -1
- package/src/constants/errors.js +2 -2
- package/src/constants/events.js +1 -1
- package/src/constants/protocol.js +2 -2
- package/src/crypto/AutoCrypto.js +2 -0
- package/src/crypto/CryptoProvider.js +17 -17
- package/src/crypto/providers/ExpoCryptoProvider.js +12 -7
- package/src/crypto/providers/QuickCryptoProvider.js +12 -7
- package/src/crypto/providers/TweetNaClProvider.js +9 -7
- package/src/errors/AudioError.js +2 -1
- package/src/errors/ConnectionError.js +2 -2
- package/src/errors/CryptoError.js +1 -1
- package/src/errors/HandshakeError.js +2 -2
- package/src/errors/MeshError.js +4 -4
- package/src/errors/MessageError.js +2 -2
- package/src/errors/ValidationError.js +3 -3
- package/src/expo/withBLEMesh.js +10 -10
- package/src/hooks/AppStateManager.js +2 -1
- package/src/hooks/useMesh.js +7 -7
- package/src/hooks/useMessages.js +13 -12
- package/src/hooks/usePeers.js +10 -9
- package/src/index.js +2 -2
- package/src/mesh/dedup/BloomFilter.js +1 -0
- package/src/mesh/dedup/DedupManager.js +4 -7
- package/src/mesh/dedup/MessageCache.js +3 -0
- package/src/mesh/fragment/Assembler.js +5 -4
- package/src/mesh/fragment/Fragmenter.js +2 -2
- package/src/mesh/monitor/ConnectionQuality.js +17 -8
- package/src/mesh/monitor/NetworkMonitor.js +22 -15
- package/src/mesh/peer/Peer.js +4 -9
- package/src/mesh/peer/PeerDiscovery.js +18 -19
- package/src/mesh/peer/PeerManager.js +14 -14
- package/src/mesh/router/MessageRouter.js +15 -15
- package/src/mesh/router/PathFinder.js +10 -13
- package/src/mesh/router/RouteTable.js +8 -7
- package/src/mesh/store/StoreAndForwardManager.js +20 -23
- package/src/protocol/message.js +5 -13
- package/src/protocol/serializer.js +4 -4
- package/src/protocol/validator.js +7 -6
- package/src/service/BatteryOptimizer.js +18 -17
- package/src/service/EmergencyManager.js +18 -25
- package/src/service/HandshakeManager.js +100 -2
- package/src/service/MeshService.js +106 -22
- package/src/service/SessionManager.js +38 -3
- package/src/service/audio/AudioManager.js +80 -38
- package/src/service/audio/buffer/FrameBuffer.js +7 -8
- package/src/service/audio/buffer/JitterBuffer.js +1 -1
- package/src/service/audio/codec/LC3Codec.js +18 -19
- package/src/service/audio/codec/LC3Decoder.js +10 -10
- package/src/service/audio/codec/LC3Encoder.js +11 -9
- package/src/service/audio/session/AudioSession.js +14 -17
- package/src/service/audio/session/VoiceMessage.js +15 -22
- package/src/service/audio/transport/AudioFragmenter.js +17 -9
- package/src/service/audio/transport/AudioFramer.js +8 -12
- package/src/service/file/FileAssembler.js +4 -2
- package/src/service/file/FileChunker.js +1 -1
- package/src/service/file/FileManager.js +26 -20
- package/src/service/file/FileMessage.js +7 -12
- package/src/service/text/TextManager.js +55 -28
- package/src/service/text/broadcast/BroadcastManager.js +14 -17
- package/src/service/text/channel/Channel.js +10 -14
- package/src/service/text/channel/ChannelManager.js +10 -10
- package/src/service/text/message/TextMessage.js +12 -19
- package/src/service/text/message/TextSerializer.js +2 -2
- package/src/storage/AsyncStorageAdapter.js +17 -14
- package/src/storage/MemoryStorage.js +11 -8
- package/src/storage/MessageStore.js +22 -30
- package/src/storage/Storage.js +9 -9
- package/src/transport/BLETransport.js +16 -14
- package/src/transport/MockTransport.js +7 -2
- package/src/transport/MultiTransport.js +13 -6
- package/src/transport/Transport.js +9 -9
- package/src/transport/WiFiDirectTransport.js +22 -17
- package/src/transport/adapters/BLEAdapter.js +19 -19
- package/src/transport/adapters/NodeBLEAdapter.js +24 -23
- package/src/transport/adapters/RNBLEAdapter.js +14 -11
- package/src/utils/EventEmitter.js +9 -7
- package/src/utils/LRUCache.js +10 -4
- package/src/utils/RateLimiter.js +1 -1
- package/src/utils/compression.js +5 -5
- package/src/utils/encoding.js +8 -2
- package/src/utils/retry.js +11 -13
- package/src/utils/time.js +9 -4
- package/src/utils/validation.js +1 -1
|
@@ -18,9 +18,9 @@ const Storage = require('./Storage');
|
|
|
18
18
|
class MemoryStorage extends Storage {
|
|
19
19
|
/**
|
|
20
20
|
* Creates a new MemoryStorage instance
|
|
21
|
-
* @param {
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* @param {any} [options={}] - Storage options
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
24
|
*/
|
|
25
25
|
constructor(options = {}) {
|
|
26
26
|
super(options);
|
|
@@ -66,8 +66,8 @@ class MemoryStorage extends Storage {
|
|
|
66
66
|
* Sets a value by key
|
|
67
67
|
* @param {string} key - Key to set
|
|
68
68
|
* @param {any} value - Value to store
|
|
69
|
-
* @param {
|
|
70
|
-
*
|
|
69
|
+
* @param {any} [options={}] - Set options
|
|
70
|
+
*
|
|
71
71
|
* @returns {Promise<void>}
|
|
72
72
|
*/
|
|
73
73
|
async set(key, value, options = {}) {
|
|
@@ -79,9 +79,12 @@ class MemoryStorage extends Storage {
|
|
|
79
79
|
this._store.size >= this._maxSize) {
|
|
80
80
|
// Remove oldest entry (first entry in Map)
|
|
81
81
|
const firstKey = this._store.keys().next().value;
|
|
82
|
-
|
|
82
|
+
if (firstKey !== undefined) {
|
|
83
|
+
this._store.delete(firstKey);
|
|
84
|
+
}
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
/** @type {any} */
|
|
85
88
|
const item = {
|
|
86
89
|
value,
|
|
87
90
|
createdAt: Date.now()
|
|
@@ -156,7 +159,7 @@ class MemoryStorage extends Storage {
|
|
|
156
159
|
const unprefixedKey = prefix ? key.slice(prefix.length) : key;
|
|
157
160
|
// Check expiration before including
|
|
158
161
|
const item = this._store.get(key);
|
|
159
|
-
if (!item.expiresAt || Date.now() <= item.expiresAt) {
|
|
162
|
+
if (item && (!item.expiresAt || Date.now() <= item.expiresAt)) {
|
|
160
163
|
result.push(unprefixedKey);
|
|
161
164
|
}
|
|
162
165
|
}
|
|
@@ -196,7 +199,7 @@ class MemoryStorage extends Storage {
|
|
|
196
199
|
|
|
197
200
|
/**
|
|
198
201
|
* Gets all entries as an array of [key, value] pairs
|
|
199
|
-
* @returns {Promise<
|
|
202
|
+
* @returns {Promise<any[]>} Array of [key, value] entries
|
|
200
203
|
*/
|
|
201
204
|
async entries() {
|
|
202
205
|
const allKeys = await this.keys();
|
|
@@ -14,6 +14,10 @@ const { MESH_CONFIG } = require('../constants');
|
|
|
14
14
|
*/
|
|
15
15
|
const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @param {Uint8Array} bytes
|
|
19
|
+
* @returns {string}
|
|
20
|
+
*/
|
|
17
21
|
function uint8ArrayToBase64(bytes) {
|
|
18
22
|
let result = '';
|
|
19
23
|
const len = bytes.length;
|
|
@@ -34,6 +38,10 @@ for (let i = 0; i < BASE64_CHARS.length; i++) {
|
|
|
34
38
|
BASE64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i;
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @param {string} str
|
|
43
|
+
* @returns {Uint8Array}
|
|
44
|
+
*/
|
|
37
45
|
function base64ToUint8Array(str) {
|
|
38
46
|
const len = str.length;
|
|
39
47
|
let padding = 0;
|
|
@@ -63,15 +71,12 @@ function base64ToUint8Array(str) {
|
|
|
63
71
|
class MessageStore {
|
|
64
72
|
/**
|
|
65
73
|
* Creates a new MessageStore instance
|
|
66
|
-
* @param {
|
|
67
|
-
* @param {Object} [options.storage] - Storage backend (defaults to MemoryStorage)
|
|
68
|
-
* @param {number} [options.maxMessages=1000] - Maximum messages to store
|
|
69
|
-
* @param {number} [options.messageTtlMs] - Message TTL in milliseconds
|
|
74
|
+
* @param {any} [options={}] - Store options *
|
|
70
75
|
*/
|
|
71
76
|
constructor(options = {}) {
|
|
72
77
|
/**
|
|
73
78
|
* Storage backend
|
|
74
|
-
* @type {
|
|
79
|
+
* @type {any}
|
|
75
80
|
* @private
|
|
76
81
|
*/
|
|
77
82
|
this._storage = options.storage || new MemoryStorage({
|
|
@@ -88,7 +93,7 @@ class MessageStore {
|
|
|
88
93
|
|
|
89
94
|
/**
|
|
90
95
|
* Index storage for queries
|
|
91
|
-
* @type {
|
|
96
|
+
* @type {any}
|
|
92
97
|
* @private
|
|
93
98
|
*/
|
|
94
99
|
this._indexStorage = options.indexStorage || new MemoryStorage({
|
|
@@ -98,13 +103,7 @@ class MessageStore {
|
|
|
98
103
|
|
|
99
104
|
/**
|
|
100
105
|
* Saves a message to storage
|
|
101
|
-
* @param {
|
|
102
|
-
* @param {string} message.id - Message ID
|
|
103
|
-
* @param {number} message.type - Message type
|
|
104
|
-
* @param {Uint8Array} [message.payload] - Message payload
|
|
105
|
-
* @param {string} [message.senderId] - Sender peer ID
|
|
106
|
-
* @param {string} [message.recipientId] - Recipient peer ID
|
|
107
|
-
* @param {number} [message.timestamp] - Message timestamp
|
|
106
|
+
* @param {any} message - Message to save *
|
|
108
107
|
* @returns {Promise<void>}
|
|
109
108
|
*/
|
|
110
109
|
async saveMessage(message) {
|
|
@@ -132,7 +131,7 @@ class MessageStore {
|
|
|
132
131
|
/**
|
|
133
132
|
* Gets a message by ID
|
|
134
133
|
* @param {string} id - Message ID
|
|
135
|
-
* @returns {Promise<
|
|
134
|
+
* @returns {Promise<any>} Message or null if not found
|
|
136
135
|
*/
|
|
137
136
|
async getMessage(id) {
|
|
138
137
|
const message = await this._storage.get(id);
|
|
@@ -157,15 +156,8 @@ class MessageStore {
|
|
|
157
156
|
|
|
158
157
|
/**
|
|
159
158
|
* Gets messages matching query options
|
|
160
|
-
* @param {
|
|
161
|
-
* @
|
|
162
|
-
* @param {string} [options.recipientId] - Filter by recipient ID
|
|
163
|
-
* @param {number} [options.type] - Filter by message type
|
|
164
|
-
* @param {number} [options.since] - Filter messages since timestamp
|
|
165
|
-
* @param {number} [options.until] - Filter messages until timestamp
|
|
166
|
-
* @param {number} [options.limit=50] - Maximum messages to return
|
|
167
|
-
* @param {number} [options.offset=0] - Offset for pagination
|
|
168
|
-
* @returns {Promise<Object[]>} Array of messages
|
|
159
|
+
* @param {any} [options={}] - Query options *
|
|
160
|
+
* @returns {Promise<any[]>} Array of messages
|
|
169
161
|
*/
|
|
170
162
|
async getMessages(options = {}) {
|
|
171
163
|
const {
|
|
@@ -270,7 +262,7 @@ class MessageStore {
|
|
|
270
262
|
* Gets messages by sender
|
|
271
263
|
* @param {string} senderId - Sender peer ID
|
|
272
264
|
* @param {number} [limit=50] - Maximum messages
|
|
273
|
-
* @returns {Promise<
|
|
265
|
+
* @returns {Promise<any[]>} Array of messages
|
|
274
266
|
*/
|
|
275
267
|
async getMessagesBySender(senderId, limit = 50) {
|
|
276
268
|
return this.getMessages({ senderId, limit });
|
|
@@ -280,7 +272,7 @@ class MessageStore {
|
|
|
280
272
|
* Gets messages by recipient
|
|
281
273
|
* @param {string} recipientId - Recipient peer ID
|
|
282
274
|
* @param {number} [limit=50] - Maximum messages
|
|
283
|
-
* @returns {Promise<
|
|
275
|
+
* @returns {Promise<any[]>} Array of messages
|
|
284
276
|
*/
|
|
285
277
|
async getMessagesByRecipient(recipientId, limit = 50) {
|
|
286
278
|
return this.getMessages({ recipientId, limit });
|
|
@@ -291,7 +283,7 @@ class MessageStore {
|
|
|
291
283
|
* @param {string} peerId1 - First peer ID
|
|
292
284
|
* @param {string} peerId2 - Second peer ID
|
|
293
285
|
* @param {number} [limit=50] - Maximum messages
|
|
294
|
-
* @returns {Promise<
|
|
286
|
+
* @returns {Promise<any[]>} Array of messages
|
|
295
287
|
*/
|
|
296
288
|
async getConversation(peerId1, peerId2, limit = 50) {
|
|
297
289
|
const allKeys = await this._storage.keys();
|
|
@@ -316,7 +308,7 @@ class MessageStore {
|
|
|
316
308
|
|
|
317
309
|
/**
|
|
318
310
|
* Updates indexes for a message
|
|
319
|
-
* @param {
|
|
311
|
+
* @param {any} message - Message to index
|
|
320
312
|
* @returns {Promise<void>}
|
|
321
313
|
* @private
|
|
322
314
|
*/
|
|
@@ -344,7 +336,7 @@ class MessageStore {
|
|
|
344
336
|
|
|
345
337
|
/**
|
|
346
338
|
* Removes a message from indexes
|
|
347
|
-
* @param {
|
|
339
|
+
* @param {any} message - Message to remove from indexes
|
|
348
340
|
* @returns {Promise<void>}
|
|
349
341
|
* @private
|
|
350
342
|
*/
|
|
@@ -352,14 +344,14 @@ class MessageStore {
|
|
|
352
344
|
if (message.senderId) {
|
|
353
345
|
const key = `sender:${message.senderId}`;
|
|
354
346
|
const ids = (await this._indexStorage.get(key)) || [];
|
|
355
|
-
const filtered = ids.filter(id => id !== message.id);
|
|
347
|
+
const filtered = ids.filter((/** @type {any} */ id) => id !== message.id);
|
|
356
348
|
await this._indexStorage.set(key, filtered);
|
|
357
349
|
}
|
|
358
350
|
|
|
359
351
|
if (message.recipientId) {
|
|
360
352
|
const key = `recipient:${message.recipientId}`;
|
|
361
353
|
const ids = (await this._indexStorage.get(key)) || [];
|
|
362
|
-
const filtered = ids.filter(id => id !== message.id);
|
|
354
|
+
const filtered = ids.filter((/** @type {any} */ id) => id !== message.id);
|
|
363
355
|
await this._indexStorage.set(key, filtered);
|
|
364
356
|
}
|
|
365
357
|
}
|
package/src/storage/Storage.js
CHANGED
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
class Storage {
|
|
16
16
|
/**
|
|
17
17
|
* Creates a new Storage instance
|
|
18
|
-
* @param {
|
|
19
|
-
*
|
|
18
|
+
* @param {any} [options={}] - Storage options
|
|
19
|
+
*
|
|
20
20
|
*/
|
|
21
21
|
constructor(options = {}) {
|
|
22
22
|
/**
|
|
23
23
|
* Storage options
|
|
24
|
-
* @type {
|
|
24
|
+
* @type {any}
|
|
25
25
|
* @protected
|
|
26
26
|
*/
|
|
27
27
|
this._options = {
|
|
@@ -43,7 +43,7 @@ class Storage {
|
|
|
43
43
|
/**
|
|
44
44
|
* Gets a value by key
|
|
45
45
|
* @abstract
|
|
46
|
-
* @param {string}
|
|
46
|
+
* @param {string} _key - Key to retrieve
|
|
47
47
|
* @returns {Promise<any>} Stored value or undefined
|
|
48
48
|
* @throws {Error} If not implemented by subclass
|
|
49
49
|
*/
|
|
@@ -54,8 +54,8 @@ class Storage {
|
|
|
54
54
|
/**
|
|
55
55
|
* Sets a value by key
|
|
56
56
|
* @abstract
|
|
57
|
-
* @param {string}
|
|
58
|
-
* @param {any}
|
|
57
|
+
* @param {string} _key - Key to set
|
|
58
|
+
* @param {any} _value - Value to store
|
|
59
59
|
* @returns {Promise<void>}
|
|
60
60
|
* @throws {Error} If not implemented by subclass
|
|
61
61
|
*/
|
|
@@ -66,7 +66,7 @@ class Storage {
|
|
|
66
66
|
/**
|
|
67
67
|
* Deletes a value by key
|
|
68
68
|
* @abstract
|
|
69
|
-
* @param {string}
|
|
69
|
+
* @param {string} _key - Key to delete
|
|
70
70
|
* @returns {Promise<void>}
|
|
71
71
|
* @throws {Error} If not implemented by subclass
|
|
72
72
|
*/
|
|
@@ -77,7 +77,7 @@ class Storage {
|
|
|
77
77
|
/**
|
|
78
78
|
* Checks if a key exists
|
|
79
79
|
* @abstract
|
|
80
|
-
* @param {string}
|
|
80
|
+
* @param {string} _key - Key to check
|
|
81
81
|
* @returns {Promise<boolean>} True if key exists
|
|
82
82
|
* @throws {Error} If not implemented by subclass
|
|
83
83
|
*/
|
|
@@ -134,7 +134,7 @@ class Storage {
|
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
136
|
* Sets multiple key-value pairs
|
|
137
|
-
* @param {Map<string, any>|
|
|
137
|
+
* @param {Map<string, any>|any} entries - Entries to set
|
|
138
138
|
* @returns {Promise<void>}
|
|
139
139
|
*/
|
|
140
140
|
async setMany(entries) {
|
|
@@ -25,7 +25,7 @@ const { ConnectionError } = require('../errors');
|
|
|
25
25
|
class BLETransport extends Transport {
|
|
26
26
|
/**
|
|
27
27
|
* Creates a new BLETransport instance
|
|
28
|
-
* @param {
|
|
28
|
+
* @param {any} adapter - BLE adapter instance (RNBLEAdapter or NodeBLEAdapter)
|
|
29
29
|
* @param {Object} [options={}] - Transport options
|
|
30
30
|
* @param {string} [options.powerMode='BALANCED'] - Power mode
|
|
31
31
|
* @param {number} [options.maxPeers=8] - Maximum peers
|
|
@@ -41,16 +41,17 @@ class BLETransport extends Transport {
|
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* BLE adapter instance
|
|
44
|
-
* @type {
|
|
44
|
+
* @type {any}
|
|
45
45
|
* @private
|
|
46
46
|
*/
|
|
47
47
|
this._adapter = adapter;
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Current power mode
|
|
51
|
-
* @type {
|
|
51
|
+
* @type {any}
|
|
52
52
|
* @private
|
|
53
53
|
*/
|
|
54
|
+
// @ts-ignore
|
|
54
55
|
this._powerMode = POWER_MODE[options.powerMode] || POWER_MODE.BALANCED;
|
|
55
56
|
|
|
56
57
|
/**
|
|
@@ -76,7 +77,7 @@ class BLETransport extends Transport {
|
|
|
76
77
|
|
|
77
78
|
/**
|
|
78
79
|
* Per-peer write queues for serializing BLE writes
|
|
79
|
-
* @type {Map<string,
|
|
80
|
+
* @type {Map<string, any[]>}
|
|
80
81
|
* @private
|
|
81
82
|
*/
|
|
82
83
|
this._writeQueue = new Map();
|
|
@@ -90,7 +91,7 @@ class BLETransport extends Transport {
|
|
|
90
91
|
|
|
91
92
|
/**
|
|
92
93
|
* Bound event handlers for cleanup
|
|
93
|
-
* @type {
|
|
94
|
+
* @type {any}
|
|
94
95
|
* @private
|
|
95
96
|
*/
|
|
96
97
|
this._handlers = {
|
|
@@ -140,7 +141,7 @@ class BLETransport extends Transport {
|
|
|
140
141
|
|
|
141
142
|
// Register disconnect callback if adapter supports it
|
|
142
143
|
if (typeof this._adapter.onDeviceDisconnected === 'function') {
|
|
143
|
-
this._adapter.onDeviceDisconnected((peerId) => {
|
|
144
|
+
this._adapter.onDeviceDisconnected((/** @type {any} */ peerId) => {
|
|
144
145
|
this._handleDeviceDisconnected(peerId);
|
|
145
146
|
});
|
|
146
147
|
}
|
|
@@ -149,7 +150,7 @@ class BLETransport extends Transport {
|
|
|
149
150
|
|
|
150
151
|
// Auto-start scanning for peers
|
|
151
152
|
await this.startScanning();
|
|
152
|
-
} catch (error) {
|
|
153
|
+
} catch (/** @type {any} */ error) {
|
|
153
154
|
this._setState(Transport.STATE.ERROR);
|
|
154
155
|
throw error;
|
|
155
156
|
}
|
|
@@ -232,12 +233,12 @@ class BLETransport extends Transport {
|
|
|
232
233
|
}
|
|
233
234
|
|
|
234
235
|
try {
|
|
235
|
-
let timeoutId;
|
|
236
|
+
/** @type {any} */ let timeoutId;
|
|
236
237
|
const timeoutPromise = new Promise((_, reject) => {
|
|
237
238
|
timeoutId = setTimeout(() => reject(new Error('Connection timeout')), this._connectTimeoutMs);
|
|
238
239
|
});
|
|
239
240
|
const device = await Promise.race([
|
|
240
|
-
this._adapter.connect(peerId).then(d => { clearTimeout(timeoutId); return d; }),
|
|
241
|
+
this._adapter.connect(peerId).then((/** @type {any} */ d) => { clearTimeout(timeoutId); return d; }),
|
|
241
242
|
timeoutPromise
|
|
242
243
|
]);
|
|
243
244
|
|
|
@@ -259,7 +260,7 @@ class BLETransport extends Transport {
|
|
|
259
260
|
peerId,
|
|
260
261
|
BLE_SERVICE_UUID,
|
|
261
262
|
BLE_CHARACTERISTIC_RX,
|
|
262
|
-
(data) => this._handleData(peerId, data)
|
|
263
|
+
(/** @type {any} */ data) => this._handleData(peerId, data)
|
|
263
264
|
);
|
|
264
265
|
|
|
265
266
|
const connectionInfo = {
|
|
@@ -271,7 +272,7 @@ class BLETransport extends Transport {
|
|
|
271
272
|
|
|
272
273
|
this._peers.set(peerId, connectionInfo);
|
|
273
274
|
this.emit('peerConnected', { peerId, rssi: device.rssi || -50 });
|
|
274
|
-
} catch (error) {
|
|
275
|
+
} catch (/** @type {any} */ error) {
|
|
275
276
|
if (error.message === 'Connection timeout') {
|
|
276
277
|
throw ConnectionError.connectionTimeout(peerId);
|
|
277
278
|
}
|
|
@@ -362,7 +363,7 @@ class BLETransport extends Transport {
|
|
|
362
363
|
* @param {string} modeName - Power mode name (PERFORMANCE, BALANCED, POWER_SAVER)
|
|
363
364
|
*/
|
|
364
365
|
setPowerMode(modeName) {
|
|
365
|
-
const mode = POWER_MODE[modeName];
|
|
366
|
+
const mode = /** @type {any} */ (POWER_MODE)[modeName];
|
|
366
367
|
if (mode) {
|
|
367
368
|
this._powerMode = mode;
|
|
368
369
|
}
|
|
@@ -384,7 +385,7 @@ class BLETransport extends Transport {
|
|
|
384
385
|
|
|
385
386
|
/**
|
|
386
387
|
* Handles discovered BLE devices
|
|
387
|
-
* @param {
|
|
388
|
+
* @param {any} device - Discovered device info
|
|
388
389
|
* @private
|
|
389
390
|
*/
|
|
390
391
|
_handleDeviceDiscovered(device) {
|
|
@@ -452,7 +453,8 @@ class BLETransport extends Transport {
|
|
|
452
453
|
}
|
|
453
454
|
|
|
454
455
|
return new Promise((resolve, reject) => {
|
|
455
|
-
|
|
456
|
+
// @ts-ignore
|
|
457
|
+
this?._writeQueue.get(peerId).push({ data, resolve, reject });
|
|
456
458
|
this._processWriteQueue(peerId);
|
|
457
459
|
});
|
|
458
460
|
}
|
|
@@ -50,6 +50,7 @@ class MockTransport extends Transport {
|
|
|
50
50
|
* @type {string|null}
|
|
51
51
|
* @private
|
|
52
52
|
*/
|
|
53
|
+
// @ts-ignore
|
|
53
54
|
this._localPeerId = options.localPeerId || `mock-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -122,7 +123,8 @@ class MockTransport extends Transport {
|
|
|
122
123
|
|
|
123
124
|
// Deliver to linked transport if available
|
|
124
125
|
const linkedTransport = this._linkedTransports.get(peerId);
|
|
125
|
-
if (linkedTransport && linkedTransport.isRunning) {
|
|
126
|
+
if (linkedTransport && /** @type {any} */ (linkedTransport).isRunning) {
|
|
127
|
+
// @ts-ignore
|
|
126
128
|
linkedTransport._receiveMessage(this._localPeerId, data);
|
|
127
129
|
}
|
|
128
130
|
}
|
|
@@ -157,7 +159,7 @@ class MockTransport extends Transport {
|
|
|
157
159
|
/**
|
|
158
160
|
* Simulates a peer connection
|
|
159
161
|
* @param {string} peerId - Connecting peer ID
|
|
160
|
-
* @param {
|
|
162
|
+
* @param {any} [info={}] - Connection info (rssi, etc.)
|
|
161
163
|
*/
|
|
162
164
|
simulatePeerConnect(peerId, info = {}) {
|
|
163
165
|
if (!this.isRunning || this._peers.has(peerId)) {
|
|
@@ -203,6 +205,7 @@ class MockTransport extends Transport {
|
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
this._linkedTransports.set(otherPeerId, otherTransport);
|
|
208
|
+
// @ts-ignore
|
|
206
209
|
otherTransport._linkedTransports.set(this._localPeerId, this);
|
|
207
210
|
}
|
|
208
211
|
|
|
@@ -212,7 +215,9 @@ class MockTransport extends Transport {
|
|
|
212
215
|
*/
|
|
213
216
|
unlinkFrom(otherTransport) {
|
|
214
217
|
const otherPeerId = otherTransport.localPeerId;
|
|
218
|
+
// @ts-ignore
|
|
215
219
|
this._linkedTransports.delete(otherPeerId);
|
|
220
|
+
// @ts-ignore
|
|
216
221
|
otherTransport._linkedTransports.delete(this._localPeerId);
|
|
217
222
|
}
|
|
218
223
|
|
|
@@ -16,7 +16,7 @@ const Transport = require('./Transport');
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Transport selection strategies
|
|
19
|
-
* @constant {
|
|
19
|
+
* @constant {any}
|
|
20
20
|
*/
|
|
21
21
|
const STRATEGY = Object.freeze({
|
|
22
22
|
/** Always use BLE */
|
|
@@ -45,6 +45,7 @@ class MultiTransport extends Transport {
|
|
|
45
45
|
* @param {number} [options.wifiThresholdBytes=1024] - Use Wi-Fi Direct for payloads above this size
|
|
46
46
|
*/
|
|
47
47
|
constructor(options = {}) {
|
|
48
|
+
// @ts-ignore
|
|
48
49
|
super(options);
|
|
49
50
|
|
|
50
51
|
this._bleTransport = options.bleTransport || null;
|
|
@@ -83,6 +84,7 @@ class MultiTransport extends Transport {
|
|
|
83
84
|
if (this._bleTransport) {
|
|
84
85
|
startPromises.push(
|
|
85
86
|
this._bleTransport.start()
|
|
87
|
+
// @ts-ignore
|
|
86
88
|
.then(() => this._wireTransport(this._bleTransport, 'ble'))
|
|
87
89
|
.catch(err => {
|
|
88
90
|
this.emit('transportError', { transport: 'ble', error: err });
|
|
@@ -93,6 +95,7 @@ class MultiTransport extends Transport {
|
|
|
93
95
|
if (this._wifiTransport) {
|
|
94
96
|
startPromises.push(
|
|
95
97
|
this._wifiTransport.start()
|
|
98
|
+
// @ts-ignore
|
|
96
99
|
.then(() => this._wireTransport(this._wifiTransport, 'wifi-direct'))
|
|
97
100
|
.catch(err => {
|
|
98
101
|
this.emit('transportError', { transport: 'wifi-direct', error: err });
|
|
@@ -170,6 +173,7 @@ class MultiTransport extends Transport {
|
|
|
170
173
|
if (!this.isRunning) { throw new Error('Transport is not running'); }
|
|
171
174
|
|
|
172
175
|
const allPeerIds = new Set();
|
|
176
|
+
/** @type {string[]} */
|
|
173
177
|
const successPeerIds = [];
|
|
174
178
|
|
|
175
179
|
// Collect all peers from all transports
|
|
@@ -191,6 +195,7 @@ class MultiTransport extends Transport {
|
|
|
191
195
|
if (r.status === 'fulfilled') { successPeerIds.push(r.value); }
|
|
192
196
|
});
|
|
193
197
|
|
|
198
|
+
// @ts-ignore
|
|
194
199
|
return successPeerIds;
|
|
195
200
|
}
|
|
196
201
|
|
|
@@ -228,9 +233,11 @@ class MultiTransport extends Transport {
|
|
|
228
233
|
_selectTransport(peerId, dataSize) {
|
|
229
234
|
switch (this._strategy) {
|
|
230
235
|
case STRATEGY.BLE_ONLY:
|
|
236
|
+
// @ts-ignore
|
|
231
237
|
return this._bleTransport;
|
|
232
238
|
|
|
233
239
|
case STRATEGY.WIFI_ONLY:
|
|
240
|
+
// @ts-ignore
|
|
234
241
|
return this._wifiTransport;
|
|
235
242
|
|
|
236
243
|
case STRATEGY.AUTO:
|
|
@@ -282,13 +289,13 @@ class MultiTransport extends Transport {
|
|
|
282
289
|
* @private
|
|
283
290
|
*/
|
|
284
291
|
_wireTransport(transport, name) {
|
|
285
|
-
const onPeerConnected = (info) => {
|
|
292
|
+
const onPeerConnected = (/** @type {any} */ info) => {
|
|
286
293
|
this._peerTransportMap.set(info.peerId, name);
|
|
287
294
|
this._peers.set(info.peerId, { ...info, transport: name });
|
|
288
295
|
this.emit('peerConnected', { ...info, transport: name });
|
|
289
296
|
};
|
|
290
297
|
|
|
291
|
-
const onPeerDisconnected = (info) => {
|
|
298
|
+
const onPeerDisconnected = (/** @type {any} */ info) => {
|
|
292
299
|
// Only remove if no other transport has this peer
|
|
293
300
|
const otherTransport = this._getFallbackTransport(transport);
|
|
294
301
|
if (!otherTransport || !otherTransport.isConnected(info.peerId)) {
|
|
@@ -298,15 +305,15 @@ class MultiTransport extends Transport {
|
|
|
298
305
|
}
|
|
299
306
|
};
|
|
300
307
|
|
|
301
|
-
const onMessage = (msg) => {
|
|
308
|
+
const onMessage = (/** @type {any} */ msg) => {
|
|
302
309
|
this.emit('message', { ...msg, transport: name });
|
|
303
310
|
};
|
|
304
311
|
|
|
305
|
-
const onDeviceDiscovered = (info) => {
|
|
312
|
+
const onDeviceDiscovered = (/** @type {any} */ info) => {
|
|
306
313
|
this.emit('deviceDiscovered', { ...info, transport: name });
|
|
307
314
|
};
|
|
308
315
|
|
|
309
|
-
const onError = (err) => {
|
|
316
|
+
const onError = (/** @type {any} */ err) => {
|
|
310
317
|
this.emit('transportError', { transport: name, error: err });
|
|
311
318
|
};
|
|
312
319
|
|
|
@@ -9,7 +9,7 @@ const EventEmitter = require('../utils/EventEmitter');
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Transport states
|
|
12
|
-
* @
|
|
12
|
+
* @type {Record<string, string>}
|
|
13
13
|
*/
|
|
14
14
|
const TRANSPORT_STATE = Object.freeze({
|
|
15
15
|
STOPPED: 'stopped',
|
|
@@ -44,7 +44,7 @@ class Transport extends EventEmitter {
|
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* Transport options
|
|
47
|
-
* @type {
|
|
47
|
+
* @type {any}
|
|
48
48
|
* @protected
|
|
49
49
|
*/
|
|
50
50
|
this._options = {
|
|
@@ -61,7 +61,7 @@ class Transport extends EventEmitter {
|
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* Connected peers map (peerId -> connection info)
|
|
64
|
-
* @type {Map<string,
|
|
64
|
+
* @type {Map<string, any>}
|
|
65
65
|
* @protected
|
|
66
66
|
*/
|
|
67
67
|
this._peers = new Map();
|
|
@@ -119,23 +119,23 @@ class Transport extends EventEmitter {
|
|
|
119
119
|
/**
|
|
120
120
|
* Sends data to a specific peer
|
|
121
121
|
* @abstract
|
|
122
|
-
* @param {string}
|
|
123
|
-
* @param {Uint8Array}
|
|
122
|
+
* @param {string} _peerId - Target peer ID
|
|
123
|
+
* @param {Uint8Array} _data - Data to send
|
|
124
124
|
* @returns {Promise<void>}
|
|
125
125
|
* @throws {Error} If not implemented by subclass
|
|
126
126
|
*/
|
|
127
|
-
async send(_peerId, _data) {
|
|
127
|
+
async send(/** @type {any} */ _peerId, _data) {
|
|
128
128
|
throw new Error('Transport.send() must be implemented by subclass');
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
132
|
* Broadcasts data to all connected peers
|
|
133
133
|
* @abstract
|
|
134
|
-
* @param {Uint8Array}
|
|
134
|
+
* @param {Uint8Array} _data - Data to broadcast
|
|
135
135
|
* @returns {Promise<string[]>} Array of peer IDs that received the broadcast
|
|
136
136
|
* @throws {Error} If not implemented by subclass
|
|
137
137
|
*/
|
|
138
|
-
async broadcast(_data) {
|
|
138
|
+
async broadcast(/** @type {any} */ _data) {
|
|
139
139
|
throw new Error('Transport.broadcast() must be implemented by subclass');
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -159,7 +159,7 @@ class Transport extends EventEmitter {
|
|
|
159
159
|
/**
|
|
160
160
|
* Gets connection info for a peer
|
|
161
161
|
* @param {string} peerId - Peer ID
|
|
162
|
-
* @returns {
|
|
162
|
+
* @returns {any} Connection info or undefined
|
|
163
163
|
*/
|
|
164
164
|
getPeerInfo(peerId) {
|
|
165
165
|
return this._peers.get(peerId);
|