UNPKG

@eventmsg/core

Version:

EventMsgV3 TypeScript library - Core protocol implementation with transport abstraction

259 lines (203 loc) 6.75 kB
# @eventmsg/core [![npm](https://img.shields.io/npm/v/@eventmsg/core)](https://www.npmjs.com/package/@eventmsg/core) [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=flat&logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![License](https://img.shields.io/npm/l/@eventmsg/core)](LICENSE) Type-safe, transport-agnostic messaging library with EventMsgV3 binary protocol for reliable device communication. ## Installation ```bash npm install @eventmsg/core ``` ### Browser CDN Usage Use directly in browser via CDN without npm: ```html <script type="importmap"> { "imports": { "@eventmsg/core": "https://cdn.jsdelivr.net/npm/@eventmsg/core@latest" } } </script> <script type="module"> import { EventMsg } from '@eventmsg/core'; // Use same API as npm version </script> ``` ## Usage ### Quick Start ```typescript import { EventMsg } from '@eventmsg/core'; import { WebBLETransport, createNordicUARTConfig } from '@eventmsg/transport-webble'; // Create transport and EventMsg instance const transport = new WebBLETransport(createNordicUARTConfig(0, 0)); const eventMsg = new EventMsg({ transport }); // Connect and send messages await eventMsg.connect(); await eventMsg.send('hello', 'Hello device!', { receiverId: 1 }); // Listen for messages with type safety eventMsg.onMessage('sensor_data', (data, metadata) => { console.log(`Data from device ${metadata.senderId}:`, data); }); ``` ### Core API #### Connection Management ```typescript await eventMsg.connect() // Connect to transport await eventMsg.disconnect() // Disconnect gracefully eventMsg.isConnected() // Check connection status eventMsg.getLocalAddress() // Get device address eventMsg.getStats() // Get connection statistics ``` #### Sending Messages ```typescript // Send to specific device await eventMsg.send('command', { action: 'led_on' }, { receiverId: 5 }); // Broadcast to all devices await eventMsg.send('announcement', 'System update', { receiverId: 255, // Broadcast receiverGroupId: 255 // All groups }); // Send with custom flags await eventMsg.send('urgent', { alert: 'emergency' }, { receiverId: 1, flags: 0x80 // Priority flag }); ``` #### Receiving Messages ```typescript // Listen for all messages eventMsg.onMessage((eventName, data, metadata) => { console.log(`Received ${eventName} from device ${metadata.senderId}`); }); // Listen for specific events with type safety eventMsg.onMessage<SensorData>('sensor_data', (data, metadata) => { console.log(`Temperature: ${data.temperature}°C`); }); // Remove listeners eventMsg.offMessage('sensor_data'); // Remove specific eventMsg.offMessage(); // Remove all ``` #### Request/Response Pattern ```typescript // Send request and wait for response const response = await eventMsg.waitFor('status_response', { timeout: 5000, filter: (meta) => meta.senderId === 1 }); // Ping/pong example const startTime = Date.now(); await eventMsg.send('ping', { timestamp: startTime }, { receiverId: 1 }); const pong = await eventMsg.waitFor('pong'); console.log(`RTT: ${Date.now() - startTime}ms`); ``` ### TypeScript Support ```typescript // Define your message types interface SensorReading { temperature: number; humidity: number; timestamp: number; } interface DeviceCommand { action: 'led' | 'relay' | 'motor'; state: 'on' | 'off'; intensity?: number; } // Type-safe messaging await eventMsg.send<DeviceCommand>('control', { action: 'led', state: 'on', intensity: 75 }, { receiverId: 1 }); // Type-safe receiving eventMsg.onMessage<SensorReading>('sensor_data', (data, metadata) => { // TypeScript knows the exact structure console.log(`${data.temperature}°C, ${data.humidity}%`); }); ``` ### Configuration ```typescript interface EventMsgConfig { transport: Transport; // Transport implementation (required) maxMessageSize?: number; // Default: 4096 bytes messageTimeout?: number; // Default: 5000ms debug?: boolean; // Default: false protocol?: ProtocolOptions; // Protocol configuration } // Example with custom configuration const eventMsg = new EventMsg({ transport, maxMessageSize: 2048, messageTimeout: 10000, debug: true }); ``` ### Event Handling ```typescript // Lifecycle events eventMsg.on('connect', () => console.log('Connected')); eventMsg.on('disconnect', () => console.log('Disconnected')); eventMsg.on('error', (error) => console.error('Error:', error)); // Debug events (when debug: true) eventMsg.on('send', (info) => console.log('Message sent:', info.event)); ``` ## Troubleshooting ### Common Issues **"Not connected to transport"** - Call `await eventMsg.connect()` before sending messages - Check if transport is properly configured **"Invalid address" errors** - Addresses must be 0-255 - receiverId is required in send options - Use 255 for broadcast addressing **"Message too large" errors** - Default limit is 4096 bytes total - Event names max 64 bytes - Event data max 3048 bytes - Increase maxMessageSize in config if needed **"Timeout" errors** - Increase timeout in waitFor options - Check if target device is responding - Verify device addressing is correct ### Error Types ```typescript import { EventMsgError, // Base error ValidationError, // Input validation ConnectionError, // Connection issues SendError, // Message sending WaitForTimeoutError, // Response timeout AddressValidationError // Invalid addressing } from '@eventmsg/core'; try { await eventMsg.send('test', {}, { receiverId: 999 }); } catch (error) { if (error instanceof AddressValidationError) { console.error(`Invalid address: ${error.value}`); } } ``` ### Debug Tips ```typescript // Enable debug logging const eventMsg = new EventMsg({ transport, debug: true }); // Monitor all events eventMsg.on('connect', () => console.log('Connected')); eventMsg.on('disconnect', () => console.log('Disconnected')); eventMsg.on('error', (error) => console.error('Error:', error)); // Log all messages eventMsg.onMessage((eventName, data, metadata) => { console.log(`📨 ${eventName}:`, data, 'from', metadata.senderId); }); // Check connection stats console.log(eventMsg.getStats()); ``` ### Protocol Information EventMsgV3 uses a binary protocol with: - 7-byte header with device/group addressing - JSON serialization for event data - Byte stuffing for reliable framing - Message size limits for transport compatibility --- **[Transport Packages](../transport-webble/) • [Documentation](https://github.com/your-org/eventmsgv3-ts#readme) • [Examples](../../examples/)**