npm package: @ribcage/expo
Description: React Native SDK for Ribcage with WebSocket and other client functionality
Author: Ribcage Team
Latest version: 1.0.0

# @ribcage/react-native-sdk

A comprehensive React Native SDK for Ribcage with WebSocket communication, automatic registration, health monitoring, and more.

## Features

- 🚀 **Simple SDK Pattern**: Initialize with `RibcageSDK.start()` 
- 🔌 **Automatic Registration**: Handles WebSocket handshake and client registration
- 💓 **Health Monitoring**: Built-in ping/pong mechanism with connection health tracking
- 🔄 **Auto-Reconnection**: Exponential backoff reconnection with message queuing
- 📱 **React Native Ready**: Designed specifically for React Native environments
- 🎯 **Type-Safe**: Full TypeScript support with exact Rust message type matching
- ⚛️ **React Hooks**: Easy-to-use hooks for React components
- 🏗️ **Modular Architecture**: Organized client structure for future expansion

## Installation

```bash
bun add @ribcage/react-native-sdk
```

## Quick Start

### SDK Initialization

```typescript
import { RibcageSDK, ClientType } from '@ribcage/react-native-sdk';

// Initialize the SDK
const sdk = await RibcageSDK.start({
  websocket: {
    enabled: true,
    clientType: ClientType.MOBILE,
    config: {
      host: '10.0.2.2', // Android emulator localhost
      port: 9001,
    },
    events: {
      onConnected: () => console.log('Connected!'),
      onMessage: (message) => console.log('Received:', message),
      onError: (error) => console.error('Error:', error),
    },
  },
});

// Send events to dashboard
await sdk.sendEvent('user_action', {
  type: 'button_click',
  data: { buttonId: 'submit' }
});

// Cleanup when done
await sdk.shutdown();
```

### React Component Example

```typescript
import React, { useEffect, useState } from 'react';
import { RibcageSDK, ClientType, type WebSocketMessage } from '@ribcage/react-native-sdk';

function MyComponent() {
  const [sdk, setSdk] = useState<RibcageSDK | null>(null);
  const [isConnected, setIsConnected] = useState(false);

  useEffect(() => {
    const initSDK = async () => {
      const sdkInstance = await RibcageSDK.start({
        websocket: {
          clientType: ClientType.MOBILE,
          config: { host: '10.0.2.2', port: 9001 },
          events: {
            onConnected: () => setIsConnected(true),
            onDisconnected: () => setIsConnected(false),
            onMessage: (message) => console.log('Message:', message),
          },
        },
      });
      setSdk(sdkInstance);
    };

    initSDK().catch(console.error);

    return () => {
      if (sdk) {
        sdk.shutdown();
      }
    };
  }, []);

  const handleSendMessage = async () => {
    if (sdk && isConnected) {
      await sdk.sendEvent('test_event', {
        message: 'Hello from React Native!',
        timestamp: Date.now(),
      });
    }
  };

  return (
    <View>
      <Text>Status: {isConnected ? 'Connected' : 'Disconnected'}</Text>
      <Button title="Send Message" onPress={handleSendMessage} />
    </View>
  );
}
```

### Using React Hooks (Alternative)

```typescript
import { useWebSocket, ClientType } from '@ribcage/react-native-sdk';

function MyComponent() {
  const {
    isConnected,
    connectionState,
    messages,
    sendEvent,
  } = useWebSocket({
    config: { host: '10.0.2.2', port: 9001 },
    clientType: ClientType.MOBILE,
    events: {
      onConnected: () => console.log('WebSocket connected'),
      onMessage: (message) => console.log('New message:', message),
    },
  });

  return (
    <View>
      <Text>Status: {isConnected ? 'Connected' : 'Disconnected'}</Text>
      <Text>Client ID: {connectionState.clientId}</Text>
      <Text>Messages: {messages.length}</Text>
    </View>
  );
}
```

## API Reference

### RibcageSDK

The main SDK class providing initialization and client management.

#### Static Methods

- `RibcageSDK.start(config): Promise<RibcageSDK>` - Initialize and start the SDK
- `RibcageSDK.init(config): Promise<RibcageSDK>` - Alias for start()
- `RibcageSDK.getInstance(config): RibcageSDK` - Get singleton instance

#### Instance Methods

- `initialize(): Promise<void>` - Initialize all enabled clients
- `shutdown(): Promise<void>` - Cleanup and shutdown all clients
- `isInitialized(): boolean` - Check if SDK is ready
- `getWebSocketClient(): WebSocketClient | null` - Get WebSocket client instance
- `connectWebSocket(): Promise<void>` - Connect WebSocket if not connected
- `disconnectWebSocket(): void` - Disconnect WebSocket
- `sendEvent(eventType, data): Promise<void>` - Send event to dashboard
- `sendToClient(clientId, payload): Promise<void>` - Send to specific client
- `broadcast(payload): Promise<void>` - Broadcast to all clients

### Configuration

```typescript
interface RibcageSDKConfig {
  websocket?: {
    enabled?: boolean;                    // Default: true
    config?: Partial<WebSocketConfig>;    // Connection config
    events?: WebSocketEvents;             // Event callbacks
    clientType?: ClientType;              // MOBILE or DASHBOARD
    metadata?: Record<string, unknown>;   // Additional client data
  };
  // Future clients can be added here
}

interface WebSocketConfig {
  host: string;                    // Server host
  port: number;                    // Server port
  reconnectInterval?: number;      // Reconnection delay (default: 5000ms)
  pingInterval?: number;           // Ping interval (default: 30000ms)
  pongTimeout?: number;            // Pong timeout (default: 5000ms)
}
```

### Message Types

All message types exactly match the Rust WebSocket server implementation:

```typescript
// Auto-registration on connection
interface RegisterMessage {
  type: "register";
  data: {
    client_type: ClientType;
    client_id: string;
    metadata?: Record<string, unknown>;
  };
}

// Event messages (mobile → dashboard)
interface DirectMessage {
  type: "message"; 
  data: {
    from: string;
    payload: unknown;
    message_id: string;
    timestamp: number;
  };
}

// Health checks
interface PingMessage {
  type: "ping";
  data: { timestamp: number };
}
```

## Architecture

### SDK Structure

```
@ribcage/react-native-sdk/
├── src/
│   ├── sdk.ts                  # Main RibcageSDK class
│   ├── clients/
│   │   └── websocket/         # WebSocket client module
│   │       ├── client.ts      # WebSocket client
│   │       ├── connection.ts  # Connection management
│   │       ├── health.ts      # Health monitoring
│   │       ├── messages.ts    # Message handling
│   │       ├── types.ts       # TypeScript types
│   │       └── hooks/         # React hooks
│   └── index.ts               # Package exports
```

### Communication Flow

1. **SDK Initialization**: `RibcageSDK.start()` initializes all clients
2. **Auto-Registration**: WebSocket client registers with server automatically
3. **Health Monitoring**: Continuous ping/pong health checks
4. **Message Routing**: 
   - Mobile → Dashboard: All events forwarded to dashboards
   - Dashboard → Mobile: Targeted messages by client ID
5. **Error Handling**: Automatic reconnection and message queuing

### Future Expansion

The SDK is designed to support additional clients:

```typescript
// Future clients can be easily added
const sdk = await RibcageSDK.start({
  websocket: { enabled: true },
  analytics: { enabled: true },  // Future
  push: { enabled: true },       // Future
  auth: { enabled: true },       // Future
});
```

## React Native Setup

For Android emulator, use `10.0.2.2` as the host to connect to localhost.
For physical devices, use your computer's IP address.

```typescript
const config = {
  host: __DEV__ ? '10.0.2.2' : 'your-production-host.com',
  port: 9001,
};
```

## License

MIT