npm package: @flightdev/realtime
Description: Agnostic real-time communication for Flight Framework. Choose your transport: WebSocket, SSE, Pusher, or custom.
Latest version: 0.0.3

# @flightdev/realtime

Real-time communication for Flight Framework. Unified API for WebSocket and Server-Sent Events (SSE).

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Adapters](#adapters)
- [Channels](#channels)
- [Presence](#presence)
- [React Integration](#react-integration)
- [Vue Integration](#vue-integration)
- [Server-Side Events](#server-side-events)
- [API Reference](#api-reference)
- [License](#license)

---

## Features

- Multiple transport adapters (WebSocket, SSE)
- Pub/sub channels with room support
- Presence tracking (who's online)
- Automatic reconnection with backoff
- Message history and replay
- Binary data support
- React and Vue hooks
- Edge-compatible SSE adapter

---

## Installation

```bash
npm install @flightdev/realtime
```

---

## Quick Start

### Client

```typescript
import { createRealtime } from '@flightdev/realtime';
import { websocket } from '@flightdev/realtime/websocket';

const realtime = createRealtime(websocket({
    url: 'wss://api.example.com/ws',
}));

// Connect
await realtime.connect();

// Subscribe to a channel
const chat = realtime.channel('chat:general');

chat.on('message', (data) => {
    console.log('Received:', data);
});

// Send a message
chat.send('message', { text: 'Hello everyone!' });
```

### Server

```typescript
import { createServer } from '@flightdev/realtime/server';

const server = createServer({ port: 3001 });

server.on('connection', (socket) => {
    console.log('Client connected:', socket.id);
    
    socket.on('message', (data) => {
        // Broadcast to all clients in the channel
        server.to('chat:general').emit('message', data);
    });
});
```

---

## Adapters

### WebSocket (Full Duplex)

Bidirectional communication for real-time apps.

```typescript
import { websocket } from '@flightdev/realtime/websocket';

const adapter = websocket({
    url: 'wss://api.example.com/ws',
    protocols: ['v1'],
    reconnect: true,
    reconnectDelay: 1000,
    maxReconnectDelay: 30000,
    pingInterval: 25000,
});
```

### SSE (Server-Sent Events)

One-way server-to-client, edge-compatible.

```typescript
import { sse } from '@flightdev/realtime/sse';

const adapter = sse({
    url: '/api/events',
    withCredentials: true,
    retryDelay: 3000,
});
```

---

## Channels

### Subscribe to Channel

```typescript
const channel = realtime.channel('notifications:user_123');

channel.on('new', (notification) => {
    showNotification(notification);
});

channel.on('read', (id) => {
    markAsRead(id);
});
```

### Send to Channel

```typescript
channel.send('typing', { userId: 'user_123' });
```

### Leave Channel

```typescript
channel.leave();
```

### Channel Events

```typescript
channel.on('join', () => console.log('Joined channel'));
channel.on('leave', () => console.log('Left channel'));
channel.on('error', (err) => console.error('Channel error:', err));
```

---

## Presence

Track who's online in a channel:

```typescript
const channel = realtime.channel('room:lobby');

// Track current user
channel.presence.enter({
    userId: 'user_123',
    name: 'John',
    status: 'online',
});

// Get current members
const members = channel.presence.get();
console.log('Online:', members);

// Listen for changes
channel.presence.on('join', (member) => {
    console.log(`${member.name} joined`);
});

channel.presence.on('leave', (member) => {
    console.log(`${member.name} left`);
});

channel.presence.on('update', (member) => {
    console.log(`${member.name} updated status`);
});

// Update presence
channel.presence.update({ status: 'away' });

// Leave
channel.presence.leave();
```

---

## React Integration

### RealtimeProvider

```tsx
import { RealtimeProvider } from '@flightdev/realtime/react';

function App() {
    return (
        <RealtimeProvider client={realtime}>
            <ChatRoom />
        </RealtimeProvider>
    );
}
```

### useRealtime Hook

```tsx
import { useRealtime } from '@flightdev/realtime/react';

function ConnectionStatus() {
    const { state, connect, disconnect } = useRealtime();
    
    return (
        <div>
            Status: {state}
            {state === 'disconnected' && (
                <button onClick={connect}>Reconnect</button>
            )}
        </div>
    );
}
```

### useChannel Hook

```tsx
import { useChannel } from '@flightdev/realtime/react';

function ChatRoom({ roomId }) {
    const [messages, setMessages] = useState([]);
    
    const { send } = useChannel(`chat:${roomId}`, {
        onMessage: (data) => {
            setMessages(prev => [...prev, data]);
        },
    });
    
    const handleSend = (text) => {
        send('message', { text, timestamp: Date.now() });
    };
    
    return (
        <div>
            {messages.map(msg => (
                <div key={msg.timestamp}>{msg.text}</div>
            ))}
            <MessageInput onSend={handleSend} />
        </div>
    );
}
```

### usePresence Hook

```tsx
import { usePresence } from '@flightdev/realtime/react';

function OnlineUsers({ roomId }) {
    const { members, enter, leave } = usePresence(`room:${roomId}`);
    
    useEffect(() => {
        enter({ name: currentUser.name });
        return () => leave();
    }, []);
    
    return (
        <ul>
            {members.map(member => (
                <li key={member.id}>{member.name}</li>
            ))}
        </ul>
    );
}
```

---

## Vue Integration

### Composables

```vue
<script setup>
import { useRealtime, useChannel, usePresence } from '@flightdev/realtime/vue';

const { state } = useRealtime();
const { messages, send } = useChannel('chat:general');
const { members, enter } = usePresence('room:lobby');

onMounted(() => {
    enter({ name: user.name });
});

const sendMessage = (text) => {
    send('message', { text });
};
</script>

<template>
    <div>
        <span>Status: {{ state }}</span>
        <div v-for="msg in messages" :key="msg.id">
            {{ msg.text }}
        </div>
        <input @keyup.enter="sendMessage($event.target.value)" />
    </div>
</template>
```

---

## Server-Side Events

### SSE Handler

```typescript
// src/routes/api/events.get.ts
import { createSSEResponse } from '@flightdev/realtime/sse';

export async function GET(request: Request) {
    const userId = getUserId(request);
    
    return createSSEResponse(request, (send, close) => {
        // Subscribe to events
        const unsubscribe = eventBus.subscribe(userId, (event) => {
            send(event.type, event.data);
        });
        
        // Cleanup on disconnect
        return () => {
            unsubscribe();
        };
    });
}
```

### SSE Client

```typescript
const events = new EventSource('/api/events');

events.addEventListener('notification', (e) => {
    const data = JSON.parse(e.data);
    showNotification(data);
});

events.addEventListener('message', (e) => {
    const data = JSON.parse(e.data);
    addMessage(data);
});
```

---

## API Reference

### createRealtime Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `reconnect` | `boolean` | `true` | Auto-reconnect |
| `reconnectDelay` | `number` | `1000` | Initial delay (ms) |
| `maxReconnectDelay` | `number` | `30000` | Max delay (ms) |
| `timeout` | `number` | `20000` | Connection timeout |

### Realtime Methods

| Method | Description |
|--------|-------------|
| `connect()` | Connect to server |
| `disconnect()` | Disconnect |
| `channel(name)` | Get or create channel |
| `on(event, handler)` | Listen to events |
| `off(event, handler)` | Remove listener |

### Channel Methods

| Method | Description |
|--------|-------------|
| `send(event, data)` | Send message |
| `on(event, handler)` | Listen to event |
| `off(event, handler)` | Remove listener |
| `leave()` | Leave channel |
| `presence` | Presence API |

### Connection States

| State | Description |
|-------|-------------|
| `connecting` | Establishing connection |
| `connected` | Connected and ready |
| `disconnected` | Not connected |
| `reconnecting` | Attempting reconnect |

---

## License

MIT