@eventmsg/core
Version:
EventMsgV3 TypeScript library - Core protocol implementation with transport abstraction
259 lines (203 loc) • 6.75 kB
Markdown
[](https://www.npmjs.com/package/@eventmsg/core)
[](https://www.typescriptlang.org/)
[](LICENSE)
Type-safe, transport-agnostic messaging library with EventMsgV3 binary protocol for reliable device communication.
```bash
npm install @eventmsg/core
```
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>
```
```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);
});
```
```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
```
```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
});
```
```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
```
```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
// 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}%`);
});
```
```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
});
```
```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));
```
**"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
```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}`);
}
}
```
```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());
```
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/)**