npm package: @leve.ai/socket-client
Description: React client library for Leve.ai WebSocket API with x-api-key authentication, namespaces, JWT tokens, and private rooms
Latest version: 1.1.9

## 🏗️ Estrutura da Biblioteca

```
lib-react/
├── src/
│   ├── hooks/                    # React Hooks principais
│   │   ├── useSocketConnection.ts       # Conexão com API_KEY + Namespaces
│   │   ├── useChannelSubscription.ts    # Subscription automática de canais
│   │   ├── useMultiChannelSubscription.ts # Subscription em múltiplos canais
│   │   ├── useJWTAuth.ts               # Autenticação JWT com metadata
│   │   └── usePrivateRooms.ts          # Gerenciamento de salas privadas
│   ├── components/
│   │   └── SocketProvider.tsx       # Context Provider para socket
│   ├── types/
│   │   └── index.ts                 # TypeScript types completos
│   └── index.ts                     # Exports principais
├── dist/                        # Build output (gerado automaticamente)
├── package.json                 # Configuração NPM
├── vite.config.ts              # Configuração de build
└── tsconfig.json               # TypeScript config
```

## 🚀 Como Usar - Build Local

### 1. Build da Biblioteca

```bash
cd /Users/5ucr4m/Projects/leve.ai/socket/lib-react

# Instalar dependências
npm install

# Build completo (ESM + CJS + Types)
npm run build

# Criar package local para teste
npm pack
```

### 2. Usar em Outros Projetos (demo/app1)

```bash
cd /Users/5ucr4m/Projects/leve.ai/socket/demo/app1

# Instalar a biblioteca local
npm install ../../lib-react/leve.ai-socket-client-1.1.0.tgz

# Executar o app
npm run dev
```

## 📝 Exemplos de Uso

### Básico - Conexão e Autenticação

```tsx
import { useSocketConnection, useJWTAuth } from '@leve.ai/socket-client'

function App() {
  const [apiKey, setApiKey] = useState('lv_development_sk_...')
  const [namespace, setNamespace] = useState('default')

  // Socket connection com nossa biblioteca
  const { socket, isConnected, authenticated, publish, authenticate } = useSocketConnection({
    server: 'http://localhost:3001',
    apiKey: apiKey,
    namespace: namespace
  })

  // JWT Authentication
  const { generateToken } = useJWTAuth({
    server: 'http://localhost:3001',
    apiKey: apiKey
  })

  const handleGenerateJWT = async () => {
    const token = await generateToken({
      userId: 'user123',
      userType: 'customer',
      metadata: { name: 'João', region: 'SP' }
    })
    console.log('Token gerado:', token)
  }

  const handleAuth = async () => {
    await authenticate({
      userId: 'user123',
      userType: 'customer',
      token: jwtToken
    })
  }

  const handleSendMessage = () => {
    publish('chat:demo', { message: 'Hello World!' })
  }

  return (
    <div>
      <button onClick={handleGenerateJWT}>Gerar JWT</button>
      <button onClick={handleAuth}>Autenticar</button>
      <button onClick={handleSendMessage} disabled={!authenticated}>
        Enviar Mensagem
      </button>
      <p>Status: {isConnected ? 'Conectado' : 'Desconectado'}</p>
      <p>Auth: {authenticated ? 'Autenticado' : 'Não autenticado'}</p>
    </div>
  )
}
```

### Canal Único - useChannelSubscription

```tsx
import { useChannelSubscription } from '@leve.ai/socket-client'

function SingleChannelChat() {
  const { socket, authenticated } = useSocketConnection(/* ... */)

  const { messages, loading, lastMessage } = useChannelSubscription(
    'order:123:chat-support',
    {
      enabled: authenticated,
      onMessage: (message) => {
        console.log('Nova mensagem:', message)
        // Notificar usuário, tocar som, etc.
      }
    },
    socket
  )

  return (
    <div>
      <h3>Chat do Pedido #123</h3>
      <div>
        {messages.map((msg, i) => (
          <div key={i}>
            <strong>{msg.senderName}:</strong> {msg.content}
          </div>
        ))}
      </div>
    </div>
  )
}
```

### Múltiplos Canais - useMultiChannelSubscription 🆕

```tsx
import { useMultiChannelSubscription } from '@leve.ai/socket-client'

function MultiOrderChat() {
  const { socket, authenticated } = useSocketConnection(/* ... */)

  // ABORDAGEM 1: Lista fixa de pedidos
  const multiChannel = useMultiChannelSubscription(
    [
      'order:123:chat-support',
      'order:456:chat-support',
      'order:789:chat-support'
    ],
    {
      enabled: authenticated,
      onMessage: (message) => {
        console.log('Nova mensagem em qualquer pedido:', message)
      },
      onChannelMessage: (channel, message) => {
        console.log(`Pedido ${channel}:`, message)
        // Atualizar estado específico do pedido
        updatePedidoNotification(channel, message)
      }
    },
    socket
  )

  // Função para adicionar novos pedidos dinamicamente
  const addNewOrder = (orderId: string) => {
    const channel = `order:${orderId}:chat-support`
    multiChannel.subscribeToChannel(channel)
  }

  const removeOrder = (orderId: string) => {
    const channel = `order:${orderId}:chat-support`
    multiChannel.unsubscribeFromChannel(channel)
  }

  return (
    <div>
      <h2>Meus Pedidos ({multiChannel.subscribedChannels.length})</h2>

      {/* Timeline global de mensagens */}
      <div>
        <h3>Últimas Mensagens</h3>
        {multiChannel.allMessages.slice(-5).map((msg, i) => (
          <div key={i}>
            <span>{msg.channel}: {msg.senderName} - {msg.content}</span>
          </div>
        ))}
      </div>

      {/* Mensagens por pedido */}
      <div>
        {multiChannel.subscribedChannels.map(channel => {
          const messages = multiChannel.getChannelMessages(channel)
          return (
            <div key={channel}>
              <h4>{channel} ({messages.length} mensagens)</h4>
              {messages.slice(-3).map((msg, i) => (
                <div key={i}>{msg.senderName}: {msg.content}</div>
              ))}
            </div>
          )
        })}
      </div>

      {/* Controles dinâmicos */}
      <div>
        <button onClick={() => addNewOrder('999')}>
          ➕ Adicionar Pedido #999
        </button>
        <button onClick={() => removeOrder('123')}>
          ❌ Remover Pedido #123
        </button>
      </div>
    </div>
  )
}
```

### Comparação das Abordagens

```tsx
// OPÇÃO 1: Múltiplos hooks individuais
const pedido1 = useChannelSubscription('order:123:chat', { enabled: true }, socket)
const pedido2 = useChannelSubscription('order:456:chat', { enabled: true }, socket)
const pedido3 = useChannelSubscription('order:789:chat', { enabled: true }, socket)

// ✅ Pros: Simples, cada pedido é independente
// ❌ Contras: Muitos hooks, difícil gerenciar dinamicamente

// OPÇÃO 2: Hook multi-canal
const multiChannel = useMultiChannelSubscription([
  'order:123:chat', 'order:456:chat', 'order:789:chat'
], options, socket)

// ✅ Pros: Um hook, timeline global, controle dinâmico
// ✅ Ideal para: Apps com muitos canais, dashboards, notificações
```

## 🔧 Configurações de Build

### package.json (NPM-ready)
```json
{
  "name": "@leve.ai/socket-client",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts", 
  "module": "dist/index.esm.js",
  "exports": {
    ".": {
      "import": "./dist/index.esm.js",
      "require": "./dist/index.js",
      "types": "./dist/index.d.ts"
    }
  }
}
```

### vite.config.ts (Library build)
```typescript
export default defineConfig({
  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.ts'),
      name: 'LeveSocketClient',
      formats: ['es', 'cjs']
    },
    rollupOptions: {
      external: ['react', 'react-dom', 'socket.io-client']
    }
  }
})
```

## 📋 Scripts Disponíveis

```bash
npm run dev          # Watch mode para desenvolvimento
npm run build        # Build completo (Vite + TypeScript)
npm run typecheck    # Verificação de tipos
npm run lint         # ESLint
npm pack            # Criar .tgz para instalação local
```

## 🎯 Funcionalidades Implementadas

### useSocketConnection
- ✅ Conexão automática com API_KEY
- ✅ Namespaces configuráveis ('default' ou personalizado)
- ✅ Estados: isConnected, isConnecting, authenticated, error
- ✅ Métodos: subscribe, unsubscribe, publish, authenticate

### useJWTAuth  
- ✅ Geração de JWT com metadata personalizável
- ✅ Validação automática de tokens
- ✅ Estados: user, isAuthenticating, error
- ✅ Métodos: generateToken, authenticateUser

### usePrivateRooms
- ✅ Criação de salas privadas com allowedUserIds
- ✅ Verificação de acesso por token JWT
- ✅ Estados: privateRooms, loading, error
- ✅ Métodos: createPrivateRoom, joinPrivateRoom, checkAccess

### useChannelSubscription
- ✅ Subscription automática de canais
- ✅ Buffer de mensagens com histórico
- ✅ Estados: messages, loading, error, lastMessage
- ✅ Callbacks configuráveis para mensagens

### useMultiChannelSubscription 🆕
- ✅ Subscription em múltiplos canais simultaneamente
- ✅ Mensagens organizadas por canal + timeline global
- ✅ Gerenciamento dinâmico de canais (subscribe/unsubscribe)
- ✅ Estados: messagesByChannel, allMessages, subscribedChannels
- ✅ Métodos: subscribeToChannel, unsubscribeFromChannel, getChannelMessages, clearChannelMessages

## 🌐 Compatibilidade

- ✅ ESM (import/export moderno)
- ✅ CommonJS (require tradicional) 
- ✅ TypeScript (types completos)
- ✅ React 17+ (peer dependency)
- ✅ Socket.io-client 4.7+ (dependency)

## 🚦 Status dos Serviços

**Server Principal**: ✅ Rodando em localhost:3001
**Demo App1**: ✅ Rodando em localhost:3001 (com biblioteca integrada)

## 📈 Próximos Passos

1. **Publicação NPM Oficial**:
   ```bash
   npm login
   npm publish --access public
   ```

2. **Testes Automatizados**:
   ```bash
   npm test  # Implementar testes com Vitest
   ```

3. **CI/CD Pipeline**:
   - GitHub Actions para build e publicação automática
   - Semantic versioning com conventional commits

4. **Documentação Completa**:
   - Storybook para componentes
   - Docs site com exemplos interativos

## 📚 API Reference - useMultiChannelSubscription

### Parâmetros

```tsx
function useMultiChannelSubscription(
  channels: string[],                          // Array de canais para subscribe
  options: MultiChannelSubscriptionOptions,   // Opções de configuração
  socket?: Socket | null                       // Instância do socket
): MultiChannelSubscriptionHook
```

### Options (MultiChannelSubscriptionOptions)

```tsx
interface MultiChannelSubscriptionOptions {
  enabled?: boolean                            // Habilita/desabilita subscription (default: true)
  onMessage?: (message: any) => void          // Callback para qualquer mensagem
  onChannelMessage?: (channel: string, message: any) => void  // Callback por canal
}
```

### Retorno (MultiChannelSubscriptionHook)

```tsx
interface MultiChannelSubscriptionHook {
  // Estados
  messagesByChannel: Record<string, any[]>     // Mensagens organizadas por canal
  allMessages: any[]                           // Timeline global ordenada por timestamp
  loading: boolean                             // Status de carregamento
  error: Error | null                          // Erro se houver
  lastMessage: any | null                      // Última mensagem recebida
  subscribedChannels: string[]                 // Lista de canais ativos

  // Métodos
  subscribeToChannel: (channel: string) => void       // Adicionar canal
  unsubscribeFromChannel: (channel: string) => void   // Remover canal
  getChannelMessages: (channel: string) => any[]      // Buscar mensagens de um canal
  clearChannelMessages: (channel?: string) => void    // Limpar mensagens
}
```

### Exemplos de Uso da API

```tsx
const multiChannel = useMultiChannelSubscription(
  ['order:123:chat', 'order:456:chat'],
  {
    enabled: authenticated,
    onMessage: (msg) => console.log('Nova mensagem:', msg),
    onChannelMessage: (channel, msg) => {
      console.log(`Canal ${channel}:`, msg)
      // Exemplo: Mostrar notificação específica
      showNotification(channel, msg.content)
    }
  },
  socket
)

// Acessar mensagens por canal
const pedido123Messages = multiChannel.getChannelMessages('order:123:chat')
const pedido456Messages = multiChannel.getChannelMessages('order:456:chat')

// Timeline global (todas as mensagens ordenadas)
const timelineMessages = multiChannel.allMessages

// Controle dinâmico
multiChannel.subscribeToChannel('order:789:chat')    // Adicionar novo pedido
multiChannel.unsubscribeFromChannel('order:123:chat') // Remover pedido finalizado

// Limpeza
multiChannel.clearChannelMessages('order:123:chat')  // Limpar um canal específico
multiChannel.clearChannelMessages()                  // Limpar todos os canais

// Estados úteis
const totalChannels = multiChannel.subscribedChannels.length
const totalMessages = multiChannel.allMessages.length
const isLoading = multiChannel.loading
const hasError = multiChannel.error
```

## 📝 Changelog

### v1.2.0 🆕
- ✨ **NOVO**: Hook `useMultiChannelSubscription` para múltiplos canais
- 🔄 Subscription simultânea em vários canais
- 📊 Timeline global + mensagens por canal
- 🎛️ Controle dinâmico: subscribe/unsubscribe em runtime
- 🧹 Limpeza seletiva de mensagens por canal
- 📱 Ideal para apps com múltiplos chats/pedidos

### v1.1.0 (Breaking Changes)
- 🚨 **BREAKING**: Mudança de autenticação de API Key
  - **ANTES**: `Authorization: Bearer {apiKey}`
  - **AGORA**: `x-api-key: {apiKey}`
- 🔄 Hooks atualizados: `useJWTAuth`, `usePrivateRooms`
- 🛡️ Separação clara: `x-api-key` para projetos, `Authorization: Bearer` para JWT
- ✅ Compatível com server-principal v1.1.0+

### v1.0.0
- 🎉 Versão inicial com API_KEY authentication
- 🔌 WebSocket connection com namespaces
- 🔐 JWT authentication
- 🏠 Private rooms com controle de acesso