npm package: @jfuente/widget-core
Description: Lógica del widget de IA embebible, independiente de framework
Latest version: 1.0.0

# @jfuente/widget-core

Nucleo del asistente en vanilla TypeScript. No tiene dependencias de React ni Angular — los wrappers de framework lo consumen por encima.

---

## Instalacion

```bash
npm install @jfuente/widget-core
```

---

## Clase principal: `AsistenteWidget`

```typescript
import { AsistenteWidget } from '@jfuente/widget-core';

const widget = new AsistenteWidget(config: ConfigWidget);
```

### Metodos

| Metodo | Descripcion |
|--------|-------------|
| `montar()` | Inyecta el FAB y el panel de chat en el DOM |
| `desmontar()` | Elimina todos los elementos del DOM creados por el widget |
| `actualizarContexto(contexto: Partial<ContextoWidget>)` | Actualiza el contexto sin reinicializar el widget |
| `actualizarAcciones(acciones: AccionesWidget)` | Agrega o reemplaza acciones disponibles |

---

## Tipos

### `ConfigWidget`

Configuracion inicial del widget.

```typescript
interface ConfigWidget {
  apiUrl: string;           // URL base del backend (sin /chat)
  token: string;            // JWT del usuario autenticado
  contexto?: ContextoWidget;
  acciones?: AccionesWidget;
  tema?: TemaWidget;
  posicion?: 'bottom-right' | 'bottom-left';  // default: 'bottom-right'
}
```

### `ContextoWidget`

Describe la pantalla activa y los datos disponibles para el asistente.

```typescript
interface ContextoWidget {
  pantalla: string;                    // nombre de la ruta o vista activa
  descripcion?: string;                // descripcion legible de la pantalla
  datos?: Record<string, unknown>;     // datos relevantes del contexto actual
}
```

**Ejemplo:**
```typescript
{
  pantalla: 'detalle-factura',
  descripcion: 'Vista de detalle de una factura electronica',
  datos: {
    facturaId: 'FE-2026-001',
    estado: 'pendiente',
    valor: 850000,
    cliente: 'Empresa XYZ',
    vencimiento: '2026-04-01',
  }
}
```

### `AccionesWidget`

Mapa de funciones que el asistente puede invocar en el producto host.

```typescript
interface AccionesWidget {
  [nombre: string]: (...args: unknown[]) => void;
}
```

**Como funciona:** el backend puede incluir en su respuesta `[ACCION:nombre:arg1,arg2]`.
El widget lo detecta, ejecuta la funcion registrada y elimina la etiqueta del texto mostrado al usuario.

**Ejemplo:**
```typescript
{
  'crear-factura':      () => navigate('/facturas/nueva'),
  'filtrar-estado':     (estado) => setFiltro({ estado }),
  'abrir-cliente':      (id) => openDrawer('cliente', id),
  'exportar-reporte':   () => descargarExcel(),
}
```

### `TemaWidget`

Personalizacion visual del widget.

```typescript
interface TemaWidget {
  colorPrimario?: string;   // color del FAB, header y burbujas del usuario (default: '#4A90D9')
  colorFondo?: string;      // fondo del panel (default: '#ffffff')
  colorTexto?: string;      // color del texto principal (default: '#1a1a1a')
  borderRadius?: string;    // radio del panel (default: '12px')
  fuente?: string;          // font-family (default: 'inherit')
}
```

### `Mensaje`

Estructura de un mensaje en el historial.

```typescript
interface Mensaje {
  id: string;
  rol: 'user' | 'assistant';
  contenido: string;
  fecha: Date;
}
```

### `ChatRequest` / `ChatResponse`

Contrato entre el widget y el backend.

```typescript
interface ChatRequest {
  pregunta: string;
  contexto: ContextoWidget;
  historial: Array<{ rol: string; contenido: string }>;
  token: string;
}

interface ChatResponse {
  respuesta: string;
  accion?: {
    nombre: string;
    args?: unknown[];
  };
}
```

---

## Uso directo (sin framework)

```typescript
import { AsistenteWidget } from '@jfuente/widget-core';

const widget = new AsistenteWidget({
  apiUrl: 'https://mi-backend.com',
  token: localStorage.getItem('token'),
  contexto: {
    pantalla: 'dashboard',
    datos: { empresa: 'Mi Empresa SAS' },
  },
  acciones: {
    'ir-facturas': () => window.location.href = '/facturas',
  },
  tema: {
    colorPrimario: '#7B2D8B',
  },
});

widget.montar();

// Al navegar:
widget.actualizarContexto({ pantalla: 'nomina', datos: { periodo: 'marzo-2026' } });

// Al destruir la pagina:
widget.desmontar();
```

---

## Estructura de archivos

```
src/
├── index.ts      # exports publicos
├── types.ts      # todas las interfaces
├── widget.ts     # clase AsistenteWidget
└── ui.ts         # funciones de render del DOM (FAB, panel, mensajes)
```