mirror of
https://github.com/xtr-dev/rondevu-client.git
synced 2025-12-10 02:43:25 +00:00
Major refactor replacing low-level APIs with high-level durable connections.
New Features:
- Automatic reconnection with exponential backoff (1s → 2s → 4s → ... max 30s)
- Message queuing during disconnections
- Durable channels that survive connection drops
- TTL auto-refresh for services (refreshes at 80% of TTL by default)
- Full configuration of timeouts, retry limits, and queue sizes
New API:
- client.exposeService() - Create durable service with automatic TTL refresh
- client.connect() - Create durable connection with automatic reconnection
- client.connectByUuid() - Connect by service UUID
- DurableChannel - Event-based channel wrapper with message queuing
- DurableConnection - Connection manager with reconnection logic
- DurableService - Service manager with TTL auto-refresh
Files Added:
- src/durable/types.ts - Type definitions and enums
- src/durable/reconnection.ts - Exponential backoff utilities
- src/durable/channel.ts - DurableChannel class (358 lines)
- src/durable/connection.ts - DurableConnection class (441 lines)
- src/durable/service.ts - DurableService class (329 lines)
- MIGRATION.md - Comprehensive migration guide
Files Removed:
- src/services.ts - Replaced by DurableService
- src/discovery.ts - Replaced by DurableConnection
BREAKING CHANGES:
- Removed: client.services.*, client.discovery.*, client.createPeer()
- Added: client.exposeService(), client.connect(), client.connectByUuid()
- Handler signature: (channel, peer, connectionId?) → (channel, connectionId)
- Event handlers: .onmessage → .on('message')
- Services: Must call service.start() to begin accepting connections
- Connections: Must call connection.connect() to establish connection
185 lines
4.8 KiB
TypeScript
185 lines
4.8 KiB
TypeScript
/**
|
|
* Type definitions for durable WebRTC connections
|
|
*
|
|
* This module defines all interfaces, enums, and types used by the durable
|
|
* connection system for automatic reconnection and message queuing.
|
|
*/
|
|
|
|
/**
|
|
* Connection state enum
|
|
*/
|
|
export enum DurableConnectionState {
|
|
CONNECTING = 'connecting',
|
|
CONNECTED = 'connected',
|
|
RECONNECTING = 'reconnecting',
|
|
DISCONNECTED = 'disconnected',
|
|
FAILED = 'failed',
|
|
CLOSED = 'closed'
|
|
}
|
|
|
|
/**
|
|
* Channel state enum
|
|
*/
|
|
export enum DurableChannelState {
|
|
CONNECTING = 'connecting',
|
|
OPEN = 'open',
|
|
CLOSING = 'closing',
|
|
CLOSED = 'closed'
|
|
}
|
|
|
|
/**
|
|
* Configuration for durable connections
|
|
*/
|
|
export interface DurableConnectionConfig {
|
|
/** Maximum number of reconnection attempts (default: 10) */
|
|
maxReconnectAttempts?: number;
|
|
|
|
/** Base delay for exponential backoff in milliseconds (default: 1000) */
|
|
reconnectBackoffBase?: number;
|
|
|
|
/** Maximum delay between reconnection attempts in milliseconds (default: 30000) */
|
|
reconnectBackoffMax?: number;
|
|
|
|
/** Jitter factor for randomizing reconnection delays (default: 0.2 = ±20%) */
|
|
reconnectJitter?: number;
|
|
|
|
/** Timeout for initial connection attempt in milliseconds (default: 30000) */
|
|
connectionTimeout?: number;
|
|
|
|
/** Maximum number of messages to queue during disconnection (default: 1000) */
|
|
maxQueueSize?: number;
|
|
|
|
/** Maximum age of queued messages in milliseconds (default: 60000) */
|
|
maxMessageAge?: number;
|
|
|
|
/** WebRTC configuration */
|
|
rtcConfig?: RTCConfiguration;
|
|
}
|
|
|
|
/**
|
|
* Configuration for durable channels
|
|
*/
|
|
export interface DurableChannelConfig {
|
|
/** Maximum number of messages to queue (default: 1000) */
|
|
maxQueueSize?: number;
|
|
|
|
/** Maximum age of queued messages in milliseconds (default: 60000) */
|
|
maxMessageAge?: number;
|
|
|
|
/** Whether messages should be delivered in order (default: true) */
|
|
ordered?: boolean;
|
|
|
|
/** Maximum retransmits for unordered channels (default: undefined) */
|
|
maxRetransmits?: number;
|
|
}
|
|
|
|
/**
|
|
* Configuration for durable services
|
|
*/
|
|
export interface DurableServiceConfig extends DurableConnectionConfig {
|
|
/** Username that owns the service */
|
|
username: string;
|
|
|
|
/** Private key for signing service operations */
|
|
privateKey: string;
|
|
|
|
/** Fully qualified service name (e.g., com.example.chat@1.0.0) */
|
|
serviceFqn: string;
|
|
|
|
/** Whether the service is publicly discoverable (default: false) */
|
|
isPublic?: boolean;
|
|
|
|
/** Optional metadata for the service */
|
|
metadata?: Record<string, any>;
|
|
|
|
/** Time-to-live for service in milliseconds (default: server default) */
|
|
ttl?: number;
|
|
|
|
/** Margin before TTL expiry to trigger refresh (default: 0.2 = refresh at 80%) */
|
|
ttlRefreshMargin?: number;
|
|
|
|
/** Number of simultaneous open offers to maintain (default: 1) */
|
|
poolSize?: number;
|
|
|
|
/** Polling interval for checking answers in milliseconds (default: 2000) */
|
|
pollingInterval?: number;
|
|
}
|
|
|
|
/**
|
|
* Queued message structure
|
|
*/
|
|
export interface QueuedMessage {
|
|
/** Message data */
|
|
data: string | Blob | ArrayBuffer | ArrayBufferView;
|
|
|
|
/** Timestamp when message was enqueued */
|
|
enqueuedAt: number;
|
|
|
|
/** Unique message ID */
|
|
id: string;
|
|
}
|
|
|
|
/**
|
|
* Event type map for DurableConnection
|
|
*/
|
|
export interface DurableConnectionEvents extends Record<string, (...args: any[]) => void> {
|
|
'state': (state: DurableConnectionState, previousState: DurableConnectionState) => void;
|
|
'connected': () => void;
|
|
'reconnecting': (attempt: number, maxAttempts: number, nextRetryIn: number) => void;
|
|
'disconnected': () => void;
|
|
'failed': (error: Error, permanent: boolean) => void;
|
|
'closed': () => void;
|
|
}
|
|
|
|
/**
|
|
* Event type map for DurableChannel
|
|
*/
|
|
export interface DurableChannelEvents extends Record<string, (...args: any[]) => void> {
|
|
'open': () => void;
|
|
'message': (data: any) => void;
|
|
'error': (error: Error) => void;
|
|
'close': () => void;
|
|
'bufferedAmountLow': () => void;
|
|
'queueOverflow': (droppedCount: number) => void;
|
|
}
|
|
|
|
/**
|
|
* Event type map for DurableService
|
|
*/
|
|
export interface DurableServiceEvents extends Record<string, (...args: any[]) => void> {
|
|
'published': (serviceId: string, uuid: string) => void;
|
|
'connection': (connectionId: string) => void;
|
|
'disconnection': (connectionId: string) => void;
|
|
'ttl-refreshed': (expiresAt: number) => void;
|
|
'error': (error: Error, context: string) => void;
|
|
'closed': () => void;
|
|
}
|
|
|
|
/**
|
|
* Information about a durable connection
|
|
*/
|
|
export interface ConnectionInfo {
|
|
/** Username (for username-based connections) */
|
|
username?: string;
|
|
|
|
/** Service FQN (for service-based connections) */
|
|
serviceFqn?: string;
|
|
|
|
/** UUID (for UUID-based connections) */
|
|
uuid?: string;
|
|
}
|
|
|
|
/**
|
|
* Service information returned when service is published
|
|
*/
|
|
export interface ServiceInfo {
|
|
/** Service ID */
|
|
serviceId: string;
|
|
|
|
/** Service UUID for discovery */
|
|
uuid: string;
|
|
|
|
/** Expiration timestamp */
|
|
expiresAt: number;
|
|
}
|