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
|
@@ -28,10 +28,7 @@ const { ValidationError } = require('../../errors');
|
|
|
28
28
|
class PathFinder extends EventEmitter {
|
|
29
29
|
/**
|
|
30
30
|
* Creates a new PathFinder
|
|
31
|
-
* @param {
|
|
32
|
-
* @param {string} options.localPeerId - Local peer ID
|
|
33
|
-
* @param {Object} options.routeTable - RouteTable instance
|
|
34
|
-
* @param {number} [options.discoveryTimeout] - Route discovery timeout
|
|
31
|
+
* @param {any} options - Configuration options *
|
|
35
32
|
*/
|
|
36
33
|
constructor(options = {}) {
|
|
37
34
|
super();
|
|
@@ -51,7 +48,7 @@ class PathFinder extends EventEmitter {
|
|
|
51
48
|
|
|
52
49
|
/**
|
|
53
50
|
* Route table reference
|
|
54
|
-
* @type {
|
|
51
|
+
* @type {any}
|
|
55
52
|
*/
|
|
56
53
|
this.routeTable = options.routeTable;
|
|
57
54
|
|
|
@@ -63,7 +60,7 @@ class PathFinder extends EventEmitter {
|
|
|
63
60
|
|
|
64
61
|
/**
|
|
65
62
|
* Pending route requests
|
|
66
|
-
* @type {Map<string,
|
|
63
|
+
* @type {Map<string, any>}
|
|
67
64
|
* @private
|
|
68
65
|
*/
|
|
69
66
|
this._pendingRequests = new Map();
|
|
@@ -77,7 +74,7 @@ class PathFinder extends EventEmitter {
|
|
|
77
74
|
|
|
78
75
|
/**
|
|
79
76
|
* Statistics
|
|
80
|
-
* @type {
|
|
77
|
+
* @type {any}
|
|
81
78
|
* @private
|
|
82
79
|
*/
|
|
83
80
|
this._stats = {
|
|
@@ -93,7 +90,7 @@ class PathFinder extends EventEmitter {
|
|
|
93
90
|
/**
|
|
94
91
|
* Finds a route to a destination
|
|
95
92
|
* @param {string} destination - Target peer ID
|
|
96
|
-
* @returns {Promise<
|
|
93
|
+
* @returns {Promise<any>} Route or null if not found
|
|
97
94
|
*/
|
|
98
95
|
async findRoute(destination) {
|
|
99
96
|
if (!destination || typeof destination !== 'string') {
|
|
@@ -113,7 +110,7 @@ class PathFinder extends EventEmitter {
|
|
|
113
110
|
/**
|
|
114
111
|
* Initiates route discovery for a destination
|
|
115
112
|
* @param {string} destination - Target peer ID
|
|
116
|
-
* @returns {Promise<
|
|
113
|
+
* @returns {Promise<any>} Discovered route or null
|
|
117
114
|
* @private
|
|
118
115
|
*/
|
|
119
116
|
_initiateDiscovery(destination) {
|
|
@@ -164,9 +161,9 @@ class PathFinder extends EventEmitter {
|
|
|
164
161
|
|
|
165
162
|
/**
|
|
166
163
|
* Processes an incoming route request
|
|
167
|
-
* @param {
|
|
164
|
+
* @param {any} request - Route request data
|
|
168
165
|
* @param {string} sourcePeerId - Source peer ID
|
|
169
|
-
* @returns {
|
|
166
|
+
* @returns {any} Reply to send or null
|
|
170
167
|
*/
|
|
171
168
|
processRouteRequest(request, sourcePeerId) {
|
|
172
169
|
this._stats.requestsReceived++;
|
|
@@ -219,7 +216,7 @@ class PathFinder extends EventEmitter {
|
|
|
219
216
|
|
|
220
217
|
/**
|
|
221
218
|
* Processes an incoming route reply
|
|
222
|
-
* @param {
|
|
219
|
+
* @param {any} reply - Route reply data
|
|
223
220
|
* @param {string} sourcePeerId - Source peer ID
|
|
224
221
|
*/
|
|
225
222
|
processRouteReply(reply, sourcePeerId) {
|
|
@@ -295,7 +292,7 @@ class PathFinder extends EventEmitter {
|
|
|
295
292
|
|
|
296
293
|
/**
|
|
297
294
|
* Gets path finder statistics
|
|
298
|
-
* @returns {
|
|
295
|
+
* @returns {any} Statistics
|
|
299
296
|
*/
|
|
300
297
|
getStats() {
|
|
301
298
|
return {
|
|
@@ -26,9 +26,9 @@ const { ValidationError } = require('../../errors');
|
|
|
26
26
|
class RouteTable {
|
|
27
27
|
/**
|
|
28
28
|
* Creates a new RouteTable
|
|
29
|
-
* @param {
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* @param {any} [options] - Configuration options
|
|
30
|
+
*
|
|
31
|
+
*
|
|
32
32
|
*/
|
|
33
33
|
constructor(options = {}) {
|
|
34
34
|
/**
|
|
@@ -45,7 +45,7 @@ class RouteTable {
|
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Routes by destination peer ID
|
|
48
|
-
* @type {Map<string,
|
|
48
|
+
* @type {Map<string, any>}
|
|
49
49
|
* @private
|
|
50
50
|
*/
|
|
51
51
|
this._routes = new Map();
|
|
@@ -130,7 +130,7 @@ class RouteTable {
|
|
|
130
130
|
/**
|
|
131
131
|
* Gets a route to a destination
|
|
132
132
|
* @param {string} destination - Destination peer ID
|
|
133
|
-
* @returns {
|
|
133
|
+
* @returns {any} Route or undefined
|
|
134
134
|
*/
|
|
135
135
|
getRoute(destination) {
|
|
136
136
|
const route = this._routes.get(destination);
|
|
@@ -197,7 +197,7 @@ class RouteTable {
|
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
199
|
* Gets all valid routes
|
|
200
|
-
* @returns {
|
|
200
|
+
* @returns {any[]} Array of routes
|
|
201
201
|
*/
|
|
202
202
|
getAllRoutes() {
|
|
203
203
|
const now = Date.now();
|
|
@@ -244,6 +244,7 @@ class RouteTable {
|
|
|
244
244
|
* @private
|
|
245
245
|
*/
|
|
246
246
|
_evictOldestRoute() {
|
|
247
|
+
/** @type {string|null} */
|
|
247
248
|
let oldest = null;
|
|
248
249
|
let oldestTime = Infinity;
|
|
249
250
|
|
|
@@ -278,7 +279,7 @@ class RouteTable {
|
|
|
278
279
|
|
|
279
280
|
/**
|
|
280
281
|
* Gets routing table statistics
|
|
281
|
-
* @returns {
|
|
282
|
+
* @returns {any} Statistics
|
|
282
283
|
*/
|
|
283
284
|
getStats() {
|
|
284
285
|
const now = Date.now();
|
|
@@ -18,11 +18,11 @@ const { randomBytes } = require('../../utils/bytes');
|
|
|
18
18
|
* @constant {string[]}
|
|
19
19
|
* @private
|
|
20
20
|
*/
|
|
21
|
-
const HEX = Array.from({ length: 256 }, (_, i) => (i < 16 ? '0' : '') + i.toString(16));
|
|
21
|
+
const HEX = Array.from({ length: 256 }, (/** @type {any} */ _, /** @type {number} */ i) => (i < 16 ? '0' : '') + i.toString(16));
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Default configuration for store and forward
|
|
25
|
-
* @constant {
|
|
25
|
+
* @constant {any}
|
|
26
26
|
*/
|
|
27
27
|
const DEFAULT_CONFIG = Object.freeze({
|
|
28
28
|
/** Maximum number of cached messages per recipient */
|
|
@@ -68,26 +68,21 @@ const DEFAULT_CONFIG = Object.freeze({
|
|
|
68
68
|
class StoreAndForwardManager extends EventEmitter {
|
|
69
69
|
/**
|
|
70
70
|
* Creates a new StoreAndForwardManager instance.
|
|
71
|
-
* @param {
|
|
72
|
-
* @param {number} [options.maxMessagesPerRecipient=100] - Max messages per recipient
|
|
73
|
-
* @param {number} [options.maxTotalMessages=1000] - Max total cached messages
|
|
74
|
-
* @param {number} [options.maxCacheSizeBytes=10485760] - Max cache size (10MB)
|
|
75
|
-
* @param {number} [options.retentionMs=86400000] - Message retention (24h)
|
|
76
|
-
* @param {number} [options.cleanupIntervalMs=300000] - Cleanup interval (5min)
|
|
71
|
+
* @param {any} [options={}] - Configuration options *
|
|
77
72
|
*/
|
|
78
73
|
constructor(options = {}) {
|
|
79
74
|
super();
|
|
80
75
|
|
|
81
76
|
/**
|
|
82
77
|
* Configuration
|
|
83
|
-
* @type {
|
|
78
|
+
* @type {any}
|
|
84
79
|
* @private
|
|
85
80
|
*/
|
|
86
81
|
this._config = { ...DEFAULT_CONFIG, ...options };
|
|
87
82
|
|
|
88
83
|
/**
|
|
89
84
|
* Message cache by recipient ID
|
|
90
|
-
* @type {Map<string,
|
|
85
|
+
* @type {Map<string, any[]>}
|
|
91
86
|
* @private
|
|
92
87
|
*/
|
|
93
88
|
this._cache = new Map();
|
|
@@ -108,14 +103,14 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
108
103
|
|
|
109
104
|
/**
|
|
110
105
|
* Cleanup timer
|
|
111
|
-
* @type {
|
|
106
|
+
* @type {any}
|
|
112
107
|
* @private
|
|
113
108
|
*/
|
|
114
109
|
this._cleanupTimer = null;
|
|
115
110
|
|
|
116
111
|
/**
|
|
117
112
|
* Statistics
|
|
118
|
-
* @type {
|
|
113
|
+
* @type {any}
|
|
119
114
|
* @private
|
|
120
115
|
*/
|
|
121
116
|
this._stats = {
|
|
@@ -135,9 +130,9 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
135
130
|
* Caches a message for an offline peer.
|
|
136
131
|
* @param {string} recipientId - Recipient peer ID
|
|
137
132
|
* @param {Uint8Array} encryptedPayload - Encrypted message payload
|
|
138
|
-
* @param {
|
|
139
|
-
|
|
140
|
-
|
|
133
|
+
* @param {any} [options={}] - Cache options
|
|
134
|
+
*
|
|
135
|
+
*
|
|
141
136
|
* @returns {Promise<string>} Cached message ID
|
|
142
137
|
*/
|
|
143
138
|
async cacheForOfflinePeer(recipientId, encryptedPayload, options = {}) {
|
|
@@ -173,7 +168,7 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
173
168
|
this._cache.set(recipientId, []);
|
|
174
169
|
}
|
|
175
170
|
|
|
176
|
-
const recipientCache = this._cache.get(recipientId);
|
|
171
|
+
const recipientCache = /** @type {any[]} */ (this._cache.get(recipientId));
|
|
177
172
|
|
|
178
173
|
// Check per-recipient limit
|
|
179
174
|
if (recipientCache.length >= this._config.maxMessagesPerRecipient) {
|
|
@@ -205,14 +200,15 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
205
200
|
* Delivers all cached messages to a peer that came online.
|
|
206
201
|
* @param {string} recipientId - Recipient peer ID
|
|
207
202
|
* @param {Function} sendFn - Async function to send message: (payload) => Promise<void>
|
|
208
|
-
* @returns {Promise<
|
|
203
|
+
* @returns {Promise<any>} Delivery result with counts
|
|
209
204
|
*/
|
|
210
205
|
async deliverCachedMessages(recipientId, sendFn) {
|
|
211
206
|
if (!this._cache.has(recipientId)) {
|
|
212
207
|
return { delivered: 0, failed: 0 };
|
|
213
208
|
}
|
|
214
209
|
|
|
215
|
-
const messages = this._cache.get(recipientId);
|
|
210
|
+
const messages = /** @type {any[]} */ (this._cache.get(recipientId));
|
|
211
|
+
/** @type {any} */
|
|
216
212
|
const results = { delivered: 0, failed: 0, remaining: [] };
|
|
217
213
|
|
|
218
214
|
for (const msg of messages) {
|
|
@@ -238,7 +234,7 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
238
234
|
messageId: msg.id,
|
|
239
235
|
recipientId
|
|
240
236
|
});
|
|
241
|
-
} catch (error) {
|
|
237
|
+
} catch (/** @type {any} */ error) {
|
|
242
238
|
results.failed++;
|
|
243
239
|
this._stats.deliveryFailures++;
|
|
244
240
|
results.remaining.push(msg);
|
|
@@ -305,7 +301,7 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
305
301
|
}
|
|
306
302
|
|
|
307
303
|
const count = cache.length;
|
|
308
|
-
const size = cache.reduce((sum, m) => sum + m.size, 0);
|
|
304
|
+
const size = cache.reduce((/** @type {number} */ sum, /** @type {any} */ m) => sum + m.size, 0);
|
|
309
305
|
|
|
310
306
|
this._cache.delete(recipientId);
|
|
311
307
|
this._totalSize -= size;
|
|
@@ -323,7 +319,7 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
323
319
|
let pruned = 0;
|
|
324
320
|
|
|
325
321
|
for (const [recipientId, messages] of this._cache) {
|
|
326
|
-
const validMessages = messages.filter(msg => {
|
|
322
|
+
const validMessages = messages.filter((/** @type {any} */ msg) => {
|
|
327
323
|
if (msg.expiresAt <= now) {
|
|
328
324
|
this._totalSize -= msg.size;
|
|
329
325
|
this._totalCount--;
|
|
@@ -350,7 +346,7 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
350
346
|
|
|
351
347
|
/**
|
|
352
348
|
* Gets store and forward statistics.
|
|
353
|
-
* @returns {
|
|
349
|
+
* @returns {any} Statistics
|
|
354
350
|
*/
|
|
355
351
|
getStats() {
|
|
356
352
|
return {
|
|
@@ -418,6 +414,7 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
418
414
|
*/
|
|
419
415
|
_removeOldestMessage() {
|
|
420
416
|
let oldestTime = Infinity;
|
|
417
|
+
/** @type {string|null} */
|
|
421
418
|
let oldestRecipient = null;
|
|
422
419
|
|
|
423
420
|
for (const [recipientId, messages] of this._cache) {
|
|
@@ -428,7 +425,7 @@ class StoreAndForwardManager extends EventEmitter {
|
|
|
428
425
|
}
|
|
429
426
|
|
|
430
427
|
if (oldestRecipient) {
|
|
431
|
-
const messages = this._cache.get(oldestRecipient);
|
|
428
|
+
const messages = /** @type {any[]} */ (this._cache.get(oldestRecipient));
|
|
432
429
|
const oldest = messages.shift();
|
|
433
430
|
if (oldest) {
|
|
434
431
|
this._totalSize -= oldest.size;
|
package/src/protocol/message.js
CHANGED
|
@@ -10,8 +10,8 @@ const { MESSAGE_FLAGS, MESH_CONFIG } = require('../constants');
|
|
|
10
10
|
const { MessageError } = require('../errors');
|
|
11
11
|
|
|
12
12
|
// Cached TextEncoder/TextDecoder singletons (avoids per-call allocation)
|
|
13
|
-
let _encoder = null;
|
|
14
|
-
let _decoder = null;
|
|
13
|
+
/** @type {any} */ let _encoder = null;
|
|
14
|
+
/** @type {any} */ let _decoder = null;
|
|
15
15
|
function _getEncoder() {
|
|
16
16
|
if (!_encoder) { _encoder = new TextEncoder(); }
|
|
17
17
|
return _encoder;
|
|
@@ -28,11 +28,11 @@ function _getDecoder() {
|
|
|
28
28
|
class Message {
|
|
29
29
|
/**
|
|
30
30
|
* Creates a new Message instance.
|
|
31
|
-
* @param {
|
|
31
|
+
* @param {any} header - Message header
|
|
32
32
|
* @param {Uint8Array} payload - Message payload
|
|
33
33
|
*/
|
|
34
34
|
constructor(header, payload) {
|
|
35
|
-
/** @type {
|
|
35
|
+
/** @type {any} */
|
|
36
36
|
this.header = header;
|
|
37
37
|
/** @type {Uint8Array} */
|
|
38
38
|
this.payload = payload;
|
|
@@ -40,15 +40,7 @@ class Message {
|
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Creates a new message with the given options.
|
|
43
|
-
* @param {
|
|
44
|
-
* @param {number} options.type - Message type from MESSAGE_TYPE
|
|
45
|
-
* @param {Uint8Array|string} options.payload - Message payload
|
|
46
|
-
* @param {number} [options.flags=0] - Message flags
|
|
47
|
-
* @param {number} [options.maxHops=7] - Maximum hops
|
|
48
|
-
* @param {number} [options.ttlMs] - Time-to-live in ms
|
|
49
|
-
* @param {number} [options.fragmentIndex=0] - Fragment index
|
|
50
|
-
* @param {number} [options.fragmentTotal=1] - Total fragments
|
|
51
|
-
* @param {Uint8Array} [options.messageId] - Optional message ID
|
|
43
|
+
* @param {any} options - Message options *
|
|
52
44
|
* @returns {Message} New message instance
|
|
53
45
|
*/
|
|
54
46
|
static create(options) {
|
|
@@ -15,7 +15,7 @@ const { MessageError } = require('../errors');
|
|
|
15
15
|
* Serializes a message header to bytes.
|
|
16
16
|
* Calculates CRC32 checksum and includes it in the output.
|
|
17
17
|
*
|
|
18
|
-
* @param {
|
|
18
|
+
* @param {any} header - Header to serialize
|
|
19
19
|
* @returns {Uint8Array} 48-byte serialized header
|
|
20
20
|
* @throws {MessageError} If header is invalid
|
|
21
21
|
*
|
|
@@ -81,7 +81,7 @@ function serializeHeader(header) {
|
|
|
81
81
|
/**
|
|
82
82
|
* Serializes a complete message (header + payload) to bytes.
|
|
83
83
|
*
|
|
84
|
-
* @param {
|
|
84
|
+
* @param {any} message - Message to serialize
|
|
85
85
|
* @returns {Uint8Array} Serialized message bytes
|
|
86
86
|
* @throws {MessageError} If message is invalid
|
|
87
87
|
*
|
|
@@ -109,8 +109,8 @@ function serialize(message) {
|
|
|
109
109
|
|
|
110
110
|
// Convert string payload to bytes
|
|
111
111
|
if (typeof payload === 'string') {
|
|
112
|
-
if (!serialize._encoder) { serialize._encoder = new TextEncoder(); }
|
|
113
|
-
payload = serialize._encoder.encode(payload);
|
|
112
|
+
if (!(/** @type {any} */ (serialize))._encoder) { /** @type {any} */ (serialize)._encoder = new TextEncoder(); }
|
|
113
|
+
payload = /** @type {any} */ (serialize)._encoder.encode(payload);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
// Default to empty payload
|
|
@@ -13,18 +13,19 @@ const { PROTOCOL_VERSION, MESSAGE_TYPE, MESH_CONFIG } = require('../constants');
|
|
|
13
13
|
* Set of valid message type values for fast lookup.
|
|
14
14
|
* @type {Set<number>}
|
|
15
15
|
*/
|
|
16
|
-
const VALID_MESSAGE_TYPES = new Set(Object.values(MESSAGE_TYPE));
|
|
16
|
+
const VALID_MESSAGE_TYPES = new Set(/** @type {number[]} */ (Object.values(MESSAGE_TYPE)));
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Cached frozen result for valid validations to avoid repeated allocations.
|
|
20
20
|
* @type {{ valid: boolean, errors: string[] }}
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
const VALID_RESULT = /** @type {{ valid: boolean, errors: string[] }} */ (Object.freeze({ valid: true, errors: Object.freeze([]) }));
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Validates a message header.
|
|
26
27
|
*
|
|
27
|
-
* @param {
|
|
28
|
+
* @param {any} header - Header to validate
|
|
28
29
|
* @returns {{ valid: boolean, errors: string[] }} Validation result
|
|
29
30
|
*
|
|
30
31
|
* @example
|
|
@@ -121,7 +122,7 @@ function validateHeader(header) {
|
|
|
121
122
|
/**
|
|
122
123
|
* Validates a complete message (header + payload).
|
|
123
124
|
*
|
|
124
|
-
* @param {
|
|
125
|
+
* @param {any} message - Message to validate
|
|
125
126
|
* @returns {{ valid: boolean, errors: string[] }} Validation result
|
|
126
127
|
*
|
|
127
128
|
* @example
|
|
@@ -208,7 +209,7 @@ function isValidMessageType(type) {
|
|
|
208
209
|
/**
|
|
209
210
|
* Checks if a message is expired.
|
|
210
211
|
*
|
|
211
|
-
* @param {
|
|
212
|
+
* @param {any} messageOrHeader - Message or header
|
|
212
213
|
* @returns {boolean} True if expired
|
|
213
214
|
*/
|
|
214
215
|
function isExpired(messageOrHeader) {
|
|
@@ -219,7 +220,7 @@ function isExpired(messageOrHeader) {
|
|
|
219
220
|
/**
|
|
220
221
|
* Checks if hop count has exceeded maximum.
|
|
221
222
|
*
|
|
222
|
-
* @param {
|
|
223
|
+
* @param {any} messageOrHeader - Message or header
|
|
223
224
|
* @returns {boolean} True if exceeded
|
|
224
225
|
*/
|
|
225
226
|
function hasExceededMaxHops(messageOrHeader) {
|
|
@@ -14,7 +14,7 @@ const EventEmitter = require('../utils/EventEmitter');
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Battery mode constants
|
|
17
|
-
* @constant {
|
|
17
|
+
* @constant {any}
|
|
18
18
|
*/
|
|
19
19
|
const BATTERY_MODE = Object.freeze({
|
|
20
20
|
HIGH_PERFORMANCE: 'high',
|
|
@@ -39,7 +39,7 @@ const BATTERY_MODE_SET = new Set(Object.values(BATTERY_MODE));
|
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* Default battery profiles
|
|
42
|
-
* @constant {
|
|
42
|
+
* @constant {Record<string, BatteryProfile>}
|
|
43
43
|
*/
|
|
44
44
|
const DEFAULT_PROFILES = Object.freeze({
|
|
45
45
|
[BATTERY_MODE.HIGH_PERFORMANCE]: {
|
|
@@ -79,7 +79,7 @@ const DEFAULT_PROFILES = Object.freeze({
|
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
81
|
* Battery level thresholds for auto mode
|
|
82
|
-
* @constant {
|
|
82
|
+
* @constant {any}
|
|
83
83
|
*/
|
|
84
84
|
const BATTERY_THRESHOLDS = Object.freeze({
|
|
85
85
|
HIGH: 50, // Above 50%: high performance
|
|
@@ -90,7 +90,7 @@ const BATTERY_THRESHOLDS = Object.freeze({
|
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* Default configuration
|
|
93
|
-
* @constant {
|
|
93
|
+
* @constant {any}
|
|
94
94
|
*/
|
|
95
95
|
const DEFAULT_CONFIG = Object.freeze({
|
|
96
96
|
/** Initial battery mode */
|
|
@@ -128,21 +128,21 @@ const DEFAULT_CONFIG = Object.freeze({
|
|
|
128
128
|
class BatteryOptimizer extends EventEmitter {
|
|
129
129
|
/**
|
|
130
130
|
* Creates a new BatteryOptimizer instance.
|
|
131
|
-
* @param {
|
|
131
|
+
* @param {any} [options] - Configuration options
|
|
132
132
|
*/
|
|
133
133
|
constructor(options = {}) {
|
|
134
134
|
super();
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
137
|
* Configuration
|
|
138
|
-
* @type {
|
|
138
|
+
* @type {any}
|
|
139
139
|
* @private
|
|
140
140
|
*/
|
|
141
141
|
this._config = { ...DEFAULT_CONFIG, ...options };
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
144
|
* Battery profiles
|
|
145
|
-
* @type {
|
|
145
|
+
* @type {Record<string, any>}
|
|
146
146
|
* @private
|
|
147
147
|
*/
|
|
148
148
|
this._profiles = { ...DEFAULT_PROFILES };
|
|
@@ -184,21 +184,21 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
184
184
|
|
|
185
185
|
/**
|
|
186
186
|
* Battery check timer
|
|
187
|
-
* @type {
|
|
187
|
+
* @type {any}
|
|
188
188
|
* @private
|
|
189
189
|
*/
|
|
190
190
|
this._batteryCheckTimer = null;
|
|
191
191
|
|
|
192
192
|
/**
|
|
193
193
|
* Transport reference for applying settings
|
|
194
|
-
* @type {
|
|
194
|
+
* @type {any}
|
|
195
195
|
* @private
|
|
196
196
|
*/
|
|
197
197
|
this._transport = null;
|
|
198
198
|
|
|
199
199
|
/**
|
|
200
200
|
* Statistics
|
|
201
|
-
* @type {
|
|
201
|
+
* @type {any}
|
|
202
202
|
* @private
|
|
203
203
|
*/
|
|
204
204
|
this._stats = {
|
|
@@ -215,7 +215,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
215
215
|
|
|
216
216
|
/**
|
|
217
217
|
* Sets the transport to control.
|
|
218
|
-
* @param {
|
|
218
|
+
* @param {any} transport - Transport instance
|
|
219
219
|
*/
|
|
220
220
|
setTransport(transport) {
|
|
221
221
|
this._transport = transport;
|
|
@@ -227,6 +227,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
227
227
|
* @returns {Promise<void>}
|
|
228
228
|
*/
|
|
229
229
|
async setMode(mode) {
|
|
230
|
+
// @ts-ignore
|
|
230
231
|
if (!BATTERY_MODE_SET.has(mode)) {
|
|
231
232
|
throw new Error(`Invalid battery mode: ${mode}`);
|
|
232
233
|
}
|
|
@@ -262,7 +263,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
262
263
|
|
|
263
264
|
/**
|
|
264
265
|
* Gets the current active profile.
|
|
265
|
-
* @returns {
|
|
266
|
+
* @returns {any} Active profile
|
|
266
267
|
*/
|
|
267
268
|
getCurrentProfile() {
|
|
268
269
|
if (this._currentMode === BATTERY_MODE.AUTO) {
|
|
@@ -273,7 +274,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
273
274
|
|
|
274
275
|
/**
|
|
275
276
|
* Gets all available profiles.
|
|
276
|
-
* @returns {
|
|
277
|
+
* @returns {Record<string, any>} Profiles
|
|
277
278
|
*/
|
|
278
279
|
getProfiles() {
|
|
279
280
|
return { ...this._profiles };
|
|
@@ -350,7 +351,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
350
351
|
|
|
351
352
|
/**
|
|
352
353
|
* Gets optimizer statistics.
|
|
353
|
-
* @returns {
|
|
354
|
+
* @returns {any} Statistics
|
|
354
355
|
*/
|
|
355
356
|
getStats() {
|
|
356
357
|
return {
|
|
@@ -374,7 +375,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
374
375
|
/**
|
|
375
376
|
* Gets the appropriate profile for a battery level.
|
|
376
377
|
* @param {number} level - Battery level
|
|
377
|
-
* @returns {
|
|
378
|
+
* @returns {any} Profile
|
|
378
379
|
* @private
|
|
379
380
|
*/
|
|
380
381
|
_getProfileForBatteryLevel(level) {
|
|
@@ -414,7 +415,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
414
415
|
|
|
415
416
|
/**
|
|
416
417
|
* Applies a battery profile to the transport.
|
|
417
|
-
* @param {
|
|
418
|
+
* @param {any} profile - Profile to apply
|
|
418
419
|
* @returns {Promise<void>}
|
|
419
420
|
* @private
|
|
420
421
|
*/
|
|
@@ -445,7 +446,7 @@ class BatteryOptimizer extends EventEmitter {
|
|
|
445
446
|
}
|
|
446
447
|
|
|
447
448
|
this.emit('profile-applied', { profile });
|
|
448
|
-
} catch (error) {
|
|
449
|
+
} catch (/** @type {any} */ error) {
|
|
449
450
|
this.emit('error', {
|
|
450
451
|
message: 'Failed to apply battery profile',
|
|
451
452
|
error: error.message
|