react-native-ble-mesh 1.0.4 → 1.1.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/src/index.d.ts CHANGED
@@ -89,6 +89,28 @@ export const POWER_MODE: {
89
89
  ULTRA_POWER_SAVER: PowerModeConfig;
90
90
  };
91
91
 
92
+ // PRD-specified battery modes
93
+ export const BATTERY_MODE: {
94
+ HIGH_PERFORMANCE: 'high';
95
+ BALANCED: 'balanced';
96
+ LOW_POWER: 'low';
97
+ AUTO: 'auto';
98
+ };
99
+
100
+ export const PANIC_TRIGGER: {
101
+ TRIPLE_TAP: 'triple_tap';
102
+ SHAKE: 'shake';
103
+ MANUAL: 'manual';
104
+ VOLUME_COMBO: 'volume_combo';
105
+ };
106
+
107
+ export const HEALTH_STATUS: {
108
+ GOOD: 'good';
109
+ FAIR: 'fair';
110
+ POOR: 'poor';
111
+ UNKNOWN: 'unknown';
112
+ };
113
+
92
114
  // ============================================================================
93
115
  // Types and Interfaces
94
116
  // ============================================================================
@@ -109,6 +131,28 @@ export interface MeshServiceConfig {
109
131
  compressionThreshold?: number;
110
132
  }
111
133
 
134
+ export interface MeshNetworkConfig {
135
+ nickname?: string;
136
+ batteryMode?: 'high' | 'balanced' | 'low' | 'auto';
137
+ encryption?: {
138
+ level?: string;
139
+ rotateKeysAfter?: number;
140
+ };
141
+ routing?: {
142
+ maxHops?: number;
143
+ bloomFilterSize?: number;
144
+ };
145
+ compression?: {
146
+ enabled?: boolean;
147
+ threshold?: number;
148
+ };
149
+ storeAndForward?: {
150
+ enabled?: boolean;
151
+ retentionHours?: number;
152
+ maxCachedMessages?: number;
153
+ };
154
+ }
155
+
112
156
  export interface Identity {
113
157
  publicKey: Uint8Array;
114
158
  displayName: string;
@@ -125,6 +169,25 @@ export interface MeshStatus {
125
169
  sessionCount: number;
126
170
  }
127
171
 
172
+ export interface NetworkHealth {
173
+ activeNodes: number;
174
+ totalKnownNodes: number;
175
+ averageLatencyMs: number;
176
+ packetLossRate: number;
177
+ overallHealth: 'good' | 'fair' | 'poor';
178
+ lastUpdated: number;
179
+ }
180
+
181
+ export interface MeshNetworkStatus {
182
+ state: 'stopped' | 'running';
183
+ identity: Identity;
184
+ peers: number;
185
+ connectedPeers: number;
186
+ channels: number;
187
+ health: NetworkHealth;
188
+ batteryMode: string;
189
+ }
190
+
128
191
  export interface PeerOptions {
129
192
  id: string;
130
193
  publicKey?: Uint8Array | null;
@@ -187,15 +250,87 @@ export class MeshError extends Error {
187
250
  static fromJSON(json: Record<string, unknown>): MeshError;
188
251
  }
189
252
 
190
- export class CryptoError extends MeshError {}
191
- export class ConnectionError extends MeshError {}
192
- export class HandshakeError extends MeshError {}
193
- export class MessageError extends MeshError {}
253
+ export class CryptoError extends MeshError { }
254
+ export class ConnectionError extends MeshError { }
255
+ export class HandshakeError extends MeshError { }
256
+ export class MessageError extends MeshError { }
194
257
  export class ValidationError extends MeshError {
195
258
  static invalidArgument(name: string, value: unknown, details?: Record<string, unknown>): ValidationError;
196
259
  static invalidType(name: string, value: unknown, expectedType: string): ValidationError;
197
260
  }
198
261
 
262
+ // ============================================================================
263
+ // PRD-Specified High-Level API
264
+ // ============================================================================
265
+
266
+ /**
267
+ * MeshNetwork - High-level API for BitChat-compatible mesh networking.
268
+ * PRD-specified primary entry point.
269
+ */
270
+ export class MeshNetwork extends EventEmitter {
271
+ static BatteryMode: typeof BATTERY_MODE;
272
+ static PanicTrigger: typeof PANIC_TRIGGER;
273
+ static HealthStatus: typeof HEALTH_STATUS;
274
+
275
+ constructor(config?: MeshNetworkConfig);
276
+
277
+ // Lifecycle
278
+ start(transport?: Transport): Promise<void>;
279
+ stop(): Promise<void>;
280
+ destroy(): Promise<void>;
281
+
282
+ // Messaging
283
+ broadcast(text: string): Promise<string>;
284
+ sendDirect(peerId: string, text: string): Promise<string>;
285
+
286
+ // Channels
287
+ joinChannel(channelName: string, password?: string): Promise<void>;
288
+ leaveChannel(channelName: string): Promise<void>;
289
+ sendToChannel(channelName: string, text: string): Promise<string>;
290
+ getChannels(): Channel[];
291
+
292
+ // Peers
293
+ getPeers(): Peer[];
294
+ getConnectedPeers(): Peer[];
295
+ getSecuredPeers(): Peer[];
296
+ blockPeer(peerId: string): void;
297
+ unblockPeer(peerId: string): void;
298
+
299
+ // Network Health
300
+ getNetworkHealth(): NetworkHealth;
301
+ getPeerHealth(peerId: string): NodeHealth | null;
302
+
303
+ // Battery Management
304
+ setBatteryMode(mode: 'high' | 'balanced' | 'low' | 'auto'): Promise<void>;
305
+ getBatteryMode(): string;
306
+ updateBatteryLevel(level: number, charging?: boolean): void;
307
+
308
+ // Security
309
+ enablePanicMode(options?: { trigger?: string; onWipe?: (result: WipeResult) => void }): void;
310
+ disablePanicMode(): void;
311
+ registerPanicTap(): void;
312
+ wipeAllData(): Promise<WipeResult>;
313
+
314
+ // Status
315
+ getStatus(): MeshNetworkStatus;
316
+ getIdentity(): Identity;
317
+ setNickname(nickname: string): void;
318
+
319
+ // Events
320
+ on(event: 'started', listener: () => void): this;
321
+ on(event: 'stopped', listener: () => void): this;
322
+ on(event: 'peerDiscovered', listener: (peer: Peer) => void): this;
323
+ on(event: 'peerConnected', listener: (peer: Peer) => void): this;
324
+ on(event: 'peerDisconnected', listener: (peer: Peer) => void): this;
325
+ on(event: 'messageReceived', listener: (message: { from: string; text: string; timestamp: number }) => void): this;
326
+ on(event: 'directMessage', listener: (message: { from: string; text: string; timestamp: number }) => void): this;
327
+ on(event: 'channelMessage', listener: (message: { channel: string; from: string; text: string; timestamp: number }) => void): this;
328
+ on(event: 'networkHealthChanged', listener: (info: { previous: string; current: string }) => void): this;
329
+ on(event: 'dataWiped', listener: (result: WipeResult) => void): this;
330
+ on(event: 'error', listener: (error: MeshError) => void): this;
331
+ on(event: string, listener: (...args: unknown[]) => void): this;
332
+ }
333
+
199
334
  // ============================================================================
200
335
  // Core Classes
201
336
  // ============================================================================
@@ -288,6 +423,247 @@ export class MeshService extends EventEmitter {
288
423
  on(event: string, listener: (...args: unknown[]) => void): this;
289
424
  }
290
425
 
426
+ // ============================================================================
427
+ // PRD-Specified Features - Stats Interfaces
428
+ // ============================================================================
429
+
430
+ /**
431
+ * Store and Forward statistics
432
+ */
433
+ export interface StoreAndForwardStats {
434
+ messagesCached: number;
435
+ messagesDelivered: number;
436
+ messagesExpired: number;
437
+ messagesDropped: number;
438
+ deliveryAttempts: number;
439
+ deliveryFailures: number;
440
+ totalCached: number;
441
+ totalSizeBytes: number;
442
+ recipientCount: number;
443
+ cacheUtilization: number;
444
+ }
445
+
446
+ /**
447
+ * Network Monitor statistics
448
+ */
449
+ export interface NetworkMonitorStats {
450
+ totalMessagesSent: number;
451
+ totalMessagesDelivered: number;
452
+ totalMessagesFailed: number;
453
+ totalMessagesReceived: number;
454
+ knownNodes: number;
455
+ pendingMessages: number;
456
+ averageLatency: number;
457
+ }
458
+
459
+ /**
460
+ * Individual node health information
461
+ */
462
+ export interface NodeHealth {
463
+ peerId: string;
464
+ lastSeen: number;
465
+ latency: number;
466
+ messagesReceived: number;
467
+ messagesSent: number;
468
+ messagesDelivered?: number;
469
+ messagesFailed?: number;
470
+ packetLoss: number;
471
+ isActive: boolean;
472
+ discoveredAt?: number;
473
+ disconnectedAt?: number;
474
+ }
475
+
476
+ /**
477
+ * Battery Optimizer statistics
478
+ */
479
+ export interface BatteryOptimizerStats {
480
+ modeChanges: number;
481
+ autoAdjustments: number;
482
+ lastModeChange: number | null;
483
+ currentMode: string;
484
+ batteryLevel: number;
485
+ isCharging: boolean;
486
+ }
487
+
488
+ /**
489
+ * Battery power profile configuration
490
+ */
491
+ export interface BatteryProfile {
492
+ name: string;
493
+ scanIntervalMs: number;
494
+ scanWindowMs: number;
495
+ advertisingIntervalMs: number;
496
+ connectionIntervalMs: number;
497
+ connectionLatency: number;
498
+ supervisionTimeoutMs: number;
499
+ }
500
+
501
+ /**
502
+ * Emergency Manager statistics
503
+ */
504
+ export interface EmergencyManagerStats {
505
+ wipesTriggered: number;
506
+ averageWipeTimeMs: number;
507
+ lastWipeTime: number | null;
508
+ }
509
+
510
+ /**
511
+ * Panic wipe result
512
+ */
513
+ export interface WipeResult {
514
+ trigger: string;
515
+ startTime: number;
516
+ endTime: number;
517
+ elapsedMs: number;
518
+ metTarget: boolean;
519
+ clearerResults: Array<{ index: number; success: boolean; error?: string }>;
520
+ errors: Array<{ index: number; error: string }>;
521
+ }
522
+
523
+ /**
524
+ * Compression statistics
525
+ */
526
+ export interface CompressionStats {
527
+ compressionAttempts: number;
528
+ successfulCompressions: number;
529
+ decompressions: number;
530
+ bytesIn: number;
531
+ bytesOut: number;
532
+ averageCompressionRatio: number;
533
+ compressionRate: number;
534
+ }
535
+
536
+ // ============================================================================
537
+ // PRD-Specified Features
538
+ // ============================================================================
539
+
540
+ /**
541
+ * Store and Forward Manager for offline peer message delivery
542
+ */
543
+ export class StoreAndForwardManager extends EventEmitter {
544
+ constructor(options?: {
545
+ maxMessagesPerRecipient?: number;
546
+ maxTotalMessages?: number;
547
+ maxCacheSizeBytes?: number;
548
+ retentionMs?: number;
549
+ cleanupIntervalMs?: number;
550
+ });
551
+
552
+ cacheForOfflinePeer(recipientId: string, encryptedPayload: Uint8Array, options?: { messageId?: string; ttlMs?: number }): Promise<string>;
553
+ deliverCachedMessages(recipientId: string, sendFn: (payload: Uint8Array) => Promise<void>): Promise<{ delivered: number; failed: number }>;
554
+ hasCachedMessages(recipientId: string): boolean;
555
+ getCachedCount(recipientId: string): number;
556
+ getRecipientsWithCache(): string[];
557
+ clearRecipientCache(recipientId: string): number;
558
+ pruneExpiredMessages(): Promise<number>;
559
+ getStats(): StoreAndForwardStats;
560
+ clear(): void;
561
+ destroy(): void;
562
+ }
563
+
564
+ /**
565
+ * Network Health Monitor
566
+ */
567
+ export class NetworkMonitor extends EventEmitter {
568
+ constructor(options?: {
569
+ latencySampleSize?: number;
570
+ nodeTimeoutMs?: number;
571
+ healthCheckIntervalMs?: number;
572
+ });
573
+
574
+ trackMessageSent(peerId: string, messageId: string): void;
575
+ trackMessageDelivered(messageId: string, latencyMs?: number): void;
576
+ trackMessageFailed(messageId: string): void;
577
+ trackMessageReceived(peerId: string): void;
578
+ trackPeerDiscovered(peerId: string): void;
579
+ trackPeerDisconnected(peerId: string): void;
580
+ generateHealthReport(): NetworkHealth;
581
+ getNodeHealth(peerId: string): NodeHealth | null;
582
+ getAllNodeHealth(): NodeHealth[];
583
+ getLastHealthReport(): NetworkHealth | null;
584
+ getStats(): NetworkMonitorStats;
585
+ reset(): void;
586
+ destroy(): void;
587
+
588
+ on(event: 'health-changed', listener: (info: { previous: string; current: string; report: NetworkHealth }) => void): this;
589
+ on(event: 'health-report', listener: (report: NetworkHealth) => void): this;
590
+ }
591
+
592
+ /**
593
+ * Battery Optimizer with adaptive power modes
594
+ */
595
+ export class BatteryOptimizer extends EventEmitter {
596
+ constructor(options?: {
597
+ initialMode?: 'high' | 'balanced' | 'low' | 'auto';
598
+ autoAdjust?: boolean;
599
+ batteryCheckIntervalMs?: number;
600
+ activityAdjust?: boolean;
601
+ });
602
+
603
+ setTransport(transport: Transport): void;
604
+ setMode(mode: 'high' | 'balanced' | 'low' | 'auto'): Promise<void>;
605
+ getMode(): string;
606
+ getCurrentProfile(): BatteryProfile;
607
+ getProfiles(): Record<string, BatteryProfile>;
608
+ updateBatteryLevel(level: number, isCharging?: boolean): Promise<void>;
609
+ setAutoAdjust(enabled: boolean): void;
610
+ isAutoAdjustEnabled(): boolean;
611
+ recordActivity(): void;
612
+ getBatteryLevel(): number;
613
+ isCharging(): boolean;
614
+ getStats(): BatteryOptimizerStats;
615
+ destroy(): void;
616
+
617
+ on(event: 'mode-changed', listener: (info: { previous: string; current: string; profile: BatteryProfile }) => void): this;
618
+ on(event: 'auto-adjusted', listener: (info: { batteryLevel: number; profile: BatteryProfile }) => void): this;
619
+ on(event: 'battery-updated', listener: (info: { level: number; isCharging: boolean }) => void): this;
620
+ }
621
+
622
+ /**
623
+ * Emergency Manager for panic mode / data wipe
624
+ */
625
+ export class EmergencyManager extends EventEmitter {
626
+ constructor(options?: {
627
+ trigger?: 'triple_tap' | 'shake' | 'manual' | 'volume_combo';
628
+ tapWindowMs?: number;
629
+ tapCount?: number;
630
+ requireConfirmation?: boolean;
631
+ });
632
+
633
+ enablePanicMode(options?: { onWipe?: (result: WipeResult) => void; trigger?: string }): void;
634
+ disablePanicMode(): void;
635
+ isEnabled(): boolean;
636
+ registerClearer(clearer: () => Promise<void>): void;
637
+ registerTap(): void;
638
+ registerAccelerometer(data: { x: number; y: number; z: number }): void;
639
+ triggerManualWipe(): Promise<WipeResult>;
640
+ wipeAllData(): Promise<WipeResult>;
641
+ getStats(): EmergencyManagerStats;
642
+ destroy(): void;
643
+
644
+ on(event: 'panic-mode-enabled', listener: (info: { trigger: string }) => void): this;
645
+ on(event: 'panic-mode-disabled', listener: () => void): this;
646
+ on(event: 'panic-wipe-started', listener: (info: { trigger: string; timestamp: number }) => void): this;
647
+ on(event: 'panic-wipe-completed', listener: (result: WipeResult) => void): this;
648
+ }
649
+
650
+ /**
651
+ * Message Compressor with LZ4 algorithm.
652
+ * Uses Knuth's multiplicative hash (constant 2654435761) for optimal distribution.
653
+ */
654
+ export class MessageCompressor {
655
+ constructor(options?: { threshold?: number });
656
+
657
+ compress(payload: Uint8Array): { data: Uint8Array; compressed: boolean };
658
+ decompress(payload: Uint8Array, wasCompressed: boolean): Uint8Array;
659
+ getCompressionRatio(original: Uint8Array, compressed: Uint8Array): number;
660
+ getStats(): CompressionStats;
661
+ resetStats(): void;
662
+ }
663
+
664
+ export function compress(payload: Uint8Array): { data: Uint8Array; compressed: boolean };
665
+ export function decompress(payload: Uint8Array, wasCompressed: boolean): Uint8Array;
666
+
291
667
  // ============================================================================
292
668
  // Transport Layer
293
669
  // ============================================================================
@@ -501,6 +877,11 @@ export namespace utils {
501
877
  // Factory Functions
502
878
  // ============================================================================
503
879
 
880
+ /**
881
+ * Create a new MeshNetwork instance (PRD-specified high-level API)
882
+ */
883
+ export function createMeshNetwork(config?: MeshNetworkConfig): MeshNetwork;
884
+
504
885
  /**
505
886
  * Create a new MeshService instance
506
887
  */
@@ -520,3 +901,4 @@ export function createNodeMesh(options?: {
520
901
  export function createTestMesh(options?: {
521
902
  displayName?: string;
522
903
  }): Promise<{ mesh: MeshService; transport: MockTransport }>;
904
+
package/src/index.js CHANGED
@@ -2,12 +2,24 @@
2
2
  * @fileoverview BLE Mesh Network Library
3
3
  * @module rn-ble-mesh
4
4
  * @description Production-ready BLE Mesh Network with Noise Protocol security
5
+ *
6
+ * This is the definitive React Native library for BitChat-compatible
7
+ * decentralized mesh networking.
5
8
  */
6
9
 
7
10
  'use strict';
8
11
 
12
+ // High-Level API (PRD-specified)
13
+ const { MeshNetwork, BATTERY_MODE, PANIC_TRIGGER, HEALTH_STATUS } = require('./MeshNetwork');
14
+
9
15
  // Core service
10
- const { MeshService } = require('./service');
16
+ const {
17
+ MeshService,
18
+ EmergencyManager,
19
+ BatteryOptimizer,
20
+ SessionManager,
21
+ HandshakeManager,
22
+ } = require('./service');
11
23
 
12
24
  // Constants
13
25
  const constants = require('./constants');
@@ -21,7 +33,7 @@ const crypto = require('./crypto');
21
33
  // Protocol
22
34
  const protocol = require('./protocol');
23
35
 
24
- // Mesh
36
+ // Mesh (including new StoreAndForward and NetworkMonitor)
25
37
  const mesh = require('./mesh');
26
38
 
27
39
  // Transport
@@ -30,7 +42,7 @@ const transport = require('./transport');
30
42
  // Storage
31
43
  const storage = require('./storage');
32
44
 
33
- // Utils
45
+ // Utils (including MessageCompressor)
34
46
  const utils = require('./utils');
35
47
 
36
48
  // Audio (from service module)
@@ -42,6 +54,17 @@ const text = require('./service/text');
42
54
  // React Native hooks
43
55
  const hooks = require('./hooks');
44
56
 
57
+ /**
58
+ * Create a new MeshNetwork instance (PRD-specified high-level API)
59
+ * @param {Object} [config] - Configuration options
60
+ * @param {string} [config.nickname] - Display name
61
+ * @param {string} [config.batteryMode] - Battery mode
62
+ * @returns {MeshNetwork}
63
+ */
64
+ function createMeshNetwork(config) {
65
+ return new MeshNetwork(config);
66
+ }
67
+
45
68
  /**
46
69
  * Create a new MeshService instance
47
70
  * @param {Object} [config] - Configuration options
@@ -108,7 +131,36 @@ const { AudioManager, LC3Codec, VoiceMessage, AudioSession } = audio;
108
131
  const { TextManager, TextMessage, Channel, ChannelManager, BroadcastManager } = text;
109
132
  const { useMesh, usePeers, useMessages, AppStateManager } = hooks;
110
133
 
134
+ // New PRD-specified components
135
+ const { StoreAndForwardManager } = mesh;
136
+ const { NetworkMonitor } = mesh;
137
+ const { MessageCompressor, compress, decompress } = utils;
138
+
111
139
  module.exports = {
140
+ // High-Level API (PRD-specified)
141
+ MeshNetwork,
142
+ createMeshNetwork,
143
+
144
+ // Battery and Power Management
145
+ BATTERY_MODE,
146
+ BatteryOptimizer,
147
+
148
+ // Security Features
149
+ PANIC_TRIGGER,
150
+ EmergencyManager,
151
+
152
+ // Network Health
153
+ HEALTH_STATUS,
154
+ NetworkMonitor,
155
+
156
+ // Store and Forward
157
+ StoreAndForwardManager,
158
+
159
+ // Compression
160
+ MessageCompressor,
161
+ compress,
162
+ decompress,
163
+
112
164
  // Main factory functions
113
165
  createMeshService,
114
166
  createNodeMesh,
@@ -180,3 +232,4 @@ module.exports = {
180
232
  // Hooks module
181
233
  hooks
182
234
  };
235
+
package/src/mesh/index.js CHANGED
@@ -9,10 +9,14 @@ const dedup = require('./dedup');
9
9
  const fragment = require('./fragment');
10
10
  const peer = require('./peer');
11
11
  const router = require('./router');
12
+ const store = require('./store');
13
+ const monitor = require('./monitor');
12
14
 
13
15
  module.exports = {
14
16
  ...dedup,
15
17
  ...fragment,
16
18
  ...peer,
17
- ...router
19
+ ...router,
20
+ ...store,
21
+ ...monitor,
18
22
  };