UNPKG

peerpigeon

Version:

WebRTC-based peer-to-peer mesh networking library with intelligent routing and signaling server

1,977 lines (1,422 loc) 49 kB
# PeerPigeon API Documentation **Version**: Complete API reference for all exposed methods and event listeners **Generated**: August 1, 2025 ## Table of Contents 1. [Main Classes](#main-classes) 2. [PeerPigeonMesh](#peerpigeonmesh) - Main mesh network class 3. [PeerConnection](#peerconnection) - Individual peer connection management 4. [SignalingClient](#signalingclient) - WebSocket signaling 5. [MediaManager](#mediamanager) - Media stream management 6. [WebDHT](#webdht) - Low-level Distributed Hash Table 7. [DistributedStorageManager](#distributedstoragemanager) - High-level distributed storage with encryption 8. [CryptoManager](#cryptomanager) - Encryption management 9. [GossipManager](#gossipmanager) - Message propagation 10. [DebugLogger](#debuglogger) - Debug logging system 11. [Environment Detection](#environment-detection) - Runtime environment utilities 12. [Event System](#event-system) - Event listener documentation 13. [Server Classes](#server-classes) - PeerPigeonServer for hosting signaling --- ## Main Classes ### Exported Classes - `PeerPigeonMesh` - Main mesh network orchestrator - `PeerConnection` - Individual WebRTC peer connection - `SignalingClient` - WebSocket signaling client - `WebDHT` - Low-level Distributed Hash Table for raw key-value storage - `DistributedStorageManager` - High-level distributed storage with encryption and access control - `DebugLogger` - Debug logging system - `EnvironmentDetector` - Runtime environment detection - `PeerPigeonServer` - WebSocket signaling server --- ## PeerPigeonMesh The main class for creating and managing a mesh network of peers. ### Constructor ```javascript new PeerPigeonMesh(options = {}) ``` **Parameters:** - `options.peerId` (string, optional) - Custom peer ID (40-character hex string) - `options.networkName` (string, default: 'global') - Network namespace for isolation - `options.allowGlobalFallback` (boolean, default: true) - Allow fallback to global network - `options.enableWebDHT` (boolean, default: true) - Enable low-level distributed hash table - `options.enableCrypto` (boolean, default: true) - Enable encryption and key management - `options.maxPeers` (number, default: 3) - Maximum number of peer connections - `options.minPeers` (number, default: 2) - Minimum number of peer connections - `options.autoConnect` (boolean, default: true) - Auto-connect when joining network - `options.autoDiscovery` (boolean, default: true) - Automatic peer discovery - `options.evictionStrategy` (boolean, default: true) - Smart peer eviction for optimization - `options.xorRouting` (boolean, default: true) - XOR distance-based routing ### Core Methods #### `async init()` Initialize the mesh network and all subsystems. **Returns:** `Promise<void>` **Throws:** Error if initialization fails **Events:** Emits `initialized` status change ```javascript const mesh = new PeerPigeonMesh(); await mesh.init(); ``` #### `async connect(signalingUrl)` Connect to a signaling server to join the mesh network. **Parameters:** - `signalingUrl` (string) - WebSocket URL of signaling server **Returns:** `Promise<void>` **Throws:** Error if connection fails **Events:** Emits `connected` when successful ```javascript await mesh.connect('wss://signaling.example.com'); ``` #### `disconnect()` Disconnect from the mesh network and clean up all connections. **Returns:** `void` **Events:** Emits `disconnected` ```javascript mesh.disconnect(); ``` ### Configuration Methods #### `setMaxPeers(maxPeers)` Set the maximum number of simultaneous peer connections. **Parameters:** - `maxPeers` (number) - Maximum peer limit **Returns:** `void` **Events:** Emits `statusChanged` with setting update #### `setMinPeers(minPeers)` Set the minimum number of peer connections to maintain. **Parameters:** - `minPeers` (number) - Minimum peer requirement **Returns:** `void` **Events:** Emits `statusChanged` with setting update #### `setAutoDiscovery(enabled)` Enable or disable automatic peer discovery. **Parameters:** - `enabled` (boolean) - Auto-discovery state **Returns:** `void` **Events:** Emits `statusChanged` with setting update #### `setEvictionStrategy(enabled)` Enable or disable peer eviction for mesh optimization. **Parameters:** - `enabled` (boolean) - Eviction strategy state **Returns:** `void` **Events:** Emits `statusChanged` with setting update #### `setXorRouting(enabled)` Enable or disable XOR distance-based routing. **Parameters:** - `enabled` (boolean) - XOR routing state **Returns:** `void` **Events:** Emits `statusChanged` with setting update ### Network Information Methods #### `getStatus()` Get comprehensive mesh network status. **Returns:** `Object` ```javascript { peerId: string, // This peer's ID connected: boolean, // Connection to signaling server connectedCount: number, // Number of connected peers discoveredCount: number, // Number of discovered peers maxPeers: number, // Maximum peer limit minPeers: number, // Minimum peer requirement autoDiscovery: boolean, // Auto-discovery enabled evictionStrategy: boolean, // Eviction enabled xorRouting: boolean, // XOR routing enabled signalingUrl: string, // Current signaling URL uptime: number // Connection uptime in ms } ``` #### `getConnectedPeerCount()` Get the number of currently connected peers. **Returns:** `number` #### `getPeers()` Get all peer connection objects. **Returns:** `Map<string, PeerConnection>` - Map of peer ID to PeerConnection #### `getConnectedPeerIds()` Get array of connected peer IDs. **Returns:** `string[]` - Array of peer IDs #### `getDiscoveredPeers()` Get information about all discovered peers. **Returns:** `Array<Object>` ```javascript [{ peerId: string, // Peer ID discoveredAt: number // Discovery timestamp }] ``` #### `canAcceptMorePeers()` Check if mesh can accept additional peer connections. **Returns:** `boolean` #### `hasPeer(peerId)` Check if a specific peer is connected. **Parameters:** - `peerId` (string) - Peer ID to check **Returns:** `boolean` ### Messaging Methods #### `sendMessage(content)` Send a broadcast message to all peers via gossip protocol. **Parameters:** - `content` (any) - Message content (string, object, etc.) **Returns:** `string|null` - Message ID if sent successfully, null on error **Events:** Triggers `messageReceived` for all peers in network ```javascript const messageId = mesh.sendMessage("Hello mesh network!"); const messageId2 = mesh.sendMessage({ type: "data", value: 42 }); ``` #### `sendDirectMessage(targetPeerId, content)` Send a direct message to a specific peer via gossip routing. **Parameters:** - `targetPeerId` (string) - Destination peer ID - `content` (any) - Message content **Returns:** `string|null` - Message ID if sent successfully, null on error **Events:** Triggers `messageReceived` for target peer ```javascript const messageId = mesh.sendDirectMessage(peerId, "Hello specific peer!"); ``` ### Media Management Methods #### `async initializeMedia()` Initialize media subsystem and enumerate devices. **Returns:** `Promise<boolean>` - Success status **Events:** Emits `mediaError` on failure #### `async startMedia(options = {})` Start local media stream (camera/microphone). **Parameters:** - `options.video` (boolean, default: false) - Enable video - `options.audio` (boolean, default: false) - Enable audio - `options.deviceIds.camera` (string, optional) - Specific camera device ID - `options.deviceIds.microphone` (string, optional) - Specific microphone device ID **Returns:** `Promise<MediaStream>` - Local media stream **Throws:** Error if media access fails **Events:** Emits `localStreamStarted` ```javascript // Start audio and video const stream = await mesh.startMedia({ video: true, audio: true }); // Start with specific devices const stream2 = await mesh.startMedia({ video: true, audio: true, deviceIds: { camera: 'camera-device-id', microphone: 'mic-device-id' } }); ``` #### `async stopMedia()` Stop local media stream and remove from all peer connections. **Returns:** `Promise<void>` **Events:** Emits `localStreamStopped` #### `toggleVideo()` Toggle video track on/off. **Returns:** `boolean` - New video state #### `toggleAudio()` Toggle audio track on/off. **Returns:** `boolean` - New audio state #### `getMediaState()` Get current media stream state. **Returns:** `Object` ```javascript { hasStream: boolean, // Has local stream isVideoEnabled: boolean, // Video track enabled isAudioEnabled: boolean, // Audio track enabled videoDeviceId: string, // Active video device audioDeviceId: string // Active audio device } ``` #### `getMediaDevices()` Get available media devices. **Returns:** `Object` ```javascript { cameras: MediaDeviceInfo[], // Video input devices microphones: MediaDeviceInfo[], // Audio input devices speakers: MediaDeviceInfo[] // Audio output devices } ``` #### `async enumerateMediaDevices()` Refresh and get available media devices. **Returns:** `Promise<Object>` - Device information (same format as getMediaDevices) **Events:** Emits `devicesUpdated` #### `getLocalStream()` Get the current local media stream. **Returns:** `MediaStream|null` - Local stream or null if not started #### `getRemoteStreams()` Get all remote media streams from connected peers. **Returns:** `Array<Object>` ```javascript [{ peerId: string, // Source peer ID stream: MediaStream // Remote media stream }] ``` ### Distributed Hash Table (WebDHT) Methods #### `async dhtPut(key, value, options = {})` Store a key-value pair in the distributed hash table. **Parameters:** - `key` (string) - Storage key - `value` (any) - Value to store - `options.ttl` (number, optional) - Time to live in milliseconds - `options.space` (string, optional) - Storage space ('private', 'public', 'frozen') **Returns:** `Promise<void>` **Events:** Emits `dhtValueChanged` ```javascript await mesh.dhtPut('user:profile', { name: 'Alice', age: 30 }); await mesh.dhtPut('temp:data', value, { ttl: 60000 }); // Expires in 1 minute ``` #### `async dhtGet(key, options = {})` Retrieve a value from the distributed hash table. **Parameters:** - `key` (string) - Storage key - `options.timeout` (number, optional) - Request timeout in milliseconds **Returns:** `Promise<any>` - Retrieved value or null if not found ```javascript const profile = await mesh.dhtGet('user:profile'); ``` #### `async dhtUpdate(key, value, options = {})` Update an existing key in the distributed hash table. **Parameters:** - `key` (string) - Storage key - `value` (any) - New value - `options.merge` (boolean, default: false) - Merge objects instead of replace **Returns:** `Promise<void>` **Events:** Emits `dhtValueChanged` #### `async dhtDelete(key)` Delete a key from the distributed hash table. **Parameters:** - `key` (string) - Storage key to delete **Returns:** `Promise<boolean>` - True if deleted, false if not found **Events:** Emits `dhtValueChanged` #### `async dhtSubscribe(key)` Subscribe to changes on a specific key. **Parameters:** - `key` (string) - Storage key to monitor **Returns:** `Promise<void>` **Events:** Will emit `dhtValueChanged` when key changes ```javascript await mesh.dhtSubscribe('shared:document'); mesh.addEventListener('dhtValueChanged', (data) => { if (data.key === 'shared:document') { console.log('Document updated:', data.newValue); } }); ``` #### `async dhtUnsubscribe(key)` Unsubscribe from changes on a specific key. **Parameters:** - `key` (string) - Storage key to stop monitoring **Returns:** `Promise<void>` ### Encryption Methods (when enableCrypto: true) #### `async sendEncryptedBroadcast(content, groupId = null)` Send an encrypted broadcast message. **Parameters:** - `content` (any) - Message content to encrypt - `groupId` (string, optional) - Group encryption key ID **Returns:** `Promise<string|null>` - Message ID if sent successfully #### `async decryptMessage(encryptedData)` Decrypt a received encrypted message. **Parameters:** - `encryptedData` (Object) - Encrypted message data **Returns:** `Promise<any>` - Decrypted content #### `async exchangeKeysWithPeer(peerId)` Exchange encryption keys with a specific peer. **Parameters:** - `peerId` (string) - Peer ID to exchange keys with **Returns:** `Promise<void>` #### `async addPeerKey(peerId, publicKey)` Add a peer's public key for encryption. **Parameters:** - `peerId` (string) - Peer ID - `publicKey` (string) - Peer's public key **Returns:** `Promise<void>` #### `getPublicKey()` Get this peer's public key. **Returns:** `string|null` - Public key if crypto is initialized ### Utility Methods #### `async cleanupStaleSignalingData()` Manually clean up stale signaling data. **Returns:** `Promise<void>` #### `forceConnectToAllPeers()` Force connection attempts to all discovered peers. **Returns:** `number` - Number of connection attempts made #### `debugConnectivity()` Log detailed connectivity debug information. **Returns:** `void` #### `getPeerStateSummary()` Get summary of all peer connection states. **Returns:** `Object` ```javascript { total: number, connected: number, connecting: number, failed: number, states: { [peerId]: string } } ``` #### `startConnectionMonitoring()` Start periodic connection health monitoring. **Returns:** `void` **Events:** Emits `connectionStats` periodically #### `stopConnectionMonitoring()` Stop connection health monitoring. **Returns:** `void` #### Static `validatePeerId(peerId)` Validate a peer ID format. **Parameters:** - `peerId` (string) - Peer ID to validate **Returns:** `boolean` - True if valid 40-character hex string #### Static `async generatePeerId()` Generate a new random peer ID. **Returns:** `Promise<string>` - New 40-character hex peer ID --- ## PeerConnection Manages individual WebRTC peer-to-peer connections. ### Constructor ```javascript new PeerConnection(peerId, isInitiator = false, options = {}) ``` **Parameters:** - `peerId` (string) - Remote peer ID - `isInitiator` (boolean) - Whether this peer initiates the connection - `options.localStream` (MediaStream, optional) - Local media stream - `options.enableVideo` (boolean, default: false) - Enable video - `options.enableAudio` (boolean, default: false) - Enable audio ### Methods #### `async createConnection()` Create and configure the RTCPeerConnection. **Returns:** `Promise<void>` **Throws:** Error if WebRTC not supported **Events:** Various connection state events #### `async createOffer()` Create an SDP offer for connection initiation. **Returns:** `Promise<RTCSessionDescription>` - SDP offer **Events:** May emit `iceCandidate` events #### `async handleOffer(offer)` Handle incoming SDP offer and create answer. **Parameters:** - `offer` (RTCSessionDescription) - Remote SDP offer **Returns:** `Promise<RTCSessionDescription>` - SDP answer **Events:** May emit `iceCandidate` events #### `async handleAnswer(answer)` Handle incoming SDP answer. **Parameters:** - `answer` (RTCSessionDescription) - Remote SDP answer **Returns:** `Promise<void>` #### `async handleIceCandidate(candidate)` Handle incoming ICE candidate. **Parameters:** - `candidate` (RTCIceCandidate) - ICE candidate **Returns:** `Promise<void>` #### `sendMessage(message)` Send a message over the data channel. **Parameters:** - `message` (any) - Message to send **Returns:** `boolean` - True if sent successfully **Events:** Triggers `message` event on remote peer #### `async setLocalStream(stream)` Set or update the local media stream. **Parameters:** - `stream` (MediaStream|null) - Media stream or null to remove **Returns:** `Promise<void>` **Events:** May trigger renegotiation #### `getRemoteStream()` Get the remote media stream. **Returns:** `MediaStream|null` - Remote stream or null #### `getLocalStream()` Get the local media stream. **Returns:** `MediaStream|null` - Local stream or null #### `getMediaCapabilities()` Get detailed media capabilities. **Returns:** `Object` ```javascript { hasLocalVideo: boolean, // Has local video track hasLocalAudio: boolean, // Has local audio track hasRemoteVideo: boolean, // Has remote video track hasRemoteAudio: boolean, // Has remote audio track canSendVideo: boolean, // Can send video canSendAudio: boolean, // Can send audio canReceiveVideo: boolean, // Can receive video canReceiveAudio: boolean // Can receive audio } ``` #### `getStatus()` Get simplified connection status. **Returns:** `string` - 'connected', 'connecting', 'failed', 'closed', etc. #### `getDetailedStatus()` Get detailed connection status. **Returns:** `Object` ```javascript { connectionState: string, // RTCPeerConnection state iceConnectionState: string, // ICE connection state dataChannelState: string, // Data channel state dataChannelReady: boolean, // Data channel ready for messages isClosing: boolean, // Connection is closing overallStatus: string // Overall status assessment } ``` #### `close()` Close the peer connection and clean up resources. **Returns:** `void` **Events:** Emits `disconnected` ### Events - `connected` - Connection established - `disconnected` - Connection closed - `message` - Data channel message received - `remoteStream` - Remote media stream received - `iceCandidate` - ICE candidate generated - `connectionFailed` - Connection failed - `dataChannelOpen` - Data channel opened - `dataChannelClosed` - Data channel closed --- ## SignalingClient Manages WebSocket connection to signaling server. ### Constructor ```javascript new SignalingClient(peerId, maxPeers = 10, mesh = null) ``` **Parameters:** - `peerId` (string) - This peer's ID - `maxPeers` (number) - Maximum peers to announce - `mesh` (PeerPigeonMesh, optional) - Reference to mesh ### Methods #### `async connect(websocketUrl)` Connect to WebSocket signaling server. **Parameters:** - `websocketUrl` (string) - WebSocket server URL **Returns:** `Promise<void>` **Throws:** Error if connection fails **Events:** Emits `connected` when successful #### `disconnect()` Disconnect from signaling server. **Returns:** `void` **Events:** Emits `disconnected` #### `async sendSignalingMessage(message)` Send a signaling message to server. **Parameters:** - `message` (Object) - Message object with type and data **Returns:** `Promise<Object>` - Server response **Throws:** Error if send fails #### `isConnected()` Check if connected to signaling server. **Returns:** `boolean` #### `getConnectionStats()` Get connection statistics. **Returns:** `Object` ```javascript { connected: boolean, lastPingTime: number, lastPongTime: number, reconnectAttempts: number } ``` #### `triggerKeepAlivePingCheck()` Force immediate keep-alive ping check. **Returns:** `void` ### Events - `connected` - Connected to signaling server - `disconnected` - Disconnected from signaling server - `signalingMessage` - Signaling message received - `statusChanged` - Status update - `error` - Connection error --- ## MediaManager Manages local media streams and devices. ### Constructor ```javascript new MediaManager() ``` ### Methods #### `async init()` Initialize media system and enumerate devices. **Returns:** `Promise<boolean>` - Success status #### `async enumerateDevices()` Get available media devices. **Returns:** `Promise<Object>` ```javascript { cameras: MediaDeviceInfo[], microphones: MediaDeviceInfo[], speakers: MediaDeviceInfo[] } ``` #### `async startLocalStream(options = {})` Start local media stream. **Parameters:** - `options.video` (boolean) - Enable video - `options.audio` (boolean) - Enable audio - `options.deviceIds.camera` (string, optional) - Camera device ID - `options.deviceIds.microphone` (string, optional) - Microphone device ID **Returns:** `Promise<MediaStream>` - Local media stream #### `stopLocalStream()` Stop local media stream. **Returns:** `void` #### `toggleVideo()` Toggle video track on/off. **Returns:** `boolean` - New video state #### `toggleAudio()` Toggle audio track on/off. **Returns:** `boolean` - New audio state #### `getMediaState()` Get current media state. **Returns:** `Object` ```javascript { hasStream: boolean, isVideoEnabled: boolean, isAudioEnabled: boolean, videoDeviceId: string, audioDeviceId: string } ``` #### Static `checkSupport()` Check browser media API support. **Returns:** `Object` ```javascript { getUserMedia: boolean, enumerateDevices: boolean, mediaDevices: boolean } ``` #### `async getPermissions()` Get media permissions status. **Returns:** `Promise<Object>` ```javascript { camera: 'granted' | 'denied' | 'prompt', microphone: 'granted' | 'denied' | 'prompt' } ``` ### Events - `localStreamStarted` - Local stream started - `localStreamStopped` - Local stream stopped - `devicesUpdated` - Device list updated - `error` - Media error --- ## WebDHT **Low-level Distributed Hash Table for raw key-value storage across the mesh network.** The WebDHT provides a Kademlia-style distributed hash table for storing arbitrary key-value pairs across the mesh. This is a low-level storage system that provides basic DHT operations without encryption or access control. **Use WebDHT for:** - Simple key-value storage across the mesh - Raw data that doesn't need encryption - Building custom storage solutions - Direct DHT operations **For encrypted storage with access control, use DistributedStorageManager instead.** ### Constructor ```javascript new WebDHT(mesh) ``` **Parameters:** - `mesh` (PeerPigeonMesh) - Reference to mesh network ### Methods #### `async put(key, value, options = {})` Store a key-value pair. **Parameters:** - `key` (string) - Storage key - `value` (any) - Value to store - `options.ttl` (number, optional) - Time to live in ms - `options.replicas` (number, optional) - Number of replicas **Returns:** `Promise<void>` #### `async get(key, options = {})` Retrieve a value by key. **Parameters:** - `key` (string) - Storage key - `options.timeout` (number, optional) - Request timeout **Returns:** `Promise<any>` - Retrieved value or null #### `async update(key, value, options = {})` Update an existing key. **Parameters:** - `key` (string) - Storage key - `value` (any) - New value - `options.merge` (boolean) - Merge with existing value **Returns:** `Promise<void>` #### `async delete(key)` Delete a key. **Parameters:** - `key` (string) - Storage key **Returns:** `Promise<boolean>` - True if deleted #### `async subscribe(key)` Subscribe to key changes. **Parameters:** - `key` (string) - Storage key **Returns:** `Promise<void>` #### `async unsubscribe(key)` Unsubscribe from key changes. **Parameters:** - `key` (string) - Storage key **Returns:** `Promise<void>` #### `getStorageStats()` Get storage statistics. **Returns:** `Object` ```javascript { localKeys: number, subscriptions: number, totalSize: number, peerCount: number } ``` ### Events - `valueChanged` - DHT value changed - `keyAdded` - New key added - `keyDeleted` - Key deleted - `subscriptionAdded` - Subscription added - `subscriptionRemoved` - Subscription removed --- ## DistributedStorageManager **High-level distributed storage with encryption, access control, and advanced features.** The DistributedStorageManager provides a sophisticated storage layer on top of WebDHT that includes encryption, access control, storage spaces, and collaborative editing features. It uses WebDHT as its storage backend but provides a much richer API. **Use DistributedStorageManager for:** - Encrypted data storage - Access control and permissions - Public/private/frozen storage spaces - Collaborative editing with CRDT support - Application-level data storage **Note:** DistributedStorageManager uses WebDHT as its backend storage but they are conceptually separate: - WebDHT: Raw key-value storage across the mesh - DistributedStorageManager: High-level storage with encryption and features High-level distributed storage with encryption and access control. ### Constructor ```javascript new DistributedStorageManager(mesh) ``` **Parameters:** - `mesh` (PeerPigeonMesh) - Reference to mesh network ### Methods #### `async store(key, value, options = {})` Store data with encryption and access control. **Parameters:** - `key` (string) - Storage key - `value` (any) - Data to store - `options.space` (string) - Storage space ('private', 'public', 'frozen') - `options.encrypt` (boolean) - Encrypt data - `options.ttl` (number) - Time to live - `options.immutable` (boolean) - Make immutable **Returns:** `Promise<string>` - Storage key ID #### `async retrieve(keyId, options = {})` Retrieve stored data. **Parameters:** - `keyId` (string) - Storage key ID - `options.decrypt` (boolean) - Decrypt data **Returns:** `Promise<any>` - Retrieved data or null #### `async update(keyId, value, options = {})` Update stored data. **Parameters:** - `keyId` (string) - Storage key ID - `value` (any) - New data - `options.merge` (boolean) - Merge with existing **Returns:** `Promise<void>` #### `async delete(keyId)` Delete stored data. **Parameters:** - `keyId` (string) - Storage key ID **Returns:** `Promise<boolean>` - True if deleted #### `async grantAccess(keyId, peerId, permissions = ['read'])` Grant access to another peer. **Parameters:** - `keyId` (string) - Storage key ID - `peerId` (string) - Peer to grant access - `permissions` (string[]) - Permissions array **Returns:** `Promise<void>` #### `async revokeAccess(keyId, peerId)` Revoke peer access. **Parameters:** - `keyId` (string) - Storage key ID - `peerId` (string) - Peer to revoke access **Returns:** `Promise<void>` #### `async subscribe(keyId)` Subscribe to data changes. **Parameters:** - `keyId` (string) - Storage key ID **Returns:** `Promise<void>` #### `async unsubscribe(keyId)` Unsubscribe from data changes. **Parameters:** - `keyId` (string) - Storage key ID **Returns:** `Promise<void>` #### `getStorageInterface()` Get lexical storage interface (GUN-like API). **Returns:** `LexicalStorageInterface` - Chainable storage interface ```javascript // Usage example const storage = mesh.distributedStorage.getStorageInterface(); await storage.get('users').get('alice').put({ name: 'Alice', age: 30 }); const name = await storage.get('users').get('alice').get('name').val(); ``` ### Events - `dataStored` - Data stored - `dataRetrieved` - Data retrieved - `dataUpdated` - Data updated - `dataDeleted` - Data deleted - `accessGranted` - Access granted - `accessRevoked` - Access revoked --- ## CryptoManager Encryption and key management (when enableCrypto: true). ### Constructor ```javascript new CryptoManager() ``` ### Methods #### `async init(options = {})` Initialize crypto system. **Parameters:** - `options.alias` (string, optional) - User alias for persistent identity - `options.password` (string, optional) - User password - `options.generateKeypair` (boolean, default: true) - Generate keypair **Returns:** `Promise<Object>` - Generated keypair #### `async createOrAuthenticateUser(alias, password)` Create or authenticate user with persistent identity. **Parameters:** - `alias` (string) - User alias - `password` (string) - User password **Returns:** `Promise<Object>` - User credentials #### `async encrypt(data, recipientPublicKey)` Encrypt data for a specific recipient. **Parameters:** - `data` (any) - Data to encrypt - `recipientPublicKey` (string) - Recipient's public key **Returns:** `Promise<Object>` - Encrypted data package #### `async decrypt(encryptedData, senderPublicKey)` Decrypt received data. **Parameters:** - `encryptedData` (Object) - Encrypted data package - `senderPublicKey` (string) - Sender's public key **Returns:** `Promise<any>` - Decrypted data #### `async sign(data)` Sign data with private key. **Parameters:** - `data` (any) - Data to sign **Returns:** `Promise<string>` - Digital signature #### `async verify(data, signature, publicKey)` Verify digital signature. **Parameters:** - `data` (any) - Original data - `signature` (string) - Digital signature - `publicKey` (string) - Signer's public key **Returns:** `Promise<boolean>` - True if valid #### `getPublicKey()` Get this peer's public key. **Returns:** `string|null` - Public key #### `addPeerKey(peerId, publicKey)` Add a peer's public key. **Parameters:** - `peerId` (string) - Peer ID - `publicKey` (string) - Peer's public key **Returns:** `void` #### `getPeerKey(peerId)` Get a peer's public key. **Parameters:** - `peerId` (string) - Peer ID **Returns:** `string|null` - Peer's public key #### `getStats()` Get encryption statistics. **Returns:** `Object` ```javascript { messagesEncrypted: number, messagesDecrypted: number, encryptionTime: number, decryptionTime: number, keyExchanges: number } ``` ### Events - `cryptoReady` - Crypto system initialized - `cryptoError` - Crypto error - `peerKeyAdded` - Peer key added - `userAuthenticated` - User authenticated --- ## GossipManager Message propagation across the mesh network. ### Constructor ```javascript new GossipManager(mesh, connectionManager) ``` ### Methods #### `broadcastMessage(content, messageType = 'chat')` Broadcast message to all peers. **Parameters:** - `content` (any) - Message content - `messageType` (string) - Message type **Returns:** `string|null` - Message ID #### `sendDirectMessage(targetPeerId, content, subtype = 'dm')` Send direct message to specific peer. **Parameters:** - `targetPeerId` (string) - Target peer ID - `content` (any) - Message content - `subtype` (string) - Message subtype **Returns:** `string|null` - Message ID #### `handleGossipMessage(message, fromPeerId)` Handle incoming gossip message. **Parameters:** - `message` (Object) - Gossip message - `fromPeerId` (string) - Sender peer ID **Returns:** `Promise<void>` ### Events - `messageReceived` - Message received - `messagePropagated` - Message propagated - `messageExpired` - Message expired --- ## DebugLogger Configurable debug logging system. ### Static Methods #### `create(moduleName)` Create debug logger for a module. **Parameters:** - `moduleName` (string) - Module name **Returns:** `Object` - Logger with log/warn/error methods ```javascript const debug = DebugLogger.create('MyModule'); debug.log('This is a debug message'); debug.warn('This is a warning'); debug.error('This is an error'); ``` #### `enable(moduleName)` Enable debugging for specific module. **Parameters:** - `moduleName` (string) - Module to enable **Returns:** `void` #### `enableAll()` Enable debugging for all modules. **Returns:** `void` #### `disable(moduleName)` Disable debugging for specific module. **Parameters:** - `moduleName` (string) - Module to disable **Returns:** `void` #### `disableAll()` Disable debugging for all modules. **Returns:** `void` #### `isEnabled(moduleName)` Check if debugging is enabled for module. **Parameters:** - `moduleName` (string) - Module to check **Returns:** `boolean` #### `listModules()` Get list of all registered modules. **Returns:** `string[]` - Array of module names #### `getState()` Get current debugging state. **Returns:** `Object` ```javascript { globalEnabled: boolean, enabledModules: string[], disabledModules: string[] } ``` ### Logger Methods Each logger instance returned by `create()` has these methods: #### `log(...args)` Log debug information. #### `warn(...args)` Log warning. #### `error(...args)` Log error. #### `info(...args)` Log info (alias for log). #### `debug(...args)` Log debug (alias for log). --- ## Environment Detection Runtime environment detection utilities. ### EnvironmentDetector Class #### Properties - `isBrowser` (boolean) - Running in browser - `isNodeJS` (boolean) - Running in Node.js - `isWorker` (boolean) - Running in web worker - `isServiceWorker` (boolean) - Running in service worker - `isWebWorker` (boolean) - Running in dedicated worker - `isSharedWorker` (boolean) - Running in shared worker - `isDeno` (boolean) - Running in Deno - `isBun` (boolean) - Running in Bun - `isNativeScript` (boolean) - Running in NativeScript - `hasWebRTC` (boolean) - WebRTC APIs available - `hasWebSocket` (boolean) - WebSocket APIs available - `hasLocalStorage` (boolean) - localStorage available - `hasGetUserMedia` (boolean) - getUserMedia available - `hasRandomValues` (boolean) - crypto.getRandomValues available #### Methods #### `getEnvironmentReport()` Get comprehensive environment report. **Returns:** `Object` ```javascript { runtime: { isBrowser: boolean, isNodeJS: boolean, isWorker: boolean, // ... other runtime flags }, capabilities: { webrtc: boolean, webSocket: boolean, localStorage: boolean, // ... other capabilities }, browser: { name: string, version: string, userAgent: string }, // ... other environment details } ``` ### Exported Functions #### `isBrowser()` Check if running in browser. **Returns:** `boolean` #### `isNodeJS()` Check if running in Node.js. **Returns:** `boolean` #### `isWorker()` Check if running in worker context. **Returns:** `boolean` #### `hasWebRTC()` Check if WebRTC APIs are available. **Returns:** `boolean` #### `hasWebSocket()` Check if WebSocket APIs are available. **Returns:** `boolean` #### `getEnvironmentReport()` Get environment report (same as class method). **Returns:** `Object` --- ## Event System All classes extend EventEmitter and support event listening. ### EventEmitter Methods #### `addEventListener(event, callback)` Add event listener. **Parameters:** - `event` (string) - Event name - `callback` (Function) - Event handler **Returns:** `void` #### `removeEventListener(event, callback)` Remove event listener. **Parameters:** - `event` (string) - Event name - `callback` (Function) - Event handler to remove **Returns:** `void` #### `emit(event, data)` Emit an event (internal use). **Parameters:** - `event` (string) - Event name - `data` (any) - Event data **Returns:** `void` ### Standard Node.js EventEmitter Compatible Methods #### `on(event, callback)` Add event listener (alias for `addEventListener`). **Parameters:** - `event` (string) - Event name - `callback` (Function) - Event handler **Returns:** `EventEmitter` - Returns this for method chaining **Example:** ```javascript mesh.on('peerConnected', (data) => { console.log('Peer connected:', data.peerId); }).on('messageReceived', (data) => { console.log('Message:', data.content); }); ``` #### `off(event, callback)` Remove event listener (alias for `removeEventListener`). **Parameters:** - `event` (string) - Event name - `callback` (Function) - Event handler to remove **Returns:** `EventEmitter` - Returns this for method chaining #### `once(event, callback)` Add one-time event listener that automatically removes itself after being called once. **Parameters:** - `event` (string) - Event name - `callback` (Function) - Event handler **Returns:** `EventEmitter` - Returns this for method chaining **Example:** ```javascript mesh.once('connected', () => { console.log('Connected to mesh!'); // This listener will be automatically removed after first execution }); ``` #### `removeAllListeners([event])` Remove all listeners for an event, or all listeners if no event is specified. **Parameters:** - `event` (string, optional) - Event name. If omitted, removes all listeners for all events **Returns:** `EventEmitter` - Returns this for method chaining **Example:** ```javascript // Remove all listeners for 'peerConnected' event mesh.removeAllListeners('peerConnected'); // Remove all listeners for all events mesh.removeAllListeners(); ``` #### `listeners(event)` Get array of listeners for an event. **Parameters:** - `event` (string) - Event name **Returns:** `Function[]` - Array of listener functions **Example:** ```javascript const peerConnectedListeners = mesh.listeners('peerConnected'); console.log(`${peerConnectedListeners.length} listeners for peerConnected`); ``` #### `listenerCount(event)` Get the number of listeners for an event. **Parameters:** - `event` (string) - Event name **Returns:** `number` - Number of listeners **Example:** ```javascript const count = mesh.listenerCount('messageReceived'); console.log(`${count} message listeners`); ``` #### `eventNames()` Get array of event names that have listeners. **Returns:** `string[]` - Array of event names **Example:** ```javascript const events = mesh.eventNames(); console.log('Events with listeners:', events); ``` ### Usage Examples #### Basic Event Handling with Standard Methods ```javascript import { PeerPigeonMesh } from 'peerpigeon'; const mesh = new PeerPigeonMesh({ peerId: 'unique-peer-id', maxPeers: 5 }); // Using standard .on() method with chaining mesh .on('connected', () => { console.log('🔗 Connected to mesh network'); }) .on('peerConnected', (data) => { console.log(`👋 Peer joined: ${data.peerId}`); }) .on('messageReceived', (data) => { console.log(`💬 Message from ${data.from}: ${data.content}`); }); // One-time listener for initialization mesh.once('initialized', () => { console.log('🎉 Mesh is ready!'); // This listener will automatically be removed after first call }); await mesh.init(); await mesh.connect('ws://localhost:3000'); ``` #### Advanced Event Management ```javascript // Store reference to listeners for later removal const messageHandler = (data) => { console.log('Message:', data.content); }; const peerHandler = (data) => { console.log('Peer event:', data.peerId); }; // Add multiple listeners mesh .on('messageReceived', messageHandler) .on('peerConnected', peerHandler) .on('peerDisconnected', peerHandler); // Check listener counts console.log(`Message listeners: ${mesh.listenerCount('messageReceived')}`); console.log(`Active events: ${mesh.eventNames()}`); // Remove specific listener mesh.off('messageReceived', messageHandler); // Remove all listeners for an event mesh.removeAllListeners('peerConnected'); // Remove all listeners for all events mesh.removeAllListeners(); ``` #### Error Handling and Cleanup ```javascript // Set up error handling mesh.on('error', (error) => { console.error('Mesh error:', error); }); // Clean up on shutdown process.on('SIGINT', () => { console.log('Shutting down...'); // Remove all event listeners to prevent memory leaks mesh.removeAllListeners(); // Disconnect from mesh mesh.disconnect(); process.exit(0); }); ``` #### Compatibility with Both Styles ```javascript // You can mix and match both styles as needed mesh.addEventListener('connected', legacyHandler); // Traditional style mesh.on('disconnected', modernHandler); // Standard style // Both work the same way mesh.removeEventListener('connected', legacyHandler); mesh.off('disconnected', modernHandler); ``` ### Main Events by Class #### PeerPigeonMesh Events - `initialized` - Mesh initialized - `connected` - Connected to signaling server - `disconnected` - Disconnected from signaling server - `peerConnected` - Peer connected - `peerDisconnected` - Peer disconnected - `peerDiscovered` - Peer discovered - `peerEvicted` - Peer evicted - `messageReceived` - Message received - `remoteStream` - Remote media stream received - `localStreamStarted` - Local stream started - `localStreamStopped` - Local stream stopped - `mediaError` - Media error - `dhtValueChanged` - DHT value changed - `statusChanged` - Status update - `peersUpdated` - Peer list updated - `connectionStats` - Connection statistics - `cryptoReady` - Crypto system ready - `cryptoError` - Crypto error - `peerKeyAdded` - Peer key added - `userAuthenticated` - User authenticated - `storageDataStored` - Storage data stored - `storageDataRetrieved` - Storage data retrieved - `storageDataUpdated` - Storage data updated - `storageDataDeleted` - Storage data deleted - `storageAccessGranted` - Storage access granted - `storageAccessRevoked` - Storage access revoked #### PeerConnection Events - `connected` - Connection established - `disconnected` - Connection closed - `message` - Data channel message - `remoteStream` - Remote media stream - `iceCandidate` - ICE candidate generated - `connectionFailed` - Connection failed - `dataChannelOpen` - Data channel opened - `dataChannelClosed` - Data channel closed #### SignalingClient Events - `connected` - Connected to server - `disconnected` - Disconnected from server - `signalingMessage` - Signaling message received - `statusChanged` - Status update - `error` - Connection error #### MediaManager Events - `localStreamStarted` - Stream started - `localStreamStopped` - Stream stopped - `devicesUpdated` - Device list updated - `error` - Media error #### WebDHT Events - `valueChanged` - DHT value changed - `keyAdded` - Key added - `keyDeleted` - Key deleted - `subscriptionAdded` - Subscription added - `subscriptionRemoved` - Subscription removed #### CryptoManager Events - `cryptoReady` - System ready - `cryptoError` - Crypto error - `peerKeyAdded` - Peer key added - `userAuthenticated` - User authenticated #### GossipManager Events - `messageReceived` - Message received - `messagePropagated` - Message propagated - `messageExpired` - Message expired --- ## Server Classes ### PeerPigeonServer WebSocket signaling server for hosting mesh networks with optional hub capabilities. #### Constructor ```javascript new PeerPigeonServer(options = {}) ``` **Parameters:** - `options.port` (number, default: 3000) - Server port - `options.host` (string, default: 'localhost') - Server host - `options.maxConnections` (number, default: 1000) - Maximum concurrent connections - `options.cleanupInterval` (number, default: 30000) - Cleanup interval in ms (30 seconds) - `options.peerTimeout` (number, default: 300000) - Peer timeout in ms (5 minutes) - `options.corsOrigin` (string, default: '*') - CORS origin - `options.maxMessageSize` (number, default: 1048576) - Max message size in bytes (1MB) - `options.maxPortRetries` (number, default: 10) - Port retry attempts if port in use - `options.isHub` (boolean, default: false) - Run as a hub server - `options.hubMeshNamespace` (string, default: 'pigeonhub-mesh') - Network namespace for hub-to-hub connections - `options.hubPeerId` (string, optional) - Custom hub peer ID (auto-generated if hub) - `options.bootstrapHubs` (Array<string>, default: []) - URIs of bootstrap hubs to connect to - `options.autoConnect` (boolean, default: true) - Auto-connect to bootstrap hubs - `options.reconnectInterval` (number, default: 5000) - Hub reconnect interval in ms - `options.maxReconnectAttempts` (number, default: 10) - Max hub reconnection attempts **Note:** All hubs in the same network must use the same `hubMeshNamespace` to discover and connect to each other. The default `'pigeonhub-mesh'` namespace works for most deployments, but you can specify a custom namespace to isolate different hub networks. #### Methods #### `async start()` Start the signaling server. Automatically tries next port if specified port is in use. **Returns:** `Promise<{host: string, port: number}>` **Throws:** Error if server fails to start **Events:** Emits `started` with `{host, port}` #### `async stop()` Stop the signaling server and disconnect from any bootstrap hubs. **Returns:** `Promise<void>` **Events:** Emits `stopped` #### `getStats()` Get comprehensive server statistics. **Returns:** `Object` ```javascript { isRunning: boolean, isHub: boolean, hubPeerId: string | null, hubMeshNamespace: string, // Current hub mesh namespace connections: number, peers: number, hubs: number, networks: number, bootstrapHubs: { total: number, connected: number }, maxConnections: number, uptime: number, host: string, port: number } ``` #### `getHubStats()` Get hub-specific statistics (only relevant if `isHub: true`). **Returns:** `Object` ```javascript { totalHubs: number, connectedHubs: number, hubs: Array<{peerId, registeredAt, lastActivity}>, bootstrapHubs: Array<{uri, connected, lastAttempt, attemptNumber}> } ``` #### `getPeers()` Get list of all connected peers. **Returns:** `Array<Object>` - Array of peer information objects #### `getHubMeshNamespace()` Get the current hub mesh namespace. **Returns:** `string` - Current hub mesh namespace ```javascript const namespace = server.getHubMeshNamespace(); console.log('Hub namespace:', namespace); // 'pigeonhub-mesh' ``` #### `setHubMeshNamespace(namespace)` Set the hub mesh namespace. Can only be called when server is stopped. **Parameters:** - `namespace` (string) - New hub mesh namespace (non-empty string) **Returns:** `string` - The set namespace **Throws:** Error if server is running or namespace is invalid ```javascript // Must be called before starting the server server.setHubMeshNamespace('production-mesh'); await server.start(); ``` **Important:** All hubs in the same network must use the same namespace to discover each other. #### `broadcastToOthers(senderPeerId, message)` Broadcast to all peers except sender. **Parameters:** - `senderPeerId` (string) - Sender peer ID - `message` (Object) - Message to broadcast **Returns:** `number` - Number of peers reached #### Events - `started` - Server started `{host, port}` - `stopped` - Server stopped - `peerConnected` - Peer connected `{peerId, totalConnections}` - `peerDisconnected` - Peer disconnected `{peerId, code, reason, totalConnections}` - `peerAnnounced` - Peer announced `{peerId, networkName, isHub}` - `peerGoodbye` - Peer said goodbye `{peerId}` - `hubRegistered` - Hub registered `{peerId, totalHubs}` (if this is a hub) - `hubUnregistered` - Hub unregistered `{peerId, totalHubs}` (if this is a hub) - `bootstrapConnected` - Connected to bootstrap hub `{uri}` (if this is a hub) - `bootstrapDisconnected` - Disconnected from bootstrap `{uri, code, reason}` (if this is a hub) - `hubDiscovered` - Discovered another hub `{peerId, via, data}` (if this is a hub) - `bootstrapSignaling` - Signaling relayed through bootstrap `{type, data, fromPeerId, targetPeerId, uri}` - `error` - Server error --- ## Usage Examples ### Basic Mesh Network ```javascript import { PeerPigeonMesh } from 'peerpigeon'; const mesh = new PeerPigeonMesh({ maxPeers: 5, enableWebDHT: true }); await mesh.init(); // Connect to signaling server await mesh.connect('wss://signaling.example.com'); // Listen for events mesh.addEventListener('peerConnected', (data) => { console.log('Peer connected:', data.peerId); }); mesh.addEventListener('messageReceived', (data) => { console.log('Message:', data.content, 'from:', data.from); }); // Send messages mesh.sendMessage('Hello mesh network!'); mesh.sendDirectMessage(peerId, 'Hello specific peer!'); ``` ### Media Streaming ```javascript // Start video call const stream = await mesh.startMedia({ video: true, audio: true }); // Handle remote streams mesh.addEventListener('remoteStream', (data) => { const videoElement = document.getElementById('remoteVideo'); videoElement.srcObject = data.stream; }); // Toggle media mesh.toggleVideo(); mesh.toggleAudio(); // Stop media await mesh.stopMedia(); ``` ### Distributed Storage ```javascript // Store data await mesh.dhtPut('user:profile', { name: 'Alice', age: 30, interests: ['music', 'technology'] }); // Retrieve data const profile = await mesh.dhtGet('user:profile'); console.log('Profile:', profile); // Subscribe to changes await mesh.dhtSubscribe('shared:document'); mesh.addEventListener('dhtValueChanged', (data) => { if (data.key === 'shared:document') { console.log('Document updated:', data.newValue); } }); // Update data await mesh.dhtUpdate('shared:document', newContent); ``` ### Encryption ```javascript const mesh = new PeerPigeonMesh({ enableCrypto: true }); await mesh.init(); // Send encrypted message const messageId = await mesh.sendEncryptedBroadcast({ type: 'secret', data: 'This is encrypted!' }); // Handle encrypted messages mesh.addEventListener('messageReceived', async (data) => { if (data.encrypted) { const decrypted = await mesh.decryptMessage(data.content); console.log('Decrypted:', decrypted); } }); ``` ### Debug Logging ```javascript import { DebugLogger } from 'peerpigeon'; // Enable debugging for specific modules DebugLogger.enable('PeerPigeonMesh'); DebugLogger.enable('ConnectionManager'); // Or enable all debugging DebugLogger.enableAll(); // Create custom logger const debug = DebugLogger.create('MyApp'); debug.log('Application started'); ``` --- This completes the comprehensive API documentation for PeerPigeon. All exposed methods, events, and their parameters are documented with usage examples.