Files
rondevu-client/EVENTBUS_EXAMPLE.md
Bas van den Aakster 5e673ac993 Add type-safe EventBus with generic event mapping
Implemented EventBus class with full TypeScript type inference:
- Generic type parameter TEvents for event name to payload mapping
- Type-safe on/once/off/emit methods with inferred data types
- Utility methods: clear, listenerCount, eventNames
- Complete JSDoc documentation with usage examples

Added core connection types:
- ConnectionIdentity, ConnectionState, ConnectionInterface
- QueueMessageOptions for message queuing
- Connection composite type

All types and classes exported from main index.

Example usage:
```typescript
interface MyEvents {
  'user:connected': { userId: string; timestamp: number };
  'message:received': string;
}

const bus = new EventBus<MyEvents>();

// TypeScript knows data is { userId: string; timestamp: number }
bus.on('user:connected', (data) => {
  console.log(data.userId, data.timestamp);
});
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-07 16:17:52 +01:00

3.1 KiB

EventBus Usage Examples

Type-Safe Event Bus

The EventBus class provides fully type-safe event handling with TypeScript type inference.

Basic Usage

import { EventBus } from '@xtr-dev/rondevu-client';

// Define your event mapping
interface AppEvents {
  'user:connected': { userId: string; timestamp: number };
  'user:disconnected': { userId: string };
  'message:received': string;
  'connection:error': Error;
}

// Create the event bus
const events = new EventBus<AppEvents>();

// Subscribe to events - TypeScript knows the exact data type!
events.on('user:connected', (data) => {
  // data is { userId: string; timestamp: number }
  console.log(`User ${data.userId} connected at ${data.timestamp}`);
});

events.on('message:received', (data) => {
  // data is string
  console.log(data.toUpperCase());
});

// Emit events - TypeScript validates the data type
events.emit('user:connected', {
  userId: '123',
  timestamp: Date.now()
});

events.emit('message:received', 'Hello World');

// Type errors caught at compile time:
// events.emit('user:connected', 'wrong type'); // ❌ Error!
// events.emit('message:received', { wrong: 'type' }); // ❌ Error!

One-Time Listeners

// Subscribe once - handler auto-unsubscribes after first call
events.once('connection:error', (error) => {
  console.error('Connection failed:', error.message);
});

Unsubscribing

const handler = (data: string) => {
  console.log('Message:', data);
};

events.on('message:received', handler);

// Later, unsubscribe
events.off('message:received', handler);

Utility Methods

// Clear all handlers for a specific event
events.clear('message:received');

// Clear all handlers for all events
events.clear();

// Get listener count
const count = events.listenerCount('user:connected');

// Get all event names with handlers
const eventNames = events.eventNames();

Connection Events Example

interface ConnectionEvents {
  'connection:state': { state: 'connected' | 'disconnected' | 'connecting' };
  'connection:message': { from: string; data: string | ArrayBuffer };
  'connection:error': { code: string; message: string };
}

class ConnectionManager {
  private events = new EventBus<ConnectionEvents>();

  on<K extends keyof ConnectionEvents>(
    event: K,
    handler: (data: ConnectionEvents[K]) => void
  ) {
    this.events.on(event, handler);
  }

  private handleStateChange(state: 'connected' | 'disconnected' | 'connecting') {
    this.events.emit('connection:state', { state });
  }

  private handleMessage(from: string, data: string | ArrayBuffer) {
    this.events.emit('connection:message', { from, data });
  }
}

Benefits

  • Full type safety - TypeScript validates event names and data types
  • IntelliSense support - Auto-completion for event names and data properties
  • Compile-time errors - Catch type mismatches before runtime
  • Self-documenting - Event interface serves as documentation
  • Refactoring-friendly - Rename events or change types with confidence